100% found this document useful (1 vote)
121 views642 pages

Z-80 Assembly Language Programming 1979 Leventhal Text

Uploaded by

linux cernel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
121 views642 pages

Z-80 Assembly Language Programming 1979 Leventhal Text

Uploaded by

linux cernel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 642

OSBOaNr f/cGRAW HILL

«i

V !
280 ASSEMBLY LANGUAGE PROGRAMMING
BY LANCE A. LEVENTHAL

'.
Z80
flss€mBLv innGUfiGC
PROGRflmnimG
Z80
ASSCmfiLV LllflGUflG€
pROGRflmmiriG

Lofice n. Leventhol

Osborne/McGraw-Hill
Berkeley, California
,

Published by
OSBORNE/McGraw-Hill
630 Bancroft Way
Berkeley, California 9471
U.S. A

For information on translations and book distributors outside of the U. S. A.


please contact the publisher at the above address.

5 6 7 8 9 DODO 8 7 6 5 4 3 2

ISBN 0-931988-21-7
Copyright © 1979 by McGraw-Hill Inc.

the United States of America. No part of this


All rights reserved. Printed in
publication may be reproduced, stored in any retrieval system, or transmitted
in any form or by any means, electronic, mechanical, photocopying, recording

or otherwise, without the prior written permission of the publishers.

Cover design by K, L T. van Genderen.


This book is dedicated to my colleagues at the Society for Computer Simula-
tion — Romeo Favreau. Natalie Fowler, Alexander McKenna, John McLeod.
Stanley Rogers, and Chip Stockton.

ACKNOWLEDGMENTS
The author would like to acknowledge the following people:
Mr. Curt Ingraham, Ms. Mary Borchers, and Ms. Janice Enger of Osborne/
McGraw-Hill, who made many corrections and suggestions; Mr. Winthrop
Seville of Sorrento Valley Associates, who provided assistance and exam-
ples; Mr. Tom Littlefield of Littlefield/Smith Associates, who provided
reference material; Ms. Marielle Carter of Sorrento Valley Associates, who
typed some of the material; Mr. Stanley Rogers of the Society for Computer
Simulation, who has continued to suggest improvements in the author's writ-
ing style; and his wife Donna, for her patience and understanding throughout
the writing of this book.

Others who provided assistance and suggestions were Mr. Colin Walsh, Mr.
Gary Hankins, Mr. Romeo Favreau, Mr. David Bulman, Ms, Kati Bulman, Mr.
Robert Turner, Mr. Irv Stafford, Mr. John Burgar, Mr. Ferenc Montvai-Lako.
and Mr. Warren McKenna. Other students and colleagues also helped to keep
the author on the right track.

The author, of course, bears responsibility for any remaining errors, miscon-
ceptions, and misinterpretations.
Contents

Chapter Page
1 Introduction to Assembly Language Programming 1-1
How This Book Has Been Printed 1-1
The Meaning of Instructions 1-1
A Computer Program 1-1
The Programming Problem 1-2
Using Octal or Hexadecimal 1-3
Code Mnemonics
Instruction 1-4
The Assembler Program 1-5
Additional Features of Assemblers 1-6
Disadvantages of Assembly Language 1-6
High-level Languages 1-7
Advantages of High-level Languages 1-7
Disadvantages of High-level Languages 1-8
High-level Languages for Microprocessors 1-9
Which Level Should You Use? 1-10
How About the Future? 1-11
Why This Book? 1-11
References 1-12

2 Assemblers 2-1
Features of Assemblers 2-1
Assembler Instructions 2-1
Labels 2-2
Assembler Operation Codes (Mnemonics) 2-4
Pseudo-operations 2-4
The Data Pseudo-operation 2-5
The Equate (or Define) Pseudo-operation 2-6
The Origin Pseudo-operation 2-7
The Reserve Pseudo-operation 2-7
Linking Pseudo-operations 2-8
Housekeeping Pseudo-operations 2-8
Labels with Pseudo-operations 2-9
Addresses and the Operand Field 2-9
Conditional Assembly 2-11
Macros 2-11
Comments 2-13
Types of Assemblers 2-14
Errors 2-14
Loaders 2-15
References 2-15
Contents (Continued)

Chapter Page

3 The Z80 Assembly Language instruction Set 3-1

CPU Registers and Status Flags 3-2


Z80 Memory Addressmg Modes 3-4
Implied 3-5
Implied Block Transfer with Auto-Jncrement/Decrement 3-7
Implied Stack 3-8
Indexed 3-10
Direct 3-11
Program Relative 3-12
Base Page 3-13
Register Direct 3-14
Immediate 3-15
Abbreviations 3-18
Instruction Mnemonics 3-21
Instruction Object Codes 3-21
Instruction Execution Times 3-21
Status 3-21
Instruction Descriptions 3-43
8080A/Z80 Compatibility 3-164
Zilog Z80 Assembler Conventions 3-170
Assembler Field Structure 3-170
Labels 3-170
Reserved Names 3-170
Pseudo-operations 3- 1 70

Examples 3-171
Labels with Pseudo-operations 3-172
Addresses 3-172
Conditional Assembly 3-174
Macros 3-174
5
1

Contents (Continued)

Chapter
Page
Simple Programs 4.I
General Format of Examples 4-I
Guidelines for Problems 4_2
Program Examples 4.3
Ones Complement 4.3
8-Bit Addition 4,4
Shift Left One Bit 4_6
Mask Off Most Significant Four Bits 4-6
Clear a Memory Location 4.7
Word Disassembly 4-7
Find Larger of Two Numbers 4-9
16-B(t Addition 4.11
Table of Squares 4-12
16-Bit Ones Complement 4-14
Problems 4_15
Twos Complement 4-1
8-Bit Subtraction 4-1
Shift Left Two Bits 4^16
Mask Off Least Significant Four Bits 4-16
Set aMemory Location to Ail Ones 4-16
Word Assembly 4_16
Find Smaller of Two Numbers 4-16
24-Bit Addition 4_16
Sum of Squares 4-17
16-Bit Twos Complement 4-I8

Simple Program Loops 5-1


Examples 5,3
Sum of Data 5.3
16-Btt Sum of Data 5-6
Number of Negative Elements 5-9
Find Maximum 5_1
Justify a Binary Fraction 5-14
Problems 5_17
Checksum of Data 5-17
Sum of 16-Bit Data 5-17
Number of Zero, Positive, and
Negative Numbers 5-18
Find Minimum 5_18
Count 1 Bits 5-18
11

Contents (Continued)

Chapter Page

6 Character-coded Data 6-1

Exampies 6-2
Length Strmg of Characters
of a 6-2
Find First Non-blank Character 6-8
Replace Leading Zeros with Blanks 6-1

Add Even Parity to ASCII Characters 6-13


Pattern Match 6-16
Problems 6-19
Length of a Teletypewriter Message 6-19
Find Last Non-blank Character 6-19
Truncate Decimal String to Integer Form 6-20
Check Even Parity tn ASCI! Characters 6-20
String Companson 6-21

"7-1
7 Code Conversion
Examples 7-1

Hex to ASCII 7-1

Decimal to Seven-Segment 7-3


ASCII to Decimal 7-8
BCD to Binary 7-10
Convert Binary Number to ASCII Stnng 7-1

Problems 7-13
ASCII to Hex 7-13
Seven-Segment to Decimal 7-13
Decimal to ASCI! 7-14
Binary to BCD 7-14
ASCII String to Binary Number 7-14
References 7-15

8 Arithmetic Problems 8-1


Examples 8-1
Multiple-Precision Addition 8-1
Block Move 8-4
Decimal Addition 8-5
8-Bit Binary Multiplication 8-8
8-Bit Binary Division 8-12
Self-Checking Numbers Double and
Double MOD 10 8-17
Problems 8-25
Multiple-Precision Subtraction 8-25
Decimal Subtraction 8-25
8-Bitby 16-Bit Binary Multiplication 8-26
Signed Binary Division 8-26
Self-Checking Numbers Aligned 1. 3. 7 MOD 10 8-27
References 8-28
Contents (Continued)

Chapter Page
9 Tables and Lists 9-1
Examples 9-1
Add Entry to List 9-1
Check an Ordered List 9-5
Remove Element from Queue 9-8
8-Bit Sort 9-10
Using an Ordered Jump Table 9-14
Problems 9-16
Remove an Entry from a List 9-16
Add an Entry to an Ordered List 9-17
Add an Element to a Queue 9-17
16-Bit Sort 9-18
Using a Jump Table with a Key 9-18
References 9-19

10 Subroutines 10-1
Subroutine Documentation 10-2
Examples 10-2
Hex to ASCI! 10-3
Length of a String of Characters 10-6
Add Even Parity to ASCI! Characters 10-9
Pattern Match 10-12
Multiple-Preciston Addition 10-16
Problems 10-19
ASCII to Hex 10-19
Length of an ASCII Message 10-19
Check Even Parity in ASCI! Characters 10-19
String Comparison 10-20
Decimal Subtraction 10-20
References 10-22

11 Input/Output 11-1
Timing Intervals (Delays) 11-8
Delay Routines 11-8
Example 11-9
Delay Program Using Accumulators 11-9
Simple I/O Devices 11-11
The Z80 Parallel Input/Output Circuit (PIO) 11-11
PIO Mode Control 11-15
Configunng the PIO 11-17
Z80 Input/Output Instructions 11-18
Examples 11-22
A Pushbutton Switch 11-22
A Toggle Switch 11-28
A Multiple-Position (Rotary, Selector, or
Thumbwheel) Switch 11-33
A Single LED 11-40
Seven-Segment LED Display 11-43
Coiitants (Contiiiuedl

Chapter Page
It (Cont.) Probtems 11-55
An on-off Pushbutton 1 1-55

Debouncing a Switch in Software 11-55


Control for a Rotary Switch 11-55
Record Switch Positions on Lights 11-56
Count on a Seven-Segment Display 1 1-56

More Complex I/O Devices 11-57


Examples 11-60
An Unencoded Keyboard 11-60
An Encoded Keyboard 11-69
A Digital-to-Analog Converter 11-72
Analog-to-Digital Converter 11-76
A Teletypewriter (TTY) 1 1-81
The Z80 Serial Input/Output Device (StOI 1 1-89
Examples 11-98
Teletypewriter i/0 via a USART 1 1-98

Standard Interfaces 11-103


Problems 11-103
Separating Closures from an Unencoded
Keyboard 11-103
Read a Sentence from an Encoded Keyboard 11 -103
A Variable Amplitude Square Wave Generator 1 1-104

Averaging Analog Readings 11-104


A 30 Character-per-Second Terminal 1 1-104

References 11-105

12 Interrupts 12-1
Z80 System
Interrupt 12-2
Non-Maskable Interrupt 12-3
Z80 Interrupt Modes 12-4
Z80/8080 Interrupt Compatibility 12-5
PIO Interrupts 12-6
Examples 12-8
SIO interrupts 12-10
Interrupt Examples 12-12
A Startup Interrupt 12-12
A Keyboard Interrupt 12-14
A Printer Interrupt 12-17
A Real-Time Clock Interrupt 12-20
A Teletypewriter Interrupt 12-26
More Genera! Service Routines 12-30
Problems 12-31
A Test Interrupt 12-31
A Keyboard Interrupt 12-31
A Printer Interrupt 12-31
A Real-Time Clock interrupt 12-31
A Teletypewriter Interrupt 12-31
References 12-32
Contents (Continued)

Chapter Page
13 Problem Definition and Program Design 13-1
The Tasks of Software Development 13-1
Definition of the Stages 13-3
Problem Definition 13-3
Defining the inputs 13-4
Defining the Outputs 13-4
Processing Section 13-5
Error Handling 13-5
Human Factors 13-6
Examples 13-6
Response to a Switch 13-6
A Switch-Based Memory Loader 13-8
A Verification Terminal 13-11
Review of Problem Definition 13-15
Program Design 13-16
Flowcharting 13-17
Examples 13-19
Response to a Switch 13-19
The Switch-Based Memory Loader 13-20
The Credit-Verification Terminal 13-22
Modular Programming 13-26
Examples 13-28
Response to a Switch 13-28
The Switch-Based Memory Loader 13-28
The Verification Terminal 13-28
Review of Modular Programming 13-30
Structured Programming 13-30
Examples 13-36
Response to a Switch 13-36
The Switch-Based Memory Loader 13-36
The Credit-Verification Terminal 13-38
Review of Structured Programming 13-43
Top-Down Design 13-44
Examples 13-45
Response to a Switch 13-45
The Switch-Based Memory Loader 13-46
The Transaction Terminal 13-47
Review of Top-Down Design 13-49
Review of Problem Definition and Program Design 13-49
References 13-50
Contents (Continued)

Chapter Page

14 Debugging and Testing 14-1


Simple Debugging Toots 14-1
More Advanced Debugging Tools 14-8
Debugging with Checklists 14-10
Looking for Errors 14-11
Debugging Example 1: Decimal to Seven-Segment
Conversion 14-16
Debugging Example 2: Sort Into Decreasing
Order 14-21
Introduction to Testing 14-27
Selecting Test Data 14-28
Testing Example 1 Sort Program
:
14-29
Testing Example 2: Self-Checking Numbers 14-29
Testing Precautions 14-29
Conclusions 14-30
References 14-31

15 Documentation and Redesign 15-1


Self-Documenting Programs 15-1
Comments 15-2
Commenting Example 1; Multiple-Precision
Addition 15-4
Commenting Example 2: Teletypewriter Output 15-5
Flowcharts as Documentation 15-7
Structured Programming Languages as
Documentation 15-7
Memory Maps 15-7
Parameter and Definition Lists 15-8
Library Routines 15-10
Library Examples 15-10
Library Example 1 ; Sum of Data 15-10
Library Example 2; Decimal-to-Seven-Segment
Conversion 15-11
Library Example 3: Decimal Sum 15-12
Total Documentation 15-13
Redesign 15-14
Reorganizing to Use Less Memory 15-15
Major Reorganizations 15-16
References 15-18

16 Sample Projects 16-1


Project #1: A Digital Stopwatch 16-1
Project #2; A Digital Thermometer 16-15
References 16-29

truction Descriptions XV
Index xvii
Chapter 1
INTRODUCTION TO ASSEMBLY
LANGUAGE PHOGRAMMING
This book describes assembly language programming. It assumes that you are
familiar with An Introduction To Microcomputers: Volume 1 Basic Concepts —
(particularly Chapters 6 and 7). This book does not discuss the general features of
computers^ microcomputers, addressing methods, or instruction sets; you should
refer to An Introduction To Microconrouters: Volume 1 for that information.

HOW THIS BOOK HAS BEEM PRINTED


Notice that text in this book has been printed in boldface type and Hghtface type.
This has been done to help you skip those parts of the book that cover subject
matter with which you are familiar. You can be sure that lightface type only ex-
pands on information presented in the previous boldface type. Therefore, only read
boldface type until you reach a subject about which you want to know more, at which
point start reading the lightface type.

THE MEANING OF INSTRUCTIONS


The instruction set of a microprocessor Is the set of binary inputs which produce
defined actions during an instruction cycle. An instruction set is to a microprocessor
what a function table is to a logic device such as a gate, adder, or shift register. Of
course, the actions that the microprocessor performs In response to the instruction in-
puts are far more complex than the actions that combinatorial logic devices perform in
response to their inputs.
An instruction is simply a binary bit pattern it must be — BINARY
available at the data inputs to the microprocessor at the INSTRUCTIONS
proper time in order to be interpreted as an Instruction. For ex-
ample, when the Z80 microprocessor receives the 8-bit binary pattern 10000000 as the
input durmg an instruction fetch operation, the pattern means;
"Add the contents of Register 8 to the contents of the Accumulator".

Similarly, the pattern 0011 11 10 means;


"Load the Accumulator wjth the contents of the next word of program memory".
The microprocessor any other computer) recognizes only binary patterns as in-
(like

structions or data; it does not recognize words or octal, decimal, or hexadecimal num-
bers.

A COMPUTER PROGRAM
A program is a series of instructions that cause a computer to perform a particular
task.

Actually, acomputer program includes more than instructions: ft COMPUTER


also contains the data and memory addresses that the PROGRAM
microprocessor needs to accomplish the task defined by the in-

1-1
structions. Ciearly.if the microprocessor is to perform an addition, it must have two

numbers toadd and a destination for the result. The computer program must determine
the sources of the data and the destination of the result as well as specifying the opera-
tion to be performed.

AN microprocessors execute instructions sequentially unless one of the instructions


changes the execution sequence or halts the computer (i.e.. the processor gets the next
instruction from the next consecutive memory address unless the current instruction
specifically directs it to do otherwise).
Ultimately every program becomes translated Into a set of binary numbers. For
example, this is the Z80 program that adds the contents of memory locations
60fg and 61 ig and places the result in memory location 62ig:
00111010
01100000
00000000
01000111
00111010
01100001
00000000
10000000
00110010
01100010
00000000
This is a machine language, or object, program. If this program OBJECT
were entered into the memory of a Z80-based microcomputer, the PROGRAM
microcomputer would be able to execute it directly.
MACHINE
THE PROGRAMMING PROBLEM LANGUAGE
PROGRAM
There are many difficulties associated with creating programs
as object, or binary machine language, programs. These are
some of the problems:
1) The programs are difficult to understand or debug (binary numbers all took the
same, particularly after you have looked at them for a few hours).
2) The programs are slow to enter since you must enter each bit individually.

3) The programs do not describe the task which you want the computer to perform in
anything resembling a human readable format.
4) The programs are long and tiresome to write.
5) The programmer often makes careless errors that are very difficult to find.

For example, the following version of the addition object program contains a single
bit error. Try to find it:

00111010
01100000
00000000
01000111
01110010
01100001
00000000
10000000
00110010
01100010
00000000

1-2
Although the computer handles binary numbers with ease, people do not. People find
binary programs long, tiresome, confusing, and meaningless. Eventually, a programmer
may start remembering some of the binary codes, but such effort should be spent more
productiyety.

USING OCTAL OR HEXADECIMAL


We can improve the situation somewhat by writing instruc- OCTAL OR
tions using octal or hexadecimal, rather than binary, numbers. HEXADECIMAL
We will use hexadecimal numbers in this book because they are
shorter, and because they are the standard for the microprocessor mdustry. Table 1-1
defines the hexadecimal digits and their binary equivalents. The Z80 program to add
two numbers now becomes:
3A
60
00
47
3A
61
00
80
32
62
00
At the very least the hexadecimal version is shorter to write and not quite so tiring to
examine.

Errors are somewhat easier to find in a sequence of hexadecimal digits. The er-
roneous version of the addition program, in hexadecimal form, becomes:

3A
60
00
47
72
61
00
80
32
62
00
The mistake is easier to spot.

What do we do with this hexadecimal program? The microprocessor understands


only binary instruction codes. The answer is that we must convert the hexadecimal
numbers to binary numbers. This conversion is a repetitive, tiresome task. People who
attempt it make all sorts of petty mistakes, such as looking at the wrong line, dropping a
bit or transposing a bit or a digit

This repetitive, grueling taskis, however, a perfect job for a com- HEXADECIMAL
puter. The computer never gets tired or bored and never makes LOADER
silly mistakes. The idea then is to write a program which takes
*-—---—-—------"
hexadecimal numbers and converts them into binary numbers. This is a standard
program provided with many microprocessors; it is called a "hexadecimal loader."
Isa hexadecimal loader worth having? If you are willing to write a program using binary
numbers, and you are prepared to enter the program In its binary form into the com-
puter, then you will not need the hexadecimal loader.

1-3
!fyou choose the hexadecima! loader, you will have to pay a price for it. The hex-
adecimal loader is itself a program which you must load into memory. Furthermore, the
hexadecimal loader will occupy memory —
memory that you may want to use in some
other way.

The basic tradeoff, therefore, is the cost and memory requirements of the hexadecima!
loader versus the savings in programmer time.
A hexadecimal loader is well worth its small cost.

A hexadecimal loader certamly does not solve every programming problem. The hex-
adecimal version of the program Is stil! difficult to read or understand; for example, it
does not distinguish instructions from data or addresses, nor does the program listing
provide any suggestion as to what the program does. What does 32 or 47 or 3A mean?
Memorizing a card full of codes is hardly an appetizing proposition. Furthermore, the
codes will be entirely different for a different microprocessor, and the program will re-

quire a large amount of documentation.


Table 1-1. Hexadecimal Conversion Table

Hexadecimal Binary Decimal


Digit Equivalent Equivalent

0000
1 0001 1

2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15

INSTRUCTIOM CODE MiMiMONICS


An obvious programming improvement is to assign a name to each Instruction
code. The instruction code name is called a "mnemonic", or memory Jogger. The
instruction mnemonic should describe in some way what the Instruction does.

!n fact,every microprocessor manufacturer (they can't remember PROBLEM


hexadecimal codes either) provides a set of mnemonics for the WITH
microprocessor instruction set. You do not have to abide by the MNEMONICS
manufacturer's mnemonics; there is nothing sacred about them.
However, they are standard for a given microprocessor and therefore understood by all
users. These are the instruction names that you wilt find in manuals, cards, books, arti-
cles, and programs. The problem with selecting instruction mnemonics is that not all in-
structions have "obvious" names. Some instructions do have obvious names {e.g..
ADD. AND, OR), others have obvious contractions (e.g., SUB for subtraction, XOR for
exclusive OR), white still others have neither. The result is such mnemonics as WMP..
PCHL and even SOB {try and guess what that means!). Most manufacturers come up
with mostly reasonable names and a few hopeless ones. However, users who devise
their own mnemonics rarely seem to do much better than the manufacturer.

1-4
Along with the instruction mnemonics, the manufacturer wil! usually assign names to
the CPU registers. As with the instruction names, some register names are obvious (e.g.,
A for Accumulator) while others may have only historical significance. Again, we will
use the manufacturer s suggestions simply to promote standardization.

If we use standard 280 Instruction and register mnemonics, as ASSEMBLY


defined by Zilog, our Z80 addition program becomes: LANGUAGE
LD A.(60Hi
PROGRAM
LD B.A
LD A.(61H)
ADD A.B
LD (62H).A

The program is still from obvious, but at least some parts are comprehensible.
far
ADD A.B is a considerable Improvement over 80: LD does suggest loading data into a
register or memory location. Such a program is an assembly language program.

THE ASSEMBLER PROGRAM


How do we get the assembly language program into the com- HAND
puter? We
have to translate it, either into hexadecimal or into- bin- ASSEMBLY
ary numbers. You can translate an assembly language program
by hand, instruction by instruction. This is called hand assembly.
Hand assembly of the addition program's instruction codes may be illustrated as
follows;

Instruction Name Hexadecimal Equivalent


LD A,(NN) 3A
LD B,A 47
ADD A,B 80
LD (NN),A 32

As in the case of hexadecimal to binary conversion, hand assemblyis a rote task which

is uninteresting, repetitive, and subject


numerous minor errors. Picking the wrong
to
line, transposing digits, omitting Instructions, and misreading the codes are only a few

of the mistakes that you may make. Most microprocessors complicate the task even
further by having instructions with different word lengths. Some instructions are one
word long while others are two or three words long. Some instructions require data m
the second and third words; others require memory addresses, register numbers, or
who knows what?
Assembly is another rote task that we can assign to the ASSEMBLER
microcomputer. The microcomputer never makes any
SOURCE
mistakes when translating codes; it always knows how many
words and what format each instruction requires. The program
PROGRAM
that does this Job Is called an "assembler". The assembler OBJECT
program translates a user program, or "source" program writ- PROGRAM
ten with mnemonics, into a machine language program, or
"object" program, which the microcomputer can execute. The
assembler's input is a source program and its output is an object program.
The tradeoffs we discussed in connection with the hexadecimal loader are mag-
nified in the case of the assembler. Assemblers are more expensive, occupy more
memory, and require more peripherals and execution time than do hexadecimal
loaders. While users may (and often do) write their own loaders, few care to write their
own assemblers.

1-5
Assemblers have their own rules that you must learn to abide by. These include the
use of certain markers (such as spaces, commas, semicolons, or colons) in appropriate
piaces. correct spelling, the proper control information, and perhaps even the correct
placement of names and numbers. These rules typicallv are a minor hindrance that can
be quickly overcome,

ADDITIONAL FEATURES OF ASSEMBLERS


Early assembler programs did little more than translate the mnemonic names of instruc-
tions and registers into their binary equivalents. However, most assemblers now pro-
vide such additional features as:

1) Allowing the user to assign names to memory locations, input and output devices,
and even sequences of instructions.
2) Converting data or addresses from various number systems (e.g., decimal or hex-
adecimal) to binary and converting characters into their ASCI! or EBCDIC binary
codes.
3) Performing some arithmetic as part of the assembly process.
4) Telling the loader program where in memory parts of the program or data should be
placed.

5) Allowing the user to assign areas of memon/ as temporary data storage and to
place fixed data in areas of program memory.
6) Providing the information required to include standard programs from program li-

braries, or programs written at some other time, in the current program.

7) Allowing the user to control the format of the program listing and the input and
output devices employed.

All ofthese features, of course, involve additional cost and memo- CHOOSING
n/.Microcomputers generally have much simpler assemblers than AN
do larger computers, but the tendency always is for the size of as- ASSEMBLER
semblers to increase. You will often have a choice of assemblers.
The important criterion is not how many offbeat features the assembler has, but rather
how convenient it is to work with in normal practice.

DISADVANTAGES OF ASSEMBLY LANGUAGE


The assembler, like the hexadecimal loaderr does not solve all the problems of
programming. One problem Is the tremendous gap between the microcomputer in-
struction set and the tasks which the microcomputer is to perform. Computer in-
structions tend to do things like add the contents of two registers, shift the contents of
the Accumulator one bit or place a new value into the Program Counter. On the other
hand, a user generally wants a microcomputer to do something like check if an analog
reading has exceeded a threshold, look for and react to a particular command from a
teletypewriter, or activate a relay at the proper time. An assembly language program-
mer must translate such tasks into a sequence of simple computer instructions. The
translation can be a difficult, time-consuming job.

Furthermore, if you are programming in assembly language, you must have detailed

knowledge of the particular microcomputer that you are using. You must know
what registers and instructions the microcomputer has. precisely how the instructions
affect the various registers, what addressing methods the computer uses, and a myriad
of other Information. None of this information is relevant to the task which the
microcomputer must ultimately perform. «™„™,»—b»«»-™™=»
assembly language programs are not portable.
In addition, | PORTABILITY |

Each microcomputer has its own assembly language, which


reflects its own architecture. An assembly language program wntten for the Z80 will

1-6
not run on the Motorola 6800. the Fairchiid F8. or the National Semiconductor PACE,
For exannple, the addition program written for the Motorola 6800 would be:

LDAA $60
ADDA $61
STAA $62
The lack of portabiiitv not oniy means that you won't be able to use your assembly
language program on another microcomputer, but it also means that you won't be able
to use any programs that weren't specificaMy written for the microcomputer you are
using. This is a particular drawback for microcomputers, since these devices are new
and few assembly language programs exist for them. The result, too frequently, is that
you are on your own. If you need a program to perform a particular task, you are not
likely to find it m the small program libraries that most manufacturers provide. Nor are

you likely to find it in an archive, journal article, or someone's old program file. You will
probably have to write it yourself.

HIGH-LEVEL LANGUAGES
The solution to many of the difficulties associated with as- COMPILE R°|
sembiy language programs is to use, instead, "high-level" or
|
1---— -J ———
"procedure-oriented" languages. Such languages allow you to describe tasks in
forms that are problem oriented rather than computer oriented. Each statement in
a high-level language performs a recognizable function; it will generally corres-
pond to many assembly language instructions. A program called a compiler transl-
ates the high-level language source program into object code or machine language
instructions.

Many different high-level languages exist for different types of I FORTRAN |


tasks. example, you can express what you want the com-
If. for '' ''

puter to do in algebraic notation, you can write your program m FORTRAN (Formula
Translation Language), the oldest and one of the most widely used of the high-level
languages. Now. if you want to add two numbers, you just tell the computer:

SUM =NUMBH-NUMB2
That is a lot simpler (and a lot shorter) than either the equivalent
machine language pro-
gram or the equivalent assembly language program. Other high-level languages in-
clude COBOL (for business applications), PASCAL (another algebraic language). PL/1 (a
combination, of FORTRAN. ALGOL and COBOL), and APL and BASIC (languages that
are popular for time-sharing systems).

ADVANTAGES OF HIGH-LEVEL LANGUAGES


make programs easier and faster to write. A common
Clearly, high-level languages
estimate programmer can write a program about ten times as fast in a
is that a
high-level language as compared to assembly language. That is just wntmg the pro-
gram: It does not include problem definition, program design, debugging, testing, or
documentation, alt of which become simpler and faster. The high-level language pro-
gram is, for instance, partly self-documenting. Even If you do not know FORTRAN, you
probably could tell what the statement illustratedabove does.
High-level languages solve many other problems associ- MACHINE
ated with assembly language programming. The high-level INDEPENDENCE
language has its own syntax (usually defined by a national or OF HIGH-LEVEL
international standard). The language does not mention the in- LANGUAGES
struction set, registers, or other features of a particular com-
puter. The compiler takes care of all such details. Programmers can concentrate on
their
own tasks; they do not need a detailed understanding of the underlying CPU architec-
ture — for that matter, they do not need to know anything about the computer they are
programming.

1-7
Programs written in a high-level language are portable
— PORTABIUTY
at least theory. They will run on any computer or
in OF HIGH-LEVEL
microcomputer that has a standard compiler for that language. LANGUAGES
At the same time, all previous programs written in a high-level
language for prior computers are available to you when programming a new computer.
This can mean thousands of programs in the case of a common language like FORTRAN
or BASIC.

DfSADVAIMTAGES OF HIGH-LEVEL LANGUAGES


Well, if all the good things we have said about high-level languages are true, if you
can write programs faster and make them portable besides, why bother with as-
sembly languages? Who wants to worry about registers, instruction codes,
mnemonics, and all that garbage! As usual, there are disadvantages that balance
the advantages.

One obvious problem Is that you have to learn the "rules" or SYNTAX OF
"syntax" of any high-level language you want to use. A high- HIGH-LEVEL
level language has a fairly complicated set of rules. You witi find LANGUAGES
that it tatces a lot oftime lust to get a program that is syntactically
correct (and even then It probably will not do what you want). A htgh-level computer
language is like a foreign language. If you have a little talent, you will get used to the
rules and be able to turn out programs that the compiler will accept. Stilt, learning the
rules and trying to get the program accepted by the compiler doesn't contribute
directly to doing your job.

Here, for example, are some FORTRAN rules:

• Labels must be numbers placed in the first five card columns


• Statements must start m column seven
• Integer variables must start with the letters L J. K. L, M, or N

Another obvious problem is that you need a compiler to transl- COST OF


ate programs written in a high-level language. Compilers are COMPILERS
expensive and use a large amount of memory. While most assem-
blers occupy 2K to 16K bytes of memory (1K^ 1024), compilers occupy 4K to 64K
bytes. So the amount of overhead involved in using the compiler is rather large.

Furthermore, only some compilers will make the Implementa- ALGEBRAIC


tion of your task simpler. FORTRAN, for example, is well-suited NOTATION
to problems that can be expressed as algebraic formulas. If.
however, your problem is controlling a printer, editing a stnng of characters, or monitor-
ing an alarm system, your problem cannot be easily expressed m algebraic notation. In
fact, formulating the solution in algebraic notation may be more awkward and more
difficult than formulating it in assembly language. One answer is to use a more suitable
high-level language. Some such languages exist, but they are far less widely used and
standardized than FORTRAN. You wilt not get many of the advantages of high-level
languages if you use these so-called system implementation langu ages.

High-level languages do not produce very efficient INEFFICIENCY


machine language programs. The basic reason for this is that OF HIGH-LEVEL
compilation is an automatic process which is riddled with com- LANGUAGES
promises to allow for many ranges of possibilities. The com-
piler works much like a computerized language translator sometimes the words are —
right but the sounds and sentence structures are awkward. A simple compiler cannot
know when a variable is no longer being used and can be discarded, or when a register
should be used rather than a memory location, or when variables have simple relation-
ships. The experienced programmer can take advantage of shortcuts to shorten execu-

1-8
tion time or reduce memory usage. A few compilers (known as optimizing compilers)
can also do this, but such compilers are much larger and slower than regular compilers.

The general advantages and disadvantages of high-ievei languages ar6:

Advantages:
• More convenient descriptions of tasks ADVANTAGES
• More efficient program coding OF
• Easier documentation HIGH-LEVEL
• Standard syntax
LANGUAGES
• Independence of the structure of a particular computer
• Portability

• Availability of library and other programs


Disadvantages:
• Special rules DISADVANTAGES
• Extensive hardware and software support required OF
• Orientation of common languages to algebraic or business HIGH-LEVEL
problems LANGUAGES
• Inefficient programs
• Difficulty of optimizing code to meet time and memory requirements
• Inability to use special features of a computer conveniently

HIGH-LEVEL LANGUAGES FOR MICROPROCESSORS


Microprocessor users will encounter several special difficulties when using high-
level languages. Among these are:

• Few high-level languages exist for microprocessors


• No standard languages are widely available
• Few compilers actually run on microcomputers. Those that do often require very large
amounts of memory-
• Most microprocessor applications are not well-suited to high-level languages.
• Memory costs are often critical in microprocessor applications.
The lack of high-level languages is partly a result of the fact that microprocessors are
quite new and are the products of semiconductor manufacturers rather than computer
manufacturers.

Very few high-level languages' exist for microprocessors. The most common are the
PL/1 type languages (such as Intel's PL/M, Motorola's MPL. and Signetics* PlfiS),
BASIC, and PASCAL

Even the few high-level languages that exist do not conform to recognized standards,
so the microprocessor user cannot expect to gain much program portability, access to
program libraries, or use of previous experience or programs. The main advantages re-
maining are the reduction in programming effort and the smaller amount of detailed
understanding of the computer architecture that is necessary.

The overhead involved In using a high-level language with OVERHEAD


microprocessors considerable. Microprocessors themselves are
is FOR
better suited to control and slow interactive applications than they HIQH-LEVEL
are to the character manipulation and language analysis involved LANGUAGES
in compilation. Therefore, most compilers for microprocessors will
not run on a microprocessor-based system. Instead, they require a much larger com-
puter, i.e.. they are cross-compilers rather than self-compilers. A user must nof only

1-9
bear the expense of the larger computer but must also phYsicaily transfer the program
from the larger computer to the micro.

A few self-compilers are avaiiable. These compilers run on the microcomputer for
which they produce object code. Unfortunately, they require targe amounts of memory
(16K or more), plus special supporting hardware and software.

High-level languages also are not generally welt-suited to UNSUITABIUTY


microprocessor applications. Most of the common languages OF HIGH-LEVEL
were devised either to help solve scientific problems or to han- LANGUAGES
dle large-scale business data processing. Few microprocessor
applications fall in either of these areas. Most microprocessor applications involve send-
ing data and control information to output devices and receiving data and status infor-
mation from input devices. Often the control and status information consists of a few
binary digits with very precise hardware-related meanings. If you try to write a typical
control program in a high-level language, you often feel like someone who is trying to
eat soup with chopsticks. For tasks in such areas as test equipment terminals, naviga-
tion systems, signal processing, and business equipment the high-level languages
work much better than they do in instrumentation, communications, peripherals, and
automotive applications.

Applications better suited to high-level languages are those which APPLICATION


require large memories. If, as in a valve controller, electronic game, AREAS FOR
appliance controller, or small instrument the cost of a single LANGUAGE
memory chip important then the inefficiency of high-level
is LEVELS
languages is intolerable. !f, on the other hand, as in a terminal or
test equipment, the system has many thousands of bytes of memory anyway, the ineffi-
ciency of high-level languages is not as important Clearly the size of the program and
the volume of the product are important factors as well. A large program wilt greatly in-
crease the advantages of high-level languages. On the other hand, a high-volume ap-
plication will mean that fixed software development costs are not as important as
memory costs that are part of each system.

WHICH LEVEL SHOULD YOU USE?


That depends on your particular application. Let us briefly note some of the factors
which may favor particular levels:

Machine Language:
APPLICATIONS
• Virtually no one programs in machine language. Its use can-
FOR MACHINE
not be justified considering the low cost of an assembler and
LANGUAGE
the increase in programming speed an assembler provides.
Assembly Language:
« Short to moderate sized programs APPLICATIONS
• Applications where memory cost is a factor
FOR ASSEMBLY
LANGUAGE
• Real-time control applications
• Limited data processing
• High-volume applications
• More input/output or control than computation

High-Level Languages:
• Long programs APPLICATIONS
• Low-volume applications requiring long programs
FOR HIGH-LEVEL
LANGUAGE
• Applications requiring large memories

1-10
More computation than input/output or control
• Compatibility with similar applications using larger computers
• Availability of specific programs in a high-level language which can be used in
the application
Many other factors are also important, such as the avaiiabiltty of a larger computer for
use in development experience with particular languages, and compatibility with other
applications.

If hardware will ultimately be the largest


cost in your appiicatloa or if speed is critical
you should favor assembly language. But be prepared to spend extra time In software
development in exchange for lower memory costs and higher execution speeds. If soft-
ware will be the largest cost in your application, you should favor a high-level language.
But be prepared to spend the extra money required for the supporting hardware and
software.

Of course, no one except some theorists will object if you use both assembly and high-
level languages. You can write the program originally in a high-level
language and then
patch some sections In assembly language. However, most users prefer not to do this
because of the havoc it creates in debugging, testing, and documentation.

HOW ABOUT THE FUTURE?


We expect that the future will tend to favor high-level languages for the following
reasons:

• Programs always seem to add extra features and grow larger FUTURE TRENDS
• Hardware and memory are becoming less expensive IN LANGUAGE
• Software and programmers are becoming more expensive LEVELS
• Memory chips are becoming available m larger sizes, at lower
"per bit" cost so actual savings in chips are less likely
• More compilers are becoming available
• More suitable and more efficient high-level languages are being developed
• More standardization of high-level languages will occur
Assembly language programming of microprocessors will not be a dying art any more
than it is now for large computers. But longer programs, cheaper memory, and more ex-
pensive programmers will make software costs a larger part of most applications. The
edge in many applications will therefore go to high-level languages.

WHY THIS BOOK?


If the future would seem to favor high-level languages, why have a book on as-
sembly language programming? The reasons are:
1) Most current microcomputer users program in assembly language (almost two-
thirds, according to one recent survey).

2) Many microcomputer users will continue to program in assembly language since


they need the detailed control that It provides.
3) No suitable high-level language has yet become widely available or standardized.
4) Many applications require the efficiency of assembly language.
5) An understanding of assembly language can help in evaluating high-level
languages.

The rest of this book will deal exclusively with assemblers and assembly language pro-
gramming. However, we do want readers to know that assembly language is not the
only alternative. You should watch for new developments that may significantly reduce
programming costs if such costs are a major factor in your application.

1-11
REFERENCES
Some overaH comparisons of the time required to write various types of programs at
different language levels are in M.H. HaJstead. Elements of Software Science American
,

Elsevier. New York, 1 977 and In V. Schneider. "Prediction of Software Effort and
Project

Duration - Four New Formulas" SIGPLAN Notices June 1978. pp. 49-55.
.

1-12
Chapter 2
ASSEMBLERS
This chapter discusses the functions performed by assemblers, beginning with features
common to most assemblers, and proceeding through more elaborate capabilities such
asmacros and conditional assembly. You may wish to skim this chapter for the present
and return to it when you feel more comfortable with the material.

FEATURES OF ASSEMBLERS
As we mentioned previously, today's assemblers do much more than translate as-
sembly language mnemonics into binary codes. But we will first describe how an
assembler handles the translation of mnemonics before describing additional as-
sembler features. Finally, we will explain how assemblers are used.

ASSEMBLER INSTRUCTIONS
Assembly language instructions (or "statements") are divided ASSEMBLY
Into a number of fields, as shown in Table 2-1. LANGUAGE
The operation code field is the only field which can never be FIELDS
empty; it always contains either an instruction mnemonic or a
directive to the assembler, called a pseudo-instruction, pseudo-operation, or
pseudo-op.
The address field may contain an address or data, or it may be blank.

Table 2-1. The Fields of an Assembly Language instruction

Operation Operand
Label Code or or
Field Mnemonic Address
Comment Field

Field Field

START: LD A.(VAL1) LOAD FIRST NUMBER INTO A


LD B,A SAVE IN B
LD A,(VAL2) LOAD SECOND NUMBER INTO A
ADD A.B ADD FIRST NUMBER TO A
LD (SUM),A STORE SUM
NEXT: ? ? NEXT INSTRUCTION

VAL1: DEFS 1

VAL2: DEFS 1

SUM: DEFS 1

The comment and label fields are optional. A programmer will assign a label to a
statement or add a comment as a personal convenience, e.g., to make the program
easier to code and read.

2-1
Of course, the assembler must have some way of telling I
FORMAT |
where one field ends and another begins. Assemblers that use
ThiS ts
punched card input often require that each field start in a specific card column.
a fixedformat However, fixed formats may be inconvenient when the input medium is
paper tape; fixed formats are also a nuisance to programmers. The alternative
is a free

format where the fields may appear anywhere on the line.


, ^.„«„.«»«.™^»««

Ifthe assembler cannot use the position in the line to tell the fields [
DELIMITERS
apart it must use something else. Most assemblers use a
special symbol or delimiter at the beginning or end of each field. The
most obvious
delimiter is the space character. Commas, periods, semicolons, colons, slashes, ques-
tion marks and other characters that would not othenA/lse
be used in assembly
language programs also may serve as delimiters. Table 2-2 lists standard Zilog
Z80 as-
sembler delimiters.
Table 2-2. Standard Z80 Assembler Delimiters

: after a label
'space' between operation code and address
, between operands in the address field
; before a comment

will have to exercise a little care with delimiters. Some assemblers


are fussy
You
about extra spaces or the appearance of delimiters in comments or labels. A well-
written assembler will handle these minor problems, but many assemblers are
not
well-written. Our recommendation Is simple: avoid potential problems if you can.
The following rules will help:

1) Do not use extra spaces, particularly after commas that separate operands.

2) Do not use delimiter characters in names or labels.

Include standard delimiters even if your assembler does not require them.
Your pro-
3)

grams will then be assembled by any assembler.

LABELS
The label field is the first field in an assembly language in- LABEL
structlon: it may be blank. If a label is present, the assembler FIELD
assigns to the label the value of the address for the memory loca-
tion mto which the first object program byte for that instruction ts loaded.
You may
subsequently use the label as data or as an address in another instruction's operand
field. The assembler will replace the label with the assigned value when
creating an ob-

ject program.

Labels are most frequently used In Jump, Call or Branch in- LABELS
structions. These instructions place a new value m the Program IN JUMP
Counter and so alter the normal sequential execution of mstruc- INSTRUCTIONS
tions. JUMP 150] 6 means "place the value 150i6 into the Pro-
gram Counter". The next instruction to be executed will be the one in memory location
150^6. The instruction JUMP START means "place the value assigned to the label
START into the Program Counter" The next Instruction to be executed will be the one
in the memory location to which the label START has been assigned. Table
2-3 contains
an example.

2-2
Table 2-3. Assigning and Using a Label

ASSEMBLY LANGUAGE PROGRAM


START LOAD ACCUMULATOR 100

{MAIN PROGRAM)

JUMP START
When the machine language version of this program is executed, the instruction JUMP
START causes the address of the instruction labeled START to be placed into the Pro-
gram Counter. The instruction with the label START will be executed next
Why use a label? Here are some reasons:
11 A label makes a program location easier to find and remember.
2) The can be moved to change or correct a program. You do not have to change
label
any subsequent instructions that use the label; the assembler will make all the
necessary changes.
3) The assembler or loader can relocate the whole program by RELOCATION
adding a constant (a relocation constant) to each address in CONSTANT
which a label was used. Thus we can move the program to
allow for the insertion of other programs or simply to rearrange memory.
4) The program is easier to use as a library program, i.e., it is easier for someone else to
take your program and add it to some totally different program.
5) You do not have to figure out memory addresses. Figuring out memory addresses is
particularly difficult with microprocessors which have instructions that vary In
length.

It makes sense to assign a label to any instruction that you might want to use as a
destination or otherwise identify.

The next question is what label to use. The assembler often CHOOSING
places some restrictions on the number of characters {usually 5 LABELS
or 6), the leading character (often must be a letter), and the trailing
characters (often must be letters, numbers, or one of a few special characters). Beyond
these restrictions, the choice is up to you.

Our own preference is to use labels that suggest their purpose, ue.. mnemonic labels.
Typical examples are ADDW in a routine that adds one word into a sum, SRETX in a
routine that searches for the ASCII character ETX, or NKEYS for a location in data
memory that contains the number of key entries. Meaningful labels are easier to
remember and contribute to program documentation. Some programmers prefer to use
a standard format for labels, such as starting with LOOOO. These labels are self-sequenc-
ing (you can skip a few numbers to permit Insertions), but they do not help document
the program.

Some label selection rules will keep you out of trouble. We RULES OF
recommend the following: LABELING
1) Do not use labels that are the same as operation codes or
other mnemonics. Most assemblers will not allow this usage; others will, but it is
very confusing.

2-3
2) Do not use labels that are longer than the assembler permits. Assemblers have
various truncation rules.
3) Avoid special characters (non-alphabettc and non-numertc) and iower-case letters.
Some assemblers will not permit them; others allow only certain ones. The simplest
practice is to stick to capital letters and numbers.

4) Start each label with a letter. Such labels are always acceptable.

5) not use labels that could be confused with each other. Avoid the letters
Do and I.

Z and the numbers 0, 1 and 2. Also avoid things like XXXX and XXXXX. There^s no
sense tempting fate and Murphy's laws.
6) When you are not sure if a label is legal, do not use it You will not get any real

benefit from discovering exactly what the assembler will accept.

These are recommendations, not rules. You do not have to follow them, but don't blame
us If you waste time on silly problems.

ASSEMBLER OPERATION CODES (MNEMONICS)


The main task of the assembler Is the translation of mnemonic operation codes
into their binary equivalents. The assembler performs this task using a fixed table

much as you would if you were doing the assembly by hand.

The assembler must, however, do more than |ust translate the operation codes. It must
also somehow determine how many operands the instruction requires and what
type they are. This may be rather complex —some instructions (like a Halt) have no
operands, others (like an Addition or a Jump instruction) have one, while stilt others
(like a transfer between registers or a multiple-bit shift) require two. Some instructions

may even allow alternatives, e.g., some computers have instructions (like Shift or Clear)

that can apply either to the Accumulator or to a memory location. We will not discuss
how the assembler makes these distinctions; we will just note that it must do so.

PSEUDO-OPERATIONS
Some assembly language instructions are not directly transl- PSEUDO-
ated Into machine language instructions. These instructions OPERATIONS
are directives to the assembler they assign the program to cer-
;
ASSEMBLER
tain areas m memory, define symbols, designate areas of RAM for
DIRECTIVE
temporary data storage, place tables or other fixed data in memo-
ry, allow references to other programs, and perform minor house-

keeping functions.

To use these assembler directives, or pseudo-operations, a programmer places the


pseudo-operation's mnemonic in the operation code field and, if the specified pseudo-
operation requires tt, an address or data in the address field.

The most common pseudo-operations are:

DATA
EQUATE or DEFINE
ORIGIN
RESERVE
Linking pseudo-operattons are:
ENTRY
EXTERNAL

2-4
Different assembiers use different names for these operations, but the purposes are the
same. Housekeeping pseudo-operations include:

END
LIST
NAME
PAGE
SPACE
TITLE
We will discuss these pseudo-operations briefly, although their functions are usually
obvious.

THE DATA PSEUDO-OPERATION


The DATA pseudo-operation allows the programmer to enter fixed data into
memory. This data may include:
• Lookup tables
• Code conversion tables
• Messages
• Synchronization patterns
• Thresholds
• Names
• Coefficients for equations
• Commands
• Conversion factors
• Weighting factors
• Characteristic times or frequencies
• Subroutine addresses
• Key identifications
• Test patterns
• Character generation patterns
• identification patterns
• Tax tables
• Standard forms
• Masking patterns
• State transition tables

The DATA pseudo-operation treats the data as a permanent part of the program.

The format of a DATA pseudo-operation is usually quite simple. An instruction


like:

DZCON DATA 12
will place the number 12 in the next available memory location and assign that
location the name DZCON. Usually every DATA pseudo-operation has a label, unless it
IS one of a series of DATA pseudo-operations. The data and label may take any form
that the assembler permits.

Most assemblers allow more elaborate DATA instructions that handle a large amount of
data at one time, e.g.;

EMESS DATA 'ERROR'


SQRS DATA 1,4.9.16,25

2-5
A single instruction fill many words of program memory, limited
may only by the length

of a line. Note thatyou cannot get all the data on one line, you can always follow one
if

DATA instruction with another, e.g..


'

MESSG DATA 'NOW IS THE


'

DATA TIME FOR ALL


'GOOD MEN
'

DATA '

DATA 'TO COME TO THE


'

DATA 'AID OF THEIR


DATA 'COUNTRY'

Microprocessor assemblers typically have some variations of standard DATA


pseudo-operations. DEFINE BYTE or FORM CONSTANT BYTE handles 8-bit numbers;
DEFINE WORD or FORM CONSTANT WORD handles 16-bit numbers or addresses.
Other special pseudo-operations may handle character-coded data.

THE EQUATE (or DEFINE) PSEUDO-OPERATION


The EQUATE pseudo-operation allows the programmer to DEFINING
equate labels and names with addresses or data. This pseudo- NAMES
operation Is almost alw^ays given the mnemonic EQU. The
names may refer to device addresses, numeric data, starting addresses, fixed ad-
dresses, etc.

The EQUATE pseudo-operation assigns the numeric value in its operand field to

the label in its label field. Here are two examples:

TTY EQU 5
LAST EQU 5000

Most assemblers will allow you to define one label in terms of another, e.g.;

LAST EQU FINAL


ST1 EQU START+1
The label in the operand field must, of course, have been previously defined. Often,
the

operand field may contain more complex expressions, as we shall see later Double
name assignments (two names for the same data or address) may be useful m patching
together programs which use different names for the same variable (or different spell-
ings of what was supposed to be the same name).

Note that an EQU pseudo-operation does not cause the as- SYMBOL
sembler to place anything Into memory. The assembler simply I
TABLE
enters an additional name into a table (called a symbol table)
which the assembler maintains. This table, unlike the mnemonic table, must be in
RAM since it varies with each program. The assembler program will always need some
RAM to hold the symbol table; the more RAM it has, the more symbols it can accept
This RAM is In addition to any which the assembler needs as temporary storage.

When do you use a name? The answer is; whenever you have a USE OF
parameter that has some meaning besides its ordinary numeric NAMES
value, or the numeric value of the parameter might be changed.
We typically assign names to time constants, device addresses, masking patterns, con-
version factors, and the like. A name like DELAY, TTY, KBD. NROW, or OPEN not only
makes the parameter easier to change, but it also adds to program documentation. We
also assign names to memory locations that have special purposes; they may hold data,
mark the start of the program, or be available for intermediate storage.

What name do you use? The best rules are much the same as CHOICE
Inthe case of labels, except that here meaningful names really OF
count Why not call the teletypewriter TTY instead of XI 5, a bit NAMES
time delay BTIME or BTDLY rather than WW, the number of the

2-6
"GO" key on a keyboard GOKEY rather than HORSE? This advice seems straightfor-
ward, but a surprising nunnber of progrannmers do not follow it

Where do you place the EQUATE pseudo-operations? The PLACEMENT


best place is at the start of the program, under appropriate OF
comment headings such as I/O ADDRESSES. TEMPORARY DEFINITIONS
STORAGE, TIME CONSTANTS, or PROGRAM LOCATIONS. This
makes the definitions easy to find if you want to change them. Furthermore, another
user will be able to look upall the definitions in one centralized place. Clearly this prac-
tice improves documentation and makes the program easier to use.

Definitions used only in a specific subroutine should appear at the start of the
subroutine.

THE ORIGIN PSEUDO-OPERATION


The ORIGIN pseudo-operation (almost always abbreviated ORG) allows the pro-
grammer to locate programs, subroutines, or data anywhere in memory. Programs
and data may be located in different areas of memory depending on the memory con-
figuration. Startup routines, interrupt service routines, and other required programs
may be scattered around memory at fixed or convenient addresses.
The assembler maintains a Location Counter (comparable to LOCATION
the computer's Program Counter) which contains the location COUNTER
in memory at which the next byte of object code generated by 1--^— ^—i
the assembler will reside when the program is loaded. An ORG pseudo-operation
causes the assembler to place a new value into the Location Counter, much as a Jump
instruction causes the CPU to place a new value into the Program Counter. The
output
from the assembler must not only contain instructions and data, but must also indicate
to the loader program where m memory it should place the instructions and
data.

Microprocessor programs often contain several ORIGIN statements for the following
purposes:

Reset (startup) address Mam program


Interrupt service addresses Subroutines
Trap addresses Memory addresses for
RAM storage input/output devices
Memon/ stack or special functions

Still other ORIGIN statements


may allow room for later insertions, place tables or data in
memory, or assign vacant RAM space for data buffers. Program and data memon/ in
microcomputers may occupy widely scattered addresses to simplify the hardware.
Typical ORIGIN statements are:

ORG RESET
ORG 1000
ORG INT3
Some assemblers assume an origin of zero if the programmer does not put an ORG
statement at the start of the program. The convenience is slight; we recommend the in-
clusion of an ORG statement to avoid confusion.

THE RESERVE PSEUDO-OPERATION


The RESERVE pseudo-operation allows the programmer to ALLOCATING
allocate RAM for various purposes such as data tables, tem- RAM
porary storage, indirect addresses, a Stack, etc.

2-7
Using the RESERVE pseudo-operation, you assign a name to the memory area
and
declare the number of locations to be assigned. Here are some examples:
NOKEY RESERVE 1

TEMP RESERVE 50
VOLTG RESERVE 80
BUFR RESERVE 100

You can use the RESERVE pseudo-operation to reserve memory locations in program
memon/ or in data memory: however the nature of the RESERVE pseudo-operation is
more meaningful when applied to data memory.
In reality, all the RESERVE pseudo-operation does is increase the assemblers Location
Counter by the amount declared in the operand field. The assembler does not actually
produce any object code.

Note the following features of RESERVE:


assigned the value of the first ad-
1) The label of the RESERVE pseudo-operation is

dress reserved. For example, the sequence:


ORG 3000
BUFl RESERVE 100
BUF2 RESERVE 50
VOLTS RESERVE 5

assigns to the label BUF1 the value 3000. to BUF2 3100, and to VOLTS 3150.

2) You must specify the number of locations to be reserved. There \s no default case.
3) No data is placed into the reserved locations. Any data that by chance, may be in
these locations will be left there.

Some assemblers allow the programmer to place initial INITIALIZING


values in RAM. We strongly recommend that you do not RAM
use this feature — it assumes that the program (along with
the initial values) will be loaded from an externa! device (e.g., paper tape or floppy disk)

each time it Most microprocessor programs, on the other hand, reside in non-
is run.
volatile ROM and start when power comes on. The RAM m such situations does not re-
tain its contents, nor is it reloaded. Always include instructions to initialize the RAM in
your program.
LURKING PSEUDO-OPERATIONS
We often want statements in one program or subroutine to EXTERNAL
use names that are defined elsewhere. Such names are called REFERENCES
external references; a special linker program is necessary to ac-
tually fill in the external values and determine if any names are undefined or doubly
defined.

The pseudo-operation EXTERNAL, usually abbreviated EXT, signifies that the


name Is defined elsewhere.

The pseudo-operation ENTRY, usually abbreviated ENT, signifies that the name is

available for use elsewhere, i.e., it is defined in this program.

The precise way in which linking pseudo-operations are implemented varies greatly

from assembler to assembler. We will not refer to such pseudo-operations again, but
they are very useful in actual applications.

HOUSEKEEPIIMG PSEUDO-OPERATIONS
There are various housekeeping pseudo-operations, which affect the operation of

2-8
the assembler and program listing rather than the output program
its itself. Com-
mon housekeeping pseudo-operations include:
1) END. which marks the end of the assembly language source program,
2) LIST, which the assembler to print the source program. Some assemblers allow
tells
such variations as NO LIST or LIST SYMBOL TABLE to avoid long, repetitive list-
ings.

3) NAME or TITLE, which prints a name at the top of each page of the listing.
4) PAGE or SPACE, which skips to the next page or next line, respectively, and im-
proves the appearance of the listing, making it easier to read.
5) PUNCH, which transfers subsequent object code to the paper tape punch. This
pseudo-operation may in some cases be the default option and therefore unnecess-
ary.

LABELS WITH PSEUDO-OPERATiONS


Users often wonder if or when they can assign a label to a pseudo-operation.
These are our recommendations:
1) All EQUATE pseudo-operations must have labels; they do not make any sense
otherwise, since their purpose is to define the meaning of the labels.
2) DATA and RESERVE pseudo-operations usually have labels. The label identifies the
first memory location used or assigned.

3) Other pseudo-operations should not have labels. Some assemblers allow


other
pseudo-operations to have labels, but the meaning of the labels varies. We recom-
mend that you avoid this practice.

ADDRESSES AND THE OPERAND FIELD


Most assemblers allow the programmer a lot of freedom In describing the con-
tents of the Operand Address field. But remember, the assembler has built-in
names for registers and Instructions and may have other built-in names
Some common options for the operand field are: DECIMAL
1} Decimal numbers DATA OR
ADDRESSES
Most assemblers assume all numbers to be decimal unless they
aremarked otherwise, So:

ADD 100
means "add the contents of memory location 100 decimal to the contents of the Ac-
cumulator"

2) Other number systems OTHER


Most assemblers will also accept binary, octal or hexadecimal en- NUMBER
tries. But you must identify these number systems m some
way,
SYSTEMS
e.g., by preceding or following the number with an Identifying

character or letter. Here are some common identifiers:

B or % for binary

0, Q, C or @ for octal {we avoid because of the confusion with zero)


H or $ for hexadecimal

D for decimal, D may be omitted: it is the default case.

2-9
Assembiers generaltv require hexadecimal numbers to start with a decima!
digit (e.g..

instead of A36) in order to distinguish between numbers


and names or labels. It is
0A36
good practice to enter numbers in the base in which their
meaning is the clearest —
I.e., decimal constants in decimal:
addresses and BCD numbers m hexadecimal: mask-
in hexadecimal if thev are long.
ing patterns or bit outputs in binan/ if they are short and

3) Symboiic names
the operand field: they wilt be treated as the data that
they repre-
Names can appear in
is a difference between data and addresses.
The se-
sent But remember.there
quence:
FIVE EQU 5
ADD FIVE

will add the contents of memon/ location 5 (not necessarily the number 5) to the con-

tents of the Accumulator.

of the location counter (usually referred to as or $).


*
4) The current value
This is useful mainly in Jump instructions; for example:

JUMP $-h6

causes a Jump to the memory location six words beyond the word that contains the
first byte of the JUMP instruction:

Memory

JUMP $ + 6 code stored here

• Jump here

will have
Most microprocessors have many two and three-word instructions. Thus, you
difficulty determining exactly how far apart two assembly
language statements are.
in errors that you
Therefore, using offsets from the Location Counter frequently results
can avoid if you use labels.

5} Character codes

Most assemblers allow text to be entered as ASCII strings. Such ASCII


stnngs may be surrounded either with single or double quotation CHARACTERS
marks; stnngs may also use a beginning or ending symbol such as
A or C. A few assemblers also permit EBCDIC strings.
We recommend that you use character strings for all text. It improves the cianty and
readability of the program.

6) Combinations of 1) through 5) with arithmetic, logical, or special operators.

Almost all assembiers allow simple anthmetic combinations such ARITHMETIC


as START+1. Some assemblers also permit multiplication, divi- AND LOGICAL
These are referred to as expres-
sion, logical functions, shifts, etc.
EXPRESSIONS
sions. Note that the assembler evaluates expressions at assembly
multiplication, you
time. Even though an expression in the operand field may involve

2-10
may not be able to use muitiplication m the logic of your own program — unless you
write a subroutine for that specific purpose.

Assemblers vary inwhat expressions they accept and how they interpret them. Com-
plex expressions make a program difficult to read and understand.
We have made some recommendations dunng this section but will repeat them and
add others here, in general, the user should emphasize clarity and simplicity. There
is no payoff for being an expert in the intricacies of
assemblers or in having the most
complex expression on the block. We suggest the following approach:
1) Use the clearest number system or character code for data. Masks and BCD num-
bers decimal. ASCII characters in octal, or ordinary numerical constants tn hex-
in

adecimal serve no purpose and therefore should not be used.


2) Remember to distinguish data and addresses.
3) Don't use offsets from the Location Counter.
4) Keep expressions simple and obvious. Don't rely on obscure features of the assem-
bier.

CONDITIONAL ASSEMBLY
Some assemblers allow you to include or exclude parts of the source program, de-
pending on conditions existing at assembly time. This is called conditional assem-
bly; it gives the assembler some of the fiexibitity of a compiler. Most microcomputer
assemblers have limited capabilities for conditional assembly. A usual form is:

IF COND

.CONDITIONAL PROGRAM

ENDIF
If the expression COND is true at assembly time, the instructions between IF and ENDiF
{two pseudo-operations) are included in the program.

Typical uses of conditional assembly are:

1) To include or exclude extra variables.

2} To place diagnostics or special conditions in test runs.

3) To allow data of various bit lengths.


4) To create specialized versions of a common program.
Unfortunately, conditional assembly tends to clutter programs and make them difficult
to read. Use conditional assembly only if it is necessary.

MACROS
You will often find that particular sequences of instructions oc- DEFINING A
cur many times in a source program. Repeated instruction se- SEQUENCE OF
quences may reflect the needs of your program logic, or they INSTRUCTIONS
may be compensating for deficiencies in your microprocessor's '

instruction set You can avoid repeatedly writing out the same instruction sequence by
itQinn a
using manrn
3 macro.

Macros allow you to assign a name to an instruction sequence. You then use the
macro name in your source program Instead of the repeated instruction sequence.

2-11
1

The assembler will replace the macro name with the appropriate sequence of in-

structions. This may be illustrated as follows:

Source Program Object Program

MAC1 MACRO (macro definition)

instruction Ml
instruction M2
instruction M3

ENOM (end of macro definitton)

mstryction P1 {mam program) instruction PI

P2 instniCtion P2
instruction

instruction P3 instruction P3

instruction M1
instruction M2
-H instruction M3
instruction P4
instruction P5
instruction P6
instruction P?

instruction Ml
instruction M2
instruction M3
instruction P8
instruction P8
instruction P9
instruction P9
instruction M1
instruction M2
instruction M3
instruction PIO
instruction PIO !

instruction P1
instruction PH

Macros are not the same as subroutines. A subroutine occurs once in a program, and
program execution branches to the subroutine. A macro is expanded to an actual in-
struction sequence each time the macro occurs; thus a macro does not cause
any
branching.

Macros have the following advantages: ADVANTAGES


OF MACROS
1) Shorter source programs.
2) Better program documentation.
3) Use of debugged instruction sequences —
once the macro has been debugged,
you are sure of an error-free instruction sequence every time you use the macro.
4) Easier changes. Change the macro definition and the assembler makes the change
for you every time the macro is used.

5) Inclusion of commands, keywords, or other computer Instructions in the basic in-

struction set. You use the macro as an extension of your instruction set

The disadvantages of macros are:


DISADVANTAGES
1) Repetition of the same instruction sequences since the OF MACROS
macro ts expanded every time it is used.

2-12
2) A single macro may create a lot of instructions.

3) Lack of standardization that may make the program difficult to read and unders-
tand.

4) Possible effects on registers and flags that may not be clearly stated.

One problem is that variables used In a macro are known only LOCAL OR
within itthey are local rather than global). This can often
(i.e., GLOBAL
create a great deal of confusion without any gain in return. You VARIABLES
should be aware of this problem when using macros.

COMMENTS
Ailassemblers allow you to place comments in a source program. Comments have
no effect on the object code, but they help you to read, understand, and document
the program. Good commenting is an essential part of writing assembly language
programs; without comments, programs are very difficult to understand.
We will discuss commenting along with documentation In a COMMENTING
later chapter, but here are some guidelines: TECHNIQUES
11 Use comments to tell what the program is doing, not what instructions do.
Comments should say things tike "IS TEMPERATURE ABOVE LIMIT?". "LINE FEED
TO TTY", or "EXAMINE LOAD SWITCH".
Comments should not say things like "ADD 1 TO ACCUMULATOR" "JUMP TO
START", or "LOOK AT CARRY", You should describe how the program is affecting
the system; internal effects on the CPU are seldom of any interest.

2) Keep comments brief and to the point Details should be available elsewhere in the
documentation.

3) Comment all key points,

4) Do not comment standard instructions or sequences that change counters and


pointers; pay special attention to instructions that may not have an obvious mean-
ing.

5) Do not use obscure abbreviations.

6) Make the comments neat and readable.

7) Comment all definitions, describing their purposes. Also mark ail tables and data
storage areas.

8) Comment sections of the program as well as individual instructions.

9) Be consistent in your terminology. You can (should) be repetitive; you do not need
to consult a thesaurus.

10) Leave yourself notes at points which you find confusing, e.g., "REMEMBER CAR-
RY WAS SET BY LAST INSTRUCTION". You may drop these in the final documen-
tation.

A well-commented program is easy to work with. You wilt recover the time spent in
commenting many times over. We wilt try to show good commenting style in the pro-
gramming examples, although we often over-comment for instructional purposes.

2-13
TYPES OF ASSEMBLERS
Although all assemblers perform the same tasks, their implementations vary
greatly. We types of assemblers; we will
will not try to describe all the existing
merely define the terms and indicate some of the choices.
A cross-assembler is an assembler that runs on a computer CROSS-
other than the one for which it assembles object programs. I
ASSEMBLER
The computer on which the cross-assembter runs is typicatly a
iarge computer with extensive software support and fast peripherals such as an IBM —
360 or 370, a Univac 1 1 08, or a Burroughs 6700. The computer for which the cross-as-
sembler assembles programs is tvpically a microcomputer like the Z80 or MC6800.
Most cross-assemblers are written in FORTRAN so that they are portable.

A is an assembler that runs


self-assembler or resident assembler RESIDENT
on the computer for assembles programs. The self-assem-
which it
ASSEMBLER
bler will require some memory and peripherals, and it may run
quite slowly.

A macroassembler is an assembler that allows you to define MACRO-


sequences of instructions as macros. ASSEMBLER
A microassembler is an assembler used to write the MICRO-
microprograms that define the instruction set of a computer. ASSEMBLER
Microprogramming has nothing specifically to do with
microcomputers.

A meta-assembler is an assembler that can handle many META-


different instruction sets. The user must define the particular in- ASSEMBLER
struction set being used.

A one-pass assembler is an assembler that goes through the ONE-PASS


assembly language program only once. Such an assembler must ASSEMBLER
have some way of resolving forward references, e.g., Jump in-
structions which use labels that appear later in the source program, i.e. that have not

yet been defined.

A two-pass assembler is an assembler that goes through the TWO-PASS


assembly language source program twice. The first time the ASSEMBLER
assembler simply collects and defines all the symbols; the
second time it replaces the references with the actual definitions. A two-pass as-
sembler solves most of the forward reference problems. However, macro expan-
sion and conditional assembly can cause problems. On some large machines seven
or more passes are needed to insure that all forward references are resolvable. A
two-pass assembler may be quite slow if no backup storage (like a floppy disk) is
available; then the assembler must physically read the program twice from a slow
Input medium {like a teletypewriter paper tape reader). Most microprocessor-
based assemblers require two passes.

ERRORS
Assemblers normally provide error messages, often consisting of a single coded
letter. Some typical errors are:

1) Undefined name (often a misspelling or an omitted definition).


2) Illegal character (e.g., a 2 in a binary number).

2-14
^ .

3) iilegai format (wrong delimiter or mcorrect operands).


4) Invalid expression (e.g.. two operators in a row).

5) Illegal value (usually too large).

6) Missing operand.
7) Double definition (i.e.. two different values assigned to one name).
8) iilegai label (e.g., a label on a pseudo-operation that cannot have one).
9) Missing label.

10) Undefined operation code.


In interpreting assembler you must remember that the assembler may get off on
errors,
the wrong track if it finds a stray
letter, an extra space, or mcorrect punctuation. Many
assemblers will then proceed to misinterpret the succeeding instructions and produce
meaningless error messages. Always look at the first error very carefully; subsequent
ones may depend on it Caution and consistent adherence to standard formats will
eliminate many annoying mistakes.

LOADERS
The loader is the program which actually takes the output (obiect code) from the as-
sembler and places it in memory. Loaders range from the ven/ simple to the ven/ com*
plex. We will describe a few different types.

A bootstrap loader is a program that uses its own first few in- BOOTSTRAP
structions to load the rest of itself or another loader program LOADER
into memory. The bootstrap loader may be m ROM. or you may
^-««^—
have to enter it into the computer memory using front panel switches. The assembler
may place a bootstrap loader at the start of the object program that it produces.
A relocating loader can load programs anywhere in memory, it RELOCATING
typically loadseach program into the memory space immediately LOADER
following that used by the previous program. The programs
however must themselves be capable of being moved around in this way, i.e.. they
must be relocatable. An absolute loader, in contrast, will always place the programs in
the same area of memory.

A programs and subroutines that have


linking loader loads LINKING
been separately assembled; it resolves external references — LOADERS
I-.—-----------«
that is, an instruction in one module that refers to a label in
another module. Object programs loaded by a linking loader must be created by an
sembler that permits and marks external references.
^ as-

An alternative approach is to separate the linking and loading


functions and have the linking performed by a program called a
link editor.

LINK
EDITOR
I—

2-15
REFERENCES
A compiete monograph on macros is M. CanRpbell-Kelly, An Introduction to Macros.
American Elsevier. New York, 1973,

Microprogramming fs described conceptuattv in An introduction to Microcom-


puters: Volume 1 — Basic ConceChapter 4. A more technical description is in A.K.
pts,

Agrawala and T.G. Rauscher, Fouridations of Microprogramming. Academic Press, New


York, 1976.
"
You can more detailed descriptions of assemblers and loaders m D.W. Barron, As-
find
semblers and Loaders" American Elsevier. New York, 1972 and m C.W. Gear, Com-
.

puter Organization and Programming. McGraw-Hill, New York, 1974.

2-16
Chapter 3
THE Z80 ASSEMBLY LANGUAGE
INSTRUCTIOISI SET
We are now ready to start writing assembly language programs. We begin in this
chapter by defining the individual instructions of the Z80 assembly language in-
struction set, plus the syntax rules of the Zilog assembler.

We do not discuss any aspects of microcomputer hardware, signals, interfaces, or


CPU architecture in this book. This information is described in detail in An Introduction
to Microcomputers: Volume 2 —
Sonne Real Microprocessors and Volume 3 Some —
Real Support Devices while Z80 Programming for Logic Design discusses assembly
,

language as an extension of digital logic. In this book, we look at programming tech-


niques from the assembly language programmer's viewpoint, where pins and sig-
nals are irrelevant and there are no important differences between a minicom-
puter and a microcomputer.

memory access, and the Stack architecture for the Z80 will be de-
Interrupts, direct
scribed chapters of this book, in conjunction with assembly language program-
in later

ming discussions of the same subjects.


This chapter contains a detailed definition of each assembly language instruction.
These definitions are identical to those found m Chapter 6 of Z80 Programming for
Logic Design.

The detailed description of individual instructions


is preceded by a general discussion

of the Z80instruction set that divides instructions into those which are commonly
used, infrequently used, and rarely used. If you are an experienced assembly language
programmer, this categorization is not particularly important — and, depending on your
own programming may not even be accurate. If you are a novice assembly
prejudices, it

language programmer, we recommend that you begin by writing programs using only
instructions in the "commonly used" category. Once you have mastered the concepts
of assembly language programming, you may examine other instructions and use them
where appropriate.

3-1
CPU REGISTERS AND STATUS FLAGS
The CPU registers and status flags for the Z80 may be illustrated as follows:

Sign
Zero
AuxiJiarv Carry

Panty/Overflow
Subtract
Carry

If

Ac
u
m_
I Flags

Accumulator

J- Secondary Data Counters


Secondary J
Accumulators \
Primary Data Counter

S|Z| M F/0|N|C- Alternate Flags

Alternate Accumulator

Alternate B I Alternate Secondary


/ Data Countere
Secondary <
Accumulators | Alternate Primary Data Counter

Stack Pointer

Program Counter

Index Register

Index Register

Interrupt Vector Register

Refresh Register

The Accumulator is the primary source and destination for one-operand and two-

operand instructions. For example, the shortest and fastest data transfers between the
CPU and i/0 devices are performed through the Accumutator. In addition, more Memo-
ry Reference instructions move data between the Accumulator and memory than bet-
ween any other register and memory. All 8-bit arithmetic and Boolean instructions take
one of the operands from the Accumulator and return the result to the Accumulator. An
instruction must therefore load the Accumulator before the Z80 can perform any 8-
bit arithmetic or Boolean operations.

The B, C, D, E, H, and L registers are all secondary registers. Data stored in any of
these SIX registers may be accessed with equal ease; such data can be moved to any
other register or can be used as the second operand in two-operand instructions.

There are, however, some important differences in the functions of Registers B, C, D. E.

H. and L.

Registers H and L are the primary Data Pointer for the Z80. That is to say, you wilt
normally use these two registers to hold the 16-bit memory address of data being ac-
cessed. Data may be transferred between any registers and the memory location ad-
dressed by H and L Since HL is the primary Data Pointer, it often takes fewer bytes of
obiect code and less instruction cycles to perform operations with it TheZSO program-
mer should try to address data memory via Registers H and L whenever possible.

Within your program logic, always reserve Registers H and L to hold a data memo-
ry address.

3-2
Registers B, C, D, and E provide secondary data storage; frequently, the second
operand for two-operand instructions is stored in one of these four registers. (The first
operand is stored in the Accumuiator, which is also the destination for the result)
There are a limited number of instructions that treat Registers 6 and C, or D and E,
as 16-bit Data Pointers. But these instructions move data between memorY and the
Accumuiator only.

Inyour program logic you should normally use Registers B, C, D, and E as tempor-
ary storage for data or addresses.

Registers IX and lY are index registers. They provide a limited indexing capability of
the type describedin An introduction to Microcomputers: Volume 1 for short instruc-
tions.

The alternate registers F', A', B', C, D', E', H', and L' provide a duplicate set of
general purpose registers. Just two single-byte Exchange instructions select and
deselect all alternate registers; one instruction exchanges AF and the alternate AF'
as a register pair, and one instruction exchanges BC, DE, and HL with the alternate BC.
DE\ and HL\ Once subsequent register operations are performed on the ac-
selected, all

tive set until the next exchange selects the inactive set. The alternate registers can be
reserved for use when a fast interrupt response is required. Or, they may be used in
any desired way by the programmer.
There are a number of instructions that handle 1 6 bits of data at a time. These in-
structions refer to pairs of CPU registers as follows:

F and A
B and C
D and E
H and L
F' and A'
B' and C
D' and e
H' and L'

High- Low-
order order
byte byte

The combination of the Accumulator and flags, treated as a 16-bitunit. is used only for
Stack operations and alternate register switches. Arithmetic operations access B and C,
D and E, or H and L as 16-bit data units.
The Carry status flag holds carries out of the most significant bit In any arithmetic
operation. The Carry flag is also included in Shift instructions; it is reset by Boolean in-
structions.

The Subtract flag is designed for internal use during decimal adjust operations. This
flag is set to 1 for all Subtract instructions and reset to for all Add instructions.
The Parity/Overflow flag is a multiple use flag, depending on the operation being
performed. For arithmetic operations, it is an overflow flag. For input, rotate, and
Boolean operations, it Is a parity flag, with 1 = even parity and = odd parity. Dur-
ing block transfer and search operations, it remains set until the byte counter decre-
ments to zero; then it is reset to zero. It is also set to the current state of the interrupt
enable flip-flop (IFF2) when a LD A,l or LD A,R instruction is executed.

The Zero flag is set to 1 when any arithmetic or Boolean operation generates a
zero result. The Zero status Is set to when such an operation generates a non-
zero result.

3-3
The Sign status flag acquires the value of the most significant bit of the result
following the execution of any arithmetic or Boolean instruction.

The Auxiliary Carry status flag holds any carry from bit 3 to 4 resulting from the
execution of an arithmetic instruction. The purpose of this status flag is to simptify
Binary-Coded-Decima! (BCD) operations; this is the standard use of an Auxiliary Carry
status flag as described m An introduction to Microcomputers: Volunne 1 Chapter 3.
.

All of theabove status flags keep their current value until an instruction that nnodlfies
them IS executed. Merely changing the value of the Accumulator will not necessarily
change the value of the status flags. For example, if the Zero flag is set and a load im-
mediate to the Accumulator is executed, that causes the Accumulator to acquire a non-
zero value; the value of the Zero flag remains unchanged.

The Stack Pointer allows you to implement a Stack anywhere in addressa-


1 6-foit

ble memory. The size of the Stack is limited only by the amount of addressable memory
present In reality you will rarely use more than 256 bytes of memory for your Stack.
You should use the Stack for accessing subroutines and processing interrupts. Do not
use the Stack to pass parameters to subroutines. This is not very efficient withm the
limitations of the Z80 instruction set The Z80 Stack ts started at its highest address. A
Push decrements the Stack Pointer contents; a Pop increments the Stack Pointer con-
tents.

The interrupt Vector register and the Refresh register are special-purpose
registers not normally used by the programmer.
The is used to store the page address of an interrupt response
Interrupt Vector register
routine; the location on the page is provided by the interrupting device. This scheme
allows the address of the interrupt response routine to be changed while stilt providing
a very fast response time for the interrupting device.

The Refresh memon/ refresh counter m the low-order seven bits.


register contains a
This counter incremented automatically after each instruction fetch and provides the
is

next refresh address for dynamic memories. The high-order bit of the Refresh register
will remain set or reset depending on how it was loaded at the last LD R,A instruction.

Z80 MEMORY ADDRESSING MODES


The Z80 provides extensive addressing modes. These Include:

• Implied
• Implied Block Transfer with Auto-increment/Decrement
• Implied Stack
• Indexed
• Direct
• Program Relative
• Base Page
• Register Indirect
• Immediate

3-4
1

Implied
in implied memory addressing, the H and L registers hold the address of the
memory location being accessed. Data may be moved between the identified memo-
ry location and any one of the seven CPU registers A. B, C. D. E. H. or L For example, the
mstruction

ID CAHl)
loads the C register with the contents of the memory location currently pointed to by
HL. This IS Illustrated as follows:

S Z AqP/Q N C Data
Memory

A ppqq
B,C g^».
O.E
HX
SP
PC Program
iX Memory
!Y

mmmm
mmmm 4-

mmmm 2 -i-

mmmm + 3
LD C.IHU

7 6 5 4 3 2 1

|o 1 1 |o 1
1 1 1
1
1
1 |o|

ti "Load Implied

"C Register
via HL

3-5
A limited number of instructions use Registers 8 and C or D and E as the Data
Pointer. These instructions move data between the Accumuiator and the mennon/ loca-
tion addressed by Registers 8 and C or Registers D and E The instruction

ID (BC),A

stores the contents of A into the nnemory location currently addressed by Register Pair
BC. This is illustrated as follows:

3 Z Ac P N C Data
-..
1 1 1 M Memory

A yy 1
ppqq
8.C PP qq! L
O.E
H,L
bH »ih^i
PC mmmm ^53 mmmm + 1^ Program
Memory
!X
tY
i
02 mmmm
R
mmmm + 1

mmmm + 2
1

mmmm + 3

LO (BO.A

[ [O [
0| 1 ^
Store Implied from A vsa 8C

3-6
1

Implied Block Transfer With Auto-Increment/Decrement


Block Transfer and Search instructions operate on a block of data whose size is
set by the programmer as the contents of the BC register pair. In this form of ad-
dressing, a byte of data is moved from the memory location addressed by Ht to
the memory location addressed by DE; then HL and DE are incremented and BC Is
decremented. Data transfer continues until BC reaches zero, at which point the In-
struction terminated. Variations include allowing other instructions to follow
is
each data transfer, with the programmer supplying the loopback; auto-decrement-
ing HL and DE instead of auto-incrementing; and a complementary set of Block
Search instructions that compare the memory byte addressed by HL with the con-
tents of the A register, setting a flag if a match is found.

The Load, Increment and Repeat instruction

LDiR
is iliustrated as follows:

Set if BC-1-9*0 j-eset otherwise

S Z Ac P/0 N C Data
'"'
I Memory |^«

^ I

yy 1 ppqq

^
r^
*-^
1
Vm
^
1
V
i
YV rrss
yrrss-M
:+1 1

fVogram
Memory

ED mmfnnn
mmmm +
mmmm 2 -i-

nnftimni +3

LDIR

< 6 5 4 3 2 1 >
1 1 1 1 t 1

I > Load, Increment, and Repeat instruction


1

L 1

A similar group of Input/Output instructions Is provided, allowing a block of data


to be input or output between memory and an I/O device. The i/0 port number ts
taken as the contents of the C register, with the single B register used as the byte
counter. Mennory is addressed by HL.

3-7
ImpHad Stack
Stack instructions as
Since the Stack is part of Read/Write memory, we must consider
Memory Reference instructions. Push and Pop instructions move two bytes of
data

between a register pair and the addressed Stack Pointer location, i.e.. current top-
of-stack. The Z80 Stack address is decremented with each
Push and incremented with
each Pop. The instruction
PUSH DE
is illustrated as follows

S Z Aq P/0 n c

'**tlS^^'^-
7 6 5 4 3 2 10
1 It 10 M 10! 1
|o ji i

tXi -

-
PUSH instruction

Register Pair DE

3-8
1 1

The Z80 also has instructions that exchange the two top-of-stack bytes with a
16-bit register — HL or one of the registers. The instruction
two index
EX (SP),HL

IS illustrated as foliows:

S Z Ac P/0 N C
Data
^i 1 I I 1
Memorv
1

qq
B.C
D.E
H,L
SP
i^r S ssss -*- 2

PC Program
IX Memory
lY
i E3 mmmm
R mmmm +
mmmm + 2
mmmm + 3

3-9
indexed
The Z80 has two 16-bit index registers, called IX and lY. They may be used in-
terchangeably. All reference operations for which (HL) can be specified can
memory
alternatively be specified as an indexed operation. The difference between implied ad-
dressing using HL and indexed addressing using IX and lY is that the index operand
includes a displacement value that is added to the index address. In the instruction
ADD A,(IX+40H)

the memon/ address is the sum of the contents of the IX register and 40-, g. This may be
illustrated as follows:

S Z AcP/0 N C Data

F tx|XiX|x|o|x|

7 6 5 4 3 2 1

1 1 1 1 i|o 1

> Add to A Indexed by IX instruction


1 -^
1 1
i Disptscement

3-10
1

Direct
Direct addressing can be used to ioad tiie Accumulator with any 8-bit value from
memory, load BC, DE, HL, SP, IX, or lY with any 1 6-bit memory value, and Jump or
call subroutines direct at any memory location. The 16-bit direct address is stored in
the lasttwo bytes of the instruction, m low-byte high-byte order (this is the reverse of
the standard high-low schenne).

The instruction

LD A,(NETX)
loads the A register with the contents of the mennory location addressed by the label
NETX, The instruction

LD HUdFFH)
loads the L register with the contents of memory location OlFF^g and the H register
with the contents of memory location 0200^ g. This may be illustrated as follows:

S ZAcP/ON C 03,3
F i I I I 1 Tl Memory

yy 01 FF
B.C 0200
0,E
HX W
SP
PC Program
IX Memory
!Y
I

R mmmm +
mmmm 2 *-

mmmm 3 -*-

LD HUIFFH)

6 5 4 3 2 1

1 1 1 Load HL Direct mstruction


1 1 t 1 1 1 1 1 Direct address - low byte

1 Direct address - High byte

The direct Jump instructions provide jumps and Jumps-tO'Subroutines, both un-
conditionai and conditional. These are all 3-byte instructions, with the direct address
stored in the second and third bytes of the instruction, as shown above for Load Direct.

There are three additional addressing modes used by Z80 Branch instruc-
tions: program relative, base page, and register indirect In general, they are shorter
and/or faster than direct jumps but may have more limited addressing capabilities.

3-11
1

Program Relative
Jump Relative instructions provide program relative addressing in the range -126,
+129 bytes from the first byte of the Program Relative instruction. These instructions
are all 2-bvte instructions, with the signed displacement
vaiue stored in the second
byte of the instruction. There are unconditional and conditional relative Jumps,
as
vtfell as a Decrement and Jump If Not Zero Instruction (DJNZ)
that facilitates loop
control.

Given the instruction


JR SRCH
assume that SRCH is a label addressing a (ocation 5A.g bytes up in memory from the

JR op-code byte. The operation may be illustrated as follows:

s z Ac P/0 N c Data
Memory

A
8.C
D,E
H.L
SP mrnmrn+*S. Program
PC mmmm
Memory
iX
ty
1
T T
!8 mmmm
R 1 1
I
5A mmmm +
mmmm + 2

7 6 5 4 3 2 t

IT 1 1
3 Jump Relative tnstructton

Displacement
bJ 1 1 1 1

11

3-12
Base Page
The Z80 has a modified
base page addressing mode for the Restart mstructioa This is
a special Call instruction that allows a single-byte instruction to Jump to one of
eight subroutines located at specific points in lower core. The effective address
is
calculated from a 3-bit code stored in the instruction, as follows:

Lower Core Address 3-Bit Code


OOH 000
08H 001
10H 010
18H Oil
20H 100
28H 101
30H 110
38H 111
The decoded address value is loaded into the low-order byte of the Program Counter:
the high-order byte of the Program Counter is set to zero. For example, the instruction

RST OOH
is illustrated as follows:

SZAc P/0 N C Data


^( n Memory

'^-*y---'^'««[*'*Y'^*'''''^*^Y***^

- Restart instruction

- Address code

3-13
Register indirect
address, and
(n standard Indirect addressing, a memory location contains the effective
the instruction specifies the address of the memory location
containing the effective
effective address, and
address, in register indirect addressing, a register contains the
the instruction specifies which of the registers contains the effective address. Note
that

for a Load, for instance, this ts just another way of describing


implied addressing.
However, the Z80 has Jump Instructions that allow a jump to the memory
location
Is contained In the specified register. This is a form of
indirect ad-
whose address
dressing, and is described separately because, while most microcomputers have im-
plied addressing, very few have register indirect jumps.

The instruction
JP (HU

jump to be taken to the memory location whose address is contained In


directs that a is

HL This may be illustrated as follows:

S Z Ac P/0 N C Data
Memory
^« I ' I II 1

B.C
D.E
qq

D
H.L pp
SP
Program
PC mmmm
Memory
IX
lY
I
E9 mmnrwn
R mmmm -f 1
1
mmmm + 2
mmmm 3 •*•

T* 1 1 Jump via HL
I I I

3-14
j 1

immediate
Some immediate instructions as Memory Reference instructions. An im-
texts identify
mediate instruction a 2-, 3-.. or 4-byte instruction in which the last one or two bytes
is

hold fixed data that is loaded into a register or memory location. The Z80 provides Im-
mediate instructions to:
• load 8-bit data into any of the 8-blt registers,
• load 16-bit data into any of the register pairs or 16-bit registers,
• store 8-bit data into any memory location using implied or indexed addressing,
• perform arithmetic and logical operations using the Accumulator and d-bit im-
mediate data.
The instruction

LD BCOBCH
toads the immediate data value BC^q into Register Pair BC. This may be illustrated as
follows:

S Z Ac P/0 N C
Data

1z 1 M II 1
Memory

A
B.C ^
DF
H.L
SP
PC mmmfTt T^mmmm + 3 F^ogram
!X
"^^s,...,:^.^ Memory
(Y
i
01

R BC mmmm +
V*— 00 mmmm + 2
rnmrnm + 3

LD BC. OBCH

7 6 5 4 3 2 10
[o|o[o|o|o o|qT1|

Load immediate to Register Pasr

Register Pair BC

10 11110 Immediate data - low-order byte

"o" ~"o Immediate data - high-order byte

3-15
Table 3-t Frequently Used Instructions of the Z80

Instruction Code Meaning ^


ADC A Add with Carn/ to Accunnulator
ADD Add
AND Logical AND
CALL addr Call Subroutine
CALL cond.addr Call Conditional
CP Compare
DEC Decrement
DJNZ Decrement and Jump If Not Zero
IN Input
INC Increment
JR Jump Relative
JR cond,addr Jump Relative Conditional
LD reg.(HL) Load Register
LD A. (addr) Load Accumulator Direct
LD data Load Immediate
LD (HU^reg Store Register
LD (addr),A Store Accumulator Direct
LD dstsrc Move Register-to-Register
OUT Output
POP Pop from Stack
PUSH Push to Stack
RET Return from Subroutine
RET cond Return Conditional
RLA Rotate Accumulator Left Through Carry
RRA Rotate Accumulator Right Through Carry
SLA Shift Left Arithmetic
SRL Shift Right Logical
SUB Subtract

3-16
Table 3-2. Occasionaltv Used instructions of the Z80

Instruction Code Meaning


BIT Test Bit
CPD. CPDR Compare, Decrement (Repeat)
CPICPIR Compare, Increment (Repeat)
CPL Complement Accumulator
DAA Decimal Adjust Accumulator
Dl Disable Interrupts
El Enable Interrupts
EX Exchange
HALT Halt
!ND. INDR Input Decrement (Repeat)
INL INIR Input Increment (Repeat)
JP addr Jump
JP cond,addr Jump Conditional
LD A,(BC) or (DE) Load Accumulator Secondary
LD HL,(addr) Load HL Direct
LD reg,(xy+disp) Load Register indexed
LD rp,(addr) Load Register Pair Direct
LD XV, (addr) Load Index Register Direct
LD (BO or (DE),A Store Accumulator Secondary
LD (addr),HL Store HL Direct
LD (xY+disp),reg Store Register Indexed
LD (addrlrp Store Register Pair Direct
LD (addr), XV Store Index Register Direct
LD (HLl.data Store Immediate to Memory
LD (xy-fdisp),data Store Immediate to Memory Indexed
LDD. LDDR Load, Decrement (Repeat)
LDL LDIR Load, Increment (Repeat)
NEG Negate (Twos Complement) Accumulator
NOP No Operation
OR Logical OR
OUTD. OTDR Output Decrement (Repeat)
OUTl. OTIR Output Increment (Repeat)
RES Reset Bit
RETI Return from Interrupt
RL Rotate Left Through Carry
RLC Rotate Left Circular
RLCA Rotate Accumulator Left Circular
RR Rotate Right Through Carry
RRC Rotate Right Circular
RRCA Rotate Accumulator Right Circular
SET Set Bit
SRA Shift Right Arithmetic
XOR Logical Exclusive OR

3-17
Table 3-3. Seidom Used Instructions of the Z80

Instruction Code Meaning

ADC HLrp Add Register Pair with Carry to HL


CCF Compiement Carry Flag
EXX Exchange Register Pairs and Alternatives
iM n Set Interrupt Mode
RETN Return from Non-Maskable Interrupt
RLD Rotate Accumulator and Memory Left Decimal
RRD Rotate Accumulator and Memon/ Right Decimal
RST Restart
SBC Subtract with Carn/ (Borrow)
SCF Set Carry Flag
LD A.! Load Accumulator from Interrupt Vector Register
LD A.R Load Accumulator from Refresh Register
LD I.A Store Accumulator to Interrupt Vector Register
LD R.A Store Accumulator to Refresh Register
LD SP^HL Move HL to Stack Pointer
LD SP.xy Move Index Register to Stack Pointer

ABBREVIATIONS
These are the abbreviations used in this chapter:

A.F.B.C, D.E.HI The 8-bit registers. A is the Accumulator and F is the Flag Word.

AF'.BCDE'.HL' The alternate register pairs

addr A 16-bit memory address


x(b) Bit b of 8-bit register or memory location x

cond Condition for program branching. Conditions are;


NZ - Non-Zero (Z - 0)
Z -Zero(Z-1)
HC - Non-carn/ (C =0)

C -Carry (C - 1)
PO - Parity Odd (P = 0)
PE -Panty Even (P = 1)
P - Positive Sign (S = 0)

M - Negative Sign (S - 1)

data An 8-bit bmary data unit

data16 A 16-bit binary data unit

disp An 8-bit signed binary address displacement

xx(HI) The high-order 8 bits of a 16-bit quantity xx

! Interrupt Vector register (8 bits)

IX lY The index registers (16 bits each)

label A 16-bit instruction memory address


xx(LO) The low-order 8 bits of a 16-bit quantity xx

LSB Least Significant Bit (Bit 0)

MSB Most Significant Bit (Bit 7)

PC Program Counter
port An 8-blt t/0 port address

3-18
1

pr Any of the following register pairs;


BC
DE
HL
AF
R The Refresh register (8 bits)

reg Any of the following registers:


A
B
C
D
E
H
L

rp Any of the following register pairs:


BC
DE
HL
SP
SP Stack Pointer (16 bits)

xy Either one of the Index registers (IX or lY)

Object Code bbb Bit number 000 (LSB) to 1 1 1 (MSB)

ccc Condition code 000 = non-zero


001 == zero
010 = no carry
01 = 1 carry
100 = parity odd
101 = parity even
110 = positive sign
111= negative sign

ddd Destination register — sanne coding as rrr

ppqq A 16-bit mennory address

rrr Register 11 1 =A
000 = B
001 =C
010 = D
Oil =E
100 =H
101 =L
sss Source register — same coding as rrr

X Index register = IX
1 =!Y
XX Register pair 00 = BC
01 =DE
10 = HL
1 = SP (rp) or AF (pr)

XXX Restart code (000 to 111)

yy An 8-bit binary data unit

yyyy A 16-bit binary data unit

3-19
Statuses The Z80 has the following status flags:
C - Carrv status

Z - Zero status
S - Sign status
P/0 - Parity/Overflow status
Aq - Auxlliarv Carry status
N - Subtract status

The following symbols are used in the status colunnns:


- flag is affected by operation
X
(blank) - flag is not affected by operation
1 - flag is set by operation
- flag is reset by operation
U - flag iSunknown after operation
P - flag shows parity status
- flag shows overflow status
1
- flag shows interrupt enabled/disabled status

[[]] Memory addressing: 1) the contents of the memon/ location


whose address is contained m the designated register. 2) an
1/0 port whose address is contained in the designated register.

[j The contents of a register or memory location.

For example:

[[HU] - [[HL]] + 1

indicates that the contents of the memon/ location addressed by


the contents of HL are incremented, whereas:

(HU — [HLl + 1

indicates that the contents of the HL register itself are incre-


mented.

A Logical AND
V Logical OR
-V- Logical Exclusive-OR
*— Data IS transferred in the direction' of the arrow

-i >
Data IS exchanged between the two locations designated on either

side of the arrows.

3-20
INSTRUCTION MNEMONICS
Table 3-4 summarizes the Z80 instruction set. The MNEMONIC column shows the
instruction mnemonic (IN, OUT, LD).The OPERAND column shows the operands,
if any, used with the instruction mnemonic.
The fixed part of an assembly language Instruction is shown in UPPER CASE. The
variable part (immediate data, I/O device number, register name, label or address)
is shown In lower case.

For closely related operands, each type is listed separately without repeating the
mnemonic. For instance, examples of the format entry

LD rp,(addrl
xy,(addr)

are- LD BC.(DAT2)
LD IX.(MEM)

INSTRUCTION OBJECT CODES


The object code aiTd instruction length in bytes are shown in Table 3-4 for each
instruction variation. Table 3-5 lists the object codes in numerical order.

For instruction bytes without variations, object codes are represented as two
hexadecimal digits (e.g., 3F).

For instruction bytes with variations In one of the two digits, the object code is
shown as one 4-bit binary digit and one hexadecimal digit (e.g., 11 x 1 D) in Table
3-5, For other instruction bytes with variations, the object code is shown as eight
binary digits (e.g., OlsssOOl).

INSTRUCTION EXECUTION TIMES


Table 3-4 lists the instruction execution times in clock periods. Real time can be
obtained by dividing the given number of clock periods by the clock frequency. For
example, for an instruction that requires 7 clock periods, a 4 MHz clock will result m a
1.75 microsecond execution time.

When two possible execution times are shown (i.e., 5/11), it indicates that the
number depends on condition flags. The first time is for "condi-
of clock periods
tion not met," whereas the second is for "condition met."

STATUS
The SIX status flags are stored in the Flag register (F) as follows:

p/o

n ii I a & i\ a n
• These bits are not used
- CaiTY status {catrv out of bit 7)
- Subtract status
after subtract operation, otherwise!

. Parity/Overflow
(for logical operations, t for even, for odd pantv.
For arithmetic, 1 for overflow)

- Auxiliary Carry status {carry out of bit 3)

Zero status (1 for zero, for nonzero)


Sign status (value of bit 7)

3-21
In the individual instruction descriptions, the effect of instruction
execution on
status is illustrated as follows:
S Z Ac P/0 N C

i I A I I
Modified to reflect results of execution
Unconditionallv reset to
- Unconditionaiiy set to 1

Unchanged
Unknown

A identifies a status
STATUS
An X identifies a status that ts set or reset.
always cleared. A identifies a status that always set. A
is
CHAMGES
that IS 1

blank means the status does not change. A question mark (?)
WITH
INSTRUCTION
means the status is not known.
EXECUTION

3-22
HIMII^K

u x: en o a
o o u ^
o III r o c
H o. 2
r
o § s o
a o "5
i- ^ o o ^
O .a
o >-
a) It
1^ ^ T3 _r
X •" X)
X3 ^
O
E 1
£ S ^ si i .

1 1
o l! 5
i
>- 2 I" iCD o 9;
1 ?
1 -5 Q. 8 t:

c RJ 0) 5 5d o -1^ a
s
i| ° b
X) O 5§
to
F - < O M « o
O o ll
1 ^ — <o
CO
r
T3
T3
2c .
;
ro

<
CD o o ^ to
T3
O g " : TI 5l CD

< o
+ 11
s =
r < m X to

is «
2 § 1 ys ^ i « ^ c ^s X i is i'i
T T i i ^ T^
T|| Is S3
S T2: Q.
1
-.
to
il P c
53 3
< < E S

z o - - -
o
< f^. (V.

£ CL ^ r..
^ P-.

5
(0 X r.. IV. ^.

isi
X - - X
O
1

in tn
o o in
O $ O o
CN cvj

«
«
> CM (S (N r-j tN
m

o
o o
T3
O
o
T3
o >
> T! (N
m <
m
CvJ
T> <
g
m O Q Q
UJ UJ g
§ D

•D

§ g O
o O)
cu
O

u
c
o
a:
£ ^ ^ o
8)
C z 1
IS

©
gi 0/1
l-

3-23
"~" ;""
5 £ o con-
low con-
high
ining

maining

o - o
by rom s% i
-o -^ £
r 1 if
o
a
s
111
5 ^
O Q o D)

? ^ u '5
T3
g ° c
XI 1 ! 1
•o 1 H i S ^ 8
X} O -2 S3 o 2 «
i
o
^ c TJ
(D
Co™
X)
o X3
03

c
o o ^ •a
r
o
III en CD
TJ Q. P
(0
c o s| S
.9 s
«
a- o 2(0 ^ ^
*- ©
1 .. in
"^
o c
-o «
1
iff I
1 _ E
=„ ;|if
0) u 7 1
13 1
8
1 T 1 - §
ill CO liTiifi
C 1
i i
1 ts i i JD
o 2 O
o S5 UHIIUII

(D
C/5 S ^ '" *"

c
o - - r^
<"
p o t^ ^
« rv.
0.
en
c 2
« «
O
00
f^.

rsj
N X ^ ^
<D
JC
O
"o
t Ji §
LTS OJ
to LO
O O *-
f o o
CM P«J
E
CO CO
9
< C^f CS( (N N CM

^ """
CO
0)
-Q O
CD
H m
i 1 CQ
o s Q
s
1 Q
o

1 < O)
33
t
a u
O
U IQ

fi; iH „
CO
O i- a:

51 1
(D O O
t-
O o
3 S
S

£ S
•D §i (penufjuoo) o/l
< H

3-24
' *

£o c
if g
i ^ o
^1 ^ 1
c
.9
i
1
:S^
x:
XI E
1 S 1 £r 1 1 >.
o
E
•5
•o o 1
to a
c 1
X)
§ 1 1
IS .9 1 E '^
c -o 1 ^ - C
£ s 1 °
c e
o So g o.

t
o ^ s o
ill o
|o5l o
E ^ £ ^ a >• o
Hi
0.
c E g 1 it
,2
E S 0} E
= 3
i
2 xj J J
o 1 1

1 r ! 1
1 5 T3
a 3
II 5 i| 1 ^1
o *-
° o
i 1^^ 1 3 X o- si
?< -2 a
T3
CD
+ Is > o i
_J
E + III ills
C X 1 < i 1
eg 5 £
^^ a o g 1 iTT~ 1 5-
C T ™ c2 «c c 1 « T Tj £ +
:=: -D £ + + O
SI'S
n
1 1 0) "S
o =
I

-^2 Y 1 j

2
J2

5 If 3 -1 "°l 2
1

o 1

8os3 ^ 3 i < -a -o

— w, *" ""* ^^ ^^ — ' " "" ^ '-' —


CO 2 r~ r-
c:
o O
<
o
w 3 a:
c
o 1 CO rv.

CO
ISI
N X X
CD
JZ
o
o
^ •n ®
CO
s 1 Ul in CO CD o o CO CO o o r*- r^
£
E
5^ r^ oj CM C^l

CO
< 1
> CM tN m CO * * fO CO -ct ^ t- ,-
ffl

T
00
^ '^
f^f
S
2^
cr cr
JD Q- S-
CD no a CL
H o CO
CJ

< Q.
o ^ K
o
<
Q.

<
a. Q.
22
CO CM CO
li
UJ ,-

"7
T3
^ < X a >•
CO
T5 T) O to

a
3. J II> •D
X)
^
TJ
i
T3
i'
XI
S
< <
fi

O < X Q.

U m
r^ irj „
< :; 'c
o a
p
§2
^ < D
O
H
D a
_i
Q o
_!
a Q Q o
c O
1 s

£ o
^ s ipenuiiuoo) o/l aou9J9iay Ajoute{/\| AjeiuiJti
< i-

3-25
i f § ? s ^ii^ ^gs
li! lit
m
C
»
*-
S-
T3
12

R
O
1^1 1^1§
U J3 « •*- Q
"=
c S
-g

° ? "
'"
^ ^
W
£ II
«
1
81?
i = 'S
Sfs
s s
S CO "-

1 11
DC 1
a
II
•- ?
^1:1
£5(1)© Mil
Etotoo)
1 : i o 1 1 Eo«« EO£«
£ 1 1 t .2 ?
C
o § 1 1
i i
1 ills i i?e
1 §1^2 « E S
m^gS i2^E«
T30^^ X!04:^
t!

25 +
= = n
= £ 1
<"T£of£=6SS ^T- i2||^SlY£5=||=S
1^ ^ 55 'S ^ t^ 2 g> 5 > i^ 1
,—, i:::^ izi .^ izl ac :z: ——" °= ^—— *-

^
<"

e> ?
0.

«
N

O
, ,

s (O CD
J? jr. 1-
cr»
o u r- r-- p- r-. 03

« o>
r^
CM CM

<s
<-
^
£Q
r- r- »- CO CO Ci

O g

O - §
1 CD
S £0

S
- ;:

1 §
c
« s 55 ? ? 1
O
?
*"
MS i If
en >.

.2
c CC
o GC
E Q a Q Q D Q
_t _I _f J -J
s
c
s

(psnui^uoo)
MOJess pu8 io^suBJX >|30ie
1

3-26
*

by by byte
ad-
con- con-
ad-
decre-
Stop Stop

zero zero
the the and block block
ddressed ddressed

and high. low

by es es
s by mes
ry
ory to
(0 T3 ° « c
<= s s
ffl

1 il
Egg
(0
O
C
-D
TJ
Tl Iff ill
to S -ri
*-
O T) ro O T3 C C
^ c o ^ o
E
.9
|sl o x: o
i 1 -i i g s ^^ ^ X ^ "s:

i 8^ ^ 2 Mo

S
1 ?5 1 II n g,
*§ III
5 c CD
e E « E E ® o " a «J C g
to
O © (D
^ E H >t E ^ _^ 3: E o) 5
« O 3 2
O
a.
^ S o © o X *^ o o
If!
o _, 1
o £ 1 X cn 111
5 + •f i <o « — g =T 7 T 1 i|<
ii
1T
\

i
ills? igg3
1
1 c " « fifh 3M 1 E i §

*~* " " —''-''—


*"" —'
i|i5 glut <? —
Z o o - ^

<" o o X X
tt>

i X X X X
s
o CO to X X
00
IM N X X
U

CD <D
CO h
" o o
CM
o
CM

CO (Q

< ^ PJ CS Oi CM
m
CO

<D

o § § m
o Q Q Q Q
at m UJ
loT
O

TJ
C
s
o
o

u
c
a Q tr
E Q Q £1-
Q
Q.
_! U u
S

s
§i {p8nu|}U03] qojees pue ioisueji ^loojg
K

3-27
onMUHin
c

S 1
1
M i
0)
s

1
i
^
i
?
tive ad-

ffl
'^

S 1 1 £
o
E -a „Q. tn
oj

=6 03

^f if ll
O £
-o
a)

O KJ
^
11
JZ s z I £ 11 ^ £
2 % JZ §
1 1 i
1 i
It =1
a.
1
o 1 o ^ =i <^ <| >:i
<i <!
c
.9
£ X 1 < 1
<1 If
"^
O O
CO
—i
c a.
w.
o E ii ?f
i
1 1 f
1 < «
£ < w
° " 1 o < S
o (0
5 1
o % 1 O O + S
1 i ^
"is i 5 ^ X £ C X £ il il
0) i|
:=: -J
ill S < o c < 1 1 < i c 51 15i f
S « ^ a S
C
o g's^
1

u 1 1 i C ^ = W
T||Tli
m U i? 03 -D
o ra

'-^ " '~'


:^
**"'
""^
1

Z ^ - o o - o o

<" X X X X X X ^

« ?
u.
X X o O o o Q. r

^ « X X X X X X X X
o
00
N X X X X X X X X

o X X X X o o

CD <0 r- 2 r. 2 r- ^ r.
2 ^ '^ ^ ^
o $

«
CM T- ro r- n T- CO T- en T- CO '-en
s
CD
CM

a a
a
%
o
^
-6
1
T3
.1
'O
XJ
•a to UJ CD UJ CD to
R m 00 00 CfJ 0) < GO
o < < to T- uu »- CD T- LU T- CO ^ to -r-

u a Q 00 o CD O cn o cw o < O 03 O
LU UJ

O X X X X X ><

T! ^ — :
"q.
.2
"^ 1 D.
Wl
a
«
C 3
to 3 -^ -^

1 < ^ > >


O < < — <
o
c
o Q o <J m u Q tE
CL CL Q a 3 CO Z o
c
u o < < CO « < ^
s

ID {penu^uoo) mojbgs
soueia^sy Ajoiuai^ Ajepuooas

3-28
.

» CO

n ^ ^ ^ ffi

^ ? 1 1 1
« + ™ m

-^^
en

i 1 '-s ^1 a ft
o
X> = + _ + »
"O 1
™ o 1

=1 II
1 11^ liTlT' u o g u o %
5= _iill4| if o
i SI

fl tii!|!i
ii: to
' ro

o i\
a
O
- 1!
w E
O ffl

3 o 1 o

c 5iii|iTiTi
II T c
Bc
o
ffl

o
o 1—. w_ _^ in
SB
oc .E tr
o
oc

Z o ^ o <- o o o
<" <- X XX o o o

o
n

(0
o

to
Q-

X
O
X
O
XX
XX
O a.

X XX
0.

XX
a.

XX
00
Nt X X X

o O X X

ii j^oj ^a> ^ m ^ m
^ n ^ «
tn CO tn uo
^
o o>
r- (N cj Jsj

s
£ <t~ m ^ <n ,-co,-co CN * CS * <N "«*

ID

CO
S- a. a a Q- (X Q.
." « «
e -D ^ ^ T-i -D T3 T3
•o

^
"J
<
lu
CO mm
-* in
CDU
0^<D
m
to
CD
O tu
CD
U

XX
m ^ ^f^ifl^ '-^(O ^r-UJ
u
<D
<0 tijj-
030 cnoC^O moo
u <-
cdo^
o '^
oaoO
u ^
'S
^ X
1- ^ r-

(0
_ 1 _ 1 _ 1
a 5+ 3-^ S + X + £ + X + X +
O i ^ ^ ^ ^ S^ ^

u
U i
u
1 g " i § ^ - i
=

a^e^oy pue ums Ajouje^


1 Ajouiat^ AjepuoDss

3-29
o m z:

1 i 1
o £ « to

<
£r
1 1^
o
CD
1

1
Q.

«
"
TT
M
11
'i
=
O
=.

£
'S
+ ^
f5

>- TS
X c
T
ZI
m.
1 a
T3

D>
*"
-J
i
M
i
1
<"
o
T3
i
o
XO) 1 '
To *- "a
C !
*S;
TJ o
s & c o
CL

o
S
o
n
i I
^
+ s
-1
r- 1.1 o

k
O
o
o

o
i
+ .9

a — o E
O

r-
il
5| X
H
5
E
r^
X
(S
E
"^
— r*
^
51
i

o
c T 1o
1
o
o
T
i2

o
"^
1

"S
E
Tl
o o
B(D ^ *- £
o 4::

a O
cc
x:
w «
jc i 1
tn S
£
to

2 o o o o
O o o o o
<
o CI. CL a_ Q.
3 n:

« oi X X X X
o
00
N X X X X

o X X X X

o u in
^
n 1/5 CD tn en
«- CM
UO
^
(T)
CM
cs ir- f'i
O ^

«
« CN -(f fS Tt CS -* (N -<t

Ifl

Q. Q. a a
VI .i2

o TJ ^ ^
TJ m m CQ m
UJ u to u UJ O UJ u
u
t°^
1- ^ Ui CN ^ (D f^ ^ u 1
n ^ UJ
CD O - m o <N OD O O i m o en
« U ^ O -r- a ^ u *-
S* ^ ^ ^x ^
o X X ^
'- *"
r- ,r-


T3 « « a s-
c
ta 3 ^ 3 ^ 3 "o 3 ^
« X + X + X + X 4-

O > >
^ ^ 1
.2

cc < < a:
1 ci: tn
y) to

o
^ {penuj^uoo} e^e)OB pue nms Ajouisy^
H

3-30
1

""
<B

.52 (0 C
O) a c
ss
.'^ o
X S
<U (0
0}
c
o -u

^ <3 S li 1
^ 1 '^
9 T3 2 - "S
« c
E
^S ts
m
"S
1 fe
-D ro
-D (n
c X „ c
^ (13
o
1 CO c
« w o O) .5 c
t; "s
a s E o
O n
'OJ TJ

^
"S

-f i
'^^

m
c
a c
;^S
B.g
^
i
^
-i
1
o
11 1 a>
= ^ E S- c
Qj
""
»^ :=; gj
I CM 2 ^ « IS
° S 5
1 .2
IIu > ^ 1
li
TO
B •- "S 3 «3

-o .i » s 7 S O Q- g X o 11 —«
1

,-
1 qT
1 o S 1 1
TS5
! T3 1 TJ 1
-D ^ £ ^ ! 9- 1 9-
cs
Q- £
i
i
1
£ E ^ E
— X —
1
' "a. -i ( ro

f CL a. 22fe ?- i '1'
Z
1

O
<
o
CL

s W
o
00
N

r^ O •* O ff) o *^ p-»
r^ ^
Tt 00
0(^ o ""
in

«
<D

> CVJ CO •<* (N ..t en CN T- (N CD m I— r~


ca
1*
CO
^
>• > a
«
:•
o >• >.

S O
^ Q.
3 § 1
at S °
O t- JS
CO Q CO
"^ 1-
o u
3* 00
r- ^X o "
O o
*"

r-

•o (o to TO -qL
_

a
1
1 11
T) T3
-.
U
^ 2
+ -O 1 1 11 1 -
o
^ Q
& s-^i
u
c
_J
E n Q Q a. OC
^ CL
^ < _t
-i
u < GI s
^

a
> e}8!peiuui| dtunp ujniQu pue t|83 auunoiqns I
K
1

3-31
c ID
CM § CM Coun Count
>
( U 1
(J)

a - E « 1 E ?
E ^. .2
3 U " T1 (0 T3 2 ^ S CS CL
< E
B < + ^; §• + £ + 2 3
cs
t« Q. CM
a- ^ 0.
"n
-J

3 .*;
I + o -!-
O + o + o
•J3
C
e ?
o
Q.
FU
£ 0.
^u^
© « £L
•f
CM
m o
^ o
< U x:
< m c o g 1 o o
i i I

I> E
CO « E IS
^ B 4°
D £
ff
is c -^ c -^ c -^ c -J
g " 2
©_2 ^^5 S«>.
w£^
(0 *E>i2
i £
S <D^ <»•£
o e ®
5i: < E < < I » 1

o ^
I
- "^
E S,
o «
ir ;n^nj^ = "qo
o 4s 1
.
< ^ o <o£

o
00
N
O O X

E
E
CO
<
CO

(M CM CM CM CM
Q. a
2 3 2 i 2

a^eiedQ a^eipeuiUJi uojtipuoQ uo dturif

3-32
c
o
o

<

o
00

E
£

CO

8AO[/^ jaiS[6ey-ja^8i6s^

3-33
"~~nm>m>m '"™~™"mmm^ ^m
>. *.
X >
o o 2
X IS <D

o
o
2 o 3 £ £
5 b X
^ E
1
3 1 2 "5
2 o X 1
B 1 ^ s
3 O < 3 c o o o O
8 O
"5
< to 1 2
3
v>
c c c
1 o < c
o c c o
£ 8 E o fe
o 2
o
o < £- « o c:
c
o c g g
< 2c c 5 o O
^ E 2 5 2
c
r E T3 o 'to 2
o o S
.5 o 8 c 'O)
c
< c
2 £ 1
O 2 1 £ o
1 o s
B t f o i
In
o Q. u ^ a
o m
« „ £ 2«
o
™ c 1 a! a
a X
-o)

+ 5
+ 2 + 1 s > i 1
< <
c
< 1 < 1 51 51 8
i 1 1 ^
™ 1to ™ to
1 11

1 1 1
1 g i ^ o
1 1
_i a i
* to
(1

^
^- 5^ ^-^
1 '

<< < ^ < CO


2« << <^ <" <^ X '- 3r >. r- J:.

z o o - - o o o - O o - o O

<" X X X X - - - X - - - - -

o o o o o Q- Q. a. o o O
, a.

to CO X X X X X X X X X X

N X X X X X X X X X X

o X X X X o o o X X X X X >£

"t -* ^ ^ ^ •* -<* •* - in in tn in

s f ^
^ ^ r~ T- T- ^ r- CM CM tv) CM
m

o o
£ t t t 5 8 8
1 1 1 1 1 8 iX
X X X
u o o o
o O o
.£, o o
^ "" '" "" O O O O o
'- "- *"
o O Q Q
§ CI
o Uw

oc a a a a
CO
« rr OJ 05 O) en a
< < < £
X X X X >
O

o
o CJ m u a m Q o u Q Q
o a D
«
CD
O X O o OD O O
g < < CO < < < CO < <
^

1 e^siBdo JeisiBea-JSlsiBsy
1-
^ ^^

3-34
are

contents

Accumulator

register
register

o r^
o n
1 a

i i

Index

complement)

§ that
or
CO 1 f
1
Index

f "
1 operands
complement)

1 or
1
pair

^
^ o1 Hh
o 1
1
assuming

tones
+
xyl
^
^
CO IJ ^
(
register
register

s [
xy]
''
o
a.
BCD
(twos
-"
contents
i i
contents

O of
Accumulator
of
of
Accumulator,

[
xy]
[
xy]

difference

1
Accumulator
1
+
register
or

1
+
contents
1
-
register
or

1
-
contents"

j
E] 1
L
adjust

or
Complement
[
reg]


[
rp] [
reg]

-
Decrement
rpl
t Decrement
1 LJ 1 l_f 1
Increment Increment

Negate — —
sum
[A]-{A]^-

Decimal

rpl
the
reg]
t ( reg)
t [
rp] 1 i
1
Z ^ ^ o ^ o o o
o X X X X o o o
< »-

i Q. O O O

o
00
1 to X XX X

N X XX X

o X X X X X
O

E
E
D
n ^ xi- CO ^ (D 2 ^ tD^ ^ ^ ^

to
to

< s>- r- ^ CM r- ^CNr- T-CM - -


ffl

00

r. ^ Z S OOO oo
^ ^ Q 1^1 s :: s
1 ^^
1
o

1 5- ?
£ - f e-

< O U U U <
1 <
-i
Q.
(5
UJ 7 -^ UJ UJ
u
o a z ^ ^ o D
i

B|&J9dO J9^Sl69H B\Bxo\ji pu8 ums ^sisiBau


1

3-35
o
u
CO

O
00
M

06
<
CO

CO

{panufiuoo) ejejoy pue xms ^eisffiea

3-36
^

M^^
-^
ffl 50 £• o
S| |<
.9
o
o| s—
o

it ^-5 1
m
2 » ^Jta- c
__ J
•tt HBBBBI "5 CO _i 1-
r-™-^
n
"
o
^
^
o < o X « _i
1
^ X ffl }s
in
CO 1 <* 2 1 ^
"D "5 «

T
OQ
0)
-"-1 r^ 4^^
E
g
i
s
5 r-
II
u a>
r-
aniKB « O
•c £ ^^* § < £ 2 „
t Q. o 0) »«- c c
o -o
c o •D £ o
g C
m c iS 1 ^
A
"£ m <s a> » U
i T
j|
e> "ui O)
- ^ 1 ^an ^3
1 £ - £
— o 1 8 O Sa> f -d
o '" ' g .^aim
« »
1
1
CO
^m— 2 £ < < 11 f
o o
ZJ
.E
c
i
c
o
To
c '-5.
?
^1
» e

o
£
«

iS
o n m "r fe
a,

o X
a;
° .9 o
"S
o o ^
'-g
g
« CO

£ o o o o

< o o o o
n
2
T g.
Q. Q. CL a.

2
o c/) CO X X X X
CO
rvi
N X X X X
U X X
o
CO
00 00 00 00
E
E
CO to
«
< s;^ CM CS C*4 CM
OS

CO
o
XI
E
1
5 o ^ to
o o o a
o o UJ UJ
QD m
o U u

ac
£ C3) en

£ £ £
o

o
< _t a o
1 tn a: tr.

c tn « a: tr

=
«
^ (penuj^uoQ) 0}B|oy pue ^^ms i0>«t&»i| |
^-
1

3-37
1

i2

I
to

i o

a o

+ ^ s ^ c O C
«
I

; >: o £ , p „ Q.
O
'5
Q- -^T
P >_ .^ T!
13
^
JO
O
U 1
__
S _ £ .2 a a;
^ o) a ^ 1
c £ 1
'^ O c:
C S o ^i
-^ f i f
5= *-
i *-s a
O
1 t^J I N.=;-B)«x«-^ro^
z:;
3 o ci i TT

o
00
N

E
E
3
<

O ^ ^ o -a
t: ^ CD o J.
E
-g S '-^
:: :q ^ u ;:
o ^
o o
O t-
o b - ;S
m <- O

« ^

uo!^0|nd|U8|/^ ^IS

3-38
»
o
E
g 1
•a
at

E £ +^

at-
0) "5

(S u
Q. 15 -S
£ Q. « £
o
1 C m a ^
£ 1 .1 E a
a O
':;
o
O 0)
O) E ^
= -S
-"^
o O
£ 3 z
-s »-l° g
c ' f
5 1 is
o ®
IIII^I
l^^^i
ffl*~i-csi
nit
ro'^'^te u 9- m
o «HEc
!

1 ^Z.\uB a-c
^ 3
ro

a g ^ «
Qiii^ = 5
1 S5 §5 1 i i <s O
.i
„_ crtnco 1

u
1

u H U
Q.

Z o o

< o <^

m
o
i^
3 0.

o »
00
^4 N

o t- X

^ ^ *~ ]*^a5cooo -* '^ -t ^
o o
t/5
«
< <D
?L T-t-i~ C^^<^j(^^C^iC^i 1— <- ^ ^
«
CO

o
*- Q in CD (D UJ
cnm^ ^^xrtnin r- u. o
o U-U.X
^
QCSOQQ
UJ LU UJ LU LU
CO en O
to
1^

§
O

TJ
C
2 C O '- (N
tD
a
O

u
e
o
£
c:
5e| £|s CO U it
s

s
?: »dnii«U| 8n»8js
H

3-39
Table 3-5. Instruction Object Codes in Numerical Order

OBJECT CODE IMSTRUCTION OBJECT CODE INSTRUCTION

00 NOP 39 ADD HL.SP

01 yyyy LD BCdatate 3A ppqq LD A,(addr)

02 LD (BO.A 38 DEC SP
03 !NC BC 3C INC A
04 iNC B 3D DEC A
DEC 8 3Eyy LD A.data
05
06 yy LD B.data 3F CCF
07 RLCA 4 Osss LD B.reg

08 EX AF.AF' 46 LD B.(HU

09 ADD HL.BC 4 1sss LD Creg


LD A,(BC) 4E LD C,(HU
OA
OB DEC BC 5 Osss LD D.reg

oc INC C 56 LD D.(HU

OD DEC C 5 1sss LD E.reg

OEyy LD Cdata 5E LD E,(HU

OF RRCA 6 Osss LD H,reQ

10 disp-2 DJNZ disp 66 LD H.(HU

11 yyyy LD DE.dataie 6 Isss LD L.reg

12 LD {DE),A 6E LD L,(HU

13 INC DE 7 Osss LD (HU.reg

14 INC D 76 HALT
15 DEC D 7 Isss LD A.reg

16 yy LD D.data 7E LD A,(HU

17 RLA BOrrr ADD A.reg

18 disp-2 JR dtsp 86 ADD AjHU


19 ADD HLDE B Irrr ADC A.reg

1A LD A,{DE) BE ADC A,(HU


IB DEC DE 9 0rrr SUB rag

1C INC E 96 SUB (HU


ID DEC E 9 1rrr SBC A.reg

lEyy LD E.data 9E SBC A,{HU


IF BRA AOrrr AND reg

20 disp-2 JR NZ.disp A6 AND (HU


21 yyyy LD HL.dataie A 1rrr XOR reg

22 ppqq LD (addrlHL AE XOR (HU


23 tNC HL B Orrr OR reg

24 INC H 86 OR (HU
25 DEC H B 1rrr CP reg

26 yy LD H.data BE CP (HU
27 DAA CO RET NZ
28 disp-2 JR Z,disp C1 POP BC
29 ADD HUHL C2ppqq JP NZ.addi

2A ppqq LD HLXaddr) C3 ppqq JP addr

28 DEC HL C4 ppqq CALL NZ.addr

20 INC L C5 PUSH BC
2D DEC L C6yy ADD A,data

2E LD L,data C7 RST OOH


2F CPL C8 RET Z
30 disp-2 JR NCdisp 09 RET
31 yyyy LD SP.data16 CA ppqq JP Z,addr
32 ppqq LD (addr),A CBOOrrr RLC reg

33 tNC SP C8 06 RLC (HU


34 INC (HU CBO Irrr RRC reg

35 DEC (HU C8 0E RRC mt)


36 yy LD (HLWata CB 1 Orrr RL reg

37 SCF CB 16 RL (HU
38 JR Cdisp CB 1 Irrr RR reg

3-40
Table 3-5. Instruction Object Codes in Numerical Order (Continued)

OBJECT CODE INSTRUCTION 1 OBJECT CODE INSTRUCTION


|

CB IE RR (HU DO CB disp tObbbllO RES b.OX + disp)


CB 2 Our SLA reg DO CB disp llbbbHO SET b,{IX + disp)
CB26 SLA (HU DO El POP iX
CB 2 Irrr SRA reg 00 E3 EX (SPUX
CB2E SRA {HU D0E5 PUSH !X
CB3 Irrr SRL reg DDE9 JP (IX)
CB3E SRL (HU DDF9 LD SP.IX
CB Olbbbrrr BIT b.reg DE VY SBC A,data
CBOIbbbllO Btr b,{HU OF RST tSH
CB lObbbrrr RES b.reg EG RET PC
CB 10bbb110 RES b,{HU El POP HL
CB nbbbrrr SET b.reg E2 ppqq JP PO.addr
CB ItbbbllO SET b,{HU E3 EX (SP),HL
CC ppqq CALL Z.addr E4 ppqq CALL PO.addr
CD ppqq CALL addr E5 PUSH HL
CEyy ADC A.data E6yy AND data
CF RST 08H E7 RST 2QH
DO RET NC E8 RET PE
01 POP DE E9 JP (HU
02 ppqq JP NCaddr EA ppqq JP PE.addr
03 w OUT {portlA EB EX OE.HL
D4 ppqq CALL NCaddr EC ppqq CALL PE.addr
05 PUSH OE ED OldddOOO IN reg,(C)
06 w SUB data ED OtsssOOl OUT (O.reg
07 RST 10H ED Olxx 2 SBC HUrp
08 RET C ED Olxx 3 ppqq LD {addr).rp
09 EXX ED 44 NEG
OA ppqq JP Caddr ED 45 RETN
OByy IN A.iport) ED010nn110 tM m
OC ppqq CALL Caddr ED 47 LD I.A

DD OOxx 9 ADD iX,pp ED 01 XX A ADC Hl,rp


DO 21 yyyv LO !X,data16 ED 01xx B ppqq LD rp,(addr)
DD 22 ppqq LD (addrUX ED 40 RET!
DO 23 INC !X E0 4F LO R.A
DD 2A ppqq LO IX.(addr) E0 57 LO A,!
D0 2B DEC fX ED5F LD A.R
00 34 disp INC {!X + disp) E0 67 RRO
00 35 dIsp DEC {IX + displ E0 6F RLD
00 36 disp yy LD (!X + displdata ED AO LOI
DD01ddd110dtsD LD reg.dX + disp) ED A1 CP!
DD / Osss disD LD {IX + displreg EDA2 IN!

DO 86 disp ADD A.dX + disp) ED A3 OUT!


DD 8E disp ADC A,{IX + disp) E0A8 LDD
00 96 disp SUB {IX + disp) E0A9 CPD
DO 9E disp SBC A.dX + disp) EDAA iND
DD A6 disp AND {IX + disp) EDAB OUTD
DD AE disp XOR (IX + disp) ED BO LDIR
DD 86 disp OR (iX + disp) EDBt CPIR
DD BE disp CP (IX + disp) EDB2 INIR
DO CB disp 06 RLC {IX + disp) EDB3 OTiR
00 CB disp OE RRC (IX + disp) E0B8 LDDR
DD CB disp 16 RL !IX + disp) E0B9 CPDR
DD CB disp 1E RR {IX + disp) ED BA INDR
DD CB disp 26 SLA (IX + disp} ED SB OTDR
DD CB disp 2E SRA (IX + disp) EEyy XOR data
DD CB disp 3E SRL (IX + disp) EF RST 28H
DDCBdispOlbfabllO BIT bJIX + disp)

3-41
Tabie 3-5. Instruction Object Codes in Numerical Order (Continued)

OBJECT CODE INSTRUCTION OBJECT CODE INSTRUCTION


| |

FO RET P FD BE disp ADC A,{IY-fd!spl

F1 POP AF FD 96 disp SUB (tY-fdisp)

F2 ppqq JP P.addr FD 9E disp SBC A.OY-fdispi

F3 Dl FD A6 disp AND OY + disp}


F4 ppqq CALL P.addr FD AE disp XOR (tY + disp)
F5 PUSH AF FD 86 disp OR |!Y + disp}
F6yv OR data FD 8E disp CP (lY + dispj
F7 RST 30H FD CB disp 06 RLC liY + disp)
F8 RET M FD CB disp OE RRC (lY + dispf
F9 LD SP.HL FD CB disp 16 RL (iY + disp)
FA ppqq JP M.addr FD C8 disp IE RR (lY+disp)

FB Et FD CB disp 26 SLA {!Y + disp)


FCppqq CALL M.addr FD CB disp 2E BRA (lY + disp)
FDOOxxS ADD lY^rr FD CB disp 3E SRL (iY + dispt
FD21 yyyy LD IY,data16 FDCBdispOlbbbllO BiT b.(!Y + disp}
FD 22 ppqq LD (addrUY FD CB disp lObbbllO RES b.(!Y + disp)
FD23 tNC lY FO CB disp llbbbllO SET b,{iY + disp)
FD 2A ppqq LD !Y,(addri FDE1 POP lY

FD28 DEC lY FDE3 EX (SPhtY

FD 34 disp INC OY + disp) FDE5 PUSH lY

FD 35 disp DEC OY + disp) FDE9 JP (lY)

FD 36 disp yy LD (lY + dispidata FDF9 LD SP.IY

FDOIddd 110 disp LD reg,(!Y4.dispJ FEyy CP data

FD 7 Osss disp LD ilY + diSpKreg FF RST 38H


FD 86 disp ADD A,(lY + disp)

3-42
1

ADC A,data — ADD IMMEDIATE WITH CARRY TO


ACCUMULATOR

S Z Ac P/0 N C Data
Memory
H IXIXIXIXIOIX 1 i
^,- ' i^,^
A XX ^ CC -*• XX + w^^l^
B.C
D,E
H,L
SP
PC mmmm ^-J^jr^mmmm + 2^ Program
tx rviemorv
!Y
1

1
CE mmmm
" 1
YY mmmm +
mmmm + 2
mmmm + 3

ADC A. data

^cT yv

Add the contents of the next program mennory byte and the Carry status to the Ac-
cumulator-

Suppose xx=3Ai6, VV=7Ci6» and Carry=0. After the instruction

ADC A7CH
has executed, the Accumulator will contain BSig:

3A = 1 1 10 10
7C 0111 1 00
1

Carry
01 1 01 1

1 setsS to 1-^-- Non-zero result set Z to

No carry, set C to 0-^- Carry, set Aq to 1

>- ^ .

0¥1-t setP/Oto1 Addition instruction, set N to

The ADC instruction is frequently used in multtbyte addition for the second and subse-
quent bytes.

3-43
1

ADC A,reg — ADD REGISTER WITH CARRY TO


ACCUMULATOR

Data
XX + Yv + C^ Memory

'^"J"'^
contents of
A3,C,D,E,H
or L is yy

Program
mmmm + j
Memory

lOOOIxxx mrnrnm
+ 1
nrimrnnfi

mrnmrn + 2
rnmmm •+•
3

ADC A, reg

10001 XXX
000 for reg=B
001 for reg==C
010 for reg=D
Oil for reg=E
100 for reg=H
101 for reg=L
111 for reg==A

Add the contents of Register A, B, C, D. E. H or L and the Carry status to the Accumula-
tor.

Suppose xx^ES-jg, Register E contains AO^g. and Carrv=1. After the instruction

ADC A.E

has executed, the Accumulator will contain 84-] g:

E3 = 1 1 1 11
AO-1010 0000
Carry = ^
1_

000 0100
1 setsS to 1-^-- Non-zero result set Z to

Carry, set C to 1-^— i No carry, set Aq to

J^
1
^
Vl"^. set P/0
:

to Addition instruction, set N to

The ADC instruction is most frequently used in muttibyte addition for the second and
subsequent bytes.

3-44
ADC A,{HL) —ADD MEMORY AND CARRY TO
ADC A,{IX+disp) ACCUMULATOR
ADC A,<IY-hdlsp)

S Z Ac P/O N C
4xixixixioTxl

The iHustration shows execution of ADC A,(HU:


ADC A,(HU

Add the contents of nmemory iocation (specified by the contents of the HL register pair)
and the Carry status to the Accumulator

Suppose xx===E3^g, yy^AOte- snd Carry=1. After the instruction

ADC A,(HU
has executed, the Accumulator will contain 84ie:

E3 = 11 1 11
AO = 1 1

Carry =
I
1 000 0100
1 sets S to Non-zero result set Z to

Carry, set C to 1 No carry, set Aq to

1¥1=0, setP/OtoO Addition instruction, set N to

ADC A,(IX+disp)

DD 8E d

Add the contents of memory location (specified by the sum of the contents of the IX
register and the displacement digit d) and the Carry to the Accumulator.

ADC A,(IY+disp)

FD 8E d
This instruction is identical to ADC A,(IX+disp), except that it uses the lY register in-
stead of the IX register.

The ADC instruction is most frequently used in muitibyte addition for the second and
subsequent bytes.

3-45
1

ADG HL,rp — ADD REGISTER PAIR WITH CARRY TO H AND L


3 Z AqP/O N C

A
B.C (*r
D.E ) -.
H.L XX XX S5
SP
mmmm
r
PC
tx
^*
>»v|
iY
!

R 1

ADC HLrp

ED 01 xxl 01
00 for rp is register pair BC
01 for rp is register pair DE
10 for rp is register pair HL
1 for rp IS Stack Pointer

Add the 16-bit value from either the BC, DE. HL register pair or the Stack Pointer, and
the Carry status, to the HL register pair.

Suppose HL contains ASSe-je, BC contains 1044^6, and Carn/=1. After execution of

ADC HLBC
the HL register pair wit! contain:

A536 = 10100101 0011 0110


1044 = 00010000 0100 0100
Carry = 1
1011 0101 0111 1011

1 sets S to 1 JV -Non-zero result set Z to

Aq
No carry, set C to -No carry, set to

JT^
0¥0=0, setP/OtoO Addition instruction, set N toO

The ADC instruction ts most frequently used in nnultibyte addition for the second and
subsequent bytes.

3-46
ADD A,data— ADD IMMEDIATE TO ACCUMULATOR
S ZAcP/ON C 03^3
F ixixix|X|0|X| Memory

ADD A. data

C6 vy
Add the contents of the next program memory byte to the Accumulator.

Suppose xx^SA-jQ, yv=7Ci6, and Carry=0. After the instruction

ADD A7CH
has executed, the Accumulator wit! contain 86t6:

3A = 1 1 10 10
7C - 1 1 1 110
1 oil Olio
1 sets S to 1 Non-zero result set Z to

No carry, set C to 0-« Carry, set A^; to 1

OV-1-1; set P/0 to 1 Addition instruction, set N to

This is a routrne data manipulation instruction.

3-47
1

ADD A.reg — ADD CONTENTS OF REGISTER TO


ACCUMULATOR
S Z Ac P/O N C Data
Memory
FIXIXIXIXIOTTI

Program
Memory

lOOOOxxx mmmm
mmmm +
mmmm + 2
mmmm 3 -*•

ADD reg

10000 XXX
000 for reg=B
001 for reg=C
010 for reg==D
011 for reg=E
100 for reg=H
101 for reg=L
111 for reg=A
Add the contents of Register A. B, C. D, E, H or L to the Accumuiator.

Suppose xx^ES-jg, Register E contains AO-jq. After execution of

ADD A,E

the Accunnulator will contain SS-jq:

E3 = 1 1 1 11
AO-1010 0000
000 001

J
1 1

1 sets S to 1 Non-zero result set Z to

Carry, set C to 1 • No carry, set Aq to

1 ¥• 1 =0. set P/O to Addition instruction, set N to

This !S a routine data manipulation instruction

3-48
ADD A,{HL) — ADD MEMORY TO ACCUMULATOR
ADD A,{IX4-disp)
ADD A,{IY-l-disp)
S Z Ac P/O N C
F ix|x|X|X|0|X|

ppqq + d

The iliustration shows execution of ADD A,{IX+disp}.

^ADD A.dX+disp)

DO 86 d
Add the contents of mennory location (specified by the sum of the contents of the IX
register and the displacement digit d) to the contents of the Accumulator.

Suppose ppqq=4000-[g, xx^lAig. and memon/ location 400Fi6 contains SOiq. After
the instruction

ADD A.(1X+0FH)
has executed, the Accumulator will contain 6Ai g.

1A = 000 1 10 10
50 = 0101 0000
110 1010
sets S to J
0^ Non-zero result set Z to

No carry, set C to O- No carry, set Aq to

0¥0-0; set P/O to Addition instruction, set N to

^ADD A,(IY 4-disp)

FD 86 d

This instruction is identical to ADD A,(IX+disp), except that it uses the lY register m
stead of the IX register.

ADD A.iHU

86
This version of the instruction adds the contents of memory location, specified by the
contents of the HL register pair, to the Accumulator.

The ADD instruction Is a routine data manipulation instruction.

3-49
1 1

ADD HLrp — ADD REGISTER PAIR TO H AND L


S Z A^P^O N C Data
Memory
"oTxl
M 1 l>^l
1

\ 8C, DE, HL or SP
A 1

BC
OE
H.L XX XX 1 t^f^xxxx -t-
VYW^^'^
SP
Program
PC mmmm Memorv
IX T mmmm + 1 J
iY
OOxxICWI. mfnmm
i

R
mmmm +
r mmmm + 2
mmmm * 3

ADD HLrp

00 XX 1001
00 for rp is register pair BC
01 for rp is register pair DE
10 for rp is register pair HL
1 for rp fs Stack Pointer

Add the 1 6-bit value from either the BC, DE, HL register pair or the Stack Pointer to the
HL register pair.

Suppose HL contains 034A^6 and BC contains 2!4Ci6- ^^ter the instruction

ADD HLBC
has executed, the HL register pair wi!i contain 2496-tg.

034A = 0000 00110100 1010


214C = 0010 0001 0100 1100
00100100 1001 0110

No carry, set C to ^^ -No carry, set A^ to

N
Addition instruction, set to

The ADD HLHL instruction Is equivalent to a 16-btt left shift

3-60
1 1

ADD xy,rp — ADD REGISTER PAIR TO INDEX REGISTER


S Z Ac P/O N C
Data
Memory

A
B.C
D.E rr ss
H.L
SP
PC mmmm Program
IX
ly

H
!
ppqq
S^
^>^
''^

Cppqq -f ^
-^
rrss^^P
Memory

11y11101
OOxxlOOl
mmmm
mmmm +
mmmm + 2
mmmm + 3

The illustration shows execution of ADD !X.DE.

11 V1 1101 OOax 1001

n''^
'

for Index reglster=iX


^ 00 for rp is register pair BC
1 for Index register==iY 01 for rp is register pair D£
10 for rp is specified Index register
1 for rp is Stack Pointer
Add the contents of the specified register pair to the contents of the specified Index
register.

Suppose lY contains 4FF0'i6 and BC contains OOOF^e. After the instruction

ADD lY.BC

has executed, Index Register lY will contain 4FFF'j6.

3-51
' 3 1

AN Ddata — ANC IMMEDIATE WITH ACCUMULATOR


1

S Z Ac P/O N C Data

XlX

A
f1 1 1 IX 10 10 i

!l
XX 1
^*a
^ ^
RC
0,E
H.L
SP
PC mmmm .m^ mmmm + 2 Program

IX
iY
i
'
E6 mmmm
R
L- YY mmmm +
mmmm 2
-J-

mmmm + 3

AND data

E6 vv

AND the contents of the next program memon/ byte to the Accumulator.

Suppose xx^SAiQ. After the instruction

AND 7CH
has executed, the Accumulator will contain SS-jS-

3A = 1 1 10 10
7C 111 1100
001 1 1000
a
sets S to 0^'^^ — -Three 1 bits, set P/O to

-Non-zero result, set Z to

This is a routine logical instruction; it is often used to turn bits "off" For example, the
instruction

AND 7FH
will unconditionally set the high order Accumulator bit to 0.

3-52
1

AND reg — AND REGISTER WITH ACCUMULATOR


S Z AcP/O N C Data
:|X|X|1|X|0|0l
XX •yy
^ Memory

t
contents of
A3,C,D,E,
H or L is yy

mmmm + j Program
Memory

lOIOOxxx

mmmm + 2
mmmm 3 -^

AND reg

10100 XXX
000 for reg=B
001 for reg^C
010 for reg==D
011 for reg=E
100 for reg=H
101 for reg-L
111 for reg=A
AND the Accumulator w!th the contents of Register A. B, C, D. E, H or L Save the result
in the Accumulator.

Suppose xx=E3i6. and Register E contains AOig. After the instruction

AND E

has executed, the Accumulator will contain AOig-

E3 = 1 1 1 11
AO 1010 0000
1010 0000
1 sets S to ,^ ii
-Two 1 bits, set P/0 to 1

-Non-zero resuit, set Z to

AND is a frequently used logical instruction.

3-53
AND (HL) — AND MEMORY WITH ACCUMULATOR
AND (IX+disp)
AND (lY+disp)
S Z Ac P/O N C

The illustration shows execution of AND (lY+disp).

AND (lY+djsp)

FD A6 d

AND the contents of memorv location (specified by the sum of the contents of the lY
register and^the displacennent digit d) with the Accumulator.

Suppose xx=E3t6, ppqq=4000i6' and memory location 400Ft6 contains AOig. After
the instruction

AND (lY+OFH)

has executed, the Accumulator will contain AOiq.

E3 1110 111
AO 1010 0000
10 10 0000
1 sets S to 1
*J 4
-Two 1 bits, set P/0 to 1

-Non-zero result set Z to

AND (IX+disp)

DD A6 d

This instruction is identical to AND (lY+disp), except that it uses the IX register instead
of the lY register.

AND (HL)

A6
AND the contents of the memory location (specified by the contents of the HL register
pair) with the Accumulator.

AND is a frequently used logical instruction.

3-54
^ 1

BIT b.reg — TEST BIT b IN REGISTER reg


S
fAq P/0
Z n c
Data
F

A
1 ulbll lulO 1
1
i.^
^\ c±> Memory

8,C yyybyyyy
D.E
H.L
SP
HC mmmm ir*< Program
IX Memory
lY
1

1
C8 mmmnn
1 Olbbbxxx mmmm +
mmmm + 2
mmmm + 3

BIT b. reg
-.m-r-m^ >—V—
CB01 bbb XXX

Bit Tested Register


000 000 B
1 001 001 C
2 010 010 D
3 011 Oil E
4 100 100 H
5 101 101 L
6 110 111 A
7 111
Place complement of indicated register s specified bit in Z flag of F register.
Suppose Register C contains 1 1 1 1 1 1 1 The instruction BIT 4.C will then set the
.
Z flag
to 1. white bit 4 m Register C remains 0, Bit is the least significant bit

3-55
BIT b.(HL) —TEST BIT b OF INDICATED MEMORY POSITION
BIT b,{IX+disp)
BIT b.(IY+disp)

S
fAcP/O N
Z c Data
Memorv
rrrr

A
^"^^b™.*-*^ VWPVVW ppqq
B.c
O.E
H.L
SP
Program
PC mmmm Memory
IX
lY
I
CB mmmm
R OlbbbllO mmmm + 1

mmmm + 2
mmmm + 3

The illustration shows execution of BIT 4.(HU. Bit ts the least significant bit

BIT ^ (HU

CB01 bbb 110

Bit Tested bbb


000
1 001
2 010
3 Oil
4 100
5 101
6 110
7 111

Test indicated bit within memon/ position specified by the contents of Register HL, and
place bit's connplement in Z flag of the F register.

Suppose HL contains 4000H and bit 3 In memon/ location 4000H contains 1. The In-

struction

BIT 3,(HL)

will then set the Z flag to 0, while bit 3 in memon/ location 4000H remains 1.

BIT b.dX+disp}

DD CB d 01 bbb 110

bbb IS the same as in BIT b.(HL)

Examine specified bit within memory location indicated by the sum of Index Register IX

and disp. Place the complement In the Z flag of the F register.

3-56
1

Suppose Index Register IX contains 4000H and bit 4 of memon/ location 4004H is 0.
The instruction
B1T4.{IX+4H)
will then set the Z flag to 1, while bit 4 of memon/ location 4004H remains 0,

BIT b.(IY+disp)

FD CB d 01 bbb 110

bbb IS the same as m BIT b,(HU


This instruction is identical to BIT b,{IX+disp), except that it uses the lY register instead
of the IX register.

CALL label— CALL THE SUBROUTINE IDENTIFIED IN THE


OPERAND
S Z Ac P/O N C

i I II I I I

xxxx-2
xxxx-
xxxx

CALL label

CD ppqq
Store the address of the instruction following the CALL on the top of the stack: the top
of the stack is a data memory byte addressed by the Stack Pointer. Then subtract 2
from the Stack Pointer in order to address the new top of stack. Move the 1 6-bit address
contained in the second and third CALL instruction object program bytes to the Pro-
gram Counter, The second byte of the CALL instruction is the low-order half of the ad-
dress, and the third byte is the high-order byte.

Consider the instruction sequence:

CALL SUBR
AND 7CH

SUBR
After the instruction has executed, the address of the AND instruction is saved at the
top of the stack. The Stack Pointer is decremented by 2. The instruction labeled SUBR
will be executed next

3-57
CALL condition, label — CALL THE SUBROUTINE IDENTIFIED IN
THE OPERAND IF CONDITION IS
SATISFIED
CALL condition, label

PP qq

f Condition Relevant Flag


000 NZ Non-Zero Z
001 Z Zero Z
010 NC Non-Carry C
oil C Carry C
100 PO Parity Odd P/0
101 PE Parity Even P/0
110 P Sign Positive S
111 M Sign Negative S

This instruction ts identicai to the CALL instruction, except that the identified
subroutine wilt be caiied only if the condition is satisfied: otherwise, the instruction se-

quentially following the CALL condition instruction will be executed.

Consider the instruction sequence:


!

CALL !
t COND.SUBR
condition not satisfied

AND f 7CH
condition
satisfied

SUBR

If the condition is not satisfied, the AND instruction will be executed after the CALL
COND.SUBR instruction has executed. the condition is satisfied, the address of the
If

AND instruction is saved at the top of the stack, and the Stack Pointer is decremented
by 2. The instruction labeled SUBR will be executed next.

3-58
1

CCF — COMPLEMENT CARRY FLAG


,1
H
S Z Ac P/O N

till
C
IXL- — *l
Data
Memorv

A
8.C
D.E
HX
SP
PC mmmm T*^ mmmm + 1^ Program
fX Memory
!Y
t

R
^ 1
3F mmmm
mmmm +
mmmm + 2
mmmm + 3

CCF

Complement the Carry flag. No other status or register contents are affected.

3-59
1

CP data — COMPARE IMMEDIATE DATA WITH


ACCUMULATOR

s
S Z Aq P/0 n c Data
VIC vf y
Ix|x|x|x| i|x|
L^^
B,C
XX -^
D,E
H.L
SP
Program
PC mmmm .^-^ mmmm + 2^ « HJI.
ivieufu! V
i

!X
!Y
i
FE mmmm
R
U_ vv mmmm +
mmmm + 2
mmmm + 3

CP data

of the Ac-
Subtract the contents of the second object code byte from the contents
both numbers as simple binan/ data. Discard the result; i.e.. leave
cumulator, treating
result of the subtrac-
the Accumulator alone, but modify the status flags to reflect the
tion.

Suppose xx=E3i6 and the second byte of the CP instruction object code contains
AOig. After the instruction
CP OAOH

has executed, the Accumulator will still contain E3i6. but statuses will be modified as
follows:

E3 - 1 1 1 11
AO-1010 0000
100 0011

sets S to 0'J Non-zero result set Z to

No borrow, set Aq to
No borrow, set C to 0-

^r^
1^1-0. set p/0 toO Subtract instruction, set N to 1

Notice that the resulting carry is complemented.

3-60
CP reg — COMPARE REGISTER WITH ACCUMULATOR

^^xx^ Data
Memory

T
4>
Contents of
ABC DE H
or L is yy

mmmm + {j Program
Memory

lOlllxxx mmmm
mmmm -f 1

mmmm + 2
mmmm + 3

CP reg

ioni XXX
000 forreg=B
001 forreg=C
010 forreg=D
Oil for reg=E
100 for reg=H
101 for reg=L
111 for reg=A

Subtract the contents of Register A. B. C. D. E, H or L from the contents of


the Ac-
cumulator, treating both numbers as simple binary data. Discard the result: i.e.,
leave
the Accumulator alone, but modify status flags to reflect the result of the
subtraction.
Suppose xx=E3^6 and Register 8 contains AO^g. After the instruction

CP B
has executed, the Accumulator will still contain E3i q, but statuses will be modified as
follows:

E3 = 1 1 1 00 11
A0 = 1010 0000
100 0011
sets S to 0*J Non-zero result set Z to

No borrow, set C to No borrow, set Aq to

1 V- 1 -0. set P/0 to Subtract instruction, set N to 1

Notice that the resulting carry is complemented.

3-61
CP (HL) —COMPARE MEMORY WITH ACCUMULATOR
CP (IX+disp)
CP (lY-hdisp)

S Z AcP^O N C
FHxIXlXiXnlxj

The illustration shows execution of CP (HL):

CP {HU

BE
contents of the HL register
Subtract the contents of memory location (specified by the
pair) from the contents of the Accumulator, treating both numbers as simple bman/
alone, but modify status flags to
data. Discard the result; i.e.. leave the Accumulator
reflect the result of the subtraction.

Suppose xx=E3i6 and yy-AOie- After execution of

CP (HU

the Accumulator will still contain ES^q, but statuses will be modified as follows:

E3 = 1 1 1 11
A0 = 0110 0000
10 11

sets S to J Non-zero result set Z

No borrow, set A^
to

to-0
No borrow, set C to 0-.

1¥-1=0. set P/0 toO Subtract instruction, set N to 1

Notice that the resulting carry is complemented.


CP (IX+disp)

DD BE d

3-62
^

Subtract the contents of memory location (specified by the sum of the contents
of the
IX register and the displacement value d) from. the
contents of the Accumulator, treat-
ing both numbers as simple binary data. Discard the result; i.e.,
leave the Accumulator
alone, but modify status flags to reflect the result of the subtraction.

CP (lY+disp)

FD BE d
This instruction is identical to CP (IX+disp). except that it uses the lY register instead of
the IX register.

CPD — COMPARE ACCUMULATOR WITH MEMORY.


DECREMENT ADDRESS AND BYTE COUNTER

S Z AcP/O'N
^1 XA-VV 1^
C
Data
Set If BC-1 ;&0,
IXIXIXI 1,1 1

otherwise
Memory
^ reset
v_^ _^i 1
.

A
XX
XX
uu
""
.^^<1^ rtitu 1

L
yy ppqq
O.E
H.L PP qq <«*—-"x^^^*— 1
SH V
-

^v—
PC mmmm S. Program
!X Memory
IV
^mmmm + >!
21
!

1 ED mmrnm
R 1 A9 mmmm + 1

mmmm + 3

ED A9
Compare the contents of the Accumulator with the contents of memory location
(specified by the HL register pair). If A is equal to memory, set Z flag.
Decrement the HL
and BC register pairs. (BC is used as the Byte Counter.)

3-63
Suppose XX-E316. ppqq=4000i6. BC contains 0001 16- and vv^AOie- After the in-

struction

CPD
has executed the Accumulator will still contain E3i6. but statuses will be modified as
follows:

E3 = 1 1 1 11
AO = 10 10 0000
100 00 11
\ k ) ^ Z
sets S to 0-^ ' 4^"*^^ Non-zero result, set to

t No borrow, set Aq to

The P/0 flag will be reset


because BC-1=0

Subtract instruction Involved,


set N to 1

Carry not affected.

The HL register pair will contain SFFF-jg, and BC=0.

CPDR — COMPARE ACCUMULATOR WiTH MEMORY.


DECREMENT ADDRESS AND BYTE COUNTER.
CONTINUE UNTIL MATCH IS FOUND OR BYTE
COUNTER IS ZERO
CPDR
ED B9
is identical to CPD. except that it is repeated
until a match is found or
This instruction
recognized and two
the byte counter is zero. After each data transfer, interrupts will be
refresh cycles will be executed.

Suppose the HL register pair contains BOOOie- the BC register pair contains OOFF-ie-
the Accumulator contains fB-\Q. and memon/ has contents as follows:
Location Contents
500016 AAi6
4FFF16 BC16
4FFE16 1916
4FFD16 7Ai6
4FFC16 F9i6
4FFB16 DDi6
execution of
CPDR
the P/0 flag will be 1, the Z flag wilt be 1, the HL register pair will contain 4FFBi6. and
the BC register pair will contain 00FAi6-

3-64
CPI — COMPARE ACCUMULATOR WITH MEMORY.
DECREMENT BYTE COUNTER.
INCREMENT ADDRESS

Compare the contents of the Accunnulator with the contents of memorv location
(specified by the HL register pair). If A is equal to memory, set the Z flag. Increment the
HL register pair and decrement the BC register pair (BC is used as Byte Counter).
Suppose xx-E3i6. ppqq=4000i6, BC contains 0032^q. and yy^ESie- After the in-
struction

CPI

has executed, the Accumulator will still contain ES-tg, but statuses will be modified as
follows:

E3 1111 0011

-E3 0000 1101


0000 0000
sets S to Result IS 0. set Z to 1

-No borrow, set Aq to

The P/0 flag will be set


because BC-1 ^0.

Subtract instruction involved,


set N to 1.

Carry not affected.


The HL register pair will contain 4001 ig, and BC will contain 0031 tg.

3-65
CPIR — COMPARE ACCUMULATOR WITH MEMORY.
COUNTER.
DECREMENT BYTl
INCREMENT ADDRESS.
CONTINUE UNTIL MATCH IS FOUND
OR BYTE COUNTER IS ZERO
CPIR

ED B1

This instruction is identicai to CPL except that it is repeated until a


match is found or
recognized and two
the byte counter is zero. After each data transfer interrupts will be
refresh cycles wit! be executed.

Suppose the HL register pair contains 4500i6. the BC register paif contains OOff-^Q,
the Accumulator contains F9-t6, and memory has contents as follows:

Location Contents
4500^6 AA16
450116 1516
4502-J6 F916

After execution of

CPIR

the P/0 flag will be 1 . and the Z flag will be 1 . The HL register pair will contain 4503-! 6-

and the BC register pair will contain 00FC'i6-

3-66
1

CPL — COMPLEMENT THE ACCUMULATOR


S Z Ac P/O N C Data
Memory

Program
Memory

2F mmmm
mmmm +
mmmm + 2
mmmm + 3

CPL

2F
Complement the contents of the Accumulator. No other registers contents are
affected.

Suppose the Accumulator contains SAig. After the instruction

CPL
has executed, the Accumulator will contain C5i6-

3A - 1 1 10 10
Complement = 1100 0101
This IS a routine logical instruction. You need not use it for binary subtraction; there are
special subtract instructions (SUB, SBC).

3-67
1

DAA — DECIMAL ADJUST ACCUMULATOR


Data
S Z Ac P/0 N C
rrr
Memory
fI
^1::j
x|x|x| |x|
r^nvert to\
A 1
XX :5±3
BC
np
H,L
SP
PC
tv
mmmm -^ mmmm + ^ Program
Memory

tY
L^ 27 mmmm
R
j

mmmm + 1

mmmm + 2
mmmm + 3

DAA
27
fornn. This instruc-
Convert the contents of the Accumulator to binary-coded decinnal
tion should only be used after adding or subtracting two
BCD nunnbers; i.e.. look upon
ADD DAA or ADC DAA or INC DAA or SUB DAA or SBC DAA or DEC DAA or NEG DAA
as compound, decimal arithmetic instructions which operate on
BCD sources to gener-
ate BCD answers.

Suppose the Accumulator contains 39i g and the B register contains 47i 6- After the in-

structions
ADD B
DAA
have executed, the Accumulator will contain S6^q. not SO^q.

Z80 CPU logic uses the values in the Carry and Auxiliary Carry, as well as the Ac-
cumulator contents, m the Decimal Adjust operation.

3-68
DEC reg — DECREMENT REGISTER CONTENTS
S 2 AcP/0 H C
^yV-I^V-^ -°^'=
n
.

F [xjxlxixM Memory

A
Contents of A,
B.C
D.E
H.L
SP
H ^^
or L is yy

^
PC
tx
iY
mmmm
^^
5r mmmm
'-' ^
-s- 1 |
Krogram
Memory

(
OOxxxlOI ninrnrn
R 1 mrnpTim + 1

mmmm + 2
mmmm + 3

DEC reg

00 XXX 101

000 for reg=B


001 for reg-C
010 forreg=D
011 for reg=E
100 forreg=H
101 for reg=L
111 for reg=A

Subtract 1 from the contents of the specified register.

Suppose Register A contains 50ig. After execution of

DEC A
Register A will contain 4Fiq.

3-69
1

DEC rp — DECREMENT CONTENTS OF SPECIFIED REGISTER


DEC IX PAIR
DECIY
3 Z A^P/O N C
^1 I I I I I I

A
B,C
D.E
H.L
SP
PC mmmm
tx
!Y

1
R

The illustration shows execution of DEC rp:

DEC rp

00 XX 1011
00 for rp IS register pair BC
01 for rp ts register pair DE
10 for rp IS register pair HL
1 for rp IS Stack Pointer

Subtract 1 from the 1 6-bit value contained in the specified register pair. No status flags
are affected.

Suppose the H and L registers contam 2F00i6. After the instruction

DEC HL
has executed, the H and L registers will contain lEff^Q.

DEC IX

DD 2B
Subtract 1 fronn the 16-bit value contained m the iX register.

DEC lY

FD 2B
Subtract 1 from the 16-bit value contained m the lY register.

Neither DEC rp, DEC IX nor DEC lY affects any of the status flags. This ts a defect in the
Z80 instruction set, inhented from the 8080. is used in Whereas the DEC reg instruction
Iterative instruction loops thatuse a counter with a value of 256 or less, the DEC rp
(DEC IX or DEC Y) instruction must be used if the counter value is more than 256, Since
I

the DEC rp instruction sets no status flags, other instructions must be added to simply

3-70
test for a zero result. This ts a typical loop form:

LD DE.DATA ;LOAD INITiAL 16-BiT COUNTER VALUE


i-OOP -
:FIRSTINSTRUCTION OF LOOP

DEC DE :DECREMENT COUNTER


LD A.D TO TEST FOR ZERO. MOVE D TO A
OR E ;THEN OR A WITH E
JP NZ.LOOP iRETURN IF NOT ZERO

DEC (HL) —DECREMENT MEMORY CONTENTS


DEC {IX-hdisp>
DEC (lY+disp)

S 2 Ac P/O N C Data
Memory

YY ppqq
B,C
O.E 4
HX
SP
qq J
PC Program
IX Memory
lY
i
35 mmmm
R mmmni -f 1

mmmm -*- 2
mmmm -t- 3

The illustration shows execution of DEC (HL):

DEC (HL)

35
Subtract 1 fronn the contents of mennory location (specified by the contents of the HL
register pair).

Suppose ppqq=4500t6, yv=5F^6. After execution of

DEC (HL)

nnemory location 4500i6 will contain BEig.

5F = 1 1 1111
-01 = 1 1 1 1 1111
lO 1 1 1110
sets S to 0- Non-zero result set Z to
-^Tif
1-^1=a setP/O toO t No borrow, set I\q to

Subtract instruction, set N to 1

3-71
1

DEC {IX+displ

DD 35 d

Subtract 1 from the contents of memory location (specified by the sum of the contents

of the iX register and the displacement value d).

DEC (lY+disp)

FD 35 d

This instruction is identical to DEC (IX+disp), except that it uses the IV register Instead
of the iX register.

PI _ DISABLE INTERRUPTS
Z Ac P/O N C

cm
S Data

n Memory

A
B,C
aE
HX
SP
mnnmm + Program
PC 1
j Memory
IX
lY
t F3 mmmm
R mmmm -*-

mmmm + 2
mmmm + 3

Di

When this instruction is executed, the maskable interrupt request is disabled and the
INT input to the CPU will be ignored. Remember that when an interrupt is
acknowledged, the maskable interrupt is automatically disabled.

The maskable interrupt request remains disabled until it is subsequently enabled by an


Et instruction.

No registers or flags are affected by this instruction.

3-72
1

DJNZ disp — JUMP RELATIVE TO PRESENT


CONTENTS OF PROGRAM COUNTER IF
REG B IS NOT ZERO

Memory

Program
Memory

10 mmnim
dd-2
mmmm + 2
mmmm + 3

DJNZ disp

10 dd-2
Decrement Register B. If remaining contents are not zero, add the contents of the DJNZ
instruction object code second byte and 2 to the Program Counter. The iump is
measured from the address of the instruction operation code, and has a range of -1 26 to
+ 129 bytes. The Assembler automaticatly adjusts for the twice-incremented PC.
If the contents of B are zero after decrementing, the next sequential instruction is ex-
ecuted.

The DJNZ instruction is extremely useful for any program loop operation, since the one
instruction replaces the typical "decrement-then-branch on condition" instruction se-
quence.

Ei — ENABLE irMTERRUPTS
S Z AcP/O N C Data
H I 11 I II Memory

A
8,C
D,E
H.L
SP
PC Program
IX Memory
!Y
t
F8 mmmm
R mmmm +
mmmm + 2
mmmm + 3

3-73
FB

Execution of this instruction causes interrupts to be enabled, but not until one more in-

struction executes.

Most interrupt service routines end with the two instructions:

E! ;ENABLE INTERRUPTS
RET :RETURN TO INTERRUPTED PROGRAM
if interrupts are processed serialiy. then for the entire duration of the interrupt service

routine all maskable interrupts are disabled — which means that in a multi-interrupt

application there is a significant possibility for one or more interrupts to be pending


when any interrupt service routine completes execution.

Ifinterrupts were acknowledged as soon as the El instructions had executed,


then the
Return instruction would not be executed. Under these circumstances, returns
would
stack up one on top of the other —
and unnecessarily consume stack memory space.
This may be illustrated as follows:
Interrupt

Interrupt service routine

Interrupt service routine

By inhibiting interrupts for one more instruction following execution of El, the Z80 CPU
ensures that the RET instruction gets executed In the sequence:

E! :ENABLE INTERRUPTS
RET ;RETURN FROM INTERRUPT
It ts not uncommon for interrupts to be kept disabled white an interrupt service routine
is executing. Interrupts are processed serially:

Interrupt Interrupt
,

Interrupt service routine Interrupt service routine

3-74
^ 1

EX AF,AF' — EXCHANGE PROGRAM STATUS AND ALTERNATE


PROGRAM STATUS
^ 1
S

I
Z AqP/O N C
I I I I > ^ — ^
Alternate
"«^--^«
p,

A
B.C
D,E
^
-n ^ J
A'
B'.C
D'.E'
H.L
SP ^^111 "^N^,.
PC mmmm Program
^^j-P'^r^mmmm +
^— — J
1

IX Memory
lY

R
I
08- mmmm
mmmm +
mmmm + 2
mmmm + 3

EX AF.AF'

08
The two-byte contents of register pairs AF and A'F are exchanged.
Suppose AF contains 4F99-i6 and A'F' contains lOAA^e- After execution of

EX AF.AF
AF will contain lOAA^e and AF' will contain 4F99i6,

3-75
1

EX DE,HL — EXCHANGE DE AND HL CONTENTS


S Z AqP/O N C Data
Memory
H LU I I I

A
B,C
D,E PP qq
H.L
SP
Program
PC
Memory
IX
lY
I
EB rnrnmm
R mmmm +
mmrnnn + 2
mnnrnnn + 3

EX DE.HL

EB

The D and E registers' contents are swapped with the H and L registers* contents.

Suppose pp=03-t6, qq=2Ai6, xx=41^5 and vy=FCi6- After the instruction

EX DE.HL

has executed. H wit! contain 03i6^ L will contain 2Ai 6- D will contain 41 16 and E will
contain FC-jS-

The two instructions:

EX DE.HL
LD A.(HL)

are equivalent to:

LD A.{DE)

but if you want to load data addressed by the D and E register into the B register.

EX DE.HL
LD B,(HL)

has no single instruction equivalent.

3-76
EX (SP).HL -EXCHANGE CONTENTS OF REGISTER AND
EX |SP).IX TOP OF STACK
EX {SP).IY
S Z Ac P/O N C
^» I I
' ' '
I

The illustration shows execution of EX (SP),HL


EX (SP),HL

E3
Exchange the contents of the L register wfth the top stack bvte. Exchange the contents
of the H register with the byte below the stack top.

Suppose xx=21 16, yy-FAi6. PP^SA^g. qq=E2t6. After the instruction

EX (SP).HL
has executed, H wtii contain SA^q, L will contain E2i6 and the
two top stack bytes will
contain FA^e and 21 -jg respectively.

The EX (SPI.HL instruction is used to access and nnaniputate data at the top of the stack.

EX (SP)JX

DD E3
Exchange the contents of the IX register's tow-order bvte with the top stack
byte. Ex-
change the IX registers high-order byte with the bvte below the stack top.

EX (SP)JY

FD E3
This instruction is identical to EX (SP)JX, but uses the tV register instead of the IX
register.

3-77
1

EXX — EXCHANGE REGISTER PAIRS AND ALTERNATE


REGISTER PAIRS

Alternate
Register Set

F'

A'
B'.C
D'.E'
HM'

Program
Memory

D9 mmmm
mmmm +
mmmm + 2
mmmm + 3

EXX

D9
BC. DE and HL are swapped with the contents of register
The contents of register pairs
pairs B'C. O'E, and H'L"

and 7251 16 respec-


Suppose register pairs BC, DE and HL contain 4901 16. 5F00i6
B*C'. D'E', H'L contain OOOOie- IOFF16 and 3333i6 respec-
tively, and register pa.rs
tively. After the execution of

EXX

the registers will have the following contents:


BC: OOOOie; DE: IOFFis; HL: 333316^
B'C 4901 16; C>'E': 5F00i6: H'L" 7251 16
provide very fast interrupt
This instruction can be used to exchange register banks to
response times.

3-78
1

HA LT
S Z Ac P/0 N C
Data
F Memory
1 1 1 1 1 1

A
B,C
Uh
HX
SP
PC mmmm ^«_„_,( nnmmm + 1
J Program
fX Memory
iY

1
76 mmmm
^ 1
1
mmmm +
mmmm +2
mmmm + 3

HALT

When the HALT instruction is executed, program execution ceases. The CPU requires
an interrupt or a reset to restart execution. No registers or statuses are affected;
however, memorv refresh logic continues to operate.

3-79
IM — INTERRUPT MODE
S Z AcP/0 N C Data

fI 1 1 M M Memory

A
RC
DE
H.L
SP
PC mmmm ^- ^f mmmm +
2^ Program
Memory
tx
!Y
* ED mmmm
j

R 46 mmmm + 1

mmmm + 2
mmmm + 3

This instruction places the CPU m interrupt nnode 0. In this nnode, the interrupting

device place an instruction on the Data Bus and the


will
CPU will then execute that in-
struction. No registers or statuses are affected.

IM 1 —INTERRUPT MODE 1

IM 1

ED 56

This instruction places the CPU m interrupt mode 1 In this


mode, the.
CPU responds to

an interrupt by executing a restart (RST) to location OOSSig.

jM 2 — INTERRUPT MODE 2
IM2
ED5E
This instruction places the CPU in mode 2. In this mode, the CPU performs an
interrupt
indirect call to any specified location m memory. A 16-bit address is formed using the
while the lower
contents of the Interrupt Vector (I) register for the upper eight bits,
supplied by the interrupting device. Refer to Chapter 12 for a full descrip-
eight bits are
tion of interrupt modes. No registers or statuses are
affected by this instruction.

3-80
1

IN A.lport) — INPUT TO ACCUMULATOR


S Z Ac P/O N C Data
y
-
'I I I I I I I/O port yy ^^ Memory

A
B,C
D.E
H,L
SP
PC Program
!X Memory
lY
I

D8 mmmm
R
yv mmmm +
mmmm + 2
mmmm + 3

IN A, (port)

DB yv
Load a byte of data mto the Accumulator from the I/O port (identified by the second IN
instruction object code byte).

Suppose 36^6 is held in the buffer of I/O port lAig. After the instruction

IN A,(1AH)

has executed, the Accunnulator will contain 36-] g-

The IN instruction does not affect any statuses.


Use of the IN instruction is very hardware dependent Valid I/O port addresses are
determined by the way in which 1/0 logic has been implemented. It is also possible to
design a microcomputer system that accesses external logic using memory reference
instructions with specific memory addresses.

3-81
INC reg — INCREMENT REGISTER CONTENTS
S Z AqP/ N C >^^ ^^ Data

fI x|x|x|>'hi J

A
BC 1 M Contents of A,

OE L
1
(S yy
H.L
"'"'
3P ^^^*' "'*^
PC mmmm "

^n"^r mmmm + j 1

>J| ~^w 1

IX
SY

i
OOxxxlOO mmmm
R mmmm + 1

mmmm + 2
mmmm + 3

tNC reg

00 XXX 100

000 for reg=B


001 for reg-C
010 for reg=D
011 for reg=E
100 forreg=H
101 for reg=L
111 for reg=A

Add 1 to the contents of the specified register.

Suppose Register E contains ASig. After execution of

!NC E

Register E v\/il! contain A9-|g.

3-82
1 1 1

INC rp — INCREMENT CONTENTS OF SPECIFIED REGISTER PAIR


INC IX
INCIY
S 2 AcP/0 N C ^^ ^^ Data
F
MINI 1
C yyvY ^ 1 y^~^ Memory

A
B.C
\ / Contents of 8C,
iff DE. HL or SP
D.E
H.L
SP
PC mrrtmm
1
^
^J-^T^mmm + 1^
.^^
Program
IX Memory
tv

1
OOxxOOl fniTirnm
H 1
mmmm +
mmnfim + 2
rnrnrnm + 3

The illustration shows execution of INC rp:

INC rp

00 XX 0011

00 for rp IS register pair BC


01 for rp IS register pair DE
10 for rp Is register pair HL
1 for rp IS Stack Pointer
Add 1 to the 16-bit value contained m the specified register pair. No status flags are
affected.

Suppose the D and E registers contain 2F7A-|g. After the instruction

INC DE
has executed, the D and E registers will contain 2F7B'je.

INC !X

DD 23
Add 1 to the 16-bit value contained m the IX register.

INC lY

FD 23
Add 1 to the 16-bit value contained in the lY register.

Just like the DEC rp. DEC IX and DEC lY, neither INC rp. INC IX nor INC iY affects any
status flags. This is a defect in the Z80 instruction set mhented fronn the 8080.

3-83
1 1

IMC (HU INCREMENT — MEMORY CONTENTS


INC (IX-hdisp)
INC (lY+disp)
S Z AcP/0 N C Data

fI X ! X 1 xlxi 1 \

^^*.«-«««^^
C^ vy + c*i: vv ppqq + d
A
RC L
DP
H.L
3P Program
PC mmmm ^r'^^f mmmm + 3
> p \Aomm-\t
!X ppqq
lY
DD mmmm
mmmm +
1 1

R 1
34
-^4 Doaa + d )d. d mmmm + 2
^****«-»»«-*^ mmmm + 3

The illustration shows execution of INC (IX+d):

INC (IX+disp)

DD 34 d

Add 1 to the contents of memorY location (specified by the sum of the contents of

Register IX and the displacennent value d).

400Fi6 contains 36i6- After execution


Suppose ppqq=4000i6 and memory location

of the instruction

INC (IX+OFH)

memory location 400Fi6 will contain 37-|6-

36 - 00 1 1 110
1

11 111

sets S to J Non-zero

No
result, set

carry, set Aq to
Z to

Carry status not affected'

0¥0=0, set P/0 toO Addition instruction, set N to

INC (lY+disp)

FD 34 d

This instruction is identical to INC (IX+disp). except that it uses the lY register instead
of the iX register

INC (HU

34

Add 1 to the contents of memory location (specified by the contents of the HL register

pair).

3-84
1

IND — INPUT TO MEMORY AND DECREMENT POINTER


S Z Aq P/0 N C

,s
r
\ Data
F L"|X|u|u|l| rfri I/O port vv i
Memory

A PPQq
B,C XX ^i 1

J yy J ^^^-^-^
D.E
H,L
SP
pp qq as<^!!:9
PC mmmm ^ Program
fX ^"^^mmmm + 2 ^ Memory
lY
1

1 ED rnmmm
1 AA mmmm +
mmmm + 2
mmmm + 3

IND

ED AA
Input from i/0 port (addressed by Regtster C) to memorv location (specified by HU
Decrement Registers B and HL
Suppose xx=05i 6, vy=15i6. ppqq=2400-|6- and held the buffer of I/O port
19i6 is in
15i6. After the instruction

IND
has executed, memorv location 2400-16 will contain ig-ig- The B register will contain
04^6 and the HL register pair 23FF'i6.

INDR — INPUT TO MEMORY AND DECREMENT POINTER


UNTIL BYTE COUNTER IS ZERO
INDR

ED BA
INDR ts identical to IND. but is repeated until Register B-0.
Suppose Registers contains 03i 6- Register C contains
15i6, and HL contains 2400i6.
The following sequence of bytes Is available at I/O port
15i6:
Hie. 59^6 and AEig
After the execution of

INDR
the HL register pair will contain 23FD]6 and Register 8 will contain zero, and memory
locations will have contents as follows;

Location Contents
2400 17^6
23FF 59-16
23FE AEi6
This instruction is extremely useful for loading blocks of data from an input device into
memory.

3-85
INI — INPUT TO MEMORY AND INCREMENT POINTER
S Z Ac P/O N C Q^xx-1^^ f Data
i/Oportyy |
Memory

ppqq

INI

ED A2
C) to memory location (specified by HL).
Input from I/O port (addressed by Register
Decrement Register B; increment register pair HL.
held the buffer or I/O port
Suppose xx-0516. vy-15i6- PPqq-2400i6. and I9i6
-s in

1516-

After the instruction


INI

memory location 2400^6 will contain 19i6. The B register will contain
has executed,
04i6 and the HL register pair 240110.

irsiiR — INPUT TO MEMORY AND INCREMENT POINTER


COUNTER ZERO
UNTIL BYTE IS
!NIR

ED B2

INIR IS identical to INL but is repeated until Register 8=0.

Suppose Registers contains 0316- Register C contains 15i6. and


HL contains 2400i6-
The following sequence of bytes is available at I/O port ISig;
17i6. 59i6 and AEig

After the execution of


!NIR

contain zero, and memory


the HL register pair will contain 2403i e and Register B will

locations will have contents as follows:

Location Contents
2400 17 16
2401 59i6
2402 AEi6
extremely useful for loading blocks of data from a device into memo-
This instruction is

ry-

3-86
1

IN reg,(C) — INPUT TO REGISTER


S Z Ac P/O N C
Data
Memory

Program
Memory

ED mmfnm
OlxxxOOO mmmm +
mmmm + 2
mrnmm -f 3

IN reg. (C)

ED 01 XXX 000

000 forreg=B
001 for reg=C
010 forreg-D
Oil for reg -E
100 for reg-H
101 forreg=L
111 for reg=A
1 10 for setting of status flags without
changing registers

Load a byte of data into the specified register (reg) from the I/O port (identified by the
contents of the C register).

Suppose 42-16 is held in the buffer of I/O port 36^q, and Register C contains 36i6-
After the instruction

IN D,{C)

has executed, the D register will contain 42-16.

During the execution of the instruction, the contents of Register B are placed on the top
half of the Address Bus, making it possible to extend the number of addressable
I/O
ports.

3-87
1

jp label — JUMP TO THE INSTRUCTION IDENTIFIED


IN THE OPERAND
S Z Ac P/O N C Data
Memorv
=cxr
A
B,C
D,E
H,L
SP
Program
PC mmmm ppqq
IX
Memorv
lY
I
C3 mmmm
R qq mmmm +
1
mmmm + 2
mmmm + 3

JP^ label

C3 ppqq
of the Jump instruction object code second and third bytes into the
Load the contents
becomes the memory address for the next instruction to be ex-
Program Counter: this

ecuted. The previous Program Counter contents are lost.

In the following sequence:

JP NEXT
AND 7FH

NEXT CPL
The CPL instruction will be executed after the JP instruction. The AND tnstruction will

never be executed, unless a Jump instruction somewhere else in the instruction se-

quence [umps to this instruction.

3-88
JP condltionjabel— JUMP TO ADDRESS IDENTIFIED IN THE
OPERAND IF CONDITION IS
SATISIFED
JP cond, label

11 cc 010 ppqq

Condition Relevant Flag


000 NZ Non-Zero Z
001 Z Zero Z
010 NC NoCarrv C
Oil C Carry C
100 PQ Parity Odd P/O
101 RE ParityEven P/O
110 P Sign Positive S
111 M Sign Negative S
This instruction is identical to the JP instruction, except that the jump will be per-
fornned only if the condition is satisfied: otherwise, the instruction sequentially follow-
ing the JP condition instruction will be executed.
Consider the instruction sequence

JP J CONDXABEL
t condition not satisfied

condition
AND # 7CH
satisfied

-LABEL OR
After the JP condJabel instruction has executed, if the condition is satisfied
then the
OR instruction will be executed. If the condition is not satisfied, the AND instruction,
being the next sequential instruction, is executed.

3-89
1

jp (HL) — JUMP TO ADDRESS SPECIFIED BY CONTENTS


JP (IX) OF 16-BIT REGISTER
JP (lY)

S Z Ac P/O N C
Memory

A
8,C
D,E
H,L PP qq
SP
Program
PC mmmrrs
Memorv
!X
tv
1
E9 mmtnm
R 1
mmrnm 4-
mmmm + 2
mmmm + 3

The illustration shows execution of JP (HL):

JP (HL)

E9
an
The contents of the HL register pair are moved to the Progrann Counter; therefore,
implied addressing )ump is performed.

The instruction sequence

LD H.ADDR
JP (HU

has exactly the same net effect as the single instruction

JP ADDR
Both specify that the instruction with label ADDR is to be executed next

The JP (HL) instruction is useful when you want to increment a return address for a

subroutine that has multiple returns.

Consider the following call to subroutine SUB:

CALL SUB CALL SUBROUTINE


JP ERR ERROR RETURN
GOOD RETURN
Using RET to return from SUB would return execution of JP ERR; therefore, if SUB ex-

ecutes without detecting error conditions, return as follows:


POP HL ;POP RETURN ADDRESS TO HL
INC HL ;ADD 3 TO RETURN ADDRESS
INC HL
INC HL
JP (HL) ;RETURN
JP (IX)

DD_E9
This instruction is identical to the JP (HL) instruction, except that it uses the IX register

3-90
instead of the HL register patr.

This instruction is identical to the JP (HL) instruction, except that it uses the \Y register
instead of the HL register pair.

JR Cdisp — JUMP RELATIVE TO CONTENTS OF PROGRAM


COUNTER IF CARRY IS SET
JR C, disp

38 dd-2
This mstruction is identical to the JR disp except that the jump is only ex-
instruction,
ecuted if the Carry status equals 1, otherwise, the next instruction is executed.

In the following instruction sequence:

4000 JR I C.$+8
^ 0=0
4002 AND J 7FH

"4008 OR 8
After the JR C,$+8 instruction, the OR instruction is executed if the Carry status equals
1. The AND instruction is executed if the Carry status equals 0,

3-91
1

JR disp — JUMP RELATIVE TO PRESENT CONTENTS OF


PROGRAM COUNTER
S Z Ac P/0 N C Data

^1 1 1 1 M 1
Memorv

A
RC
n p

H,L
RP Program
PC mmmm Memory
IX

lY
18 mmmm
R
1

1
dd-2 mmmm +
mmmm + 2
mmmm + 3

JR disp

18 dd-2

Add the contents of the JR instruction object code second byte, the contents of the Pro-
gram Counter, and 2. Load the sunn mto the Program Counter. The jump ts measured
from the address of the instruction operation code, and has a range of -126 to -H29
bytes. The Assembler automatically adjusts for the twice-incremented PC.

The foilowmg assembly language statement is used to jump four steps forward from ad-
dress 4000^6-

JR $-f4

Result of this instruction Is shown below:


Location Instruction

4000 18
4001 02
4002 -

4003

-

4004 <s^ new PC value

3-92
JR NCdisp — JUMP RELATIVE TO CONTENTS OF PROGRAM
COUNTER IF CARRY FLAG IS RESET
JR NC.disp

30 dd-2
This instruction is tdentica! to the JR disp
except that the jump is oniy ex-
instruction,
ecuted if the Carry status equals 0; otherwise, the next instruction is executed,

in the following instruction sequence:

1 »i-4000 ADD j A.7FH


4001
0-0 0=1
4002 ;

4003 JR J NC,$-3
4005 OR I B
^
After the JR NC,$-3 instruction, the OR instruction is executed if the Carry status equals
1. The ADD instruction is executed if the Carry status equals 0.

JR NZ,disp — JUMP RELATIVE TO CONTENTS OF PROGRAM


COUNTER IF ZERO FLAG IS RESET
JR NZ.djsp

20 dd-2
This instruction is identical to the JR disp instruction, except that the jump is only ex-
ecuted if the Zero status equals 0: otherwise, the next instruction is executed.
In the following instruction sequence:

4000 JR j
NZ.$-H6
4002 AND X 7FH
4004 - ?z=i
4005
^^4006 OR B

After the JR NZ.$-f-6 instruction, the OR instruction is executed if the Zero status equals
0. The AND instruction Is executed if the Zero status equals 1.

3-93
jR z,disp — JUMP RELATIVE TO CONTENTS
SET
OF PROGRAM
COUNTER IF ZERO FLAG IS

JR Z,disp

28 dd-2

This instruction is identical to the JR disp instruction, except that the jump is only ex-

ecuted if the Zero status equals 1 . otherwise, the next instruction is executed.

In the foilowmg instruction sequence:

4000 JR Z.$+6
A
4002 AND 1

1
7FH
z„-(
4004 z=o
4005 t
^^
6^4006 OR B

After the JR Z.$+6 instruction, the OR instruction is executed if the Zero status equals
1, The AND instruction is executed if the Zero status equals 0.

LD A,l — MOVE CONTENTS OF INTERRUPT VECTOR OR


LD A,R REFRESH REGISTER TO ACCUMULATOR

3 Z AcP/0 N C Data
Memory
F iXiXlOjXlOl I

A XX iicf!!!

BC
0,E
H.L
SP
Program
PC mmmm ^Tnnmmm + 2. \

Memory
IX
lY
j XX ED mmrnm
R 57 mmmm + 1

mmmm + 2
mmmm + 3

The illustration shows execution of LD A, I:

LD AJ.

ED 57
Move the contents of the Interrupt Vector register to the Accunnulator, and reflect inter-

rupt enable status in Parity/Overflow flag.

Suppose the Interrupt Vector register contains "^F-jg, and interrupts are disabled. After
execution of

LD AJ
Register A will contain 7f]Q. and P/O will be 0.

LD A.R

ED 5F
Move the contents of the Refresh register to the Accunnulator. The value of the interrupt
flip-flop will appear in the Parity/Overflow flag.

3-94
1

LD A,(addr) — LOAD ACCUMULATOR FROM MEMORY USING


DIRECT ADDRESSING
S Z Ac P/O N C
Data
M I I I I I I
Memory

A
B,C
D.E
H,L
SP
PC Program
!X Memory
lY

R
I

3A mmmm
qq mmmm +
PP mmmm + 2
mmmm + 3

LD A, (addr)

3A ppqq
Load the contents of the memorv
byte (addressed directly by the second and third
bytes of the LD A, (addr) instruction object code) into the Accumulator. Suppose
memo-
ry byte 084A-I6 contains 20^q. After the instruction

label EQU 084AH

LD A.dabel)

has executed, the Accumulator will contain 2Q^q.


Remember EQU
an assembler directive rather than an instruction:
that is
it tells the As-
sembler to use the 16-bit value 084Ai6 wherever the label appears.

The instruction

LD A. (label)

IS equivalent to the two instructions

LD HL.Iabel
LD A.(HL)

When you are loading a single value from memory, the LD A,(label) instruction is prefer-
red; uses one instruction and three object program bytes to do what the LD HLIabel,
It

LD A,(HL) combination does m two instructions and four object program bytes. Also,
the LD HLIabel. LD A,(HL) combination uses the H and L registers, which LD A.
(label)
does not.

3-95
LD A,(rp) — LOAD ACCUMULATOR FROM MEMORY LOCATION
ADDRESSED BY REGISTER PAIR
S Z AcP/0 N C Data

HI 1 1 1 1 iJ
.«,
yy yy ppqq
B.C
—^-BC or DE contain ppqq k
D.E
H.L
SP
PC mmmrn •"jI'^T^mrnrnm -^
1^
Memorv
IX
lY
t
000x1010 ninnrnni

R rnrnmni + 1
1

mmmm + 2
rnrninrn "^ 3

LD A.(rp)

000x1010
if register pair=BC
1 if register pair=DE

Load the contents of the memory byte (addressed by the BC or DE register pair) into the
Accumulator.

Suppose the B register contains OS-] g, the C register contains 4A-) g, and memory byte
084Ai6 contains 3Ai6- After the instruction

LD A.(BC)

has executed, the Accumulator v\/iil contain SA^q.

Normally, the LD A,(rp) and LD rp.data will be used together, since the LD rp,data in-

struction loads a 16-bit address into the BC or DE registers as follows:

LD BC,084AH
LD A.{BO

3-96
1 1

LD dstsrc — MOVE CONTENTS OF SOURCE REGISTER TO


DESTINATION REGISTER
S Z AcP/O N C Data
Memory
M I I I I I I
Register A. B. C,
D, E, HorL
A
8,C
1/
i^/^
t
Register A, B. C
D,E
H.L
SP
PC Program
IX Memory
!Y
I

Oldddsss nnmninri
R
mmmm +
mmmm + 2
mmmm + 3

LD dst src

000 for dst or src===B


001 for dst or src=C
010 for dst or src=D
01 for dst or src=E
100 for dst or src=H
101 for dst orsrc=L
111 for dst or src=A

The contents of any designated register are loaded into any other register.

For example;

LD A,B
loads the contents of Register B into Register A.

LD LD
loads the contents of Register D into Register L.

LD C.C
does nothing, smce the C register has been specified as both the source and the
destination.

3-97
1

LD HL.(addr) — LOAD REGISTER PAIR OR INDEX REGISTER


LD rp,(addr) FROM MEMORY USING DIRECT ADDRESSING
LD IX,(addr)
LD IY,(addr)

S Z AcP/O N C Data
Memory
M ' ' I I I i

ppqq
A
B.C ppqq + 1

D.E
H.L yy
SP
Program
PC
Memory

2A mmmm
qq mmmm +
PP mmmm + 2
mmmm + 3

The iiJustration shows execution of LD HL(ppqq):


LD HL.addr

2A ppqq
Load the HL register pair from directly addressed memory location.

Suppose memory location 4004t6 contains ADi6 and memorv location 4005i6 con-
tains 12-J6. After the instruction

LD HL,{4004H)
has executed, the HL register pair will contain 12ADi6.

LD rp, (addr)

ED 01 dd 1011 ppqq

00 for rp is register pair BC


01 for rp is register pair DE
10 for rp IS register pair HL
11 for rp IS Stack Pointer

Load register pair from directly addressed memory.

Suppose memory location 49FFi6 contains BE-jg and memory location 4A00-J6 con-
tains SS-jQ. After the instruction

LD DE,(49FFH)
has executed, the DE register pair will contain SSBE-jg.

LD IX.(addr)

DD 2A ppqq
Load IX register from directly addressed memory.

3-98
Suppose memory location 0111^6 contains FFig and memorv location D1 12i6 con-
tains 56-16. After the instruction

LDIX.(D111H)
has executed, the IX register wilt contain BeFF-jg.

LD lY.iaddrl

FD 2A ppqq
Load lY register from directly addressed memory.
Affects lY register instead of IX. Otherwise Identical to LD IX(addr).

LD i,A — LOAD IIMTERRUPT VECTOR OR REFRESH


LD R,A REGISTER FROM ACCUMULATOR
S Z Ac P/O N C
Data
i II I I! I
Memorv

A XX
B,C
D.E
H.L
SP
PC rnmmm —mX Program
iX
lY
^d-^ mfTimm + 2 1
Memory

IV
R —^ ED mmmm
I 4F mmmm + t

mmmm + 2
mmmm + 3

The illustration shows execution of LD R.A;

LD R.A

ED4F
Load Refresh register from Accumulator.

Suppose the Accumulator contains 7F-j6. After the instruction

LD R,A
has executed, the Refresh register will contain IF-^q.

LDLA
ED 47
Load Interrupt Vector register from Accumulator

3-99
1

LD reg.data — LOAD IMMEDIATE INTO REGISTER


S 2 Ac P/O N C Data
Memorv
M I I I I I I

A
I Destination is
8.C
>^- Register A, B, C,^
D.E
I D, E. H or L
H.L
SP
Program
PC
Memorv
tx
tY
t
OOxxxHO mmmrn
R VY mmmm 4-

mmmrn + 2
mnimm + 3

LD^r eg.data

OOxxxHOvv
000 for reg=B
001 for reg=C
010forreg=D
011 for reg=E
100 for reg=H
101 for reg=^L
111 for reg=A

Load the contents of the second object code byte into one of the registers.

When the instruction

LD A,2AH
has executed, 2A'i6 is loaded into the Accumulator.

3-100
1

LD rp,data — LOAD 16 BITS OF DATA IMMEDIATE INTO


LD IX,datd REGISTER
LD IY,data

S Z Ac P/O N C
Data
^' I I I I I I Memorv

BX
D,E
A
\ ^ Select BC, DE.

\^ SP. Load ppqq into


HI or

HX V^— selected destination


SP
PC
IX
tY
(

The Illustration shows execution of LD rp.data:

LD rp, data

00 XX 0001 ppqq

00 for rp IS register pair BC


01 for rp is register pair DE
10 for rp is register pair HL
1 for rp is Stack Pointer

Load the contents of the second and third object code bytes into the selected register
pair. After the instruction

LD SP.217AH
has executed, the Stack Pointer will contain 217A'j6.

LD !X. data

DD 21 ppqq
Load the contents of the second and third object code bytes into the Index register tX.

LD iY, data

FD 21 ppqq
Load the contents of the second and third object code bytes into the Index Register lY

Notice that the LD rp,data instruction is equivalent to two LD reg.data instructions.

For example:

LD HL032AH
is equivalent to

LD H.03H
LD L2AH

3-101
1

LD reg,(HL) —
LOAD REGISTER FROM MEMORY
LD reg,{IX+clisp)
LD reg,(IY+disp)
S Z Ac P/O N C

M I I I I I i

A
8.C
D.E
H.L
SP
PC rnmmm
IX ppqq
iY
t

R 1

The iilustration shows execution of LD reg,{lX+disp):

LD reg. OX + disp)

DD01 xxxllOd
000 for reg=B
001 for reg=C
010 for reg-D
01 for reg=E
100 for reg=H
101 for reg=L
111 for reg=A

Load specified register from memorv location (specified by the sum of the contents of
the IX register and the displacement digit d).

Suppose ppqq=^4004t 6 and memory location 4010^6 contains FF-jg. After the instruc-

tion

LD B{1X+0CH)
has executed. Register B will contain ff^Q.

LD reg, (lY + disp)

FD01 xxxllOd
^same as for LD reg,(iX-fdlsp)

This instruction is identical to LD reg.(IX+disp), except that it uses the IY register in-

stead of the IX register.

3-102
1 1

LD reg,(HU

01 XXX 110
L ^-same as for LD reg,{!X+disp)

Load specified register from memory location (specified by the contents of the HL
register pair),

LD SP,HL-™MOVE CONTENTS OF HL OR INDEX REGISTER


LD SP,IX TO STACK POINTER
LD SP,1Y

S Z Ac P/O N C

^' ' I I I n Data


Memorv

A
B.C
D.E
H,L PP qq
SP
PC rnmmm
2.
5*\ mmmm + Program
tx Memory
lY
1
F9 mmmm
R mmmm +
mmmm + 2
mmmm 3 -f

The iliustration shows execution of LD SP.HL.


LD SP.HL

F9

Load contents of HL into Stack Pointer.

Suppose pp=08-|6 and qq=3Fi6. After the instruction

LD SP.HL
has executed, the Stac(< Pointer will contain 083Fi5.

LD SP.IX

DD F9

Load contents of Index Register !X into Stack Pointer.


LD SPJY

FD F9
Load contents of index Register lY into Stack Pointer.

3-103
LD (addr),A — ST ORE ACCUMULATOR IN MEMC>RY USIN( 3

Dl RECT ADDRESSING
S Z Ac P/O N C Data

F 1 M 1 1 1 1
ivjemory

A yy ^ yv ppqq
B.C k
OF
H.L
SP )

PC mmmm ^ B^Y^mmmm + 3 -J Program


ivsemorv
!X
lY
i
'

32 mmmm
" - qq mmmm -f 1

PP mmmm + 2
mmmm 3 -f

LD (addrl.A

32 ppqq

Store the Accumulator contents in the nnemory byte addressed directly by the second
and third bytes of the LD (addr),A instruction object code.
Suppose the Accumulator contains 3Aig. After the instruction

label EQU 084AH

LD (label).A

has executed, memory byte 084Aig will contain SA-jg.

Remember that EQU is an assembler directive rather than an mstructioTTT it tells the As-
sembler to use the 16-bit value 084AH whenever the word "label" appears.

The instruction

LD (addr),A

ts equivalent to the two Instructions

LD H.label
LD (HU.A
When you are storing a single data value in memory, the LD (labet),A instruction is
preferred because it uses one Instruction and three object program bytes to do what the

LD H(label), LD {HL).A combination does in two instructions and four object program
bytes. Also, the LD H(labet), LD (HL),A combination uses the H and L registers, whiie the
LD (label), A instruction does not.

3-104
1

LD (addr),HL — STORE REGISTER PAIR OR INDEX


LD (addr),rp REGISTER IN MEMORY USING DIRECT
LD (addr),xy ADDRESSING

S Z Ac P/O N C
Data
^1 I I I I I I Memorv

[PPqq
;^
B.C
D.E
H,L
SP
::^ £ ippqq+ 1

PC Program
IX Memory
tY
!
ED mmmm
R 01010011 mmmm + 1

qq mmmm + 2
n pp mmmm + 3

The illustration shows execution of LD (ppqq),DE:


LD (addr), rp

ED 01 XX 0011 ppqq

00 for rp is register pair BC


01 for rp is register pair DE
10 for rp is register pair HL
1 for rp is Stack Pointer

Store the contents of the specified register pair in mennory. The third and fourth object
code bytes give the address of the memory location where the low-order byte is to be
written. The high-order byte is written Into the next sequential memon/ location.

Suppose the BC register pair contains 3C2A'{s. After the instruction

label EQU 084AH

LD (label).BC

has executed, memory byte 084Aie will contain 2A^ 5, Memon/ byte 0848^6 will con-
tain SCiQ,
Remember that EQU is an assembler directive rather than an instruction; it tells the As-
sembler to use the 16-bit value 084Aie whenever the word "label" appears.

LD {addr),HL

22 ppqq
This is a three-byte version of LD {addr).rp which directly specifies HL as the source
register pair.

3-105
LD (addr)JX

DD 22 ppqq
Store the contents of index register IX in nnemory. The third and fourth object code
bytes give the address of the nnemory location where the low-order byte is to be writ-
ten. The high-order byte is written into the next sequentiai memory location.

LD (addr)JY

FD 22 ppqq
This instruction is identical to the LD (addr),IX instruction, except that it uses the lY
register instead of the IX register.

3-106
LD (HL), data — LOAD IMMEDIATE INTO MEMORY
LD (IX+disp),data
LD |IY+disp).data
S Z Ac P/O N C

M I I I I I I

ppqq + d

The illustration shows execution of LD (IX+d),xx:

LD (!X+dlsp).data

DO 36 d XX
Load immediate into the Memory location designated by base relative addressing.

Suppose ppqq=5400-|6. After the instruction

LD (tX+9).FAH
has executed, memory location B409^q will contain FAig.

LD {IY+disp).data

FD 36 d XX
This instruction is identical to LD (IX+disp).data. but uses the !Y register instead of the
IX register.

LD (HU.data

36 XX
Load Immediate into the Memon/ location (specified by the contents of the HL register
pair).

The Load Immediate into Memory instructions are used much less than the Load Im-
mediate into Register instructions.

3-107
LD (HL),reg —
LOAD MEMORY FROM REGISTER
LD {!X+disp),reg
LD {IY-hdisp),reg
Data
S Z Ac P/0 N C Mpmnrv 1

N
\ Contents of A. 8,-^» yv ppqp
A 1

k
1 C. D, E, H or L
BC >—^is f
yy
D.E
1
HX PP qp ^
SP
'z:^:,
y"'^
i^'f mmnuH +
^^1 Program
PC mmmm 1

Memory
IX
!Y
omoxxx mrnmm
mmmm
}

-f 1
R 1

mmnfim + 2
mmmm + 3

The illustration shows execution of LD (HL).reg:

LD (HLl.reg

01110 XXX

000 for reg=B


001 for reg=C
010 for reg-D
Oil for reg=E
100 for reg-H
101 for reg=L
111 for reg=A

Load memory location (specified by the contents of the HL register pair) from specified
register.

Suppose ppqq=4500i6 and Register C contains FSig. After the instruction

LD (HU.C

has executed, memory location 4500^6 will contain FG-jq,

LD (iX+disp),r^eg

DDOmOxxxd
x_ ^same as for LD (HD.reg

Load memory location (specified by the sum of the contents of the IX register and the

3-108
displacement value d) from specified register.

LD {tY+disp),reg

FDOmOxxxb
^-same as for LD (HU.reg
This instruction is identical to LD (!X+disp),reg. except that it uses the lY register in-
stead of the !X register

LD {rp),A — LOAD ACCUMULATOR INTO THE MEMORY


LOCATION ADDRESSED BY REGISTER PAIR
S Z AqP^O n c Data
Memory
M I I I I I I

A yv ppqq
B,C BC DE
or
D.E contain ppqq
H.L
SP L
PC mmmm + 1
Program
IX Memorv
IV

t
000x0010 mmrnm
R nnmnrim + 1

mmmm + 2
mmmm + 3

LD (rp),A

if register pair^BC
1 if register pair^DE

Store the Accumulator in the memory bvte addressed by the BC or DE register pair.

Suppose the BC register pair contains 084Ai6 and the Accumulator contains SA-jg.
After the instruction

LD (BC),A

has executed, memory byte 084Ai6 wit! contain SA^g.


The LD (rp),A and LD rp.data
normally be used together, since the
will LD rp.data in-
struction loads a 16-bit address into the BC or DE registers as follows:

LD BC.084AH
LD (BO.A

3-109
1

LDD — TRANSFER DATA BETWEEN AND


MEMORY LOCATIONS,
SOURCE ADDRESSES
DECREMENT DESTINATION
Set if BC-1 ^0, reset oth 3rwjse

S Z Ac P/0 N C Data
C ttuu-1
J Memorv
f| 1 lol lol 1

ppqq-1
yv ^ppqq
A !

8,C tt uu
rrss-
rr ss
^.l PP qq "1_ yy rrss

SP ^'^^^^qqT^
PC mmmm
Memorv
IX
1Y
1
C mmmm + 2 1 ED (niTifnrn

A8 rnnnrnpn -*• 1
R 1
mmmm 2 -i-

mmmm + 3

LDD
ED A8
Transfer a byte of data from memorv location addressed by the HL register pair to
memory location addressed by the DE register pair. Decrement contents of register
pairs BC,. DE, and HL.

Suppose register pair BC contains 004F^6, DE contains 4545i6, HL contains 201 2i 6-


and memory location 201 2-] g contains ^B^Q. After the instruction
LDD
has executed, memory 454516 wil! contain IS^e-
location register pair BC will contain
004E'j6, DE will contain 4544i6, and HL will contain 201 1 ig.

3-110
LDDR — TRANSFER DATA BETWEEN MEMORY
LOCATIONS UNTIL BYTE COUNTER IS
ZERO. DECREMENT DESTINATION AND
SOURCE ADDRESSES
LDDR

This instruction is identical to LDD. except that it is repeated untii the BC


register pair
contains zero. After each data transfer, interrupts wit! be recognized and two refresh cy-
cles will be executed.

Suppose we have the following contents in mennon/ and register pairs:

Register/Contents Location/Contents
HL 2012^6 201216 18-16
DE 454516 201 lie AA^e
BC 0003^6 2010^6 25^6
After execution of

LDDR
register pairs and nnemorv locations will have the following contents:
Register/Contents Location/Contents Location/Contents
HL 200916 201216 ^Q^6 4545i6 18i6
DE 454216 201 lie AAi6 4544i6 AAi6
BC OOOO16 2OIO16 25i6 454316 25i6
This instruction is extremely useful for transferring blocks of data from one area of
memory to another.

3-111
1

LDI— TRANSFER DATA BETWEEN MEMORY


LOCATIONS. INCREMENT DESTINATION AND
SOURCE ADDRESSES
^
SetifBC- - 1 =i^ 0, reset oth erwise

S Z Ac P/0 N C Data
C ttuu- 1
J Memory
^1 LL |o| hi 1

YY
f
PPqq
A ppqq + 1
\

tt uu <.
D,E rr ss YY rrss

PP qq ~~\\ J rrss + 1

Vw. r
SP
mmmm Program
PC
Memory
IX
JY
1
rrnmmm + 2 1 m mftinim

R 1
AO mmmm +
mmmm + 2
mmmm + 3

LDi

ED AO
Transfer a byte of data from memory location addressed by the HL register pair to
memory location addressed by the DE register pair. Increment contents of register pairs
HL and DE. Decrement contents of the BC register pair.
Suppose register pair BC contains 004F^6, DE contains 4545^6. HL contains 2012i6,
and memory location 2012i6 contains 18i6- ^^^^^ the instruction
LDI

has executed, memory location 4545i6will contain IS-tg, register pairBC will contain
004Ei6' DE will contain 4546-16, and HL willcontain 2013-16.

3-112
1

LDIR — TRANSFER DATA BETWEEN MEMORY


LOCATIONS UNTIL BYTE COUNTER IS
ZERO. INCREMENT DESTINATION AND
SOURCE ADDRESSES
LDIR

ED BO
This instruction is identical to LDL except
that it is repeated until the BC register pair
contains zero. After each data transfer, interrupts will be recognized and two refresh cy-
cies will be executed.

Suppose we have the following contents tn memory and register pairs:

Registe -/Contents Location/Contents


HL 201216 201216 I816
DE 454516 201316 CD16
BC 000316 201416 FO16
After execution of

LDIR
register pairs and memory wi 1 have the following contents:
Register/Contents Location/Contents Location/Contents
HL 201516 201216 I816 454516 I816
DE 454816 201316 CD16 454616 CD16
BC OOOO16 201416 FOI6 454716 FO16
This instruction is extremely useful for transferring blocks of data from one area of
memon/ to another.

NEG — NEGATE CONTENTS OF ACCUMULATOR


S Z Ac P/O N C
Data
Memory

A
B.C
XX
^*t
^ >

D,E
HX
SP
PC mmmm 5r*t mmmm + 2 Program
IX Memory
!Y
J

>ED mmmm
R
.
44 mmmm +
mmmm + 2
mmmm + 3

Negate contents of Accumulator. This is the same as subtracting contents of the Ac-
cumulator from zero. The result is the two's complement 80H will be left unchanged.
Suppose xx=5Ai6- After the Instruction

NEG
has executed, the Accumulator will contain A616.

5A = 1 1 10 10
Two's complement = 10 10 110

3-113
^ 1

NOP — NO OPERATION
S Z AqP/O n c Data

1 M 1 1 1
Memory

A \

R r
pp
HX
SP Program
PC mmmm .«^ mmmm + 1
Memory
sx
!Y
^™™ mmmm
1 1
00
R 1
mmmm +
mmmm 2 -t-

mmmm 3 •*•

This IS a one-byte instruction which performs no operation, except that the Program
Counter is incremented and memory refresh continues. This instruction is present for
several reasons:

1) A program error that fetches an object code from non-existent memon/ will fetch
00. It is a good idea to ensure that themost common program error will do nothing.

2) The NOP instruction allows you to give a label to an object program byte:
HERE NOP
3) To fine-tune delay times. Each NOP instruction adds four clock cycles to a delay.

NOP is not a very useful or frequently used instruction.

3-114
I i

OR data — OR IMMEDIATE WITH ACCUMULATOR


S 2 Ac P/O N C
F||X|X|1|X|0|0|

OR data

F6 T7
OR the Accumutator with the contents of the second instruction object code byte.

Suppose xx=3At6. After the instruction

OR 7CH
has executed, the Accumulator will contain ^E-jg.

3A = 1 1 10 10
7C = 1 1 1 110
111 1110
sets S to 0-«a— t — Six 1 bits, set P/O to 1

I
—-Non-zero result set Z to
This is a routine logical mstructlon: it is often used to turn bits "on" For example, the
Instruction

OR 80H
will unconditlonallv set the high-order Accumulator bit to 1.

3-115
1

OR reg — OR REGISTER WITH ACCUMULATOR


S Z Ac P/O N C Data
Memory

Contents of A, B,
B.C
, D, E, H or L
D.E
is YV
H.L
SP
Program
PC mmmm
Memory
IX
lY
i
10110XXX mmmm
R
mmmm +
mmmm + 2
mmmm + 3

OR reg

10110 XXX
000 for reg=B
001 for reg-C
010 for reg=D
011 for reg=E
100 for reg=H
101 for reg=L
111 for reg=A

LogicaHY OR the contents of the Accumulator with the contents of Register A, B, C, D,


E, H or L. Store the result in the Accumulator.

Suppose xx=E3i6 and Register E contains AS^q. After the instruction

OR E

has executed, the Accumulator will contain EB-jg.

E3 1110 001 1

AS 1010 1000
1110 1011

1 sets S to 1 ^ —

*
Six 1

Non-zero
bits, set P/O

result, set
to

Z
1

to

3-116
OR {HU — OR MEMORY WITH ACCUMULATOR
OR (IX+disp)
OR OY-f disp)
S 2 Ac P/O N C
FixixiiixiTTol

The illustration shows execution of OR (HL):

OR (HU
B6
OR contents of memory location (specified by the contents of the HL register pair) with
the Accumulator.

Suppose xx=E3i 6, ppqq=4000'i6, and memory location 400016 contains ASi 6- After
the instruction

OR (HL)

has executed, the Accumulator will contain EB-jq.

E3 = 1 11 011
A8 = 1 1 10

1 sets S to u 1110 1011

^

Six 1 bits, set

Non-zero result set Z to


P/O to 1

OR (IX+disp)

DO 86 d
OR contents of memory location (specified by the sum of the contents of the IX register
and the displacement value d) with the Accumulator.

OR (lY+disp)

FD 86 d

This instruction is identical to OR (IX+disp), except that it uses the lY register instead of
the IX register

3-117
1

OUT (C),reg — OUTPUT FROM REGISTER


S Z Ac P/O N C Data

M I I I I i
Memory

i
A
8.C ^^
"^"
Register A, 8, C,

D, E, H or L
D,E
H,L
SP
Program
PC
Memory
iX
lY
I
ED mmmm
R OlxxxOOl mmmm +
mmmm + 2
mmmm + 3

OUT (C).reg

000 for reg=B


001 for reg=C
010 for reg=D
011 for reg=E
100 for reg=H
101 for reg=L
111 for reg=A
Suppose yy=1Fie and the contents of H are AA-jg. After the execution of

OUT (C).H

AA-j 5 v^ill be m the buffer of I/O port 1 F-j g.

3-118
OUTD — OUTPUT FROM MEMORY. DECREMENT ADDRESS

S 2 Ac P/O N C

OUTD
ED AB
Output from memory location specified by HL to I/O port addressed by Register C.
Registers B and HL are decremented.

Suppose xx=0Ai6. vv=FFi6.


ppqq-5000i6. and memory location 5000^6 contains
77-jg. After the instruction

OUTD
has executed. 77ie will be held tn the buffer of I/O port FFig. The B
register will con-
tain 09i6, and the HL register patr4FFF^6-

OTDR — OUTPUT FROM MEMORY. DECREMENT ADDRESS,


CONTINUE UNTIL REGISTER 8=0
OTDR
ED BB
OTDR is identical to OUTD. but is repeated until Register B contains 0.

Suppose Register B contains 03-| g- Register C contains FF-{ g, and HL contains 5000^ q.
Memon/ locations 4FFEi6 through 5000^6 contain:
Location/Contents
4FFE16 CAi6
4FFF16 1Bi6
5000^6 File
After execution of

OTDR
register pair HL will contain 4FFDi6. Register B will contain zero, and the sequence
^"^le- fBi6' CA^e will have been written to t/0 port FF15.

This instruction is very useful for transferring blocks of data from memory to output
devices.

3-119
OUTI — OUTPUT FROM MEMORY. INCREMENT ADDRESS
Data

^M I/O port yy j
Memorv

A
ppqq

i^KEB^
Program
Memory

ED mmmm
A3 mmmm + 1

mmmm + 2
mmmm + 3

OUTI

ED A3

Output from memorv location specified bv HL to t/0 port addressed by Register C.

Register B is decremented and the HL register pair is incremented.

Suppose xx=0Ai6. VV=FFl6' ppqq=5000i6. and memorv location 5000i6 contains


77iQ. After the instruction
OUT!
The B register vyiti con-
has executed, 77i6 will be held in the buffer of I/O port FF-|6-
5001 tg.
tain09t6 and the HL register pair wilt contain

OTIR — OUTPUT FROM MEMORY. INCREMENT ADDRESS,


REGISTER B-0
CONTINUE UNTIL
OTIR

ED B3

OTIR is identical to OUTi, except that it ts repeated until Register B contains 0.

Suppose Register B contains 04-16, Register C contains ff^Q. and HL contains 5000 1 6-
Memory locations 500016 through 5003^6 contain:

Location/Contents
5000-16 CAi6
500116 1Bi6
500216 B1i6
500316 ADi6
After execution of

OTIR

HL will contain 5004i6. Register B will contain zero and


register pair the sequence

CAi6. 1Bi6. B1i6 and ADie will have been written to t/O port FFi6-
This instruction is very useful for transferring blocks of data from memory to an output
device.

3-120
1

OUT lport),A — OUTPUT FROM ACCUMULATOR


S Z Ac P/0 N C
f Data
F
C 1 1 1 1
1
1 !/0 port yy I^J-^ Memory

A
B.C
0,E
HX
yp 1

PC mmmm Program
IX Memory
lY
i

D3
R
yy mmmm +
mmmm + 2
mmmm 3 4-

OUT (portl.A

Output the contents of the Accumulator to the I/O port identified bv the second OUT in-
struction object code byte.

Suppose 36^6 is held in the Accumulator. After the instruction

OUT (lAH).A
has executed, 36i6 will be in the buffer of I/O port IA^q.
The OUT instruction does not affect any statuses. Use of
the OUT instruction is very
hardware-dependent. Valid I/O port addresses are determined
by the way in which I/O
logic has been implemented. It is also possible
to design a microcomputer system that
accesses external logic using memory reference instructions
with specific memory ad-
dresses. OUT instructions are frequently used m
special ways to control microcomputer
logic external to the CPU.

3-121
1

POP rp — READ FROM THE TOP OF THE STACK


POP IX
POP !Y

The illustration shows execution of POP 8C.


POP rp

11 XX 0001

00 for rp is register pair 8C


01 for rp is register pair DE
10 for rp is register pair HL
1 for rp is register pair A and F

POP the two top stack bytes into the designated register pair.

Suppose qq=01 16 a^^i pp=2Ai6- Execution of

POP HL
into the H register Execution of the instruction
ioads 01 16 into the L register and 2Ai 6
POP AF

loads 01 into the status flags and 2Ai6 tnto the


Accumulator. Thus, the Carry status
win be set to 1 and other statuses will be cleared.
POP IX

DD E1

POP the two top stack bytes tnto the IX register.


POP lY

FD El

POP the two top stack bytes tnto the lY register.

The POP instruction is most frequently used to restore register and status contents
which have been saved on the stack; for example, while servicing an interrupt

3-122
1 1 1

PUSH rp — WRITE TO THE TOP OF THE STACK


PUSH IX
PUSH lY
S Z Ac P/O N C Data
^1 I I I I I I Memory
qq ssss-2
A ssss-
B,C
D.E
HX
SP
PC
IX
mmmm
ssss
^ ^ mmmm + 2 S Program
Memory
lY ppqq
i

FD mmmm
H
1 E5 mmmm +
mmmm + 2
mmmm + 3

The illustration shows execution of PUSH lY:

PUSH !Y

FD E5
PUSH the contents of the !Y register onto the top of the stack.

Suppose the !Y register contains 45FFi6. Execution of the instruction

PUSH lY

ioads 45i6, then FF-jg onto the top of the stack.

PUSH IX

DD E5
PUSH the contents of the IX register onto the top of the stack.

PUSH rp

11 XX 0101

00 for rp is register pair BC


01 for rp IS register pair DE
10 for rp is register pair HL
1 for rp IS register pair A and F

PUSH contents of designated register pair onto the top of the stack.

Execution of the instruction

PUSH AF
loads the Accunnulator and then the status flags onto the top of the stack.

The PUSH instruction is most frequently used to save register and status contents; for
example, before servicing an interrupt.

3-123
1

FS^S b,reg — RESET INDICATED REGISTER BIT


Data
s Z Ac P/0 N C
Memory
c 1 1 1 1 1

A J yyyyyyyy (
8.C
O.E
_4 J

H.L
SP
mmmm + 2 ^ Program
PC mmmm Memorv
IX
lY
*-* C8 mmmm
i

lObbbxxx mmmm +
R L_ mmmfn + 2
mmmm + 3

RES b,reg

^ii
CB 10
Bit
bbb XXX
bbb XXX Reqister

000 000 B
1 001 001 C
2 010 010 D
3 Oil Oil E
4 100 100 H
5 101 101 L
6 110 111 A
7 111

Reset indicated bit withm specified register

After the instruction

RES 6.H

has executed, bit 6 m Register H will be reset (Bit iS the least significant bit)

3-124
RES b,(HL) —
RESET BIT b OF INDICATED MEMORY POSITION
RES b.dX+disp)
RES b,{IY+dlsp)
SZAgP/O N C

The illustration shows execution of SET b,{IX+disp). Bit is execution of SET


b,(IX+disp). Bit (s the least significant bit

RES b,(IX+dlsp)

DDCB d 10 bbb 110

bbb Bit Reset


000
001 1

010 2
011 3
100 4
101 5
110 6
111 7
Reset indicated bit within mennorv location indicated by the sum of Index Register IX
and d.

Suppose IX contains 41 ^0^Q. After the instruction

RES 0.(IX+7)
has executed, bit in memory location 41 17^6 will be 0.

RES b,{IY+disp)

FDCB d 10 bbb 110

bbb IS the same as in RES b,(IX+disp)


This instruction is identical to RES b.OX+disp), except that it uses the lY register instead

3-125
of the IX register.

RES b.(HL)

CB lObbb 110

bbb IS the same as in RES b.(!X+disp)

Reset indicated bit within nnennorv location indicated by HL.

Suppose HL contains 4444 -[0. After execution of

RES 7,(HL)

bit 7 in memorv location 4444^6 will be 0.

RET — RETURN FROM SUBROUTINE


C Data
S Z Ac P/0 N
Memory
^i I I ' I I I
qq xxxx
PP xxxx + 1

xxxx + 2

Program
Memorv

C9 mmmrn

mmmm + 3

RET

C9

Move the contents of the top two stack bytes to the Program Counter; these two
bytes
Previous Program Counter
provide the address of the next instruction to be executed.
contents are lost Increment the Stack Pointer by 2, to address the
new top of stack.
Return) instruction;
Every subroutine must contain at least one Return (or conditional
this is the last instruction executed within the
subroutine, and causes execution to

return to the calling program.

3-126
RET cond — RETURN FROM SUBROUTINE IF CONDITION
IS SATISFIED
RET cond

1 XXX 000

Condition Relevant Flag


000 NZ Non-Zero Z
001 Z Zero z
010 NC Non-Carry c
011 C Carry c
100 PO Parity Odd P/0
101 PE Parity Even P/0
110 P Sign Positive s
111 M Sign Negative s
This instruction is identical to the RET instruction, except that the return is not ex-
ecuted unless the condition issatisfied; otherwise, the instruction sequentially follow-
ing the RET cond instruction will be executed.

Consider the instruction sequence:

CALL SUBR
AND 7CH-^

SL/Bfr- ;First subroutine instruction

condition satisfied

R(iT cond I

condition not
satisfied

0^ 80H

After the RET cond is executed, if the condition is satisfied then execution returns to the
AND instruction which follows the CALL If the condition is not satisfied, the OR in-
struction, being the next sequential instruction, is executed.

3-127
RETI — RETURN FROM INTERRUPT
S Z AcP/O N C

RETI

ED 4D

the contents of the top two stack bytes to the Program Counter:
these two bytes
Move
Progrann Counter
provide the address of the next instruction to be executed. Previous
contents are lost increment the Stack Pointer by 2. and address the
new top of stack.

This instruction is used at the end of an interrupt service routine,


and, in addition to

returning control to the interrupted program, it is used to signal an I/O


device that the
logic necessary
interrupt routine has been completed. The I/O device must provide the
to sense the instruction operation code: refer to An
introduction to Microcom-
pu ters: Volume 2 for a description of how the RETI instruction operates with the Z80
family of devices.

3-128
1

RETIM — RETURN FROM NOIM-MASKABLE INTERRUPT


S Z Ac P/O N C
Data
^M I I I I I Memory
qq mmmm
A
PP mmmm + 1
B.C
D,E
mmmm + 2
H,L
SP xxxx
Pt mmmm Program
IX
Memory
lY
1
mmmm
I

1
ED
L 1 45 mmmm +
mmmm + 2
mmmm + 3

RETN

ED 45
Move the contents of the top two stack bytes to the Program
Counter: these two bvtes
provide the address of the next instruction to be
executed. Previous Program Counter
contents are lost. Increment the Stack Pointer bv 2 to
address the new top of stack
Restore the interrupt enable logic to the state it had prior
to the occurrence of the non-
maskable interrupt
This instruction
is used at the end of a service
routine for a non-maskable interrupt and
causes execution to return to the program that was interrupted.

3-129
RL reg — ROTATE CONTENTS OF REGISTER LEFT
THROUGH CARRY
S Z AqP/O n ) Data

fL X |x!o
%igim
X oJv-i —— \
t

" ^TT—T
\
— *Wl 11 1
1 I 1

1
1

»
1

L-[
!

H.L
r
SP
mmmm
Byy""^""''''^'^"''^ Program
PC mmmm ^.w* ^*ni + 2 b
Memory
IX
tv
i
i„^^
1
CB mmmm
R 1
00010001 mmmm + 1

mmmm +2
mmmm + 3

The illustration shows execution of RL C


RL reg

CB 00010 XXX
000 for reg=B
001 for reg=C
010 for reg=D
011 for reg=E
100 for reg=H
101 forreg=L
111 for reg=A

Rotate contents of specified register !eft one bit through Carry.

Suppose D contains AS-js and Carrv=0. After the instruction

RL D
'

has executed, D will contain b2^Q and Carry wiil be 1

Before After

Register D Carry Register D

110 10 1 oT| fo 101 01 ooi'-qI

sets S to Non-zero result set Z to


3 ones, set P/0 to

3-130
1

RL (HL) — ROTATE CONTENTS OF MEMORY LOCATION


RL (IX-hdispi LEFT THROUGH CARRY
RL (lY-hdisp)

~^^
S 2 AnP'O N i
Data

A
l^l>^l^|MO|^
^ Memory

^ -Jppqq+d

B.C
D.E
H.L
3P
PC mmmm + 4^ Program
IX ppqq Memory
lY

DD
^«^' '

'^N^ CB mmmm +
mmmm + 2
ppqq + d
^^<« ^^JT^ d
16 mmmm + 3
mmmm + 4

The iliustration shows execution of RL (IX+disp):

RL i!X+disp)

DD CB d 16
Rotate contents of mennory location (specified by the sum of the contents
of Index
Register IX and displacement tnteger d) left one bit through Carry.

Suppose the iX register contains 4000-|6- memory location 4007^6 contains 2Fi6. and
Carry is set to 1. After execution of the Instruction

RL {IX+7}
memory location 4007^ g will contain BF^q, and Carry is 0:

Before After
Memory Carry Memory Carry

IQQ10 1 1 1 1|
D] 10101 1 ml [oj

sets S to O- Non-zero result, set Z to


6 ones, set P/0 to 1

RL (lY+disp)

FD CB d 16
This instruction is identical to RL (IX+disp), but uses the lY register instead of the iX
register.

3-131
Rotate contents of memorv location (specified by the contents of the HL register pair)
left one bit through Carry.

RLA — ROTATE ACCUMULATOR LEFT THROUGH CARRY


S 2 AqP/O N i Data
-
Memory
f I I lol lol^l

"TT- 4>l I I I I I I

B.C
D.E
H.L
SP
Program
PC
Memory
iX
!Y
1i. mrrtmm
mmmm -f 1

mmmm + 2
mmmm 3 -+•

RLA
17

Rotate Accumulator contents left one bit through Carry status.

Suppose the Accurr^ulator contains 2A^ g and the Carry status is set to 1 .
After the in-

struction

RLA
has executed, the Accumulator will contain F5i g and the Carry status will be reset to 0:
Before After

Accumulator Carry Accumulator Carry

ioi 1 1 10101 Q] 11111 1 11 m

3-132
; 1

RLC reg — ROTATE CONTENTS OF REGISTER LEFT CIRCULAR


S Z Ac P/O N C 1
I Data
1 HxixioixioTlg--^ Memory

A
B.C

I I I I
g™^
HX
SP
PC Program
iX Memory
tY

R
i

CB mmmm
OOCXXX)!! mmmm +
mrnrnm + 2
mmmm + 3

The illustration shows execution of RLC E;

RLC reg

CB 000 00 XXX
000 for reg-=B
001 for reg-C
O10forreg-D
011 for reg-E
lOOforreg-H
101 for reg-L
111 for reg^A

Rotate contents of specified register left one bit, copying bit 7 into Carry.
Suppose Register D contains A9^6 and Carry is 1. After execution of

RLC D
Register D will contain 53-jg and Carry wilt be 1

Before After
Register D Carry Register D Carry

n 01 1 ooTI Q] 10101 001 11 Q]

sets S toO- Non-zero result set Z to


4 ones, set P/O to 1

3-133
:

RLC (HU —
ROTATE CONTENTS OF MEMORY LOCATION
RLC OX+disp) LEFT CIRCULAR
RLC (lY+dIsp)

S Z Ac P/O N C Data
Memory
F JxixlQlxloi H^-
/ppqq
ffi
B,C
D,E
HX qq
SP
Program
PC
Memory
iX

lY
t CB mmmrrt
R 06 mmmm -h 1

mmmm 2 -f

mmmm + 3

The illustration shows execution of RLC (HU:


RLC (HU

CB 06
Rotate contents of memory location (specified by the contents of the ML register pair)

left one bit copying bit 7 mto Carry.

Suppose register pair HL contains 54FF^6. Memory location 54FF'|6 contains ABtq,
and Carry is 0. After execution of
RLC (HU
memory location 54FFi6 will contain 4Big, and Carry will be 1

Before After

Memory Carry Memory Carry

|i 01 01 oT] \o\ |oi 00 1 oi"n Q]

setsS toO- >Non-zero result set Z lo


4 ones, set P/O to 1

RLC (iX+disp)

DD CB a 06

Rotate memon/ location (specified by the sum of the contents of Index register IX and
displacement integer d) left one bit copying bit 7 into Carry.

Suppose the IX register contains 4000-j g. Carry is 1 , and memon/ location 4007 g con- -j

tains 2F-J5. After the instruction

RLC (IX+7)

3-134
has executed, memory location 4007ie will contain 5E\q, and Carry wil! be 0:
Before After

Memory Carry Memory Carry

1001 1 1 1T| \T} [0101 111^ \o}

sets S to '
Non-zero result, set Z to
5 ones, set P/0 to

RLC (lY+dJsp)

FD CB d 06
This instruction is identical to RLC (IX+disp), but uses the !Y register instead of the iX
register.

RLCA — ROTATE ACCUMULATOR LEFT CIRCULAR


S Z AqP/ON c

^1 I lol l°l iJ-~ Data


Memory

--A-

Program '

Memory

07 mmmm
mmmm + 1

mmmm + 2
mmmm 3 -f

RLCA
07
Rotate Accumulator contents left one bit copying bit 7 into Carn/.

Suppose the Accumulator contains 7A^e and the Carry status is set to 1. After the in-
struction

RLCA
has executed, the Accumulator wil! contain F4i g and the Carry status will be reset to 0:

Before After

Accumulator Carry Accumulator Carry

|01 1 1 1 01 0| [3 11 1 1 1 01 ool [o]

RLCA should be used as a logical instruction.

3-135
1

RLD — ROTATE ONE BCD DIGIT LEFT BETWEEN


THE ACCUMULATOR AND MEMORY LOCATION
S Z AcP^O N C Data
Memory
F iXiXlOlXlOl I

ppqq
B.C
O.E

SP
5j
Program
PC
Memory

ED mmmm
6F mmmm +
mmmm + 2
mmmm + 3

RLD

ED 6F
bits of a memory iocatton (specified by the contents of register
pair
The four low-order
are copied into the four high-order bits of the same memory location. The
previous
HU
contents of the four high-order bits of that memory location are copied into the four
low-order bits of the Accumulator. The previous four low-order bits of the Accumulator
are copied into the four low-order bits of the specified memon/ location.

Suppose the Accumulator contains 7Fi 5, HL register pair contains 4000i6. and memo-
ry location 4000i6 contains 12i6. After execution of the instruction

RLD

the Accumulator will contain 71 ig and memon/ location 4000i6 will contain 2F^6:

Before After

Accumulator Memory Accumulator Memory

7 I F I
7 I 1 I [hf]

high-order bit=0, set S to • •-Non-zero result set Z to

4 ones, set P/O to 1

3-136
: 1

RR reg — ROTATE CONTENTS OF REGISTER RIGHT THROUGH


CARRY

S Z Aq P/0 n c
Data
I F vivjlnlv/bnl ^ k Memory
r" ^

A 1
Si r
D.E
, , ,
1" 1 1 1
J
H.L
SP
mmmm
PC
!X ^ ^1V^
mmmm 2%
mrflff
-^ + Program
Memory
!Y
!

1 CB mmmm
" 1 00011001 mmmm +
mmmm + 2
1
mmmm + 3

The illustration shows execution of RR C;

RR reg

CB 0001 1 XXX

000 forreg=B
001 for reg=C
010 for reg=D
011 forreg=E
100 for reg=H
101 for reg=L
111 for reg-A

Rotate contents of specified register right one bit through Carry.

Suppose Register H contains OF^g and Carry js set to 1, After the instruction

RR H
has executed. Register H wilt contain 87^6, and Carry will be 1

Before After
Register H Carry Register H Carry

lOOOQ 1 1 1 1| U] IIQOO 01111 m


1 sets S to 1 "•Non-zero result, set Z to
4 ones, set P/0 to 1

3-137
1

RR (HL) — ROTATE CONTENTS OF MEMORY LOCATION


RIGHT THROUGH CARRY
RR (IX+disp)
RR (lY+disp)

S Z AqP^O N C Data
Memory I

fI x|x|oixlolw_1
II 1 II 1 1
PP :iq4-d
A
i 1
BC
D.E
H.L 1

:dP """**%
__Bm,^_^^'^" Program
PC mmmm
!X
tY
(

R
'
11

«
^^ t ppqq + d
V^ J^
^./^ ,
FD
C8
d
1E
mmmm
mmmm +
mmmm + 2
mmmm + 3
mmmm +4

The illustration shows execution of RR (!Y+disp):

RR (!Y+diS£)

FD CB ci 1E

Rotate contents of nnemorv location (specified by the sunn of the contents of the lY
register and the displacement value d) right one bit through Carry.

Suppose the lY register contains 4500^ 6- memon/ location 450F^ g contains 1 Di g, and
Carry ts set to 0. After execution of the instruction

RR (lY+OFH)

memory location 450F-|g will contain OEig, and Carry will be 1 -

Before After

Memory Carry Memory Carry

I0QQ1 noil [o] lOOOO 1 1 10l Q]

sets S to - Non-zero result set Z to


3 ones, set P/0 to

RR (iX-f-disp)

DD C8 d 1E

This instruction is identical to RR (lY+disp), but uses the tX register instead of the lY
register.

3-138
Rotate contents of memorv location {specified by the contents of the HL register pair)
right one bit through Carry.

RRA — ROTATE ACCUMULATOR RIGHT THROUGH CARRY


j S Z Aq P/0 n 1 Data
Memorv

W-h
B.C
D.E
H.L
SP
PC Program
IX Memory
lY

1F mmmm
mmmm -f 1

mmmm + 2
mmmm + 3

RRA
1F
Rotate Accumulator contents right one bit through Carry status.
Suppose the Accunnulator contains 7At 6 and the Carry status is set to 1, After the in-
struction

RRA
has executed, the Accumuiator will contain BD^e and the Carry status will be reset to

Before After
Accumulator Carry Accumulator Carry

|01 1 1 1010] Q] 1101 1 1101] [0]

3-139
: 1

BBC reg — ROTATE CONTENTS OF REGISTER RIGHT CIRCULAR


S Z Ac P/O N C Data
Memory

A
B,C
D,E
1 ItaH I I

SP Program
PC Memory
IX
tY
C8 mmmm
t

R
00001101 mmmm +
mmmm + 2
mmmm + 3

The illustration shows execution of RRC L;

RRC reg

CB 00001 XXX

000 reg=B for


001 reg=C for
OlOfor reg=D
011 for reg=E
100 for reg^H
101 for reg=L
111 for reg^A

copying into the Carry


Rotate contents of specified register right one bit circularry, bit

status.

Suppose Register D contains A9-t6 and Carn/ is 0. After execution of

RRC D

Register D will contain DA-jg, and Carn/ will be 1

Before After

Register D Carry Register D Carry

hoio looil HI ii 101 oioo1 Q]

1 sets S to 1
- •-Non-zero result set Z to
4 ones, set P/O to 1

3-140
RRC (HU — ROTATE CONTENTS OF MEMORY LOCATION
RRC (IX-f disp) RIGHT CIRCULAR
RRC (lY+disp)

S Z Ac P/O N C
-ixixioixio-rt

The itiustration shows execution of RRC (HU:


RRC (HL)

CB OE
Rotate contents of nnemory location (specified by the contents of
the HL register pair)
right one bit circularly, copying bit into the Carry status.

Suppose the HL register pair contains


4500i6, memory location 450016 contains
34i6, and Carry is set to 1. After execution of

RRC (HU
memon/ location 450016 will contain lA^g, and Carry will be 0:

Before After
Memory Carry Memory Carry

I0Q1 1 01001 [D 10001 10101 [O]

sets
3 ones, set P/0 to
S to - L Non-zero result set Z to

RRC OX+disp)

DD CB d OE
Rotate contents of memon/ location (specified by the sum of the contents of the IX

3-141
^

one bit circularly, copying btt mto the Ca-


register and the displacement value d) right

try status.

RRC (lY+disp)

FD CB a OE

(tX+disp) instruction, but uses the lY register


in-
This Instruction is identical to the RRC
stead of the IX register.

RRCA — ROTATE ACCUMULATOR RIGHT CIRCULAR


*i -"- —
S Z AcP/ON C Data
i i
Memory
' Hu 1 lol ioJ_J» —

B.C
DF
H,L
SP Program
PC mmmm -^^-^'^i^mmmT^S
IX
!Y
OF mmmm
t

R
1

1
mmmm + 1

mmmm + 2
mmmm + 3

RRCA
OF
copying bit mto the Carry status.
Rotate Accumulator contents right one bit circularly,

After the in-


Suppose the Accumulator contains 7A^6 and the Carry status is set to 1.

struction

RRCA
contain 3Di 6 and the Carry status will be reset to
has executed, the Accumulator will

0:

Before After

Accumulator Carry Accumulator Carry

10 111 1 1 61 [D 1001 1 1 1011 [o]

RRCA should be used as a logical instruction.

3-142
RRD — ROTATE ONE BCD DIGIT RIGHT BETWEEN THE
ACCUMULATOR AND MEMORY LOCATION
S Z AcP/O N C

RRD
^^
The four high-order bits of a memory location (specified
bv the contents of register pair
HU are copied into the four iow-order bits of the
same memory iocation. The previous
contents of the four low-order bits are copied into
the four low-order bits of the Ac-
cumulator. The previous four low-order bits of the Accumulator
are copied Into the four
high-order bits of the specified memory location.

Suppose the Accumulator contains 7F^ q, HL register pair contains 4000i r, and memo-
ry location 4000^6 contains M^q. After execution of the instruction

RRD
the Accumulator will contain
72i6 and memon/ location 4000^6 will contain F^q:
_Before After
Accumulator Memory Accumulator Memory
IZO
High-order bit=0. set S to N on -zero result
4 ones, set P/O to 1 set Z to

3-143
RST n — RESTART
S Z Ac P/O N C

H I I I I M

RST n

11 XXX 111

Call the subroutine origined at the low memory address specified by n.

When the instruction


RST 18H

has executed, the subroutine origined at memory location 001 81 6 is called.


The pre
vious Program Counter contents are pushed to the top of the stack.

Usually, the RST instruction is used in conjunction with interrupt processing, as de


scribed in Chapter 12.

If your application does not use all RST instruction codes to service SUBROUTINE
interrupts, do not overlook the possibility of catling subroutines CALL USING
using RST instructions. Origin frequently used subroutines at ap- RST
propriate RST addresses, and these subroutines can be called with
a single-byte RST instruction instead of a three-byte CALL instruction

3-144
SBC A.data — SUBTRACT IMMEDIATE DATA FROM
ACCUMULATOR WITH BORROW

S Z Aq P/O N c
r
Ftxlxlxlxlvlxl

Subtract the contents of the second object code bvte and the Carry
status from the Ac-
cumulator.

Suppose xx=3A-|5 and Carrv=1. After the instruction

SBC A.7CH
has executed, the Accumulator will contain BD^q.

3A = 1 1 10 10
Twos comp of 7C 1 000 00
1

Twos comp of Carry 1111 1111


1 11 110 1

1 sets S to 1
Non-zero result set Z to

Borrow, set C to 1
Sorrow, set A^ to 1

1 ¥ 1 =0, set P/O to Subtract instruction, set N to 1

The Carry flag is set to 1 for a borrow and reset to if there ts no borrow,

3-145
1

SBC A,reg — SUBTRACT REGISTER WITH BORROW


FROM ACCUMULATOR

S Z AqP'O N C Data
Memorv
Mx|x|x|x|Hx
A
I Contents' of A, B,
B.C
>-^C, D, E, H or L
O.E
I is VY
H,L
SP
Progranr>
PC
Memory
IX
iY
10011 XXX mmrnnn
t

R
mmmm +
mmmm + 2
mmmm + 3

SBC A, reg

10011 XXX
000 for reg=B
001 for reg=C
010 for reg=D
Oil for reg=E
100 for reg=H
101 for reg=L
111 for reg=A

Subtract the contents of the specified register and the Carry status from the Accumula-
tor.

Suppose xx=E3i6' Register E contains AOie. and Carn/=1. After the instruction

SBC A.E

has executed, the Accumulator wii! contain 42i5.


E3 = 1 1 1 11
Two's comp of AO = 1 1

Two's comp of 1 = 1111 1111


100 0010
sets S to Non-zero result set Z to

No borrow, set C to 0-« No borrow, set A^ to

1-V-1=0. set P/0 toO Subtract instruction, set N to 1

The Carry flag is set to 1 for a borrow and reset to if there is no borrow-

3-146
SBC A.{HL) — SUBTRACT MEMORY AND CARRY FROM
SBC A,(IX4-disp) ACCUMULATOR
SBC A,{IY"fdisp)

S Z Ac P/O N C
F>X|X|X|XM|X^

The illustration shows execution of SBC A,(HL):

SBC A,{HL)

9E
Subtract the contents of mennorv location (specified by the
contents of the HL register
pair) and the Carry from the Accumulator.

Suppose Carry=0. ppqq-4000i6. xx-3Ai6- and memory location 4000^ ft contains


/C^g, After execution of the instruction

SBC A,(HU
the Accumulator will contain BEiq,

3A = 1 1 10 10
Two's comp of7C = 1000 0100
Two's comp of Carry =
oil 1110

J
1

1 sets S to 1
Non-zero result set Z to

Borrow, set C to 1- t Borrow, set Ac to 1

0V-0=0, setP/0 toO Subtract instruction, set N to 1

The Carry flag is set to 1 for a borrow and reset to if there is no borrow
SBC A.(tX+disp)

DD 9E d
Subtract the contents of memory location {specified by the sum of the contents of the
IX register and the displacement value d) and the Carry from the Accumulator.
SBC A.dV+disp)

FD 9E d
This instruction is identical to the SBC A,(IX+disp) instruction, except that it uses the lY
register instead of the IX register.

3-147
1 —

SBC HL.rp — SUBTRACT REGISTER PAIR WITH CARRY


FROM H AND L
S Z AcP^O N C Data
^/^
xlxjxixi 1
m
mMmm ?v Memory

A
, IT
HL SP
BC 1 BC, DE, or

D.E \ contains yyyy



H.L XX XX i^f— 'J
SP
PC mmmm )^^mmmm
1™^ **nj +
^v
21 Program
Memory
IX
lY
1
ED mmmm
R OlxxOOlO mmmm + 1

mmmm + 2
mmmm + 3

SBC HL rp

01 XX 0010

00 for rp is register pair BC


01 for rp !S register pair DE
10 for rp IS register pair HL
1 for rp IS Stack Pointer

Subtract the contents of the designated register pair and the Carry status from the HL
register pair.

Suppose HL contains F4A2^6, BC contains A034i6, and Carry=0. After the instruction

SBC HLBC
has executed, the HL register pair will contain 546E-j6:

Two's comp of F4A2 = 1111 0100 1010 0010


Two^s comp of A034 = 0101 1111 1100 1100
Two's comp of Carry =
0101 0100 0110 1110

sets S to *J V i-,Non-zero result set Z to

No borrow, set C to 0^ No borrow.


^ ^
1 ¥ 1 =0. set P/0 to Subtract instruction, set N to 1

The Carry flag is set to 1 for a borrow and reset to if there is no borrow.

3-148
SCF — SET CARRY FLAG
S Z Ac P/O N C
Data
M ill 1 1 h>cr!> Memory

A
B.C
D.E
H,L
SP
PC mmmm Program
iX Memory
lY
i
1
1
37 mmmrn
I
! mmmm + 1

mmmm + 2
mmmm 3 -f

SCF

37
When SCF instruction is executed, the Carry status is set to
the 1 regardless of its pre-
vious value. No other statuses or register contents are affected.

3-149
1

SET b,reg — SET INDICATED REGISTER BIT


Data
3 Z Ac P/0 N C
^' ' ' ' I M Memory

A
B.C
D,E
H.L
t
yyyy vvyy
<I^
SP Program
PC Memory
!X
iY
CB mmmm
I

1 Ibbbxxx mmmm +
R
mmmm + 2
mmmm + 3

SET b,reg

CB 11 bbb XXX

Bit bbb XXX Register

000 000 B
1 001 001 C
2 010 010 D
3 011 Oil E
4 100 100 H
5 101 101 L
6 110 111 A
7 111

SET indicated bit within specified register. After the instruction

SET 21
2 in Register L will be set (Bit is the least significant bit)
has executed, bit

3-150
SET b.lHL) —
SET BIT b OF INDICATED MEMORY POSITION
SET b,|IX+dlsp)
SET b,(IY+dlsp)
S 2 Ar P/O N C
Data
^
1 I I I I I I
CI> Memorv

The Illustration shows execution of SET b,(HL). Bit is the least significant bit

SET b,(HL)

T\'\
J
CB
t 11 bbb 110

Bit Set bbb


000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

Set indicated bit withm nriemorv location indicated by HL


Suppose HL contains 4000i6. After the instruction

SET 5,(HU
has executed, bit 5 m memory position 400016 will be 1.

SET b,(IX+disp)

DD CB d 11 bbb 110

bbb is the same as In SET b,(HU

Set indicated bit within memon/ location indicated by the sum of Index Register iX and
displacement.

3-161
1

Suppose Index Register IX contains 4000i6- After execution of

SET 6.(!X+5H)

bit 6 in memon/ location 4005i6 will be 1.

SET b,(IY+disp)

FD CB d 11 bbb 110

bbb is the same as in SET b,(HU

identical to SET b.OX+disp). except that it uses the !Y register instead


This instruction is

of the IX register.

SLA reg — SHIFT CONTENTS OF REGISTER LEFT ARITHMETIC


S Z A qP/O n Data

F ^XixiO|x|o|f| m Memory

-ere = 1111 1 11
<:z>
0,E
HX
SP Program
PC
Memory
iX
tY
1
CB mmmm
R 00100001 mmmm +
mmmm 2 -*-

mmmrrt + 3

The illustration shows execution of SLA C;

SLA reg

CB 001 00 XXX
000 for reg=B
001 for reg=C
010 for reg=D
Oil for reg=E
100 for reg=H
101 for reg=L
111 for reg=A

Shift contents of specified register left one bit resetting the least significant bit to 0.

Suppose Register B contains IFig, and Carrv=1. After execution of

SLA B
Register B will contain SE-je and Carn/ wilt be zero.

3-152
Before After
Register B Carry Register B Carry

IQ001 11 111 m 1001 1 11 1Q| [0]

sets S to •
^Non-zero result set Z to
5 ones, set P/0 to ^

SLA (HL) — SHIFT CONTENTS OF MEMORY LOCATION


SLA (IX+disp) LEFT ARITHMETIC
SLA (lY-hdisp)

S Z Ac p/0 N C V 1^^ Data


F i xi X 1 1 X 1 !
1^
i^
A
B.C
4444+4+ ^ J
PP
0,E i
HX pp qq
SP
PC mmmm mmmm + 2^ Program
IX Memory
iY
1

1
CR
^ 1 26 mmmm -f 1

mmmm + 2
mmmm + 3

The illustration shows execution of SLA (HL):

SLA (HL)

CB 26
Shift contents of memory location (specified by the contents of the HL register pair) left
one bit resetting the least significant bit to 0.

Suppose the HL register pair contains 4500^6, memory location 4500i6 contains
and Carry^O. After execution of
04-1 g,

SLA (HL)

memory location 4500i6 will contain OS^q, and Carry will be 1.

Before After
Memory Carry Memory Carry
llOOO OlOOl (T| IQOOO 10001 Q

1 one. set
sets S to
P/0 to
- L Non-zero result set 2 to

3-153
1

SLA (IX-f-dlsp)

DB C8 a 26

location (specified by the sum of the contents of the


IX
Shift contents of memory
anthmetically, resetting least signifi-
register and the displacement value d) left one bit
cant bit to 0.

SLA (lY+disp)

FD CB a 26

This instruction is identical to SLA (IX+disp). but uses the lY register instead of the IX

register.

SRA reg — ARITHMETIC SHIFT RIGHT CONTENTS OF


REGISTER
S Z Ac P/O N C Data
Memory
FDiJLxioixioJLJH 1
A
8,C
0,E €?
NX
SP
mmmnn + 2 Program
PC
Memory
IX
lY
CB mmmm
mmmm +
I

R 00101111
mmmm 2
-f

mmmm + 3

The illustration shows execution of SRA A:

SRA reg

CB 00101 XXX
000 reg=B
for
001 reg=C
for
010 for reg=D
011 for reg-E
100 forreg=H
101 for reg=^L
111 for reg=A

Shift specified register right one bit Most significant bit is unchanged.

Suppose Register H contains 59i6, and Carry=0, After the instruction


SRA H
has executed. Register H will contain 2C-|6 and Carry wilt be 1.

3-154
Before After
Register H C Register H C
[0101 1 00 1|
m 10010 1100l HI

sets S to Non-zero result set Z to


3 ones, set P/O to

SRA HL) — ARITHMETIC SHIFT RIGHT CONTENTS OF


SRA (IX-fdisp) MEMORY POSITION
SRA OY+disp)

S 2 AqP'O N i
ix|x|oix|o|f|
A
B.C
U.b

SP
PC mmmm Program
IX Memory
ppqq
lY

DD mmmm
H
r CB
d
mmmm +
mmmm + 2
t

2E mmmm + 3
mmmm + 4

The illustration shows execution of SRA (IX+disp):

SRA (iX+disp)

DD CB d 2E
Shift contents of
mernorY location {specified bv the sum of the contents of Register IX
and the displacement value d) right Most significant bit is
unchanged
Suppose Register IX contains 340016, memorv 34AAi6
location contains 27^R and
CarrY=1. After execution of

SRA (IX+OAAH)
memory location 34AAi6 will contain IS-jg, and Carry will be 1.

Before After
Memory Carry Memon/ Carry

1 1 11 T|
iJI [000 1 001 1
m
sets S to 0- *•—-^a>-
Non-zero result set Z to
3 ones, set P/O to

3-155
I

SRA (!Y+disp)

FD CB a 2E

This instruction is identical to SRA OX+disp), but uses the iY register instead of the IX
register.

SRA (HU
CB 2E

Shift contents of memory location (specified by the contents of the HL register pair)

right one bit Most significant bit is unchanged.

SRL reg — SHIFT CONTENTS OF REGISTER RIGHT


LOGICAL

S Z Ac P/O N C <z> Data


Memorv
^'°'xl°lxlol U

1 1 1 II

B^ r mmmm + Program
2J Memorv

CB mmmm
00111011 mmmm + 1

mmmm + 2
mmmm 3 -i-

The illustration shows execution of SRL £:

SRL reg

CB 00111 XXX

000 for reg=B


001 for reg=C
010 for reg=D
Oil for reg=E
100 for reg=H
101 for reg=L
111 for reg=A
one bit Most significant bit is reset to 0.
Shift contents of specified register right

Suppose Register D contains IF^e- and Carry=0. After execution of

SRL D

Register D will contain Qf-\Q, and Carry will be 1.

3-156
Before After
Register D Carry Register D Carry

10001 111 i| [o] 10000 n 1 il \T\


4 ones, set P/0 to 1
u Non-zero result set Z to

SRL (HU SHIFT CONTENTS OF MEMORY LOCATION


SRL (IXH-disp) RIGHT LOGICAL
SRL (lY+disp)

S Z Aq p/0 n c

The illustration shows execution of SRL (HL):

SRL (HL)

CB 3E
Shift contents of memory location (specified by the contents of the HL register pair)
right one bit Most significant bit is reset to 0,

Suppose the HL register pair contains 2000^6, memon/ location 2000^6 contains SF-jg,
and Carry=0. After execution of

SRL (HL)

memory location 2000-J6 will contain 47 iq. and Carry will be 1.

Before After
Memory Carry Memory Carry

1 1 1 1 1 fl [o] 10100 011 n [T]

4 ones, set P/0 to 1 Non-zero result set Z to

SRL (IX+disp:

DD CB d 3E
Shift contents of memory location (specified by the sum of the contents of the IX
register and the displacement value d) right one bit Most significant bit is reset to 0,

3-157
1

SRL (lY-l-disp)

FD DB d 3E

This instruction is identical to SRL (IX+disp), but uses the iY register instead of the !X
register.

SUB data — SUBTRACT IMMEDIATE FROM ACCUMULATOR


S Z AcP/O N C Data
Memory
F |X|X|X|X|1 |X|

A
B,C
D,E
H.L
SP
Program
PC
Memory
!X
!Y
t
D6 mmmm
R mmmm-J-
mmmm + 2
mmmm + 3

SUB data

D6 VY

Subtract the contents of the second obiect code byte from the Accumulator.

Suppose xx=3Ai6. After the instruction

SUB 7CH
has executed, the Accumulator will contain BEig.

3A = 1 1 10 10
Two"s comp of 7C = 1OOP 01 00
1011 1110

1 sets S to ,^) u ^ Non-zero result, set Z to

Borrow, set C to 1 Borrow, set Aq to 1

0V0=0. setP/0 toO Subtract instruction, set N to 1

Notice that the resulting carry is complemented.

3-158
SUB — SUBTRACT REGISTER FROM ACCUMULATOR
reg

sx
A

0,E
H.L
SP
S Z

ixixixixiux
Aq P/0 n c
m^^
^i N
XX
L
-
,
V
r^^O,
V xx-vY

Contents of A, 8.
E, H or L is vv
}

C,
Data
Memory

PC mmmm Program
iX MemorY
lY

10010XXX
1 mmnnnrt + 1

mmmm + 2
mmmm + 3

3UB reg

1 ooT XXX
000 forreg=B
001 for reg =C
010 forreg=D
011 forreg-E
100 forreg-H
101 for reg=L
111 for reg=A
Subtract the contents of the specified register fronn the Accumulator

Suppose xx=E3 and Register H contains AQ^q. After execution of

SUB H
the Accumulator wili contain
43-|e.

E3 = 1 1 1 11
Two"s comp of AO = 0110 0000
1 00 0011
sets S to ^J Non-zero result set Z to

No borrow, set C to O-- No borrow, set A^ to

1 ¥ 1 =0, set P/0 to Subtract instruction, set N to 1

Notice that the resulting carry is complemented.

3-159
SUB {HU —SUBTRACT MEMORY FROM ACCUMULATOR
SUB (IX+disp)
SUB (lY-hdisp)
S Z Ac P/O N C

ppqq+d
B,C
D,E
H.L
SP
PC
IX
iY
I

The iNustration shows execution of SUB (iX+d):

SUB (tX+displ

DD 96 d

Subtract contents of memory location {specified by the sum of the contents of the !X

register and the displacement value d) from the Accumulator.

Suppose ppqq=4000^6, xx^FFig, and memon/ location 40FF'j6 contains BOiq. After
execution of
SUB (IX+OFFH)

the Accumulator will contain AFtg.

FF = 1 1 1 1 1111
Two's comp of 50 = 10 11 0000
10 1111

J
1

1 sets S to 1 Non-zero result set Z to

No borrow, set C to t No borrow, set Aq to

1 ¥ 1 =0, set P/O to Subtract instruction, set N to 1

Notice that the resulting carry is complemented.


SUB (lY+disp)

FD 96 d

This instruction is identical to SUB (IX+disp), except that it uses the !Y register instead
of the IX register.

Subtract contents of memory location (specified by the contents of the HL register pair)

from the Accumulator.

3-160
I

XOR data — EXCLUSIVE-OR IMMEDIATE WITH ACCUMULATOR


S Z Ac P/O N C
^^
jxixji i xioio

XOR data

Exclusive-OR the contents of the second object code byte with the Accumulator.

Suppose xx=3Aie, After the instruction

XOR 7CH
has executed, the Accumulator will contain 46iq.

3A = 11 10 10
7C = 1 11 1100
01 00 110
sets S toO-i* — -Non-zero result set Z to

-Three 1 bits, set P/O to

The Exc(usive-OR instruction is used to test for changes m bit status.

3-161
1

XOR reg — EXCLUSIVE-OR REGISTER WITH ACCUMULATOR


S Z Ac P/O N C Data
Memory
F fxTxh |x|0|0i
A Contents of A, B,
B.C C. D. E. H or L
D.E
H.L
SP
K^
I
,s

PC mmmm -*- 1
Program
Memorv
fX
!Y
lOIOIxxx mmmm
I

R
mmmm -»-

mmmm + 2
mmmm + 3

XOR reg

10101 XXX
000 for reg=B
001 for reg-C
010 for reg=D
011 for reg=E
100 for reg=H
101 forreg=L
111 for reg==A

Exclusive-OR the contents of the specified register with the Accumulator

Suppose xx=E3i6 and Register E contains A0i6- After the mstruction


XOR E

has executed, the Accumulator wii! contain 4316.

E3= 1 11 11
AO = 10 10 0000
01 00 001 1

k
sets S to O^H-J Non-zero result set Z to

-Three 1 bits, set P/O to

The Exclus!ve-OR instruction ts used to test for changes m bit status.

3-162
XOR (HU — EXCLUSIVE-OR MEMORY WITH ACCUMULATOR
XOR (IX+disp)
XOR (lY+dIsp)
S Z Ac P/O N C
x|x| |x|o |o|

A XX <^ ppqq + d
B.C
D,E
H,L
SP
PC mmmm *0^
!X ppqq
tY
1

The iliustration shows execution of XOR (IX+disp):

XOR (IX-l-disp)

DD AE d

Exclusive-OR contents of memory location (specified by the sum of the contents of the
IX register and the displacement value d) with the Accumulator.

Suppose xx=E3i6. ppqq=4500i6, and memory location 45FF'{6 contains AOig. After
the Instruction

XOR (IX+OFFH)

has executed, the Accumulator will contain ^S^Q.

E3 - 1 1 1 11
AG = 1010 0000
1 00 001 1

k
sets S to o*J -Non-zero result set Z to

-Three 1 bits, set P/O to

XOR ilY+disp)

FD AE d

This instruction is identical to XOR (IX+disp), except that it uses the !Y register instead
of the IX register.

XOR (HL)

AE
Exclusive-OR contents of memory location (specified by the contents of the HL register
pair) with the Accumulator.

3-163
8080A/Z80 COMPATIBILITY
Although the Z80 microprocessor can certainly be used on 8080A/Z80
its own merits, one of Its important characteristics is its
COMPATIBILITY
compatibility with the 8080A microprocessor. This com- FEATURES
patibility has the following features:

1) At! 8080A machine language instructions are also Z80 machine language instruc-

tions.

2) All 8080A registers are also Z80 registers (see Table 3-6).

3) Almost alt 8080A programs will run on a Z80. with some mtnor differences to be

noted later.

4) The Z80 has instructions, registers, and other features not present on the 8080A,
so Z80 programs wilt not generally run on 8080A processors.

Note that this compatibility does not extend to assembly 8080A/ZdO


language source statements since Z80 assemblers and 8080A ASSEMBLY
assemblers use different operation code mnemonics. Table 3-7 LEVEL
contains a list of the 8080A mnemonic codes and the corres- CONVERSION
ponding Z80 codes, while Table 3-8 is the same list organized
by Z80 codes.
Readers should note the binary coding limitations that this com- 8080A
patibility places on the extra features of the Z80 microprocessor.
UNUSED
The 8080A has some unused operation codes (see Table 3-9) that OPERATION
are used for some of the Z80's extra instructions. But there are
COPES
simply not enough such codes to cover the targe number of
features in a simple form.

Thus, many of the added Z80 instructions require a 2-byte opera- 2-BYTE
tion code. The first byte is CB, DD. ED, or FD. Note the following
OPERATION
meanings of these codes from Table 3-9: CODES
CB — a register or bit operation
DD ™ an operation involving register IX
ED — a miscellaneous non-8080A Instruction not covered elsewhere

FD — an operation involving register lY


The second byte of the operation code describes the actual operation to be performed.

The end that these multi-byte instructions execute rather


result is
FASTER AND
slowly (and use more memory) because an additional memory SLOWER
access is required. The reader should be aware of this variation m EXECUTING
execution times and try to use faster executing instructions when INSTRUCTIONS
possible. This warning particularly applies to the extra shift

instructions (RLC RRC, RL. RR, SRA, SRL) and to instructions involving the index
registers IX and lY.
There are a few minor incompatibilities between the 8080A/Z80
8080A and the Z80. These are: INCOMPATIBILITIES!
ties]

1} The Z80 uses the P (or P/0) flag to indicate twos com-
plement overflow after arithmetic operations. The 8080A always uses this flag for

parity.

2) The Z80 and 8080A execute the DAA instruction differently. On the Z80, this in-

struction will correct decimal subtraction as well as decimal addition. On the

8080A. It will correct only decimal addition.


3) The Z80 rotate instructions clear the Aq flag. The 8080A rotate instructions do
not affect the Aq flag.

3-164
Tabie 3-6. Register and Flag Correspondence between
Z80 and 8080A

Z80 Register 8080A Register

A A
A' None
B B
8'
None
C C
C None
D
D' None
e E
E' None
F Least Stgnificant Half of PSW
F'
None
H H
H' None
t
None
iX None
!Y None
L L
L* None
R None
PC PC
SP SP
Z80 Register Pairs 8080A Register Pairs

BC 8
DE D
HL H
AF PSW
Z80 Flags 8080A Flags

C (Carrvl C (Carrv)
H {Half-CarrY) AC (Auxiliary Canrv)
N {Subtract) None
P {Parityj

SiSignj S (Sign)
Z (Zero! Z (Zero)
J
The Z80 is not compatible with the extra features of 8085/Z80
the 8086 microprocessor. The codes used for RIM and INCOMPATIBILITliS
SIM on the 8085 are used for relative jumps (NZ and NC) on
the Z80.

Instruction timings on the 8080A, 8085, and Z80 all TIMING


differ.Programs that depend on precise instruction tim- INCOMPATtBIUTIES
ings will therefore execute properly only on the pro-
cessor for which they were written.

The N flag on the Z80 occupies bit 2 of the F register; the corresponding bit in the
Processor Status Word of the 8080A is always a logic '1'.

3-165
Table 3-7 Correspondence between 8080A and Z80 Mnemonics

Z80 Mnemonic SOSOA Mnemonic Z80 Mnemonic 1


SOSOA Mnemonic | | |

LHLD addr LD HL,(addr)


AC! data ADC A.data
rp,data16 LD rp,data16
ADC reg or M ADC A.reg or (HL) LXI

ADO reg or M ADD A.reg or iHU MOV reg.reg or M LD reg.reg or (HL)

MOV reg or M.reg LD reg or (HD.reg


AD! data ADD A.data
MVI reg or M,data LD reg or (HL).data
ANA reg or M AND reg or {HU
AND data NOP NOP
AN! data
CALL addr CALL addr ORA reg or M OR rag or (HU

CAU C.addr ORI data OR data


CC addr
CALL M.addr OUT port OUT (portJ.A
CM addr
PCHL JP (HU
CMA CPL
CCF POP pr POP pr
CMC
PUSH PUSH pr
CMP reg or M CP rag or (HL) pr

CNC addr CALL NC.addr RAL RLA


CALL NZ.addr RAR RRA
CNZ addr
RC RET C
CP addr CALL P.addr
CALL PE.addr RET RET
CPE addr
CP data RLC RLCA
CP! data
CALL PO.addr BM RET M
CPO addr
CALL Z.addr RNC RET NC
CZ addr
RNZ RET NZ
DAA DAA
ADD HUrp RP RET P
DAD rp
RPE RET PE
OCR reg or M DEC reg or {HU
RPO RET PC
DCX rp DEC rp

D! RRC RRCA
D!
Et BST n RST n
Ei
RZ RET Z
HIT HALT
!N port !N A.lport) SBB reg or M SBC A,reg or (HU
data SBC A.data
INR reg or M INC reg or (HL) SBi

iNC rp SHLD addr LD {addr),HL


INX fP
Caddr SPHL LD SP.HL
JC addr JP
M.addr STA addr LD !addr),A
JM addr JP
addr STAX 8 orD LD (BO or (DE),A
JMP addr JP
JP NCaddr STC SCF
JNC addr
JP addr JP P.addr SUB reg or M SUB reg or (HL)

JP NZ.addr SUI data SUB data


JNZ addr
JPE addr JP PE.addr XCHG EX DE.HL

JPG addr JP PO.addr XRA rag or M XOR reg or (HL)

JZ addr JP Z.addr XRI data XOR data

LD XTHL EX (SP),HL
LDA addr A,{addrj

LDAX BorD LD A,(8C) or (DE)

3-166
Table 3-8. Correspondence between Z80 and 8080A Mnemonics
Z80 Mnemonic 8080A Mnemonic Z80 Mnemonic 8080A Mnemonic
ADC A.data AC! data INC rp INX rp
ADC A.(HL) ADC M INC xy —
ADC A.reg ADC reg INC (xy *- disp) _
ADC A,{xy + disp) IND _
ADC HL.rp INDR
ADD A.data ADi data INI
ADD A,{HL) ADD M INIR
ADD A.reg ADD reg JP addr JMP addr
ADD A,{xv •+• dispj JP Caddr JC addr
ADD HL.rp DAD JP (HL) PCHL
ADD tX.pp JP M.addr JM addr
ADD IY,rr
JP NCaddr JNC addr
AND data ANI data JP NZ.addr JNZ addr
AND (HL) ANA M JP P.addr JP addr
AND reg ANA reg JP PE.addr JPE addr
AND {xy + disp) JP PO.addr JPO addr
BIT b,{HL) JP Z.addr JZ addr
BIT b.reg JP
BIT b,(xy + disp) JR Cdisp
CALL addr CALL addr JR disp
CALL Caddr CC addr JR NCdJsp
CALL M.addr CM addr JR NZ.disp
CALL NCaddr CNC addr JR Z,disp
CALL NZ.addr CNZ addr LD A.(addr) LDA addr
CALL P,addr CP addr LD A,{8C) or (DE) LDAX B or D
CALL PE.addr CPE addr LD A.i
CALL PO.addr CPO addr LD A,R
CALL Z,addr CZ addr LD (addr),A STA addr
CCF CMC LD (addr),BC or DE
CP data CPI data LD {addr).HL SHLD addr
CP CMP M LD (addr),SP
CP reg CMP reg LD {addr},xy
CP (xy + disp) LD (BO or (DEKA STAX 8 or D
CPD LO BC or DE,(addr)
CPDR LD HLjaddr) LHLD addr
CPI
LD (HD.data MVi M.data
CPIR LD (HD.reg MOV M.reg
CPL CMA LD t,A
DAA DAA LD R.A
DEC (HL) DCR M LD reg.data MVI reg.data
DEC reg DCR reg LD reg.CHU MOV reg.M
DEC OCX rp LO reg, reg MOV reg.reg
DEC LD reg,(xy + disp)
DEC (xy + disp) LD rp,data16 LXI rp,data16
Dl Dl LD SP,{addr)
DJNZ disp LD SP.HL SPHL
Ei El LD SP.xy
EX AF.AF LD xy,data16
EX DE.HL XCHG LD xy,(addr)
EX (SP),HL XTHL LD (xv + dispi.data
EX (SPUv LD (xy -i- dtsp),reg
EXX LDD
HALT HLT LDDR
IM LD!
tN A,{port) tN LDIR
IN reg,{C) NEG
INC (HU INR M NOP NOP
INC reg INR reg OR ORI
- indicates that there is no corresponding instructron.

3-167
Table 3-8. Correspondence between Z80 and 8080A Mnennonics (Continued)

Z80 Mnemonic 8080A Mnemonic Z80 Mnemonic |


8080A M nemonic

OR IHL) ORA M RR (HU "


OR reg ORA reg RR reg

OR {xv + disp)
_ RR (xy + disp)

UIDH — RRA RAR
^ RRC (HL)

OTIR
OUT — RRC reg

OUT
{Clreg
(port), A OUT port RRC (xy + disp) —
OUTD _ RRCA RRC

OUTI
_ RRD —
POP pr RST n RST n
POP pr
SBC A.data SBI data
POP XV
PUSH pr PUSH pr SBC A,(HU SBB M
PUSH xy
„ SBC A.reg see reg

_ SBC A,{xy + disp)



RES
RES
b.lHU
b,reg
_ SBC HL,rp

+ — SCF STC
RES b,|xv disp!
RET SET b,{HL)

RET
RET C RC SET b,reg

RET M RM SET b,(xy 4- disp)

RET NO RNC SLA (HL)

RET NZ RNZ SLA reg

RET P RP SLA (xy + disp)

RET RPE SRA (HL)

RET
PE
PO RPO SRA reg

RET Z RZ SRA (xy + disp)
~
™ SRL (HU —
RET!
RETN — SRL reg —
RL {HU — SRL (xy + dispj —
RL reg
^ SUB data SUI data

RL (xy + disp) _ SUB (HU SUB M


RLA RAL SUB reg SUB reg

RLC !HL)
— SUB {xy + disp)

XOR data XR! data
RLC reg

RLC {xy + displ _ XOR (HU XRA M


RLCA RLC XOR reg XRA reg

RLO — XOR (xy + disp) ~


— indicates that there ss no con-esponding instruction

3-168
Table 3-9. Unused 8080A Operation Codes and Their Z80 Meanings

8080A Operation Code Z80 Use

08 EX AF.AF'
10 DJN7 disp
18 JR disp
20 (RIM on 8085) JR NZ.disp
28 JR Z.disp
30 (SIM on 8085) JR NC.disp
38 JR Cdisp
C8 BIT, RES. RL. RLC. RR, RRC. SET, SLA SRA, SRL
09 EXX
DD All instructions involving Register iX.
ED ADC HL,rp LP AJ NEG
CPD LD A.R OTDR
CPDR LD (addr),rp OTIR
CPI LD I.A OUT (C),reg

CPtR LD R,A OUTD


IM m LD rp,{addr| OUT!
IN reg,(C) LDD RETI
IND LDDR RETN
!NDR LDi RLD
INI LDIR RRD
INIR SBC HL.rp

FD All instructions involving Register !Y.

3-169
ZILOG Z80 ASSEMBLER CONVENTIONS
The standard Z80 assembler is available from 280 manufacturers and on the major
time-sharing networks; it is also part of most development systems.
Cross assem-
bler versions are available for most large computers and
many minicomputers.

ASSEMBLER FIELD STRUCTURE


field structure (see Table
The assembly language instructions have the standard
2-1). The required delimiters are:
and
1) A colon after a label, except for the pseudo-operations EQU, DEFL,
MACRO, which require a space.
2) A space after the operation code.
3) A comma between operands in the operand field. (Remember this one!)
4) A semicolon before a comment.
5) Parentheses around memory references.

Typical Z80 assembly language instructions are:

START: LD A,(1000) ;GET LENGTH


ADD HLDE
HALT

LABELS
The assembler allows six characters in labels; the first character must be a letter,
while subsequent characters must be letters, numbers, ?, or the underbar
character (J. We will use only capital letters or numbers, although some versions
of the assembler allow lower-case letters and other symbols.

RESERVED NAMES
Some names are reserved as keywords and should not be used by the program-
mer. These are the register names (A, B, C, D, E, H, L, I, R), the double register
names (IX, lY, SP), the register names (AF, BC, DE, HL, AP, BC, DE', HL'), and
the states of the four testable flags (C, NC, Z, NZ, M, P, PE, PO).

PSEUDO-OPERATIONS
The assembler has the following basic pseudo-operations:
DEFB - DEFINE BYTE
DEFL - DEFINE LABEL
DEFM - DEFINE STRING
DEFS - DEFINE STORAGE
DEFW - DEFINE WORD
END - END
EQU - EQUATE
ORG - ORIGIN
DEFB, DEFM, and DEFW are the Data pseudo-operations used to DEFB,D£FM,
place data in ROM. DEFB iS used for 8-bit data. DEFW for 16-bit DEFW
data, and DEFM for ASCII strings (63 or less characters iong). The PSEUDO-
on!v unusual feature to remember !S that DEFW stores the eight OPERATIONS
ieast significant bits of data m the first word and the eight most
significant bits m the second word. This is the standard 8080A/8085/Z80 procedure for
storing addresses in memory, but is contrary to normal practice. You must be aware of
the order when storing 16-bit data.

3-170
Note that DEFB and DEFW define the value of only a smgle byte or single word respec-
tively. Establishing a table of values requires a series of DEFB or DEFW
pseudo-opera-
tions, one for each byte or word of data.
Examples:
ADDR: DEFW 3165H
results in (ADDR) =65, and {ADDR+D -31 (hexadecimal).

TCONV: DEFB 32
This pseudo-operation places the number 32 in the next byte of ROM and assigns the
name TCONV to the address of that byte.

ERROR: DEFM 'ERROR'


This pseudo-operation places the 7-bit ASCII characters E. R. R.
0, and R in the next five
bytes of ROM and assigns the name ERROR to the address of
the first byte.

OPERS; DEFW FADD


DEFW FSUB
DEFW FMUL
DEFW FDIV

This series of pseudo-operations places the addresses FADD. FSUB. FMUL and FDIV in
the next eight bytes of memory and assigns the name OPERS to the address of the first
byte. Note that the first byte contains the least significant bits of address FADD.
DEFS IS the Reserve pseudo-operation used to assign locations in DEFS
RAM; It allocates a specified number of bytes.
PSEUDO-
OPERATION
EQU IS the Equate or Define pseudo-operation used to assign EQU
values to names.
PSEUDO-
OPERATION
DEFL IS similar to EOU, except that DEFL allows the name to be DEFL
redefined later. DEFL Is much like the SET directive In other as- PSEUDO-
semblers. It should only be used to define
assembly time variables OPERATION
(i.e., those variables used in conditional assembly or conditional
macro expansion statements).
ORG is the standard Ongin pseudo-operation.
ORG
Z80 programs usually have several origins; the origins are used as PSEUDO-
follows: OPERATION
1) To specify the RESET address (usually zero).
2) To specify interrupt entry points (usually may be anywhere
to 66i q but In memo-
ry.

3) To specify the starting address of the mam program.


4) To specify the starting addresses of subroutines.
5) To define areas for RAM storage.
6) To define an area for the RAM Stack.
7) To specify addresses used for I/O ports and special functions.

3-171
Examples:
RESET EQU
ORG RESET
RESET instruction sequence in mennory beginning at address
This sequence places the
0,

1NT1 EQU 38H


ORG tNTI

stored in memory beginning a t location 38^ e


The instruction sequence that follows is

END simply marks the end of the assembly language program.


END
PSEUDO-
The special purpose pseudo-operations COND.
MACRO. ENDC, OPERATION
and ENDM are described later in this chapter.
LABELS WITH PSEUDO-OPERATIONS
The rules and recommendations for labels with Z80 pseudo-operations are as
follows:
require labels, since the function of these
pseudo-opera-
1) EQU, DEFL and MACRO
tions IS to define the meaning of that label.

2) DEFB. DEFM. DEFW, and DEFS usually have labels.


labels, since the meaning of
3) ORG. COND, ENDC, ENDM. and END should not have
such labels is unclear.

ADDRESSES
The Zilog Z80 assembler allows entries m the address field in any NUMBERS AND
CHARACTERS
of the following forms:
IN ADDRESS
Decimal (the default case) FIELD
Example: 1247
2) Hexadecimal (must start with a digit and end with an H)
Examples: 142CH. 0E7H
Octal (must end with or 0, but is far less confusing)
3)
Example: 1247Q or 12470
4) Binary (must end with B)
Example: 100100100011 IB
5) ASCII (enclosed m single quotation marks)
Example: 'HERE
6) As an offset from the Program Counter ($)

Example: $+237H
All arithmetic and logic operations within an address field
assume ASSEMBLER
all arguments are 16-bit data; they produce 16-bit results. These
ARITHMETIC
operations are allowed as part of expressions in the address field. AND LOGICAL
OPERATIONS
When defining address constants, hexadecimal notation should
be used. Binary constants of 16 bits are unwieldy and hence
error-
fact that addresses are stored in
prone. Octal constants are inconvenient due to the
low-order byte high-order byte format This division occurs
m the middle of an octal
causes you have to split a digit For example, to express the address
digit which to
9D7FH or 1 165770 m low-high format you get 7F9DH or 772360. As you can
see. in

hexadecimal notation the digits are simply transposed, while no such simple relation-
ship exists for octal notation.

3-172
OPERATOR FUNCTION PRIORITY
+ UNARY PLUS 1
-
UNARY MINUS 1
.NOT. or \ LOGICAL NOT 1
.RES. RESULT
** 1

*
EXPONENTIATION 2
MULTIPLICATION 3
/ DIVISION 3
.MOD. MODULO 3
.SHR. LOGICAL SHIFT RIGHT 3
.SHL LOGICAL SHIFT LEFT 3
+ ADDITION
-
4
SUBTRACTION 4
.AND. or a LOGICAL AND 5
.OR. or f LOGICAL OR 6
.XOR, LOGICAL XOR Q
.EQ. or = EQUALS 7
• GT. or > GREATER THAN 7
.LT. or < LESS THAN 7
,UGT. UNSIGNED GREATER THAN 7
.ULT, UNSIGNED LESS THAN 7

Inaddress expressions wrth more than one operator,


the order of evaluation is defined
by the pnonties given m the list above. Operators
havmg the same pnonties are evalu-
ated from (eft to right Expressions m parentheses
are evaluated first Remember that
enclosing an expression entirely in parentheses
indicates a memory address.
Note the following:
1) The Result operator (.RES.) causes overflow to be suppressed; i.e.. a change in siqn
caused by overflow into the sign bit does not result m an assembler error.
2) The shifts have the form:

,SHR. op1,op2
.SHL op1,op2
where op1 is the number to be shifted and op2 is the number of shifts. The
shifts
are logical, i.e.. zeros are shifted into the high-order or low-order
bits, respectively.
3) The comparison operators produce a result of either logical True (all ones) or logical
False (zero). ^

4) The operators GT. and XT. assume signed twos


complement numbers, whereas
.UbL and .ULT, assume unsigned operands. This means
that for .GT. and LT
positive twos complement numbers are larger
than negative twos complement
numbers, while the opposite is the case for.UGT. and
.ULT.

3-173
CONDITIONAL ASSEMBLY
The Z80 assembler has a simple conditional assembly
CONDAND
capability based on the pseudo-operations COND and
ENDC. ENDC
COND !S followed by an expression, for example:
PSEUDO-
OPERATIONS
COND BASE- lOOOH
or
COND BASE- 0PER1
instructions up to the
if the expression is not zero, the assennbler includes all of the
ENDC pseudo-operation m the program; if the expression is zero, the assembler ignores
all instructions between COND and ENDC.
capability again; it is sonnettmes
We will not use conditional assemblies or refer to this
configuring unique versions
handy for adding or eliminating debugging instructions, or
of a common program.

MACROS
The standard Z80 assembler has a macro capability that
MACRO AND
assigns names to Instruction sequences. Use the pseudo-opera-
ENDM
MACRO to begin the definition and ENDM to end it The PSEUDO-
tion
OPERATIONS
macro may have parameters and may include any assembly
language instructions except the definitions of other macros.

The macro capability is often a convenient progrannming shorthand, but we will not use

It.

generally quite short; they


Note that instruction sequences defined by macros are
instructions. Longer sequences should be made into
should not exceed ten or fifteen

subroutines to conserve memory space.

Every MACRO pseudo-operation must have a label; the label is the name with which
you identify the macro. For a discussion of this subtect see Chapter 2.

3-174
Chapter 4
SIMPLE PROGRAMS
The only way to assembly language programming is to write assembly
learn
language programs. That
is what we will do for the next
six chapters, which con-
tain examples of typical microprocessor
tasks. Problems at the end of each
chapter contain variations on the examples given
in the text of the chapter. You
should try to run the examples on a Z80-based
microcomputer system to ensure
that you understand the material covered in
the chapter.
in this chapter we begin with sonne very simple programs.
GENERAL FORMAT OF EXAMPLES
Each program example contains the following parts:
EXAMPLE
1) A title that describes the general problem. FORMAT
21 A statement of purpose which describes the specific
task that
the program performs, plus the memory
locations that it uses.
3) A sample problem showing input data and results.
4) A flowchart if the program logic is complex.
5) The source program or assembly language listing of the program.
6) The object program or hexadecimal machine language
listing of the program.
7) Explanatory notes that discuss the instructions and
methods used in the program.
The problems at the en(^ of the chapter are similar to
the examples; problems
should be programmed on a ZSO-based microcomputer
system using the examples
as guidehnes.

The source programs in the examples have been constructed as follows:

Standard Zilog Z80 assembler notation used, as sum-


is
GUIDELINES
marized in Chapter 3.
FOR
2) The forms in which data and addresses appear are selected for
EXAMPLES
than for consistency. We use hexadecimal num-
clarity rather
bers for memory
addresses, instruction codes, and BCD data: decimal
for numeric
constants; binary for logical masks; and ASCII for
characters.
3} Frequently used instructions and programming techniques
are emphasized.
4) Examples illustrate tasks that microprocessors perform
m communications, instru-
mentation, computer, business equipment industrial,
and military applications,
5) Detailed comments are included.

6) Simple and clear structures are emphasized, but programs are


as efficient as possi-
ble Within this guideline. The notes often describe more efficient procedures.
7) Programs use consistent memon/ Each program starts in memory loca-
allocations.
tion 0000 (the RESET location) and ends with the HALT instruction. !f your

4-1
microcomputer has no monitor and no Interrupts, vou mav prefer to end programs
with an endless loop instruction, e.g.:

HERE: JR HERE
the HALT or JR
The hexadecimal version ts 18 followed by FE. You may replace
control back to
HERE instruction with a RESTART or JP instruction that transfers
the monitor in some Z80-based microcomputers.
determine the required memory
Consult the user's manual for your microcomputer to
particular system.
allocations and terminating instruction for your

GUIDELINES FOR PROBLEMS


When tackling the problenfis at the end of each chapter, try PROGRAMMING
guidelines: GUIDELINES
to work within the following
1) Comment each program so that others can understand it
The comments can be brief and ungrammatical; they
program. Comments
should explain the purpose of a section or instruction in the
is available in
should not describe the operation of instructions: that description
obvious. You
manuals. You do not have to comment each statement or explain the
may follow the format of the examples but provide less detail.
Emphasize clarity, simplicity, and good structure in programs.
While programs
2)
reasonably efficient, do not worry about saving a single byte of program
should be
memory or a few microseconds.
3) Make programs reasonably general. Do not confuse parameters (such as the num-
ber of elements in an array) with fixed constants (such as tt or ASCII C).

4) Never assume fixed initial values for parameters, i.e., use an instruction to load an
initial value into a parameter.
the examples and defined Chapter 3.
5) Use assembler notation as shown in in

6) Use hexadecimal notation for addresses. Use the clearest possible form for data.

7} Ifyour microcomputer allows it start ail programs in memory location 0000 and
Other-
use memory locations starting with 0040^ g for data and temporan/ storage.
wise, establish equivalent addresses for your microcomputer
and use them consis-
tently. Again, consult the user^s manual.

81 Use meaningful names for labels and variables, e.g.. SUM or CHECK rather than X.

Y. or Z.

9) Execute each program on your microcomputer. There is no other way of ensuring


that your program is correct We have provided sample data with each problem.
Be
sure that the program works for special cases.

We now summarize some useful information that you should keep In mind when
writing programs.

Almost ail processing instructions (e.g.. ADD, SUBTRACT. USING THE


AND, OR) use the Accumulator. In most cases you will load ACCUMULATOR
data into the Accumulator with LD. using either LD A.(addr) to
load data from any memon/ location or using LD A,(HU to load
data from the address specified in Registers H and L Remember that the parentheses
indicate a memory address rather than data.

The preferred method of memory is using implied ad-


accessing USING
H and L that is. using (HL). This code causes
dressing via Registers
REGISTER
the Z80 to perform a memory access using the address stored in
PAIR HL
Registers H and L You can use LD HL, datal 6 to load a fixed num-

4-2
ber into Registers H and L or LD HL,{addr) to toad the contents of two successive memo-
n/ locations into H and L You can use INC HL or DEC HL to increment or decrement (by
1) the address in Registers H and L

The and logical operations all use the data in the Accumulator as one of
8-bit arithmetic
their operands and place their result into the Accumulator.

Some of the 8-bit arithmetic and logical operations have special SPECrAL
uses, for example:
INSTRUCTIONS
SUB A (or XOR A) clears the Accumulator.

ADD A.A shifts the Accumulator left one bit logicallv. This instruction also multiplies
the contents of the Accumulator by 2. AND A (or OR A) clears the Carry flag while
preserving the contents of the Accumulator.

A logical AND can mask off parts of a word. The required mask has '1' bits in the posi-
tions that vou want to reserve and '0' bits m the positions that you want to clear.

PROGRAM EXAMPLES
Ones Complement
Purpose: Logically complement the contents of memory location 0040 and place the
result into memory location 0041,

Sample Problem:
(0040) = 6A
Result: (0041) = 95
Source Program:
LD A.(40HI ;GET DATA
CPL ; COMPLEMENT
LD (41H),A ;STORE RESULT
HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 3A LD A,(40H)
0001 40
0002 00
0003 2F CPL
0004 32 LD (41H),A
0005 41
0006 00
0007 76 HALT
The LD and LD (addr),A instructions contain addresses to determine the source
A,(addr)
or destination of the data. The addresses are 16 bits long, with the
eight least signifi-
cant bits in the word immediately following the instruction code and the eight
most sig-
nificant bits in the next word (this order is contrary to normal computer
practice). CPL is
a one-word instruction that inverts each bit of the Accumulator. '0'
It replaces each
with a '1' and each 'T with a '0\ just like a set of inverter gates.

HALT is used to end all the examples.

Note that we could also place an address into Registers H and L and then use that ad-
dress throughout the program. This is shown in the following program.

4-3
Source Program:
LD HU40H POINT TO OPERAND
LD A.iHLi GET DATA
CPL COMPLEMENT
iNC HL POINT TO DESTINATION I

LD (HU,A STORE RESULT


HALT
Object Program :

Memory Adciress Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A,(HL)

0004 2F CPL
0005 23 !NC HL
0006 77 LD (HU.A
0007 76 HALT

Which version do you think is better?


second
The two versions require the same number of bytes of memory even though the
This because the second version uses fewer ex-
version is two instructions longer. is

plicit addresses.

8-Bit Addition
Purpose: Add the contents of memory locations 0040 and 0041. and place the result

mto memory location 0042.

Sample Problem:
(0040) = 38
(0041) = 2B
Result: (0042) = 63
Source Program:
LD A,(40H) GET FIRST OPERAND
LD B,A SAVE FIRST OPERAND
LD A,(41H) GET SECOND OPERAND
ADD A.B ADD OPERANDS
LD (42H).A STORE SUM
HALT

4-4
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 3A LD A,(40H)
0001 40
0002 00
0003 47 LD B.A
0004 3A LD A,(41H)
0005 41
0006 40
0007 80 ADD A.B
0008 32 LD (42H),A
0009 42
OOOA 00
OOOB 76 HALT
Here again, we could alternativeiy use Registers H and L as the source
for ail addresses,
Source Program:
LD HL.40H
LD A,(HL) ;GET FIRST OPERAND
INC HL
ADD A,(HU ;ADD SECOND OPERAND
INC HL
LD (HU,A :STORE RESULT
HALT
Object Program :

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A,(HL)
0004 23 INC HL
0005 86 ADD A.(HL)
0006 23 INC HL
0007 77 LD (HLKA
0008 76 HALT
In thrs case, the program using Registers H and L is shorter than the one using direct
addressing. Why?
LD HL40H loads the contents of the following two words of
program memory mto
Register Pair HL. The first word goes into Register
L the second into Register K
The code (HL) means that data is obtained from or
sent to the memory location ad-
dressed by Registers H and L Thus. LD A.(HU loads the
Accumulator with the contents
of the addressed memory location; LD (HL).A
loads the addressed memory location with
the contents of the Accumulator. ADD A.(HL) adds
the contents of the location ad-
dressed by HL to the contents of the Accumulator. Remember
that H and L contain a
16-bit address, but the memory location with that address
contains eight bits of data
Note the difference between ADD A,(HL) and ADD A.H or ADD
AX.
INC HL performs a 16-bit increment in one instruction cycle. The CPU doesn't use the
8-bit arithmetic unit for the increment; It uses the incrementer that it normally uses to
increment the 16-bit Program Counter.

4-5
whenever you
LD A,(HU and LD (HU.A are preferable to LD A,(addr) and LD (addrKA
use adjacent locations, because LD A.iHLI
use the same memory location repeatedly or
howeyer. that you must
and LD (HL),A require less program memory and time. Note,
load Registers H and L before you can use (HL).

Shift Left On@ Bit


Purpose: Shift the contents of memory location 0040 left one bit and place the result
This type of shift
into memorv location 0041. Clear the empty bit position. is

known as a logical shift. In a logical shift a yatue of zero is always shifted m.

Sample Problem:
(0040) - 6F
Result; (0041) - DE
Source Program:
LD A,{40H) :GETDATA
ADD A.A :SHIFTLtt-l
LD (41H),A :STORE RESULT
HALT
Object Program:
Memory Address Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 3A LD A.(40H)
0001 40
0002 00
0003 87 ADD A.A
0004 32 LD (41 H), A
0005 41
0006 00
0007 76 HALT

ADD A.A simply adds the contents of the Accumulator The result of course, is
to itself.

twice the original data, which is the same result that a logical left shift
would produce.
zero, since 0+0 -1 + 1 =0; 1 + 1 also produces a
The least significant bit of the result iS

Carry to the next bit

Alternatively, we ADD A.A with SLA A. certainly the more obvious


could replace
choice. However, SLA A two words of program memory and eight clock cycles.
requires
cycles. The
white ADD A,A requires one word of program memory and four clock
difference is caused by the fact that SLA A is one of the extra instructions added to the
original 8080A set (remember the comparison presented earlier).

Mask Off Most Significant Four Bits


Purpose: Place the least significant four bits of memory location 0040 into the least

significant four bits of memory location 0041. Clear the most significant four

bits of memon/ location 0041.

Sample Problem:
(0040) - 3D
Result: (0041) = OD

4-6
Source Program:
LD A.(40H) GET DATA
AND 000011118 MASK 4 LSB'S
LD (41H).A STORE RESULT
HALT
Note: B means binary in standard Z80 assembler notation.
Object Program:

Memory Address Memory Contents instruction


(Hex) (Hex) (Mnemonic)
0000 3A LD A.(40H)
0001 40
0002 00
0003 E6 AND 000011118
0004 OF
0005 32 LD (41H),A
0006 41
0007 00
0008 76 HALT
The mask (00001 1 1 1 is written in binary to make its function clearer
)
to the reader. Bin-
ary notation for masks is generally much clearer than
hexadecimal notation, although
the results are the same. Hexadecimal notation should
be used for masks longer than
four bits. The comments should explain the masking
operation.
When the argument in the address field is a number. AND logically
ANDs the contents
of the Accumulator with the contents of the word of program memory
immediately
following the instruction. AND may be used to clear bits
that are not in use. The four
least significant bits could be an input from a switch
or an output to a numeric display.

Clear a Memory Location


Purpose: Clear memory location 0040.
Source Program :

SUB A
LD (40H),A ;CLEAR LOCATION 40
HALT
Object Program:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 97 SUB A
0001 32 LD (40H),A
0002 40
0003 00
0004 76 HALT
SUB A subtracts the number in the Accumulator from itself. The result is to clear the
Accumulator. SUB A. XOR A. or LD A.O can all clear the Accumulator.
LD A,0 takes
more time and memory but doesn't affect the status flags.

Word Disassembly
Purpose: Divide the contents of memory location 0040 into two 4-bit sections and
store them Inmemory locations 0041 and 0042. Place the four most signifi-
cant bits of memory location 0040 into the four least significant bit positions

4-7
place the four least significant bits of memory
of memory location 0041:
0040 into the four least significant bit positions of memory location
location
0042. Clear the four most significant bit positions of memory locations 0041
anci 0042.

Sample Problem:
(0040) = 3F
Result: (0041) = 03
(0042) - OF
Source Program:
LD HL40H
LD A,(HU ;GET DATA
LD B.A
RRA ;SHIFT DATA RIGHT 4 TIMES
RRA
RRA
RRA
AND 0000111 18 :MASK OFF MSB'S
tNC HL
LD (HL),A :STORE MSB'S
LD A.B :RESTORE ORIGINAL DATA
AND 00001 111B :MASK OFF LSB'S
INC HL
LD (HU.A :STORE LSB'S
HALT
Object Program:
Memory Contents Instruction
Memory Address
(Hex) (Hex) (Mnemonic)

0000 21 LD HU40H
0001 40
0002 00
0003 7E LD A,(HL)

0004 47 LD B.A
0005 IF RRA
0006 1F RRA
0007 IF RRA
0008 1F RRA
0009 E6 AND 0000111 18
OOOA OF
OOOB 23 INC HL
OOOC 77 LD (HU.A
OOOD 78 LD A.B
OOOE E6 AND 000011118
OOOF OF
0010 23 INC HL
0011 77 LD (HU,A
0012 76 HALT
only one word of program
Instructions using the address in Registers H and L occupy
loaded before the address can be used. Thus, implied
memon/. However. HL must be
memory addressing saves time and memory, as compared to direct memory addressing,
only when the program repeatedly uses the same address or consecutive addresses.

4-8
RRC shifts the Accumulator right one bit circular, with the least significant bit going to
the most significant bit position and to the Carn/. Shifting the Accumulator nght four
times requires four RRCs. We
could use SRL A to provide a logical shift directly (no final
AND would then be necessary). However, SRL A requires twice as much time and
memory as RRC. Try substituting SRL A for RRC and see the difference. Another alter-
nativewould be to use the RLD instruction to replace both the mask and the store.
However, this solution is not optimal in terms of either storage or execution speed due
to the constraint that the high-order nibble of each result must equal zero.

Many Z80 instructions affect a pair of 8-bit registers. The pairs are HL (H and L), DE (D
and E). and BC (B and C). Registers B, D. and H are the most significant eight bits of the
pairs; Registers C, E. and L are the least significant eight bits. The common instructions
that use pairs of registers are LD rp (Load Register Pair). INC rp (Increment Register
Pair), DEC rp (Decrement Register Pair), and ADD HLrp (Add Register Pair to H and L).

Find Larger of Two Numbers


Purpose: Place the larger of the contents of memory locations 0040 and 0041 into
memory location 0042. Assume that the contents of memory locations 0040
and 0041 are unsigned binary numbers.
Sample Problems:
II CO U.
(0040)
II CM CO
(0041)

Result: (0042) = 3F
(0040) = 75
(0041) = A8
Result: (0042) = A8
Source Program:
LD HL.40H
LD A.(HL) :GET FIRST OPERAND
INC HL
CP (HL) :IS SECOND OPERAND LARGER?
JR CDONE
LD A.fHL) ;YES, GET SECOND OPERAND INSTEAD
DONE; INC HL
LD (HU.A ;STORE LARGER OPERAND
HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemomc)
0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A,(HU
0004 23 INC HL
0005, BE CP (HL)
0006 30 JR NC.DONE
0007 01
0008 7E LD A.(HL)
0009 23 DONE: INC HL
OOOA 77 LD (HL),A
OOOB 76 HALT

4-9
addressed by H and L
CP (HU sets the flags as if the contents of the memory location
However, the contents of
had been subtracted from the contents of the Accumulator.
or other processing.
the Accumulator are left unchanged for later comparisons

If A isthe contents of the Accumulator and X is the second operand for a CP instruc-

tion, then the flags are set as follows:

1) Zero-1 if A- X
Zero = if A X
=i^

2) Carry - 1 if A <X
Carry = if A >X
(A, X are unsigned binary numbers)

CP sets the Carry to 1 if a borrow would be necessary to


actually perform the subtrac-

tion i.e., if number being subtracted from the contents of the Accumulator is
the
than those contents. Thus, the sequence CP.. JR NC.DONE
causes a jump to
greater
other number.
DONE if the contents of the Accumulator are greater than or equal to the

JR NC.DONE causes a jump to memory location DONE if the Carn/ flag


== 0. OthenA/ise

(if carn/
= 1), the computer continues with the next sequential memory location after

the JR instruction.

DONE is a label, a name which you assign to a


location in memory so that it Is easier to

remember. Note that labels are followed by a colon on the line where they
are defined.

The makes the destination of the branch clearer, particularly when relative ad-
label
being used. The assembler calculates the required offset (caution: some
Z80
dressing is
the offset (i.e.,
assemblers will not do this}. Using a label is preferable to just specifying
JR NC.$4-3) since the Z80's instructions vary in length. You could therefore easily make
an error in determining an offset.

the next se-


If the branch conditions are not satisfied, the processor simply proceeds to
quential location in program memon/ (i.e., it executes the instruction
LD A,(HL)).

The Z80 assemblers allow six characters in labels —


the first must be a letter, while the
others may be letters or numbers (some special characters are allowed but we will not
use them).

The JR instruction uses relative addressing in which the second word of the instruction
isan 8-bit twos complement number that the CPU adds to the address of the next in-
struction to find the target address. In the example, the relative offset is 0009
(target

address) minus 0008 (address immediately following the branch) or 01.

We should note that some Z80 assemblers will not calculate the offset in the form
shown. These assemblers require an offset in the address field, rather than the label of
the target instruction. If you have such an assembler, use the form JR
NC.DONE-$.
Remember that $ means "the address of the current instruction".

The Z80 has two sets of JP (Jump) and JR (Jump Relative). The JP
jump instructions,
Instructions require a complete memon/ address; they occupy three bytes of memory
and execute in ten clock cycles. The JR instructions require only a one-word offset:
they occupy two bytes of memory and execute in 12 cycles if a jump is actually per-
formed and in 7 if not So the JR instructions use less memory than JP instructions but
may require a little extra time if a jump is performed (the extra time is used to execute
the required 16-bit addition of program counter and offset).

4-10
16-Bit Addition
r>urpo8e: Add the 16-bit number in mennorv locations 0040 and 0041 to the 16-bit
number in memory locations 0042 and 0043. The most significant eight bits
are in memory locations 0041 and 0043. Store the result in
memory loca-
tions 0044 and 0045, with the most significant bits in 0045.

Sample Problem:
(0040) = 2A
(0041) = 67
(0042) - F8
(0043) - 14
Result: 672A + 14F8 = 7C22
(0044) = 22
(0045) = 7C
Source Program :

LD HL,(40H) :GET FIRST 16-8IT NUMBER


LD DE,(42H) :GET SECOND 16-BIT NUMBER
ADD HLDE ;16-BIT ADDITION
LD (44H),HL ;STORE 16-BIT RESULT
HALT
Object Program :

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 2A LD HL,(40H)
0001 40
0002 00
0003 ED LD •
DE.(42H)
0004 5B
0005 42
0006 00
0007 19 ADD HLDE
0008 22 LD (44H),HL
0009 44
OOOA 00
OOOB 76 HALT
LD HL,(addr) loads Registers H and L from two memory locations, the one
specified in
the instruction and the next consecutive one. The contents of the first addressed
loca-
tion go to Register L The contents of the next location go to Register
H. Thus, LD
HL,(40H| means L = (40), H = (41), The actual transfer proceeds one byte at a time
and
takes 16 clock cycles. The advantage of the 16-bit Load instruction over two 8~bit
Load
instructions is that the CPU has to fetch only one instruction from memory.

Note the difference between LD HL.(addr), which loads the contents of the two RAM
locations at addr and addr-f-1 into H and L and LD HLdatal 6, which loads the contents
of the next two bytes pointed to by the instruction counter into H and L Since these
two bytes immediately follow the op-code, loads of this type are referred to as load im-
mediate instructions.

LD DE.(addr) is similar to LD HL(addr) except that it takes one extra word of memory
and four more clock cycles. This is one of the instructions that is present in the Z80 set
but not in the 8080/8085 sets. An aiternatiye approach is:

EX DE.HL :SAVE FIRST 16-BiT NUMBER IN DE


LD HL(42H} :GET SECOND 16-BIT NUMBER

4-11
EX DE.HL exchanges the contents of Registers D and E with H and L. No numbers are
changed or destroyed. The advantage of EX DE,HL wilt become obvious if you try to
replace it with a series of LD instructions.

ADD HLDE adds the 16-bit number in Registers D and E to the 16-bit number in

Registers H and L The result is placed into Registers H and L ADD HLDE actually adds
one byte at a time. It executes in 1 1 clock cycles.

LD (addrl.HL stores the contents of Registers H and L into two memory locations, the
one specified m the instruction and the next consecutive one. The contents of L go into
the specified location and the contents of H go into the next location. Thus, LD
(44H),HL
means (44) = L, (45) = H. As with LD HL(addr), the actual transfer proceeds one byte at
a time and requires 16 clock cycles.

Although theZSO is an 8-bit processor, it has instructions that handle 16-bit numbers.
These instructions are intended primarily for handling addresses, but you can also use
them for 16-bit data. The most common ones and thetr uses are:
11 ADD HLrp — 16-Bit Add
Used to access tables and to add 16-bit data units
2) DEC rp — 1 Decrement
6-Bit
Used to subtract one from the contents of a register pair

3) INC — 16-Bit Increment


rp
Used add one
to the contents to of a register pair

4) LD rp,data16 — 16-8it Load Immediate


Used to mitialize a register pair with a fixed value, e.g.. the starting address of an ar-
ray or table

5) LD HL,(addri — 16-Bit Load HL Direct


Used to place variable addresses into the main address register (H and L)

61 LD (addr),HL — Store HL Direct


1 6-Bit
Used to store addresses to memory from the main address register (H and L).

Table of Squares
Purpose: Calculate the square of the contents of memory location 0040 from a table
and place it into memory location 0041. Assume that memon/ location 0040
contains a number between and 7 inclusive (0 < (0041) < 7).

The table occupies memory locations 0050 to 0057

Entry
Memory Address
(Hex) (Hex) (Decimal)

0050 00 (0^)
0051 01 1 (i;)

0052 04 4 (2^)
0053 09 9 (3^)

0054 10 16 (4^)
0055 19 25 ibp
0056 24 36 (6:f)

0057 31 49 (7^)

Sample Problems:
a. (0041) = 03
Result: (0042) = 09
b. (0041) = 06
Result: (0042) = 24

4-12
Source Program:
LD A.(40H) :GET DATA
LD L.A ;MAKE DATA INTO 16-8IT INDEX
LD H,0
LD DE,SQTAB ;GET STARTING ADDRESS OF TABLE
ADD HLDE ;INDEX TABLE WITH DATA
LD A.(HL) ;GET SQUARE OF DATA
LD (41H),A
HALT
ORG 50H ;SQUARE TABLE
SQTAB: DEF8
DEFB 1

DEFB 4
DEFB 9
DEFB 16
DEFB 25
DEFB 36
DEFB 49
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 3A LD A,(40H)
0001 40
0002 00
0003 6F LD L.A
0004 26 LD H,0
0005 00
0006 11 LD DE.SQTAB
0007 50
0008 00
0009 19 ADD HLDE
OOOA 7E LD A.(HL)
OOOB 32 LD (41 H),A
OOOC 41
OOOD 00
OOOE 76
0050 00 SOTAB: DEFB
0051 01 DEFB 1

0052 04 DEFB 4
0053 09 DEFB 9
0054 10 DEFB 16
0055 19 DEFB 25
0056 24 DEFB 36
0057 31 DEFB 49
Note that you must also enter the table of squares into memory (the assembler pseudo-
operation DEFB will handle this). The table of squares is constant data, not parameters
that may change; that is why you can initialize the table using the DEFB pseudo-opera-
tton, rather than by executing instructions to load values into the table. Remember that
the table is part of the program memory (ROM in most systems).

LD L.A moyes the data in the Accumulator to Register L. The data is the eight least sig-
nificant bits of the index. You cannot always assume that the data presented to your

4-13
program is in the proper range. It is always a good practice to range check ait criticai
values. Range checking consists of testing a value to ensure that it is within the proper
lower and upper limits. Anv byte can have a value in the range to 255. If the value
will reference
stored in the byte at location 0040H is greater than seven, the program
an undefined byte beyond the end of the square table, causing the program to generate
erroneous results Range checking will prevent this error from occurring.
starting
LD H,0 clears Register H so that it does not interfere with the 1 6-bit addition of
address and index. Never assume that a register contains zero at the start of a program.

LD DESQTAB loads the starting address of the table into Registers D and E. We use D
and E for the starting address since the ADD HL instruction does not change D and E
Thus, the starting address of the table will still be in D and E after the addition, in the
event that we want another element from the table.

ADD HLDE adds the starting address and the index; the result in H and L is thus the ad-
dress of the correct entry. LD A,{HL) then moves that entry to the Accumulator.
Arithmetic that a microprocessor cannot do directly in a few instructions is often best
performed with lookup tables. Lookup tables simply contain all the possible answers to
the problem; they are organized so that the answer to a particular problem can be
found easily. The arithmetic problem now becomes an accessing problem how do—
we get the correct answer from the table? We
must know two things: the position of
the answer in the table (called the index) and the base, or starting, address of the table.
The address of the answer is then the base address plus the index.

The base address, of course, is a fixed number for a particular table. How can we deter-
mine the index? In simple cases, where a single piece of data is involved, we can organ-
izethe table so that the data is the index. In the table of squares, the 0th entn/ in the ta-
ble contains zero squared, the first entry one squared, etc. In more complex cases,
where the spread of input values is very large or there are several data items involved
(e.g., roots of a quadratic or number of permutations), we must use more complicated
methods to determine indexes.

The basic tradeoff in using a table is time vs. memory. Tables are faster, since no com-
putations are required, and simpler, since no mathematical methods must be devised
and tested. However, tables can occupy a large amount of memory if the range of the
input data is large. We
can often reduce the size of a table by limiting the accuracy of
the results, scaling the input data, or organizing the table cleverly. Tables are often
used to compute transcendental and trigonometric functions, linearize inputs, convert
codes, and perform other mathematical tasks.

1 6-Blt Ones Complement


Purpose: Place the ones complement of the 16-bit number in memor/ locations 0040
and 0041 into memory locations 0042 and 0043. The most significant bytes
are in locations 0041 and 0043.

Sample Problem:
(0040) - 67
(0041) = E2
Result: (0042) - 98
(0043) = 1D
The ones complement inverts each bit of the original number; the sum of the original
number and its ones complement will always be all 1 bits.

4-14
Source Pro9ram :

LD HL{40H) :GET DATA


LD AX :COMPLEMENT 8 LSB'S
CPL
LD LA
LD A.H :COMPLEMENT 8 MSB'S
CPL
LD H.A
LD (40H),HL :STORE ONES COMPLEMENT
HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 2A LD HL,{40H)
0001 40
0002 00
0003 7D LD A,L
0004 2F CPL
0005 6F LD L.A
0006 7C LD A.H
0007 2F CPL
0008 67 LD H.A
0009 22 LD (42H).HL
OOOA 42
0008 00
OOOC 76 HALT
Despite the Z80's 1 6-bit instructions, you must use 8-bit instructions to perform most
arithmetic and logical operations. The 16-bit instructions can. however, be used to load
and store data and occasionally to do a few 16-bit arithmetic operations, such as addi-
tion, subtraction, incrementing, and decrementing. You will soon learn that the 16-bit
instructions are far from a complete set and you may often run into awkward problems
if using them to manipulate 16-bit data.

PROBLEMS
1) Twos CompKemant
Purpose: Place the twos complement of the contents of memory location 0040 into
memory location 0041. The twos complement is the ones complement plus
one.

Sample Problem:
(0040) = 3E
Result: (0041) = C2
The sum of the original number and its twos complement is zero (try the sample case).

2) 8-Bit Subtraction
Purpose: Subtract the contents of memory location 0041 from the contents of memory
location 0040. Place the result into memory location 0042.

Sample Problem:
(0040) = 77
(0041) = 39
Result: (0042) 3E

4-15
3) Shift Left Two Bits
Purpose: Shift the contents of memory location 0040 left two bits and place the result

into memory location 0041. Clear the two least significant bit positions.

Sample Problem:
(0040) = 5D
Result: (0041) = 74
4) Mask Off Least Significant Four Bits
Purpose: Place the four most significant bits of the contents of memory location
0040
memon/ location 0041. Clear the four least significant bits of memory
into
location 0041.

Sample Problem:
(0040) - C4
Result: (0041) = CO

5) Set a Memory Location to All Ones


Purpose: Memory location 0040 is set to all ones (FF hex).

6) Word Assembly
Purpose: Combine the four least significant bits of memory locations 0040 and 0041
into a word and store them in memory location 0042. Place the four least
sig-

nificant bits of memory location 0040 into the four most significant bit posi-
tions of memory location 0042; place the four least significant bits of memo-
ry location 0041 into the four least significant bit positions of memory loca-
tion 0042.

Sample Problem:
{0040} - 6A
(0041) - B3
Result: (0042) = A3

7) Find Smaller of Two Numbers


Purpose: Place the smaller of the contents of memon/ locations 0040 and 0041 into

memon/ location 0042. Assume that 0040 and 0041 contain unsigned bin-

ary numbers.

Sample Problems:
a. (0040) - 3F
(0041) = 2B
Result: (0042) = 2B
b. (0040) - 75
(0041) - A8
Result: (0042) = 75

8) 24-Bit Addition
Purpose: Add the 24-bit number in memory locations 0040. 0041, and 0042 to the 24-

bit number memory locations 0043. 0044, and 0045. The most significant
in

eight bits are in memory locations 0042 and 0045: the least significant eight
bits are in memory locations 0040 and 0043. Store the result in memory
locations 0046, 0047. and 0048 with the most significant bits in 0048 and
the least significant bits in 0046.

4-16
Problem:
(0040) - 2A
(0041) - 67
(0042) - 35
(0043) = F8
(0044) = A4
(0045) = 51

Result: (0046) - 22
(0047) - OC
(0048) = 87
that is. 35672A
+51A4F8
870C22
9) Sum of Squares
Purpose: Calculate the squares of the contents of nnemory locations 0040 and 0041
and add them together. Place the result into memon/ location 0042. Assume
that memory locations 0040 and 0041 both contain numbers between and
7 inclusive (0 <, (0040) ^ 7 and ^ (0041) ^ 7). Use the table of squares
from the example entitled Table of Squares.
Sample Problem:
(0040) = 03
(0041) = 06
Result: (0042) = 2D
that is, 32 + 6^ = 9 + 36 = 45 (decimal)
- 2D (hex)

10) 16-8it Twos Complement


Purpose: Place the twos complement of the 16-bit number in memory locations 0040
and 0041 (most significant bits in 0041) into memory locations 0042 and
0043 (most significant bits in 0043).

Sample Problems:
a. (0040) = 00
(0041) = 58
Result: (0042) - 00
(0043) = A8
b. (0040) = 72
(0041) = 00
Result: (0042) - 8E
(0043) = FF

4-17
Chapter 5
SIMPLE PROGRAM LOOPS
The program loop Is the basic structure that forces the CPU to repeat a sequence of in-
structions. Loops have four sections:
1) The initialization section, which establishes the starting values of counters, address
registers (pointers), and other variables.
2) The processing section, where the actual data manipulation occurs. This is the sec-
tion that does the work.
3) The loop control section, which updates counters and pointers for the next itera-
tion.

4) The concluding section, which analyzes and stores the results.

Note that the computer performs Sections 1 and 4 once, while it may perform Sections
2 and 3 many times. Thus, the execution time of the loop will mainly depend on the ex-
ecution time of Sections 2 and 3. You will want Sections 2 and 3 to execute as quickly
as possible; do not worry about the execution time of Sections 1 and 4. A typical pro-
gram loop can be flowcharted as shown in Figure 5-1 or the positions of the processing
.

and loop control sections may be reversed as shown in Figure 5-2. The processing sec-
tion in Figure 5-1 is always executed at least once, while the processing section in
Figure 5-2 may not be executed at all. Figure 5-1 seems more natural, but Figure 5-2 is
often more efficient and avoids the problem of what to do when there is no data (a
bugaboo for computers, and the frequent cause of silly situations like the computer
dunning someone for a bill of $0,00).
The loop structure can be used to process entire blocks of data. To accomplish this, the
program must increment an address register (usually register pair HL) after each itera-
tion so that the address register points to the next element in the data block. The next
iteration will then perform the same operations on the data in the next memon/ loca-
tion. The computer can handle blocks of any length with the same set of Instructions.
Implied addressing through register pairs (particularly HLl is the key to processing a
block of data with the Z80, since it allows you to vary the actual memory address by
changing the contents of registers. Indexed addressing, while longer and slower on the
Z80 than implied addressing, may be handy when processing more than one block of
data.Note that in the immediate and direct addressing modes, the addresses that are
used are completely determined by the instruction (and thus fixed if the program
memon/ is read-only).

5-1
r Start ^

Initialization

Section

m^
mrh

Processing
Section

Loop Control
Section

No ^^he task been^%


^%^compieted ^^^

J^Yes

Conciuding
Section

i
^"^
C ]
1

Figure 5-1. Flowchart of a Program Loop

5-2
CIEZD
Initialization

Section

-^"f
Loop Control
Section

Concluding

Section

CZEID
Figure 5-2. A Program Loop that Aliows Zero Iterations

EXAMPLES
Sum of Data
Purpose: Calculate the sum numbers. The length of
of a series of 8-8IT
the series is m memory location 0041.
and the series SUMMATION
begins in memory location 0042. Store the sum in
memory location 0040. Assume that the sum is an 8-bit
number so that you can ignore carries.
Sample Problem:
(0041) 03
(0042) 28
10043) 55
(0044) 26
Result: (0040) (0042) + (0043) + (0044)
28+55+26
A3
There are three entries in the sum, since (0041)— 03.

5-3
Flowchart:
c D
Pointer = 41
Count = (Pointer)

Sum ~

Pointer = Pointer + 1

Sum =Sum
+ (Pointer)

(40) = Sum

^
C End
J
Note; (Pointer) is the contents of the memory location addressed by Pointer. Remember
that on the Z80, Pointer is a 16-bit address, while (Pointer) is an 8-bit byte of
data.

Source Program :

ID HL41H
LD B.(HL) ;COUNT = LENGTH OF SERIES
SUB A :SUM=ZERO
SUMD; INC HL
ADD A,(HU ;SUM = SUM + DATA
DEC B
JR NZ.SUMD
LD (40H).A ;STORE SUM
HALT

5-4
Object Program :

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 21 LD HL,41H
0001 41
0002 00
0003 46 LD B,{HU
0004 97 SUB A
0005 23 SUMD: INC HL
0006 86 ADD A.(HL)
0007 05 DEC B
0008 20 JR NZ.SUMD
0009 FB
OOOA 32 LD (40H).A
OOOB 40
OOOC 00
OOOD 76 HALT
The initialization section of the program is the first three instructions which set the sum,
counter, and data pointer to their starting values.

Note that you can use LD to transfer data between memory and any of the primary
general purpose registers (i.e.. A. B, C. D, E. H. U using the address in Registers H and L
Howeyer, the only transfers allowed using direct addressing are those that move data to
or from theAccumulator (i.e., LD A,(addr) and LD (addr),A there ts no instruction LD —
E,(addr), for example).

The processing section of the program Is the single instruction ADD A,(HL) which adds
the contents of the memory location being addressed by Registers H and L to the con-
tents of the Accumulator, and stores the result in the Accumulator. This mstruction
does the real work of the program.

The loop control section of the program consists of the instructions INC HL and DEC 8.
INC HL updates the pointer so that the next Iteration adds the next number to the sum.
DEC B decrements the counter that keeps track of how many iterations are left.

The JR NZ causes a branch if the Zero flag is zero. The offset ts a twos com-
instruction
plement number, and the count begins from the memory location immediately follow-
ing the JR instruction. In this case, the required !ump is from memory location OOOA to
memory location 0005. So the offset is:
0005 ^ 05
-OOOA +F6
FB
If the Zero flag is one. the CPU executes the next instruction m sequence (i.e., LD
(40H).A). Since DEC B was the last instruction before JR to affect the Zero flag. JR
NZ.SUMD causes a jump to SUMD if DEC B does not produce a zero result, i.e.;

!SUMD if B ?tO

PC-f2 if B =0
(The 2 IS caused by the two-word JR mstruction).

5-5
The loop sequence DEC followed by JR NZ is so common that the Z80 has a
control
decrements the counter and performs the jump. This In-
special instruction that both
struction iS DJNZ. Decrement and Jump on Not Zero, which decrements Register B and
then lumps by the specified relative offset if the remainder is not zero. So we could
change the end of the example to:
DJNZ SUMO
LD (40H),/^^
HALT
Which has the object form:

07 10 DJNZ SUMD
08 FC
09 32 LD (40H),A
OA 40
OB 00
OC 76 HALT
This change saves one byte of memon/ and three clock cycles. Note, however, that you
must use Register 8 as the counter since this is the register that DJNZ decrements.
Since the offset in Z80 relative lumps is only one byte long, such jumps can go no
further than 127 locations forward or 128 locations backward (actually 129 fonA/ard or
126 backward, since the count starts at the end of the 2-word instruction). Longer
jumps must use the JP instructions.
Most computer loops count down rather than up so that the Zero flag can serve as an
exit condition. Remember that the Zero flag is 1 if the result was zero and if the result
was not zero. Try rewriting the program so that it counts up rather than down; which
method is more efficient?

The order of instructionsis often very Important DEC 8 must come right before JR

NZ,SUMD, since otherwise the Zero result set by DEC B could be changed by another
instruction. INC HL must come before ADD A.iHL) or else the first number added to the
sum will be the contents of memory location 0041 instead of the contents of memory
location 0042.

16-BltSumof Data
Purpose: Calculate the sum numbers. The length of the series is m
of a series of
memory location 0042 and itself begins in memory location 0043.
the series
Store the sum in memory locations 0040 and 0041 (eight least significant
bits m 0040).

Sample Problem:
(0042) = 03
(0043) - C8
(0044) = FA
(0045) - 96
Result; C8 -F FA -F 96 =^0258
(0040) - 58
(0041) - 02

5-6
:

Flowchart:
c D
Pointer = 42
Count = (Pomter)
SumI =
Sumu ==

Pointer ^ Pointer + 1

SumI =Sumi
+ (Pointer)

Sumu =Sumu + 1

Count = Count - 1

(40) = SumI
(41) - Sumu

C End
3
Program
LD HU42H
LD B.fHL) :COUNT = LENGTH OF SERIES
SUB A :LSB'SOFSUM=0
LD C.A :MSB'SOFSUM=0
): iNC HL
ADD A,(HU :SUM = SUM + DATA
JR NC.CHCNT
INC C :ADD CARRY TO MSB'S OF SUM
: DJNZ DSUMD
LD HL.40H
LD (HU.A iSTORELSB'SOFSUM
INC HL
LD {HL),C ;STORE MSB'S OF SUM
HALT

5-7
Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex! (Mnemonic) |

0000 21 LD HL42H
0001 42
0002 00
0003 46 LD B,(HL)
0004 97 SUB A
0005 4F LD C,A
0006 23 DSUMD: INC HL
0007 86 ADD A,(HL)
0008 30 JR NC.CHCNT
0009 01
OOOA OC iNC C
OOOB 10 CHCNT: DJNZ DSUMD
OOOC F9
OOOD 21 LD HL,40H
OOOE 40
OOOF 00
0010 77 LD (HU.A
0011 23 INC HL
0012 71 LD (HU.C
0013 76 HALT
The structure program ts the same as the structure of the last one. The most sig-
of this
nificant bits of the sum
nov^ must be initialized and stored. The processing section con-
sists of three instructions (ADD A,(HL); JR NC.CHCNT: and INC C), including a Condi-
tional Jump.

JR NC, CHCNT causes a lump to memory location CHCNT if the Carry ^ 0. Thus, if there
\s no carry from the 8-b(t addition, the program jumps around the statement that incre-

ments the most significant bits of the sum. The relative offset is:

OOOB
-OOOA
01

The relative offset for DJNZ DSUMD is;

0006 06
-OOOD +F3
F9
INC C adds 1 to the contents of Register C. Note that INC BC is a 16-bit increment that
adds 1 to Register C and adds the resulting carry to Register B; INC C is an 8-bit incre-
ment that does not account for the carry.

5-8
Number of Negative Elements
Purpose: Determine the number of negative
elements (most significant bit 1) in a
block. The length of the block memory
location 0041 and the block itself
is in

starts in memory location 0042. Place the number of negative elements in


memory location 0040.
Sample Problem:
(0041) = 06
(0042) = 68
(0043) = F2
(0044) z= 87
(0045) :^ 30
(0046) = 59
(0047) = 2A
Result: (0040) = 0043 and 0044 contain
02, since
numbers
nur with an MSB of 1.
Flowchart:
CIjEID
Pointer = 41
Count = (Pointer)

Nneg =

Pointer = Pointer + 1

Nneg = Nneg + 1

Count = Count - 1

5-9
Source Program :

LD HL41H
LD B,(HU iCOUNT = NUMBER OF ELEMENTS
LD CO ;NUMBER OF NEGATIVES = ZERO
SRNEG: INC HL
LD A.(HU :GET NEXT ELEMENT
AND A ;JS MSB ZERO?
JP P.CHCNT
INC C :N0, ADD 1 TO NUMBER OF NEGATIVES
CHCNT: DJNZ SRNEG
LD A.C :STORE NUMBER OF NEGATIVES
LD (40H),A
HALT
Object Program :

Memorv Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)

0000 21 LD HL41H
0001 41
0002 00
0003 46 LD B.(HU
0004 OE LD CO
0005 00
0006 23 SRNEG: fNC HL
0007 7E LD A.(HL)
0008 A7 AND A
0009 F2 JP P.CHCNT
OOOA OD
OOOB 00
OOOC OC INC C
OOOD 10 CHCNT: DJNZ SRNEG
OOOE F7
OOOF 79 LD A.C
0010 32 LD (40H),A
0011 40
0012 00
0013 76 HALT
AND A Simply sets the flag bits according to the contents of the Accumulator without
affecting those contents; OR A has the same effect. This Is necessary since merely load-
ing the Accumulator does not affect the flags.

JP P.CHCNT requires a full 16-bit address. There is no relative jump on the Sign flag like

there is on the Carry and Zero flags.

Note that al! we really want to do is test the value of bit 7 of the memory location ad-
dressed by Registers H and L The Z80 has a special bit testing instruction, BIT. that is
designed specifically for this purpose. BIT sets the Z flag to the complement of the indi-
cated bit within the indicated register or memory location. For example, BIT 5,D will set
Z to 1 If bit 5 of Register D is zero, and to if bit 5 of Register D is one. An implementa-
tion of this alternative is as follows.

5-10
Source Program:
LD HL41H
LD B,(HL) :COUNT = NUMBER OF ELEMENTS
LD CO ;NUM8ER OF NEGATIVES = ZERO
; INC HL
BIT 7,(HL) :iS NEXT ELEMENT NEGATIVE?
JR Z.CHCNT
iNC C ;YES. ADD 1 TO NUMBER OF NEGATIVES
':
DJNZ SRNEG
LD A.C ;STORE NUMBER OF NEGATIVES
LD (40H).A
HALT
Object Program:
Memory Address Memorv Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL41H
0001 41
0002 00
0003 46 LD B.(HL)
0004 OE LD CO
0005 00
0006 23 SRNEG; !NC HL
0007 CB BIT 7.(HL)
0008 7E
0009 28 JR Z.CHCNT
OOOA 01
OOOB OC INC C
OOOC 10 CHCNT: DJNZ SRNEG
OOOD F8
OOOE 79 LD AC
OOOF 32 LD (40H),A
0010 40
0011 00
0012 76 HALT
BIT 7,(HL) sets the Z bit if bit 7 of the memorv location addressed by Registers H and L is
zero, and clears the Z bit if bit 7 of that location is one. BIT does not affect any registers
or memory locations.

This program uses JR Z.CHCNT since no incrementing is necessary if the addressed bit
is zero.

Stillanother approach would be to use the instruction RLC (HL) to shift the sign bit of
the data in memorv to the Carrv. The required jump would then be JR NCCHCNT.

Howeyer, this approach uses extra time (RLC (HL) takes 15 cycles as compared to the
12 needed by BIT 7,{HL)) and also changes the data In memory which may be needed
for other purposes. Note that these disadvantages are related: the extra time is needed
to return the result to the memorv location.

Find Maximum
Purpose: Find the largest element in a block of data. The length of the block is in
memory location 0041 and the block begins in memory location 0042.
itself
Store the maximum m memory location 0040. Assume that the numbers in
the block are all 8-blt unsigned binary numbers.

5-11
Sample Problem:
(0041) 05
(0042) 67
(0043) 79
(0044) 15
(0045) E3
(0046) 72

Result: (0040) E3, since thisis the largest of

the five unsigned numbers.

Flowchart:

f Start
J

Pointer = 41
Count = iPointerJ

Max =

i
Pointer = Pointer + 1

Max = (Pointer)

Count = Count - 1

{401 = Max

'"'
( )

5-12
Source Program:
LD HL41H ;POINTTO COUNT
LD B,(HL) :COUNT = NUMBER OF ELEMENTS
SUB A :MAX!MUM = MINIMUM POSSIBLE VALUE (ZERO)
NEXTE: INC HL
CP (HL) :!S NEXT ELEMENT ABOVE MAXIMUM?
JR NC.DECNT
LD A,(HL) ;YES, REPLACE MAXIMUM WITH ELEMENT
DECNT: DJNZ NEXTE
LD (40H),A :SAVE MAXIMUM
HALT
Object Program:
Memory Address Memory Contents instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL41H
0001 41
0002 00
0003 46 LD B.(HL)
0004 97 SUB A
0005 23 NEXTE: INC HL
0006 BE CP (HL)
0007 30 JR NCDECNT
0008 01
0009 7E LD A,(HU
OOOA 10 DECNT: DJNZ NEXTE
OOOB F9
OOOC 32 LD (40H).A
OOOD 40
OOOE 00
OOOF 76 HALT
The relative offset for JR NCDECNT is:

OOOA
-0009
01
The relative offset for DJNZ NEXTE rs:

0005 ^ 05
-OOOC -i-F4

F9
The first three instructions of this program form the initialization section.

This program takes advantage of the fact that zero is the smallest 8-bit unsigned binary
number. When you set the register that contains the maximum value —
in this case the
Accumulator — to the minimum
possible value before you enter the loop, then the pro-
gram will set the Accumulator to a larger value unless alt the elements in the array are
zeros.

5-13
The program works properly if there are two elements, but not if there are one or none

at alJ Why? How could you solve this problem?

CP (HU sets the Carry flag as follows (ELEMENT is the contents of the
The instructton
address in Registers H and L and MAX is the contents of the Accumulator):

CARRY = 1 if ELEMENT > MAX


CARRY = if ELEMENT < MAX
CARRY = 0. the program proceeds to DECNT and does not change the maximum. If
if

CARRY = 1. the program replaces the old maximum with the current element by ex-
ecuting the instruction LD A,(HL).

The program does not work if the numbers are signed because
negative numbers will
appear to be larger than positive numbers. The problem is somewhat tricky because
overflow could make the result appear to have the wrong sign.

Remember that overflow occurs when the magnitude of a result affects its sign bit The
Z80 has a Parity/Overflow flag that indicates
overflow has oc-
when twos complement
curred. Arithmetic operations that result in overflow set this flag.
You can then test its
value with the instructions JP PE.ADDR (Jump on Parity Even

or Jump on Overflow)

or JP PO.ADDR (Jump on Parity Odd —or Jump on No


Overflow). One thing you may

have to watch is that this Z80 usage is inconsistent with the 8080A or
8085
microprocessors, which aiwavs use the P flag to indicate parity. The 8080A and 8085
microprocessors have no overflow indicator.

Justify a Binary Fraction


Purpose: Shift the contents of memory location 0040 left until the most significant bit
of the number is 1. Store the result in memory location 0041 and the
number
of left shifts required in memory location 0042. tf the contents of
memory
location 0040 are zero, clear both 0041 and 0042.

Note: The process is lust like converting a number to a scientific notation: for example:

0.0057 = 6.7x10"^

Sample Problems:
a. (0040) = 22
Result: (0041) :rz
88
(0042) 02
(0040) = 01

Result: (0041) = 80
(0042) 07
(0040) = CB
Result: (0041) CB
(0042)
: 00

(0040) = 00
Result: (0041) = 00
(0042) 00

5-14
Flowchart:

Source Program:
LD B.O ;NUMBER OF SHIFTS-ZERO
LD HL,40H
LD A,{HL) ;GET DATA
AND A ;ISDATAZERO>
JR Z.DONE ;YE$. DONE
CHKMS. JP M.DONE ;DONE !F SIGN BIT IS ONE
INC B ;ADD TO NUMBER OF SHIFTS
1

ADD A.A ;SH!FT LEFT ONE BIT


JP CHKMS
DONE; INC ML
LD (HL).A :SAVE JUSTIFIED DATA
iNC HL
LD (HL),B ;SAVE NUMBER OF SHIFTS
HALT

5-16
Object Program:
Memory Contents Instruction
Memory Address
(Hex) (Mnemonic)
(Hex)

06 ID B.O
0000
0001 00
21 LD HL.40H
0002
0003 40
0004 00
0005 7E LD A,(HL)

A7 AND A
0006
28 JR Z.DONE
0007
0008 08
FA CHKMS: JP M.DONE
0009
OOOA 11

OOOB 00
04 INC B
OOOC
OOOD 87 ADD A.A
C3 JP CHKMS
OOOE
OOOF 09
0010 00
23 DONE: INC HL
0011
0012 77 LD (HL),A

23 INC HL
0013
0014 70 LD (HL),B

0015 76 HALT
DONE the Sign bit is 1. ThiS condition may
JP M DONE causes a jump to location if

most sigmti-
or may just mean that its
mean that the last result was a negative number
cant bit was 1 —the computer supplies only the results: the
programmer must provide
the interpretation.
program uses this instruc-
ADD A A adds the number in the Accumulator to itself. The
RLA and RLCA
tion, rather thanRLA or RLCA. because ADD A affects the Sign bit while
do not
We could reorganize this program so as to eliminate
an extraneous JP and use relative
rather than absolute jumps. One reorganized version would be:
LD B.O :NUMBER OF SHIFTS -ZERO
LD HU40H
LD A,(HU GET DATA
AND A IS DATA ZERO?

JR Z.DONE YES.DONE
DEC B ADJUST NUMBER OF SHIFTS BACK ONE
CHKMS; INC B ;ADD TO NUMBER OF SHIFTS
1

RLA SHIFT LEFT ONE BIT


JR NCCHKMS CONTINUE IF MSB NOT ONE
RRA :ADJUST DATA BACK
DONE: INC HL
LD (HL).A :SAVE JUSTIFIED DATA
INC HL
LD (HU.D :SAVE NUMBER OF SHIFTS
HALT
Show that this version also works. What are its advantages and disadvantages as com-
pared to the previous program?

5-16
PROBLEMS
1) Checksum of Data
Purpose: Calculate the checksum of a series of numbers. The length of the series Is in
memory location 0041 and the series itself begins in memory location 0042,
Store the checksunn in memory location 0040, The checksum is formed by
Exclusive-ORing all the numbers in the series together.

Note; Such checksums are often used m paper tape and cassette systems to ensure
that the data has been read correctly. The calculated checksum is compared to
the one stored with the data — if the two checksums do not agree, the system
will usually either indicate an error to the operator or automatically read the data
again.

Sample Problem:
(0041) = 03
(0042) = 28
(0043) - 55
(0044) = 26
Result: (0040) = (0042) © (0043) ® (0044)
= 28®55®26
= 00101 000
® 01 010101
01111101
© 001 001 1

10 110 11
= 5B
2) Sum of 16- Bit Data
Purpose: Calculate the sum of a series of 16-bit numbers. The length of the senes !S in
memory location0042 and the series itself begins in memory location 0043.
Store the sum in memory locations 0040 and 0041 (eight most significant
bits in 0041). Each 16-bit number occupies two memory locations, with the
eight most significant bits in the higher address. Assume that the sum can
be contained in 16 bits.

Sample Problem;
(0042) = 03
(0043) = F1
(0044) = 28
(0045) = 1A
(0046) = 30
(0047) = 89
(0048) ^ 4B
Result: 28F1 +301A H

(0040) = 94
(0041) = A4

5-17
3) Wumber of Zero, Positive, and Negative Numbers
Purpose: Determine the number of zero, positive (most significant bit zero but entire
number not zero), and negative (most significant bit 1) elements In a block.
The length of the block is in memory location 0043 and the block itself starts
in memory location 0044. Place the number of negative elements in memory

location 0040, the number of zero elements in memory location 0041. and
the number of positive elements in memory location 0042.

Sample Problem:
(0043) = 06
(0044) = 68
(0045) = F2
(0046) = 87
(0047) - 00
(0048) = 59
(0049) = 2A
Result; 2 negative, 1 zero, and 3 positive, so
(0040) = 02
(0041) - 01
(0042) = 03

4) Find Minimum
Purpose: Find the smallest element in a block of data. The length of the block is in
memory location 0041 and the block itself begins in memory location 0042.
Store the minimum m memory location 0040. Assume that the numbers in
the block are 8-btt unsigned binary numbers.

Sample Problem:
(0041) - 05
(0042) = 67
(0043) = 79
(0044) = 15
(0045) = E3
(0046) = 72
Result: (0040) = 15, since this
15. is the smallest of the
five unsigned numbers.

5) Count 1 Bits
Purpose: Determine hov\/ many bits in memory location 0040 are one and place the
result m memory location 0041.

Sample Problem:
(0040) = 38 = 00111011
Result: (0041) = 05

5-18
Chapter 6
CHARACTER-CODED DATA
Microprocessors often handle character-coded
data. Not only do keyboards,
teletypewriters, comnnunicattons devices, displays, and computer terminals expect or
provide character-coded data; many instruments, test systems, and controllers also re-
quire data in this form. The most commonly used code is ASCII. Baudot and EBCDIC
are
found less frequently. We will assume all of our character-coded data to be 7-bit ASCII
with the most significant bit zero {see Table 6-lK

Some principles to remember in handling ASCII-coded data are: HANDLING


11 The codes for the numbers and letters form ordered sub-se- DATA IN
quences. The codes for the decimal numbers are hex 30 ASCII
through 39, so that you can convert between decimal and
ASCI! with a simple additive factor. The codes for the upper-case letters are hex 41
through 5A, so that you can do alphabetic ordering by sorting the data m increas-
ing numerical order.

2) The computer draws no distinction between printing and non-printing characters.


This distinction is made only by I/O devices.

3) An ASCII device wilt handle only ASCII data. To pnnt a 7 on an ASCII printer, the
microprocessor must send hex 37 to the printer: hex 07 Is the 'bell' character.
Similarly, the microprocessor will receive the character 9 from an ASCII keyboard
as hex 39; hex 09 is the 'tab' character.

4) Some ASCI! devices do not use the full character set. For example, control charac-
ters and lower-case letters may be ignored or printed as spaces or question marks.
5) Some widely used ASCII characters are;

OA.(g- linefeed (LF)

OD.|g - carriage return (CR)

20^ g - space
3F^g - ^ (question mark)

7F^g - rubout or delete character


6) Each ASCI! character occupies seven bits. This allows a large character set but is
wasteful when the data is limited to a small subset such as the decimal numbers.
An 8-bit byte, for example, can hold only one ASCII-coded decimal digit, while i^

can hold two BCD-coded digits.

6-1
Tab!e6-1. Hex-ASCI! Table

"\^9» MSD
1 2 3 4 § 6 7
H®K ISD^"^^\^
NUL DLE SP @ P P
1 SOH DC1 1 1 A Q a q
2 SIX DC2 2 B R b r

3 ETX DCS # 3 C S c s

4 EOT DC4 $ 4 D T d t

S ENQ NAK % 5 E U e u
6 ACK SYN & 6 F V f V
7 BEL ETB 7 G w g w
8 BS CAN ( 8 H X h X

9 HT EM ) 9 1 Y i
y
«
A LF SUB J Z i
z

B VT ESC + K [ k (

C FF FS ,
< L \ 1
1

D CR GS - ~ M ] m 1

A -^
E SO RS , > N n
F SI US / 7 — DEL

EXAMPLES
Length of a String of Characters
Purpose: Determine the length of a string of ASCI! characters (seven bits with most
significant bit zero). The string starts in memory location 0041; the end of
the string is marked by a carriage return character ('CR\ hex OD). Place the
length of the string (excluding the carriage return) into memory location
0040.

Sample Problems:
(0041) - OD
Result: (0040} - 00 smce
smc the first character is a carriage return.

(0041) = 52 'R'

(0042) = 41 'A'

(0043) - 54 'T'

(0044) = 48 'H'

(0045) - 45 'E*

(0046) = 52 'R'

(0047) = OD CR
Result: (0040) 06

6-2
1

Flowchart:

c
Pointer = 41
Length =

Length = Length +
Pointer = Pointer + (40) = Length
1

d^ZD
Source Program:
LD HL41H POINTER - START OF STRING
LD B.O STRING LENGTH -ZERO
LD A.ODH GET ASCII CARRIAGE RETURN TO COMPARE
CHKCR: CP (HU IS CHARACTER A CARRIAGE RETURN?
JR Z.DONE YES, DONE
INC B NO, ADD 1 TO STRING LENGTH
INC HL
JR CHKCR :TRY NEXT CHARACTER
DONE; LD A,B ;SAVE STRING LENGTH
LD (40H).A
HALT

6-3
Memory Address Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 21 LD HL41H
0001 41
0002 00
0003 06 LD B.O
0004 00
0005 3E LD A,ODH
0006 OD
0007 BE CHKCR: CP (HL)

0008 28 JR Z.DONE
0009 04
OOOA 04 INC B
OOOB 23 INC HL
OOOC 18 JR CHKCR
OOOD F9
OOOE 78 DONE: LD A,B
OOOF 32 LD (40H).A
0010 40
0011 00
0012 76 HALT
The carnage return (CR) is just another ASCII character (hex OD) as far as the computer
IS concerned. The fact that the output device treats
the carnage return as a control
character rather than as a pnntmg character does not affect the computer.

The Compare instruction, CP, sets the flags as if a subtraction had been performed, but
leaves the carnage return character m the Accumulator for later comparisons.
The Zero
(Z) flag is affected as follows:

Z = 1 if the character in the stnng is a carnage return

Z = if It is not a carnage return

The instruction INC B adds 1 to the string length counter in Register B. LD B,0 mitializes

this counter to zero before the loop begins.


Remember to initialize vanables before
using them in a loop.

This loop does not terminate because a counter is decremented to zero. The computer
will simply continue examining characters until it finds a carnage return.
You may have
to place a maximum count in a loop like this to avoid problems with erroneous strings

that do not contain a carriage return. What would happen if the example program were
used with such a stnng?

Note that by rearranging the logic and changing the initial conditions, you can shorten
the program and decrease its execution time. If we adjust the flowchart so that the pro-
gram increments the counter and pointer before it looks for the carnage return, only one
Jump Instruction is necessary instead of two. The new flowchart and program are as
follows:

6-4
1

Flowchart:

f Start
J

Pointer = 40
Length = -

I
Length = Length + 1

Pointer = Pointer + 1

{40} = Length

C End
_)

Source Program:
LD HL.40H POINTER = BYTE BEFORE STRING
LD B.OFFH LENGTH =-1
LD A.ODH GET ASCII CARRIAGE RETURN TO COMPARE
CHKCR: iNC HL
!NC B ADD TO STRING LENGTH
1

CP (HU IS CHARACTER A CARRIAGE RETURN?


JR NZ.CHKCR NO, CHECK NEXT CHARACTER
LD A,B YES. SAVE STRING LENGTH
LD (40H).A
HALT

6-5
Object Program:
Memorv Contents instruction
Memory Address
(Hex) (Hex) (Mnemonic)

0000 21 ID HL,40H
0001 40
0002 00
06 LD B^OFFH
0003
0004 FF
0005 3E LD A.ODH
0006 OD
0007 23 CHKCRR: INC HL
0008 04 INC B
0009 BE CP (HL)

OOOA 20 JR NZ.CHKCR
OOOB FB
OOOC 78 LD A,B
OOOD 32 LD (40H),A

OOOE 40
OOOF 00
0010 76 HALT
m a list table, or string is a common one. The
The task of looking for a particular value
Z80 microprocessor has. in fact, special instructions that simplify this task

These special instructions are called Block Search Instructions; BLOCK


they operate as follows:
SEARCH
INSTRUCTIONS
CPi compares the contents of the memory location addressed by
HL with the contents of the Accumulator (just like CP (HL)). It then
increments HL and decrements the byte counter (register pair BC). The Parity/Overflow
bit IS reset if the byte counter is decremented to zero
and set otherwise. CPD is the
same instruction except that it decrements HL instead of incrementing it

CPtR and CPDR are the repeated forms of the Block Search instructions. These instruc-
tions repeat the basic Search instruction until either BC is decremented to zero or a true
comparison occurs (i.e.. A = (HL)). Remember that decrementing BC to zero resets the
Parity/Overflow bit, while finding a match sets the Zero bit

Note that BC contains a 16-bit counter. Thus, the Block Search Instructions can handle
strings of any length.

A version of the previous program using CPi is shown below.


Source Program:
LD HL41H POINTER = START OF STRING
LD SCO BYTE COUNTER = ZERO
LD A.ODH GET ASCI! CARRIAGE RETURN TO COMPARE
CHKCR: CPI IS CHARACTER A CARRIAGE RETURN?

JR NZ.CHKCR NO, CHECK NEXT CHARACTER


LD A.OFFH YES. CALCULATE STRING LENGTH
SUB C
LD (40H).A ;SAVE STRING LENGTH
HALT

6-6
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL41H
0001 41
0002 00
0003 01 ID SCO
0004 00
0005 00
0006 3E LD A.ODH
0007 OD
0008 ED CHKCR: CPl
0009 A1
OOOA 20 JR NZ.CHKCR
OOOB FC
OOOC 3E LD A,OFFH
OOOD FF
OOOE 91 SUB C
OOOF 32 LD (40H),A
0010 40
0011 00
0012 76 HALT
A manipulation is necessary to calculate the string length, since CPl decrements
little

the byte counter (BC) instead of incrementing it as we did with INC B m the earlier
pro-
gram. Also, the byte counter is decremented one extra time when the carriage return is
found. How could you adjust the initial conditions to handle this problem?

In fact, we can imorove


the program even further by using CPIR to remove the need for
the relative lump CPIR does everything that CP! does, but it also automatically
JR.
repeats the comparison procedure unless A = (HL) or BC has been decremented to zero.
The program using CPIR is shown below.
Source Program:
LD HL,41H POINTER = START OF STRING
LD BCO BYTE COUNTER = ZERO
LD A.ODH ;GET ASCII CARRIAGE
RETURN TO COMPARE
CPIR SEARCH FOR CARRIAGE RETURN
LD A.OFFH CALCULATE STRING LENGTH FROM COUNTER
SUB C
LD (40H).A ;SAVE STRING LENGTH
HALT

6-7
Object Program:
Memorv Contents Instruction
Memory Address
(Hex) (Hex) (Mnemonic)

0000 21 LD HL.41H
0001 41
0002 00
0003 01 LD SCO
0004 00
0005 00
0006 3E LD A.ODH
0007 OD
0008 ED CPIR
0009 B1
3E LD A.OFFH
OOOA
OOOB FF
OOOC 91 SUB C
GOOD 32 LD (40H),A

OOOE 40
OOOF 00
0010 76 HALT
same effect as the se-
The multiple operation instructions like CPt and CPIR have the
quences thev replace. The savings in execution time and memory come about because
the processor needs fewer instructions for each pass through
the loop. Thus, the real
savings is in loop execuion.

Allthese programs assume that the stnng is less than 256 bytes long. How would you

change them to handle longer stnngs?

Find First Non-Blank Character


Purpose: Search a string of ASCI! characters (seven bits with most significant
bit zero)

for a non-blank character. The string starts in memory


location 0042, Place

the address of the first non-blank character into memon/ locations


0040 and
0041 (most Significant bits in 0041). A blank character is hex 20 in ASCII.

Sample Problems:
a. (0042) - 37 7'

Result: (0040) - 42, since memory location 0042 contains a non-blank


character.
(0041) = 00
b. (0042) = 20 SP
(0043) - 20 SP
(0044) = 20 SP
(0045) = 46 F
(0046) - 20 SP
Result: (0040) == 45, since the three previous memory locations all

contain blanks.
(0041) = 00

6-8
Flowchart:

f Start "1

Pornter = 42

^^•^^ {Pointer) =^Sfe No


%^ASCil btank^

Pointer = Pointer + 1 (40 and 41) = Pointer

t
^ Snd
J

Source Program:
LD HL42H POINTER -START OF STRING
LD A.20H GET ASCI! SPACE FOR COMPARISON
CHBLK: CP (HU IS CHARACTER AN ASCII SPACE" >

JR NZ,DONE NO, THROUGH


INC HL
JR CHBLK YES, EXAMINE NEXT CHARACTER
DONE; LD (40H),HL NO, SAVE ADDRESS OF FIRST NON-BLANK
CHARACTER
HALT
Object Program:

Memory Adciress Memor V Contents Instruction


(Hex) Hex) (Mnemonic)
0000 21 LD HL42H
0001 42
0002 00
0003 3E LD A.20H
0004 20
0005 BE CHBLK: CP (HU
0006 20 JR NZ.DONE
0007 03
0008 23 tNC HL
0009 18 JR CHBLK
OOOA FA
OOOB 22 DONE: LD (40H),HL
OOOC 40
OOOD 00
OOOE 76 HALT

6-9
Looking for spaces in strings is a common task. Spaces often are eliminated from
formats. It is
strings when they are used simplv to increase readability or to fit particular
extra spaces, particularly
obviously wasteful to store and transmit beginning, ending or
If you are paying for the
communications capability and memory required. Data and
Microcom-
program entry, however, are much simpler if extra spaces are tolerated.
are often used in situations like this to convert data between forms that are easy
puters
for humans to use and forms that are efficiently handled on computers and com-
munjcations lines.

The LD (addr),HL is convenient for storing addresses in the


instruction
Z80 format (least
significant byte first). LD (40H),HL stores the contents of Register
L in memory location
0040 and the contents of Register H in memon/ location 0041.
Again, if we alter the initial conditions so that the loop control section precedes the pro-
reduce the number of bytes
we can in the program and decrease the
cessing section,
loop's execution time. The rearranged flowchart is:

f Start
I

Pointer = 41

(40 and 41} = Pointer

C End
_)
Source Program:
LD HL,41H :POINT TO BYTE BEFORE STRING
LD A.20H :GET ASCI! SPACE FOR COMPARISON
CHBLK; INC HL
CP (HU :1S CHARACTER AN
ASCII SPACE?
JR Z.CHBLK ;YES. KEEPEXAMINING CHARACTERS
LD (40H),HL ;N0. SAVE ADDRESS OF FIRST NON-BLANK
. CHARACTER
HALT

6-10
Object Program:
Memory Address Memory Contents instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL41H
0001 41
0002 00
0003 3E LD A,20H
0004 20
0005 23 CH8LK: INC HL
0006 BE CP (HL)
0007 28 JR Z.CHBLK
0008 FC
0009 22 LD (40H),HL
OOOA 40
OOOB 00
OOOC 76 HALT
As m the previous example, we
could replace the sequence INC HL CP (HL) with the
single instruction CPI. However, since we do not need
the byte counter in this program.
CPI takes just as much memory (two bytes) and more time
(16 clock cycles instead of
1 3) than the instructions it
replaces. We could not use CPiR here since we want the pro-
gram to terminate when the characters are not the same.

Replace Leading Zeros with Blanks


Purpose: Edit a string of ASCIIdecimal characters by replacing all leading zeros with
blanks. The memory location 0041: assume that tt consists
string starts in
entirely of ASCII-coded decimal digits. The length of the string
is in memory
location 0040.

Sample Problems:
a. (0040) - 02
(0041) - 36 '6'

The program leavess the string unc han


unchanged, since the leading digit is not zero,
b. (0040) = 08
(0041) = 30 '0'

(0042) = 30 '0'

(0043) = 38 '8'

Result: (0041) = 20 SP
(0042) = 20 SP

6-11
Flowchart:

{Pointer} = ASCII SP
= 20 (Hex)
Pointer - Pointer +1
Count = Count - 1

Source Program:
LD HL.40H
LD B.fHLl ;COUNT = STRING LENGTH
LD A,*0' ;GET ASCI! ZERO FOR COMPARISON
CHKZ: INC HL
CP (HL) IS LEADING DIGIT ZERO?
JR NZ.DONE NO. THROUGH
LD (HU,20H REPLACE LEADING ZERO WITH BLANK
DJNZ CHKZ EXAMINE NEXT DIGIT IF ANY
DONE: HALT
Single quotation marks around characters indicate ASCII.

6-12
Object Program:

Memory Address Memory Contents instruction


(Hex) (Hex) (Mnemonic)
0000 21 LD HL40H
0001 40
0002 00
0003 46 ID B,(HL)
0004 3E LD A.'O'
0005 30
0006 23 CHKZ: iNC HL
0007 BE CP (HL)
0008 20 JR NZ.DONE
0009 04
OOOA 36 ID (HU,20H
OOOB 20
OOOC 10 DJNZ CHKZ
OOOD F8
OOOE 76 DONE: HALT
You win frequently want to edit decimal strings before they are printed or displayed
to
improve their appearance. Common editing tasks include eliminating
leading zeros,
justifying numbers, adding signs or other identlfyrng
markers, and rounding. Clearly
printed numbers like 0006 or $27.34382 can be confusing
and annoying.
Here the loop has two exits — one if the processor finds a non-zero digit and the other if
it has examined the entire string.

The instruction LD (HL).20H places 20 (hex) into the memory location addressed by
Registers H and L You could also initialize Register C to 20 hex (i.e., LD C,20H) and use
LD (HL),C to replace the leading zero with a blank. Note the
tradeoffs inyotved In this ex-
ample. LD (HL)X executes faster than LD (HU,20H and would thus
decrease the inner
loop s execution time. The overhead required, however, is
an LD C,20H instruction in
the initialization section of the routine. If this example were
to be used in a cash register
application, which sequence would you choose and why?

Alt digits in the string are assumed to be ASCII: that is. the digits are hex 30 through 39
rather than the ordinary decimal to 9. The conversion from decimal to ASCII is simply
a matter of adding hex 30 to the decimal digit
You may have to be careful, when blanking leading zeros, to leave one zero m the event
that all the digits are zero. How would you do this?
Note that each ASCII digit requires eight bits, as compared to four for a BCD
digit
Therefore, ASCIIis an expensive format in which to store
or transmit numerical data.
Add Even Parity to ASCII Characters
Purpose: Add even parity to a string of 7-bit ASCII characters. The length of the string
IS in memory location 0040 and the string itself begins in
location memory
0041. Place even parity the most significant bit of each character by set-
in
ting the most significant bit to 1 if that makes the total number
of 1 bits in
the word an even number.

6-13
Sample Problem
(0040) = 06
(0041) = 31
(0042) = 32
(0043) - 33
(0044) = 34
(0045) = 35
(0046) = 36

Result: (0041) = B1
(0042) = B2
(0043) = 33
(0044) - 84
(0045) = 35
(0046) - 36

Flowchart:

f Start
J

Pointer = 41
Count = (40)

{Pointer) "{Pointer)

OR 10000000B
(set paritv bit)

Pointer = Potnter +1
Count = Count - 1

6-14
Source Program:
LD HL40H
LD 8.(HL) :GET STRING LENGTH
LD C.10000000B ;GET PARITY BIT OF 1
SETPR: iNC HL
LD A,(HU :GET A CHARACTER
OR C :SET PARITY BIT TO 1 AND TEST PARITY
JP PO.CHCNT :IS PARITY NOW EVEN?
LD (HU.A :YES. SAVE CHARACTER WITH EVEN PARITY
CHCNT: DJNZ SETPR
HALT
Object Program:

Memorv Address Memory Contents Instruction


(Hex) (Hex) (Mnennonic)

0000 21 LD HL,40H
0001 40
0002 00
0003 46 LD B,(HL)
0004 OE LD CJOOOOOOOH
0005 80
0006 23 SETPR: INC HL
0007 7E LD A,(HU
0008 B1 OR C
0009 E2 JP PO.CHCNT
OOOA OD
OOOB 00
OOOC 77 LD (HU.A
OOOD 10 CHCNT; DJNZ SETPR
OOOE F7
OOOF 76 HALT

Parity is often added to ASCII characters before they are


transmitted on noisy com-
munication lines, to provide a simple error-checking faciiity. Parity detects ail single-bit
errors but does not allow error correction (i.e.. you know that an
error has occurred
when the received parity is wrong, but you cannot tell which bit was changed).
LD C.IOOOOOOOB saves a parity bit of 1 in Register C. (Note the use of the binary mask:
the purpose of the mask is clearer when It is specified in this manner rather than as 80H
or 128 decimal.)
The instruction OR C sets the parity (most significant) bit to 1 while retaining alt the
other bits as they were, as well as setting the Z80 Parity flag.

The following procedure is used to determine if in memory is odd


the parity of the byte
or even. We OR a parity bit into the byte loaded memory and then test to see if the
from
parity is odd. If the parity is odd, then the byte in memory has even
parity, and we jump
down to decrement the count of remaining bytes. If the parity is even, then we know
that the byte in memory has odd parity, and therfore we store the
byte in the Ac-
cumulator into that memory location.

The conditional jumps JP PO (Jump on Parity Odd) and JP PE (Jump on Parity Even) are
seldom used except in parity generation and checking. Note that there are no relative
jumps conditional on the value of the Panty bit. just as there are none conditional on
the value of the Sign bit.

6-15
Do not confuse the Parity bit included in each character and the ZSO's Parity flag,

which IS set to 1 if the last arithmetic or Boolean result had


even parity.

An alternative approach uses the Z80 SET instruction. This version takes a little longer

but does not require a tennporary register for the parity bit

Source Program:
LD HL40H
LD B,(HL) :GET STRING LENGTH
SETPR: INC HL
LD A.(HL) :GET A CHARACTER
OR A ;DOES CHARACTER HAVE EVEN PARITY?
JP PE.CHCNT
SET 7,(HU ;N0. SET PARITY BIT TO 1

CHCNT DJNZ SETPR


HALT
Object Program:
Memory Address Memory Contents instruction
(Hex) (Hex) (Mnemonic)

0000 21 LD HL40H
0001 40
0002 00
0003 46 LD B.(HL)
0004 23 SETPR: INC HL
0005 7E LD A,(HL)
0006 87 OR A
0007 EA JP PE.CHCNT
0008 OC
0009 00
OOOA CB SET 7.(HU
OOOB FE
OOOC 10 CHCNT; DJNZ SETPR
OOOD F6
OOOE 76 HALT

Pattern Match
Purpose: Compare two strings of ASCII characters to see If they are the same. The
length of the strings is In memory location 0041 one
, string starts in memory
location0042 and the other in memory location 0052. if the two stnngs
match, clear memon/ location 0040: otherwise, set memon/ location 0040 to
FF hex (all ones).

Sample Problems:
(0041) - 03
(0042) = 43 'C
(0043) = 41 'A
(0044) = 54 T'

(0052) = 43
(0053) - 41 'A
(0054) = 54 'T'

Result: (0040) 00, since the two strings are the same.

6-16
(0041) = 03
(0042) =:::
52 'R'

(0043) = 41 'A'
(0044) = 54 T'

(0052) = 43 'C
(0053) =: 41 'A'
(0054) = 54 T
Result: (0040) = FF, since the first characters in the
strings differ.

Note: The nnatching process ends as soon as the


the strings need not be examined.
CPU finds a difference — the rest of

Flowchart:

Pointer = 42
1 1
= 52
Pointer 2 I

Count = (41) i

Mark = FF (hex) I

Mark =

#4

(40) = Mark

C_^)

6-17
Source Program:
LD HL41H
LD B.(HL) COUNT -LENGTH OF STRINGS
INC HL POINTER = START OF STRING
1 1

LD DE,52H POINTER 2 = START OF STRING 2


LD COFFH MARK = FF (HEX)
CHCAR: LD A.(DE) GET CHARACTER FROM STRING 2
CP IHU IS THERE A MATCH?

JR NZ.DONE NO, DONE


!NC DE
tNC HL
DJNZ CHCAR :CHECK NEXT PAIR !F ANY LEFT
LD CO ;MARK = IF ALL CHARACTERS MATCH
DONE: LD A,C
LD (40H),A ;SAVE MARK
HALT
Object Program:
Memory Address Memory Contents instruction 1

(Hex) (Hex) (Mnemonic) |

0000 21 LD HL.41H
0001 41
0002 00
0003 46 LD B,(HL)
0004 23 INC HL
0005 11 LD DE52H
0006 52
0007 00
0008 OE LD COFFH
0009 FF
OOOA 1A CHCAR: LD A,(DE)
OOOB BE CP (HL)

OOOC 20 JR NZ.DONE
OOOD 06
OOOE 13 INC DE
OOOF 23 !NC HL
0010 10 DJNZ CHCAR
oon F8
0012 OE LD CO
0013 00
0014 79 DONE: LD A.C
0015 32 LD (40H),A
0016 40
0017 00
0018 76 HALT
Matching strings of ASCII characters is an essential part of looking for commands,
recognizing names, identifying variables or operation codes m assemblers and com-
pilers, finding files, and many other tasks.

The program uses two pointers, one in Register Pair HL and the other in Register Pair
DE, The only instructions that use the address in DE are LD A,(DE} (Load Accumulator
From Memory Location Addressed by DE) and LD (DE),A (Store Accumulator in Memon/
Location Addressed by DE). Arithmetic and logfcat operations with memory and
transfers to or from other registers (e.g., ADD A,(HL); AND (HL); LD B,(HL); LD (HU,E)
can only be performed using the address in Register Pair HL. or using an index register.

6-18
The order of operations is very important because of the small
number of instructions
that use the address in You must move a character from the string
Register Pair DE.
pointed to by DE to the Accumulator and compare it to a character in the string pointed
to by HL. This order of operations is necessary because the Z80 has no instruction
which allows a companson to a character in a string pointed to by DE.
For example,if you replaced LD A,(DE) with LD A,(HU, what would the next Instruction

be? This asymmetry Is peculiar to the Z80 and can cause programming nightmares.

Note that each iteration updates both pointers.


This program could take advantage of the fact that a register is known to contain zero
after a particular conditional jump is executed. When the DJNZ CHCAR instruction is
executed, if the branch Is not performed, then we know that Register B contains zero.
Therefore, we can move Register B to Register C. our flag register, to indicate that a
match has been found.
We could aiso use the ZSO's SET and RESET Instructions to handle the flag if we
needed to conserve bits for other purposes.

PROBLEMS
1) Length of a Teletypewriter Message
Purpose: Determine the length of an ASCI! message. All characters are 7-bit A^SCIt
with MSB = 0. The which the message is embedded
string of characters tn
starts In memory location 0041. The message itself starts with an ASCII STX
character (hex 02) and ends with ETX (hex 03). Place the length of the
message (the number of characters between the STX and the ETX but in-
cluding neither) into memory location 0040.

Sample Problem:
(0041) - 40
(0042) = 02 STX
(0043) = 47 'G'
(0044) - 4F •0'

(0045) = 03 ETX
Result: (0040) = 02. since there are two characters between
the STX in location 0042 and ETX in
location 0045.

2} Find Last Non-Blank Character


Purpose: Search a string of ASCII characters for the last non-blank character. The
string starts in memory location 0042 and ends with a carnage return
character (hex OD). Place the address of the last non-blank character into
memory locations 0040 and 0041 (most significant bits in 0041).

Sample Problems:
(0042) ~ 37 'T
(0043) OD CR
Result: (0040)
~
= 42. since the last (and only) non-blank character
is In memory location 0042.
(0041) = 00

6-19
(0042) = 41 'A'

(0043) = 20 SP
(0044) = 48 •H'

(0045) = 41 'A'

(0046) = 54 T'
(0047) = 20 SP
(0048) = 20 SP
(0049) = Ob CR
Result: (0040) - 46
(0041) = 00

3) Truncate Decimal String to Integer Form


Purpose: Edit a string of ASCII decimal characters by replacing all digits to the right of
the decimal point with ASCII blanks (hex 20). The string starts in memory
location 0041 and is assumed to consist entirety of ASCII-coded decimal
digits and a possible decimal point (hex 2E). The length of the string is in
memory location 0040. !f no decimal point appears in the string, assume that
the decimal point is implicitly at the far right

Sample Problems:
a. (0040) = 04
(0041) = 37 7'
(0042) = 2E
(0043) = 38 '8'

(0044) = 31 'V

Result: (0041) = 37 7'


(0042) = 2E
(0043) = 20 SP
(0044) = 20 SP
(0040) = 03
(0041)
~ 26 '6'

(0042)
~ 37 7'
== '1'
(0043) 31
Result: Unchanged, as number is assumed to be 671,

4} Check Even Parity in ASCII Characters


Purpose: Check even parity m a string of ASCII characters. The length of the string is

in memory location 0041, and the stnng Itself begins in memory location
0042. If the parity of all the characters in the string is correct clear memon/
location 0040: otherwise, place FF hex (all ones) into memory location 0040

6-20
Sample Problems:
a. {0041} = 03
(0042) = B1
(0043) - B2
(0044) = 33
Result: (0040) = 00. since all the characters have even parity.

b. (0041) - 03
(0042) - B1
(0043) = 86
(0044) = 33
Result: (0040) = FF since the character in memorv
location 0042 does not have even parity-

5) String Comparison
Purpose: Compare two strings of ASCII characters to see which is larger (i.e.. which
follows the other in 'alphabetical' ordering). The length of the strings is m
mennory location 0041; one string starts in nnemory location 0042 and the
other in memory location 0052. If the string starting In memory location

0042 is greater than or equal to the other string, clear memory location
0040; otherwise, set memory location 0040 to FF hex (all ones).

Sample Problems:
a. (0041) = 03
(0042) = 43 'C
(0043) = 41 'A'
(0044) - 54 'T'

(0052) = 42 'B'

(0053) = 41 'A'

(0064) = 54 T
Result: (0040) = 00. since CAT is 'larger' th3n BAT
b. (0041) = 03
(0042) 3= 43 c
(0043) == 41 'A'

(0044) = 54 T
(0052) = 43 'C
(0053) ^ 41 •A'

(0054) = 54 T
Result: (0040) = 00. since the two strings are equal.

(0041) - 03
(0042) = 43 'C
(0043) = 41 'A'

(0044) - 54 'T'

(0052) = 43 'C
(0053) = 55 'U'
(0054) - 54 T'

Result: (0040) = FF, since CUT is 'larger* than CAT.

6-21
Chapter 7
CODE CONVERSION
Code conversion is problem in nnost microcomputer applications. Periph-
a continual
erals provide data in ASCII.BCD. or venous special codes. The system must convert the
data into some standard form for processing. Output devices may require data in ASCII
BCD. seven-segment, or other codes. Therefore, the system must convert the results to
a suitable form after the processing is completed.

There are several ways to approach code conversion:


1} Some conversions can easily be handled by algorithms involving arithmetic or logi-
cal functions. The program may, however, have to handle some special cases sepa-
rately.

2) More complex conversions can be handled with lookup tables. The lookup table
method requires little programming and is easy to apply. However, the table may
occupy a large amount of memory if the range of input values is large.
3) Hardware is some conversion tasks. Typical examples are
readily available for
decoders for BCD
seven-segment conversion and Universal Asynchronous
to
Receiver/Transmitters (UARTs) for conversion between parallel (ASCII) and serial
(teletypewriter) formats.

In most applications, the program should do as much as possible of the code conversion
work. This results in a savings in parts and board space as well as in increased
reliability. Furthermore, most code conversions are easy to program and require little

execution time.

EXAMPLES
Hex to ASCII
Purpose: Convert the contents of memory location 0040 to an ASCII character.
Memory location 0040 contains a single hexadecimal digit (the four most
significant bits are zero). Store the ASCII character m memory location
0041.

Sample Problems:
a. (0040) - OC
Result: (0041) = 43 'C
b. (0040) = 06
Result: (0041) - 36 '6'

7-1
Flowchart:

Data = Data
+ ASCn A
-ASCIi 9 - 1

Resuit =

Data + ASCII Zero

{411= Result

C D
SourceJ Program:
LD A,(40H) ;GET DATA
CP 10 :!S DATA 10 OR MORE?
JR C.ASCZ
ADD a;a'-'9'-i ;YES.ADD OFFSET FOR LETTERS
ASCZ: ADD a;o' ;ADD OFFSET FOR ASCti
LD (4!H).A :STORE ASCII RESULT
HALT
Object Program:
Memory Address Memory Contents Instruct ion 1

(Hex) (Hex) (Mnemonic) |

0000 3A LD A,(40H)
0001 40
0002 00
0003 FE CP 10
0004 OA
0005 38 JR C.ASCZ
0006 02
0007 C6 ADD a;a'-'9'-i
0008 07
0009 C6 ASCZ: ADD A/0'
OOOA 30
OOOB 32 LD (41H),A
OOOC 4i
GOOD 00
OOOE 76 HALT

7-2
In thisprogram, the basic idea is to add ASCII to all the hexadecimal digits. This addi-
tion converts the decimal digits correctlv: however, there ts a break between ASCII 9
(39 hex) and ASCI! A (41 hex) which must be considered. This break must be added to
the nondecimal digits A, B. C. D, E. and F This is accomplished by the ADD A instruc-
tion which adds the offset 'A'-'9'-1 to the contents of the Accumulator. Can you explain
why the offset ts 'A'-'9'-1 ?

Note that the addition terms are placed in the assembly language program in ASCII
form (apostrophes surround an ASCI! character or string of characters). The offset for
the letters is left as an arithmetic expression. The effort is to make the purpose of the
terms as clear as possible in the assembly language listing. The extra assembly time is a
very small price to pay for a large increase in clarity.

This routine could be used in a variety of programs; for example, monitor programs
must convert hexadecimal digits to ASCII in order to display the contents of memory
locations in hexadecimal on an ASCII printer or video display.

Another (quicker) conversion method that requires no conditional jumps at all is the
following program, described by Allison in Computer magazine.''

LD A,(40H) ;GET HEX DIGIT


ADD A.90H : DEVELOP EXTRA 6 AND CARRY
DAA
ADC A.40H ;ADD IN CARRY. ASCII OFFSET
DAA
LD (4!H),A ;STORE ASCII DIGIT
HALT
Try this program on some digits. Can you explain why it works?

Decimal to Seven-Segment
Purpose: Convert the contents of memory location 0040 to a seven-segment code in
memory location 0042. If memory location 0040 does not contain a single
decimal digit, clear memory location 0042.

Seven-segment table: The following table can be used to convert decimal numbers to
seven-segment code. The seven-segment code is organized with the most significant
bit always zero followed by the code (1 = on, = off) for segments g, f. e, d, c, b. and a
(see Figure 7-1).

a
Digit Code

3F
1 06 f b
2 5B
3 4F
4 66 g
5 6D
e
6 7D c

7 07
1 i
8 7F
9 6F d

Figure 7-1. Seven-segment Arrangement

7-3
Note that the table uses 7D for 6 rather than the alternative 7C (top bar off) to avoid
confusion with lower case b. and 6F for 9 rather than 67 (bottonn bar off), for no particu-
lar reason.

Sample Problems:
a, (0040) = 03
Result: (0042) = 4F
b. (0040) = 28
Result: (0042) - 00
Flowchart:

->
f^ Start
\

Data ={40)

Yes
^^ Data > 9
>
u
Result =
Result =0
{SSEG + Data)

i^*-
r*"
(42) = Result

t
r End
D 1

Note that the addition of base address SSEG and index (DATA) produces the address
that contains the answer

7-4
Source Program:
LD B.O GET ERROR CODE TO BLANK DISPLAY
LD A.(40H) GET DATA
CP 10 iS DATA A DECIMAL DIGIT?
JR NC.DONE NO, KEEP ERROR CODE
LD LA YES, MAKE DATA INTO A 16-BIT INDEX
LD H.O
LD DE.SSEG ;GET BASE ADDRESS OF 7-SEGMENT TABLE
ADD HL.DE ;FIND ELEMENT BY INDEXING
LD B.(HL) ;GET 7-SEGMENT CODE FROM TABLE
DONE: LD A,B :SAVE 7-SEGMENT CODE OR ERROR CODE
LD (42H),A
HALT
ORG 20H :SEVEN-SEGMENT CODE TABLE
SSEG: DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7FH
DEFB 6FH

7-5
Object Program:
Memory Address Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 06 LD B,0
0001 00
0002 3A LD A,(40H)
0003 40
0004 00
0005 FE CP 10
0006 OA
0007 30 JR NC.DONE
0008 08
0009 6F LD LA
OOOA 26 LD H,0
OOOB 00
OOOC 11 LD DE.SSEG
GOOD 20
OOOE 00
OOOF 19 ADD HLDE
0010 46 LD 8. (ML)

0011 78 DONE: LD A,B


0012 32 LD (42H),A
0013 42
0014 00
0015 76 HALT
0020 3F SSEG: DEFB 3FH
0021 06 DEFB 06H
0022 58 DEFB 58H
0023 4F DEFB 4FH
0024 66 DEFB 66H
0025 6D DEFB 6DH
0026 7D DEFB 7DH
0027 07 DEFB 07H
0028 7F DEFB 7FH
0029 6F DEFB 6FH

The program calculates the memory address of the desired code by adding the index

the digit to be displayed) to the base address of the seven-segment code table.
(i.e..

This procedure is known as a table lookup.

The assembly language pseudo-operation DEFB (Define Byte) places constant data into
program memory. Such data may include tables, headings, error messages, priming
messages, format characters, thresholds, etc. The label attached to a DEFB pseudo-
operation IS assigned the value of the address into which the byte of data is placed.

Tables are often used to perform code conversions that are more complex than the pre-
vious example. Such tables typically contain all the results organized accordirig to the
input data, e.g.. the first entry ts the code corresponding to the number zero.

Seven-segment displays provide recognizable forms of the decimal digits and a few let-
ters and other characters. Calculator-type seven-segment displays are inexpensive,
easy to combine, and use tittle power. However, the seven-segment coded digits are
somewhat difficult to read.

The assembler simply places the data for the table into memory. Note that one DEFB
pseudo-operation fills one byte of memory. We have left some memory space between
the program and the table to allow for later additions or corrections.

7-6
An alternative approach wouid be to use one of the Z80's index USE OF 280
registers, say IX, The programmer must be aware of the following INDEX
features of the ZSO's index registers: REGISTERS
1) The fixed offset m program memory is only eight bits long and
so cannot hold a complete memon/ address. It must be used either as a short dis-
placement or to hold the eight least significant bits of a memory address.
2) The index can be loaded from memory
registers are 16 bits long. Either IX or lY just
like a register pair — from two consecutive memory addresses with the least sig-
nificant eight bits at the lower address.

3) All operations involving the mdex registers take extra time and memory because
one word of the operation code simply declares that an mdex register is to be used.

The following program uses Register IX to perform the table lookup:

Source Program:
LD B,0 GET ERROR CODE TO BLANK DISPLAY
LD A.{40H) GET DATA
CP 10 IS DATA A DECIMAL DIGIT?
JR NC.DONE NO, KEEP ERROR CODE
LD HL,41H SAVE TABLE PAGE NUMBER IN MEMORY
LD (HL).O
LD IX.{40H) GET TABLE OFFSET
LD B,(!X+SSEG) GET 7-SEGMENT CODE FROM TABLE
DONE. LD A,B SAVE 7-SEGMENT CODE OR ERROR CODE
LD (42H).A
HALT
Object Program:
Memory Address Memory Contents Instruct ion 1

(Hex) (Hex) (Mnemonic) |

0000 06 LD B.O
0001 00
0002 3A LD A,{40H)
0003 40
0004 00
0005 FE CP 10
0006 OA
0007 30 JR NCDONE
0008 OC
0009 21 LD HL41H
OOOA 41
OOOB 00
OOOC 36 LD (HU.O
OOOD 00
OOOE DD LD IX.(40H)
OOOF 2A
0010 40
0011 00
0012 DD LD B.dX+SSEG)
0013 46
0014 20
0015 78 DONE. LD A.B
0016 32 LD {42H),A
0017 42
0018 00
0019 76 HALT

7-7
The Indexed load instruction LD B,(iX + SSEG) adds the index (i.e., the digit to be dis-
played) to the base of the seven-segnnent table to get the address of the desired code.
Note that the 16-bit index register contains the data as its eight least significant bits
and the most significant bits of the starting address of the table as its eight most signifi-
cant This odd arrangement is necessary because the offset Included with the In-
bits.

dexed instruction is only eight bits long and can therefore hold only the eight least sig-
nificant bits of the starting address of the table.

A more general program would allow the table to be placed anywhere in memory. If the
table starting address is SSEGM (eight MSBs) and SSEGL (eight LSBs}. the instruction
LD (HU,0 must be replaced by LD (HL). SSEGM. Why is this change necessary?

Note that at! operations involving Index Register IX have a 2-word operation code in

which the first word is DD.


Clearly this is not a very efficient use of the index registers. These MOVING DATA
registers realty become useful when you must access several data WITHIN
in a block. The block might contain the characteristics of a A BLOCK
message, the parameters an equation, the current state of a pro-
of
cess or machine, or the data for a video display. You could, for example, take the con-
tents of the twelfth location in the block and move them to the twentieth location with
either of the following programs, assuming that the starting address of the block iS
stored in memory locations PTR and PTR+1.
1) Using DE and HL
LD DE,(PTR) :GET STARTING ADDRESS
LD HL12 :CALCULATE SOURCE ADDRESS
ADD HL.DE
LD A,(HL) :GET DATA FROM SOURCE
LD HL20 iCALCULATE DESTINATION ADDRESS
ADD HLDE
LD (HU.A ;MOVE DATA TO DESTINATION
2) Using iX.

LD IX, (PTR) ;GET STARTING ADDRESS


LD A,(IX-l-12) :GET DATA FROM SOURCE
LD (IX-i-20),A :MOVE DATA TO DESTINATION
The program using the Index registers is far shorter and clearer, tts only limitation is

that the offsets must be small enough to fit into an 8-bit byte.

ASCII to Decimal
Purpose: Convert the contents of memory location 0040 from an ASCII character to a
decimal digit and store the result in memory location 0041. If the contents of
memory location 0040 are not the ASCII representation of a decimal digit,
set the contents of memory location 0041 to FF (hex).

Sample Problems:
a. (0040) - 37 '7'

Result: (0041) = 07
b. (0040) = 55
Result: (0041) - FF

7-8
Flowchart:

CIEZ)

Yes
Data < A^ni n^S
^^^^ 7 ^^^
^TNo

Yes '\
Data > ASCi! 9^
^s^^?^^^^
jC^°
'1

ResuSt =
Result = FF (Hex)
Data - ASCI!

A^
!41)= Result

C D

Source Program:
LD B.OFFH GET ERROR MARKER
LD A.(40H) GET DATA
'0'
SUB IS DATA BELOW ASCII ZERO?
JR C.DONE YES. NOT A DIGIT
CP '9'
+ 1 IS DATA ABOVE ASCII NINE
JR NC.DONE YES. NOT A DIGIT
LD B,A SAVE DIGIT IF VALID
DONE; LD A.B SAVE DIGIT OR ERROR MARKER
LD (41 H). A
HALT

7-9
Object Program:
Memory Address Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 06 LD B.OFFH
0001 FF
0002 3A LD A,(40H}
0003 40
0004 00
'0'
0005 D6 SUB
0006 30
0007 38 JR CDONE
0008 05
CP '9'+1
0009 FE
OOOA 3A
OOOB 30 JR NCDONE
OOOC 01
OOOD 47 LD B,A
OOOE 78 DONE; LD A.B
OOOF 32 LD (41HKA
0010 41
0011 00
0012 76 HALT
This program handles ASCIi-coded characters just like ordinary numbers. Note that the
decimal digits and the letters form groups of consecutive codes. Strings of letters (like
names) can be alphabetized by placing their ASCII representations m increasing
numerical order (ASCII B -= ASCII A + 1 for example).

Subtracting ASCII zero (30 hex) from any ASCII decimal digit gives the BCD represen-

tation of that digit

ASCII to decimal conversion is necessary when decimal numbers are being entered
from an ASCII device like a teletypewriter or video terminal.

The basic idea of the determine if the character is between ASCII


program is to and
ASCII 9. inclusive. If if s an ASCII decimal digit since the digits form a
the character is,

sequence. It may then be converted to decimal simply by subtracting hex 30 (ASCII 0),
e.g., ASCII 7 - ASCII - 37-30 = 7
Note that one comparison is done with an actual subtraction (SUB
'0') since the subrac-

tion is necessary to convert ASCII to decimal. The other comparison is done with an im-
plied subtraction (CP '9'+1) since the final result is now in the Accumulator if the origi-
nal number was valid.

BCD to Binary
Purpose: Convert two BCD digits in memory locations 0040 and 0041 to a binary
number in memon/ location 0042. The most significant BCD digit is in

memory location 0040.

Sample Problems:
(0040) 02
(0041) 09

Result: (0042) = ID (hex) - 29 (decimal)

b. (0040) 07
(0041) 01

Result: (0042) = 47 (hex) = 71 (decimal)

7-10
Note; No fiowchart is mctuded since the program multiplies the most significant digit
by 10 simply by using the formula 10x =^ 8x + 2x. Multiplying by 2 requires one
arithmetic left shift and multiplying by 8 requires three such shifts.

Source Program:
LD HL.40H :GET MOST SIGNIFICANT DIGIT (MSD)
LD A,(HL)
ADD A.A ;MSD TIMES TWO
LD B,A :SAVE MSD TIMES TWO
ADD A.A ;MSD TIMES FOUR
ADD A.A :MSD TIMES EIGHT
ADD A.B :MSD TIMES TEN
INC HL :PO!NT TO LEAST SIGNIFICANT DIGIT
ADD A,(HU ;ADD TO FORM BINARY EQUIVALENT
INC HL
LD (HU,A :STORE BINARY EQUIVALENT
HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A.(HL)
0004 87 ADD A.A
0005 47 LD 8.A
0006 87 ADD A.A
0007 87 ADD A.A
0008 80 ADD A.B
0009 23 INC HL
OOOA 86 ADD A.(HL)
0008 23 INC HL
OOOC 77 LD (HU.A
OOOD 76 HALT

BCD entries are converted to binary in order to save on storage and to simplify calcula-
tions. However, the conversion may offset some of the advantages of binary storage
and arithmetic.
This program multiplies the BCD digit in memory location 0040 by ten using
repeated
addttions.2 Note that ADD A.A multiplies the contents of the Accumulator by 2. This
allows you to multiply the contents of the Accumulator by small decimal numbers in a
few instructions. How would you use this procedure to multiply by 16? fay 12? by 7?
BCD numbers require about 20% more storage than do binary numbers. Representing
to 999 requires 12 bits in BCD form but only 10 bits in binan/ (since
210 = 1024==: 1000).

Convert Binary Number to ASCII String


Purpose: Convert the 8-bit binary number in memory location 0041 to eight ASCI!
characters (either ASCII or ASCI! 1) in memory locations 0042 through
0049 (the most significant bit is in 0042).

7-11
Sample Problem:
(0041) = D2 = 11010010
Result: (0042) = 31 *r
(0043) = 31 'V
(0044) = 30 •0'

(0045) = 31 'V
(0046) = 30 *0'

(0047) = 30 *0'

(0048) - 31 '1'

(0049) = 30 '0'

Flowchart:

c D
Pointer = 41
Data = (Pointer}

Counter = 8

Pointer = Pointer H
|
(Pointer) = ASCII |

I Shift Data left one bit I

(Pointer) =
ASCI! 1, i.e..

(Pointer) •+ 1

Source Program:
LD HL41H
LD A.(HU GET DATA
LD B,8 COUNTER = NUMBER OF BITS IN WORD
LD CO' GET ASCII ZERO TO STORE IN STRING
CONV: !NC HL
LD (HU.C :PUT ASCII ZERO !N STRING
RLA ;IS NEXT BIT OF DATA 1?
JR NCCOUNT lYES, MAKE STRING ELEMENT ASCII ONE
INC (HL)
COUNT: DJNZ CONV
HALT

7-12
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL41H
0001 41
0002 00
0003 7E ID A,(HU
0004 06 LD B.8
0005 08
0006 OE LD CO'
0007 30
0008 23 'CONV: !NC HL
0009 71 LD (HU.C
OOOA 17 RLA
OOOB 30 JR NC.COUNT
OOOC 01
OOOD 34 INC (HL)
OOOE 10 COUNT: DJNZ CONV
OOOF F8
0010 76 HALT
The ASCII form a sequence so ASCII 1 = ASCII 0+1. Remember that the Z80
digits
registers have special uses. You should place the loop counter into Register B so that
you can use the DJNZ instruction.
Be careful of the difference between INC HL, which adds one to the 16-btt contents of
Register Pair HL, and INC (HL), which adds one to the 8-bit contents of the memon/
location addressed by Register Pair HL.

Binary-to-ASCN conversion is necessary when numbers are prrnted in binary form on an


ASCII device.

The conversion to ASCII simply involves adding ASCI! (hex 30).

PROBLEMS
1) ASCII to Hex
Purpose: Convert the contents of memory location 0040 to a hexadecimal digit and
store the result in memory location 0041. Assume that memory location
0040 contains the ASCII representation of a hexadecimal digit (7 bits with
MSB 0).

Sample Problems:
a. (0040) = 43 'C
Result: (0041) = OC
b. (0040) = 36 '6'

Result: (0041) = 06
2) Seven-Segment to Decimal
Purpose: Convert the contents of memory location 0U40 from a seven-segment code
to a decimal number in memory location 0041 If memory location 0040 does
.

not contain a valid seven-segment code, set memory location 0041 to FF


(hex). Use the seven-segment table given under the Decimal to Seven-Seg-
ment example and try to match codes.

7-13
Sample Problems:
a. (0040) = 4F
Result: (0041) = 03
b. (0040) = 28
Result: (0041) = FF

3) Decimal to ASCII
Purpose Convert the contents of memorv location 0040 fronn a decinna! digit to an
ASCII character and store the result in memory location 0041. If the number
in memory location 0040 is not a decimal digit set the
contents of memon/
location 0041 to an ASCII blank character (20 hex).

Sample Problems:
a. (0040) = 07
Result: (0041) = 37 7'

b.
* (0040) = 55

Result: (0041) - 20 SP

4) Binary to BCD
Purpose: Convert the contents of memon/ location 0040 to two BCD digits in memory
locations 0041 and 0042 (most significant digit m 0041). The number in
memory location 0040 is unsigned and less than 100.
Sample Problems:
a. (0040) = 1D (29 decimal)

Result: (0041) = 02
(0042) - 09
b. (0040) = 47 (71 decimal)

Result: (0041) = 07
(0042) = 01

5) ASCII String to Binary Number


Purpose: Convert the eight ASCII characters in memory locations 0042 through 0049
to an 8-bit bmary number in memory location 0041 (the most significant bit
IS in 0042). Clear memory location 0040 if all the ASCII characters are either
ASCII 1 or ASCII and set it to FF otherwise.

Sample Problems:
'1'
a. (0042) - 31
(0043) =31 'V
(0044) = 30 '0'

(0045) - 31 'V
(0046) - 30 '0'

(0047) = 30 '0'

(0048) =31 '1'

(0049) = 30 '0'

Result: (0041) - D2
(0040) = 00
b. same as "a' except:
•!'
(0045) - 37
Result: (0040) = FF

7-14
REFERENCES
AMison, D,R.. "A Design Philosophy for Microcomputer Architectures," Computer.
February 1977, pp. 35-41. This is an excellent article which we recommend highly.

Other BCD-to-blnary conversion methods are discussed in J.A. Tabb and M.L
Roginsky, "Microprocessor Algorithms Make BCD-Binary Conversions Super-fast"
EDN, January 5, 1977, pp. 46-50 and in J.B. Peatman. Microcomputer-b ased
Design. McGraw-Hiii, New York, 1977.. pp. 400-406.

7-15
Chapter 8
ARITHIVIETiC PROBLEMS
Most arithmetic in microprocessor applications consists of multiple-word binary or
decimal manipulations. A decimal correction (decimal adjust) or some other means
for
performing decimal arithmetic is frequently the only arithmetic instruction provided
besides basic addition and subtraction. You must implement other arithmetic
opera-
tions with sequences of instructions.

Multiple-precision binary arithmetic requires simple repetitions of the basic single-word


instructions. The Carry bit transfers information between words. Add with
Carry and
Subtract with Carry use the mformation from the previous arithmetic operations You
must be careful to clear the Carn/ before operating on the first words (obviously there is
no carry into or borrow from the least significant bits).

Decimal arithmetic is a common enough task for microprocessors that most have
special instructions for this purpose. These instructions may either perform decimal
operations directly or correct the results of binary operations to the proper decimal
form. Decimal arithmetic is essential In such applications as point-of-sale terminals,
calculators, check processors, order entry systems, and banking terminals.
You can implement multiplication and division as series of additions and subtractions
respectively, muchas they are done by hand. Double-word operations are necessary
since a multiplication produces a result twice as long as the operands, white a division
similarly contracts the length of the result Multiplications and divisions are
time-con-
suming when done in software because of the repeated arithmetic and shift operations

Of course, multiplying or dividing by a power of 2 is simple because


that are necessary.
such operations can be implemented with an appropriate number of left or right
anthmetic shifts.

EXAMPLES
Multiple-Precision Addition
Purpose: Add two multiple-word binary numbers. The length of the numbers (in bytes)
is in memory location 0040, the numbers themselves start
(least significant
bits first) in memon/ locations 0041 and 0051, respectively, and the sum
replaces the number starting in memory location 0041.

8-1
Sample Problem:
(0040) = 04
(0041) = C3
(0042) - A7
(0043) = 5B
(0044) = 2F
(0051) = 88
(0062) - 35
(0053) = DF
(0054) = 14
Result: (00411 = 7B
(0042) - DD
(0043) - 3A
(0044) = 44
that IS, 2F5BA7C3
+ 14DF35B8
443ADD7B
Flowchart:

c D
Couni = (40)
Pointer t =41
Pointer 2 =51
Carry =

1) ==
riinter ^
(Pointer 1}

{Pointer 2) +
Carry
(This step aiso produces a new Carry)

8-2
Source Program:
LD HL40H ;COUNT = LENGTH OF STRINGS (IN BYTES)
LD B.(HU
INC HL POINTER 1 - FIRST WORD OF STRING 1

LD DE.51H POINTER 2 = FIRST WORD OF STRING 2


AND A CLEAR CARRY TO START
ADDW: LD A,(DE) GET WORD FROM STRING 2
ADC A.(HU ADD WORD FROM STRING 1

LD (HU.A STORE RESULT IN STRING 1

iNC DE
INC HL
DJNZ ADDW
HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL40H
0001 40
0002 00
0003 46 LD 8,(HL)
0004 23 INC HL
0005 11 LD DE.51H
0006 51
0007 00
0008 A7 AND A
0009 1A ADDW: LD A.(DE)
OOOA 8E ADC A.(HL)
OOOB 77 LD (HU.A
OOOC 13 INC DE
OOOD 23 iNC HL
OOOE 10 DJNZ ADDW
OOOF F9
0010 76 HALT

The relative address for DJNZ ADDW is:

09 09
-10 +F0
F9
The instruction AND A
used to clear the Carry bit Any other logical operation would
is

have the same effect The Carry must be cleared, since there is no carry involved in the
addition of the least significant bytes.

The instruction ADC. Add with Carry, Includes the Carry from the previous words in the
addition. ADC is the only instruction m the loop that affects the Carry Remember that
neither INC nor DJNZ does.

Both the pointer In Register Pair DE and the one in HL must be updated during each
iteration.

8-3
DECIMAL
This procedure can add binary numbers of up to 256
bytes in

Note that the ten binary bits correspond to three decinnai ACCURACY
length.
can calculate the num- IN BINARY
digits, since 2^0 = 1024 === 1000. So, you
decimal digits. For
ber of' bits required to give a certain accuracy in
example, ten decimal digit accuracy requires;
/ l0 bits \ ^ 33 bits
(10 digits) ^ \3 digits/

transferring the data from one place in memory BLOCK


If we were only
we could use the ZSO's TRANSFER
to another and not also processing it
instruction INSTRUCTIONS
powerful block transfer instruction LDIR. This single
moves a bvte of data from the address in HL to the address in
counter m BC. It
DE increments the pointers in HL and DE, and decrements the byte
BC decremented to zero. LDI is the same instruction
repeats the move operation until is

without the repetition factor: LDD and LDDR are non-repeated and repeated moves,
respectively, that decrement the pointers rather than incrementing them.

A program to transfer a fixed number of bytes (LENGTH) from one place in memory
in memory (starting at PTR2) is the
following.
(starting at PTR1) to another place

Block Move
Purpose: Move a block of data BC characters long from the address m HL to the ad-

dress m DE.

Sample Problem:
(HL) = 40
(DE) = 50
(BC) = 3

(0040) - 31
(0041) = 32
(0042) = 33
(0050) =
(0051) -
(0052) =
Result: (0050) = 31
(0051) = 32
(0052) = 33

Source Program:
LD BC.LENGTH COUNT - LENGTH OF TRANSFER (IN BYTES)
LD HUPTRI POINTER - START OF DATA SOURCE AREA
1

LD DE.PTR2 POINTER 2 - START OF DATA DESTINATION


AREA
LDIR
HALT

8-4
Object Program:
Memorv Address Memorv Contents Instruction 1

(Hex) (Hex) (Mnemonic) |

0000 01 LD BC. LENGTH


0001
0002 LENGTH
0003 21 LD HLPTR1
0004
0005 PTR1
0006 11 LD DE.PTR2
0007
0008 PTR2
0009 ED LDIR
OOOA BO
OOOB 76 HALT

Try to implement the same program without the LD!R instruction. How many bytes of
memory and clock cycles does it require each way?

Decimal Addition
Purpose: Add two multiple-word decimal (BCD) numbers. The length of the numbers
is in memory location 0040, the numbers themselves start (least significant

bits first) in memory locations 0041 and 0051, respectively, and the sum
replaces the number starting in memory location 0041.

Sample Problem:
(0040) 04
(0041) = 85
(0042) = 19
(0043) =r 70
(0044) = 36
(00511 = 59
(0052) = 34
(0053) = 66
(0054) = 12
Result: (0041) = 44
_.
(0042) 54
(0043) = 36
(0044) = 49
that is, 36701985
f 12663459
~
49365444

8-5
Flowchart:

Start
I J

Count = (40)
Painter 1 =41
Pointer 2 = 51
Carry =

"fr^
(Pointer 1) =
{Pointer 1)
(Pointer 2}
Carry +
Decimal correction (This step aiso produces a new Carry)

Pointer 1 =
Pointer 1 + 1^

Pointer 2 =
Pointer 2 + 1

Count = Count - 1

Source Program:
LD HL40H
LD B.(HL) COUNT = LENGTH OF STRINGS {IN BYTES)
INC HL POINTER - FIRST 1 WORD OF STRING 1

LD DE,51H POINTER 2 = FIRST WORD OF STRING 2


AND A CLEAR CARRY TO START
DECAD: LD A.(DB GET 2 DECIMAL DIGITS FROM STRING 2
ADC A.iHL) ADD PAIR OF DIGITS FROM STRING 1
DAA MAKE ADDITION DECIMAL
LD (HU.A STORE RESULT IN STRING 1
INC DE
INC HL
DJNZ DECAD
HALT

8-6
Object Program:

Memory Address Memory Contentss Instruction


(Hex) (Hex) (Mnemonic)
0000 21 LD HL40H
0001 40
0002 00
0003 46 LD B,(HL)
0004 23 INC HL
0005 11 LD DE51H
0006 51
0007 00
0008 A7 AND A
0009 1A DECAD: LD A.(DE)
OOOA 8E ADC A.(HL)
OOOB 27 DAA
OOOC 77 LD (HL),A
OOOD 13 INC DE
OOOE 23 INC HL
OOOF 10 DJNZ DECAD
0010 F8
0011 76 HALT
The Decimal Adjust instruction (DAA) uses the Carry (C) and Half
Carry (H) bits to correct the following situations:
DECIMAL
ADJUST
1) The sum oftwo digits is between 10 and 15, inclusive, in this
case, SIX must be added to the sum to give the right result i.e.
0101 (5)

+ 1000 (8)

1101 (D)
0110
0001 0011 (BCD 13, which is correct)

2) The sum of two digits is 16 or more. In this case the result is a proper BCD number
but SIX less than It should be, i.e.
1000 (8)

+ 1001 (9)

0001 0001 (BCD 11)


+ 0110
0001 01 1 1 (BCD 17, which is correct)

Six must be added both situations. However, case 1 can be recognized by the fact
in

that the sum is not a BCD digit, it is between 10 and 15 (or A and F hexadecimal). Case
2 can be recognized only by the fact that the Carry (most significant digit) or Half Carry
(least significant digit) has been set to 1 since the result Is a valid BCD number. DAA is
,

the only instruction that uses the Half Carry. Note that DAA operates only on the Ac-
cumulator.

The Z80 microprocessor also has a flag that distinguishes be- ADD/SUBTRACT
tween Add instructions (ADD. ADC) and Subtract instructions FLAG
(SUB, SBC), This flag, called the Add/Subtract flag or N flag, is
cleared by all Add Instructions and
Subtract instructions. The sole use of this
set by all

flag IS to allow the DAA instruction to correctly change binary addition into BCD addi-
tion and binary subtraction into BCD subtraction. The 8080 and 8085 microprocessors
do not have an N flag, and so their DAA instructions operate properly only after addi-
tion.

8-7
Accumulator
DAA can be used only after mstructions that place their result into the
Thus, you cannot
and that properly affect the Carry, Half-Carry, and Add/Subtract flags.
the double-word
use DAA after INC (since INC does not affect the Carry), DEC, or any of
mstructions that place their results into the index registers or Regi ster
Pair HL

This procedure can add decimal (BCD) numbers of any length.


ACCURACY IN
Here four binary bits are required for each decimal digit so ten- BINARY AND
digit accuracy requires: BCD
10x4 = 40 bits

as opposed to 33 bits in the binary case. This ts essentially five 8-bit words instead of

four. The decimal procedure also takes a little longer per word because of the extra
DAA instruction.

8-Btt BlnarY Multiplication


Purpose: Multiply the 8-bit unsigned number m memory location 0040 by the 8-bit
unsigned number in memon/ location 0041 Place the eight least significant
.

bits of the result Into memory location 0042 and the eight most
significant

bits into memory location 0043.

Sam pie Problems:

a. (0040) = 03
(0041) = 05
Result: (0042) = OF
(0043) - 00
or in decimal 3x5 = 15

b. (0040) = 6F
(0041) = 61
Result: (0042) = OF
(0043) = 2A
or 111 X 97 = 10.767

You can perform multiplication on a computer in the same way that you do long
multiplication by hand. Since the numbers are binary, the only problem is whether to
multiply by or 1-, multiplying by zero obviously gives zero as a result while multiplying
by one produces the same number that you started with (the multiplicand). So, each
step m a binary multtplication can be reduced to the following operation.
If the current bit in the multiplier is 1, add the multiplicand MULTIPLICATION
to the partial product ALGORITHM
The only remaining problem is to ensure that you tine everything up correctly each
time. The following operations perform this task.

1) Shift multiplier left one bit so that the bit to be examined is placed into the Carry.

2) Shift product left one bit so that the next addition is lined up correctly.

The complete process for binary multiplication is as follows:

Step 1 - Initialization

Product ==
Counter = 8

Step 2 - ShiftProduct so as to tine up properly


Product = 2 X Product (LSB = 0)

Step 3 - Shift Multiplier so bit goes to Carry


Multiplier = 2xMultipner

8-8
Step 4 - Add Multiplicand to Product if Carry Is 1

If Carry = 1. Product = Product -f Multiplicand


Step 5 - Decrement Counter and check for zero
Counter = Counter - 1
If Counter 7^ go to Step 2
In the case of Sample Problem b. where the multiplier is 61 (hex) and the multiplicand is
6F (hex) the process works as follows:

Initialization:

Product 0000
Multiplier 61
Multiplicand 6F
Counter 08
After first iteration of steps 2-5:

Product 0000
Multiplier C2
Multiplicand 6F
Counter 07
Carry from Multiplier

After second iteration:

Product 006F
Multiplier 84
Multiplicand 6F
Counter 06
Carry from Multiplier 1

After third iteration:

Product 014D
Multiplier 08
Multiplicand 6F
Counter 05
Carry from Multiplier 1

After fourth iteration:

Product 029A
Multiplier 10
Multiplicand 6F
Counter 04
Carry from Multiplier

After fifth iteration:

Product 0534
Multiplier 20
Multiplicand 6F
Counter 03
Carry from Multiplier

After sixth iteration:

Product 0A68
Multiplier 40
Multiplicand 6F
Counter 02
Carry from Multiplier

8-9
After seventh iteration:

Product 14D0
Multiplier 80
MuttipHcand 6F
Counter 01
Carry from Multiplier

After eighth iteration:

Product 2A0F
Multiplier 00
Multiplicand 6F
Counter 00
Carry from Multiplier 1

Flowchart:

c Start

D
Muttipticand = M0)|
Multiplier = (41)
j
Product = I
Count

3"
Product =2 X Product!
{Shift left 1 biti 1
Multiplier =2xlVlu!t!plier|
(Shift left 1 bit)
I

Product =
Product +
Multiplicand

CHZ3
8-10
Source Program:
LD HL40H
LD E,(HU ;GET MULTIPLICAND
LD D.O :EXTENDTO 16 BITS
INC HL
LD A.(HL) GET MULTIPLIER
LD HLO PRODUCT = ZERO
LD B.8 COUNT = BIT LENGTH OF MULTIPLIER
MULT; ADD HLHL SHIFT PRODUCT LEFT 1 BIT
RLA SHIFT MULTIPLIER LEFT 1 BIT
JR NC.CHCNT IS CARRY FROM MULTIPLIER 1?
ADD HL.DE YES. ADD MULTIPLICAND TO PRODUCT
CHCNT: DJNZ MULT
LD (42H).HL :SAVE PRODUCT IN MEMORY
HALT
Object Program:
Memory Address Memory Contents Instruction |

(Hex) (Hex) (Mnemonic) j

0000 21 LD HL.40H
0001 40
0002 00
0003 5E LD E.(HL)
0004 16 LD D.O
0005 00
0006 23 INC HL
0007 7E LD A.(HL)
0008 21 LD HL.0
0009 00
OOOA 00
OOOB 06 LD B.8
OOOC 08
OOOD 29 MULT; ADD HLHL
OOOE 17 RLA
OOOF 30 JR NC.CHCNT
0010 01
0011 19 ADD HL.DE
0012 10 CHCNT; DJNZ MULT
0013 F9
0014 22 LD (42H),HL
0015 42
0016 00
0017 76 HALT

Note that the multiplicand must be extended to 16 bits by clearing Register D so that it

can be added to the product using the ADD HL.DE instruction.

The instruction ADD HLJHL acts as a 16-bit logical left shift for the 16-bit product.

in this program, the Z80 16-bit instructions handle data rather than addresses. LD HLO
is used to initialize the product; ADD HLHL to perform a 16-bit logical left shift; ADD
HLDE add the multiplicand to the partial product; and LD (42H).HL to store the
to
result inmemory. You must be careful to extend 8-bit quantities (like the multiplicand
m this example) to 1 6 bits. Note that you cannot use the 1 6-blt facilities simultaneously
for addressing and data manipulation. However, if you have no other'heed for the alter-

nate registers, you could save the old contents of the regular registers there and restore

8-11
them afterward using the EXX instruction. This instruction exchanges the contents
of

Register Pairs BC, DE. and HL with the contents of their alternate counterparts in just
four clock cycles.

Besides its obvious use in calculators and point-of-sale terminals, multiplication is a key
part of almost all signal processing and control algorithms. The speed at which
multiplications can be performed determines the usefulness of a CPU in process con-

trol, signal detection, and signal analysis.

The algonthm takes between 390 and 440 clock cycles to multiply on a Z80
microprocessor. The precise time depends on the number of one bits in the
multiplier.

Other algorithms may be able to reduce the average execution time somewhat but 400
clock cycles will still be a typical execution time for a software multiplication.^

8-Blt Binary Division


Purpose: Divide the 16-bit unsigned number in memory locations 0040 and 0041
(most significant bits in 0041) by the 8-btt unsigned number in memory loca-
tion 0042. The numbers are normalized so that 1) the most significant bits of
both the dividend and the divisor are zero and 2) the number in memory
location 0042 Is greater than the number in memory location 0041. i.e., the
quotient is an 8-bit number. Store the quotient in memory location 0043 and
the remainder in location 0044,

Sample Problems:
a. (0040) = 40 (64 decimal)
(0041) - 00
(0042) = 08
Result = (0043) =08
(0044) = 00
i.e., 64/8=8
b. (0040) = 6D (12.909 decimal)
(0041) - 32
(0042) = 47 (71 decimal)

Result = (0043) =B5 (181 decimal)


(0044) =3A (58 decimal)
i.e.. 12.909/71 = 181 with a remainder of 58

You can perform division on the computer iust like you would per- DIVISION
form division with pen and paper, i.e., using trial subtractions. ALGORITHM
Since the numbers are binary, the only question is whether the bit
in the quotient is or 1 i.e., whether or not the divisor can be subtracted from what is
,

left of the dividend. Each step in a bmary division can be reduced to the following

operation:

the divisor can be subtracted from the eight


If

most significant bits of the dividend without


a borrow, the corresponding bit in the quo-
tient IS 1 ; otherwise it is 0.

The only remaining problem is to line up the dividend and quotient properly. You can
do this by shifting the dividend and quotient logically left one bit before each tnal
subtraction. The dividend and quotient can share a 16-bit register, since the procedure
clears one bit of the dividend at the same time as it determines one bit of the quotient.

8-12
The complete process for binary division is:

Step 1 - Initialization:
Quotient =
Counter = 8
Step 2 - Shift Dividend and Quotient so as to line up properly:
Dividend - 2 x Quotient
Quotient = 2 x Quotient
Step 3 - Perform trial Subtraction. If no Borrow add 1 to Quotient:
If 8 MSBs of Dividend > Divisor then
MSBs of Dividend = MSBs of Dividend - Divisor
Quotient = Quotient + 1

Step 4 - Decrement counter and check for zero:


Counter = Counter - 1
if Counter 5^0, go to Step 2

Remainder = 8 MSBs of Dividend


In the case of sample problem b, where the dividend is 326D (hex) and the divisor is 47
(hex), the process works as follows:

Initialization:
Dividend 326D
Divisor 47
Quotient 00
Counter 00
After first iteration of Steps 2 - 4:
(Note that the dividend is shifted prior to the trial subtractton)
Dividend 1DDA
Divisor 47
Quotient 01
Counter 07
After second iteration of Steps 2 - 4:
Dividend 3BB4
Divisor 47
Quotient 02
Counter 06
After third iteration:
Dividend 3068
Divisor 47
Quotient 05
Counter 05
After fourth iteration:
Dividend 19D0
Divisor 47
Quotient OB
Counter 04
After fifth iteration:

Dividend 33A0
Divisor 47
Quotient 16
Counter 03

8-13
After sixth iteration:
Dividend 2040
Divisor 47
Quotient 2D
Counter 02

After seventh iteration:


Dividend 4080
Divisor 47
Quotient 5A
Counter 01

After eighth iteration:


Dividend SAGO
Divisor 47
Quotient B5
Counter 00

So the quotient is B5 and the remainder is 3A.

The MSBs dividend and divisor are assumed to be zero so as to simplify caicuiations
of
(the shift prior to the trial subtraction would otherwise place the MSB of the dividend in
the Carry). Problems that are not in this form must be simplified by removing parts of
the quotient that would overflow an 8-bit word. For example:

1024 400 (Hex) 100 (Hex)


100 +

The last problem is now m the proper form. An extra division may be necessary.

8-14
Flowchart:
r Start
J

Dividend =
{40 and 41)1
Divisor = (42)
Count = 8
Quotient =

Dividend =
2\ Dividend
' =
Quotient
2 X Quotient
(Shift both left 1 bit)

8 MSBs of
Dividend = 8 MSBs
of Dividend - DIvrsor
Quotient =Quotient-M

Count = Count -

(43} = Quotient
(44) = 8 MSBs of
Dividend

C 3
Source Program:
LD HL.(40H) ;GET DtViDEND
LD A,{42H) ;GET DIVISOR
LD C.A
LD B,8 ;COUNT = NUMBER OF BITS IN DIVISOR
DiV: ADD HLHL ;SHIFT DIVIDEND,QUOTIENT LEFT 1 BIT
LD A,H :CAN DIVISOR BE SUBTRACTED?
SUB C
JR C.CNT ;N0.GO TO NEXT STEP
LD H,A ;YES,SUBTRACT DIVISOR FROM DIVIDEND
INC L ;ADD TO QUOTIENT
1

CNT; DJNZ DIV


LD (43H).HL ;SAVE QUOTIENT, REMAINDER IN MEMORY
HALT

8-15
Object Program:
Memory Address Memorv Contents Instruction
(Hex) (Hex) (Mnemonic)

0000 2A LD HL.(40H)
0001 40
0002 00
0003 3A LD A,(42H)
0004 42
0005 00
0006 4F LD C.A
0007 06 LD B.8
0008 08
0009 29 DIV: ADD HLHL
OOOA 7C LD A,H
OOOB 91 SUB C
OOOC 38 JR CCNT
OOOD 02
OOOE 67 LD H.A
OOOF 2C INC L
0010 10 CNT: DJNZ OIV
0011 F7
0012 22 LD (43H),HL
0013 43
0014 00
0015 76 HALT

Register Patr HL holds both the dividend and the quotient The quotient simply replaces
the dividend in Register L as the dividend is shifted left logically.

For longer division problems, vou could use the instruction SBC HL which subtracts the
contents of a register pair and the contents of the Carry from the contents of Register
Pair HL
The instruction INC L sets the least significant bit of the quotient to 1 . since ADD HLHL
has previously cleared that bit

Division is necessary in calculators, terminals, communications error checking, control


algorithms, and many other applications.

This algorithm takes between 400 and 430 clock cycles to divide on a Z80
microprocessor. The depends on the number of one bits in the quotient
precise time
Other algorithms may reduce the average execution time somewhat but 400 clock cy-
cles will still be typical for a software division. Some of the references listed at the end
of this chapter discuss faster methods for implementing division.

8-16
Self-Checking Numbers
Double Add Double Mod 10
Purpose: Calculate a checksum digit from a string of BCD digits.The length of the
string of digits (number of words) is in memory location 0041 the string of
;

digits (2 BCD digits to a word) starts in memon/ location 0042, Calculate the
checksum digit by the Double Add Double Mod 1 technique^ and store it in
memory location 0040.

The Double Add Double Mod 10 technique works as follows: SELF-CHECKING


1) Clear the checksum to start. NUMBERS
2) Multiply the leading digit by two and add the result to the
checksum.
3) Add the next digit to the checksum.
4) Continue the alternating process until you have used all the digits.
5) The least significant digit of the checksum is the self-checking digit
Self-checking digits are commonly added to identification numbers on credit cards, in-
ventory tags, luggage, parcels, etc.. when they are handled by computenzed systems.
They may also be used in routing messages, files, and other applications.
identifying
The purpose of the digits is to minimize entn/ errorssuch as transposing digits (69 in-
stead of 96), shifting digits (7260 instead of 3726), missing digits by one (66 instead of
64), etc. You can check the self-checking number automatically for correctness
upon
entry and can eliminate many errors immediately.

The analysis of self-checking methods is quite complex. For example, a plain checksum
will not find transposition errors (4 + 9 - 9 -H 4). The Double Add Double algorithm will
find simple transposition errors (2x4-1-9 ==17 9^2x9 + 4); but will miss
some errors,
such as transpositions across even numbers of digits (367 Instead of 763). However,
this method will find many common errors! The value of a method depends on what er-
rors it will detect and on the probability of particular errors in an application.
For example, if the string of digits is

549321
the result will be:

Checksum = 5x2-l-4 + 9x2-F3 + 2x2-h1=40


Self-checking digit = (least significant digit of a checksum)
Note that an erroneous entry like 543921 would produce a different self-checking digit
(4), but erroneous entries like 049321 or 945321 would not be
detected.
Sample Problems:
a, (0041) = 03
(0042) = 36
(0043) = 68
(0044) - 51
Result: Checksum =3x2-l-6 + 6x2-l-8 + 5x2-{-1 =43
(0040) - 03
b. (0041) - 04
(0042) - 50
(0043) = 29
(0044) = 16
(0045) = 83
Result: Checksum ==5x2-H0 + 2x2 + 9-l-1x2-l-6 + 8x2-F3=50
(0040) - 00

8-17
Flowchart:

Checksum = |
Count == {41)1
Pointer = 42 i

MSD= (Pointer)/ 16
LSD = Pointer AND
00001111B
Checksum =Checksui
+ 2 X MSD = LSD
]
Pointer = Pointer +1

Count = Count - 1

8-18
Source Program:
LD A.(41H) : COUNT - LENGTH OF STRING !N BYTES
LD B,A
LD CO : CHECKSUM =
LD HL,42H : POINT TO START OF STRING OF DIGITS
CHDIG: LD A,(HL) : GET TWO BCD DIGITS FROM STRING
LD D.A : SAVE COPY
RRA GET MSD BY SHIFTING AND MASKING
RRA
RRA
RRA
AND 00001 11 IB
ADD A.A : ;DOUBLE MSD
DAA MAKE DOUBLED MSD DECIMAL
ADD A.C
':

ADD DOUBLED MSD TO CHECKSUM


DAA : KEEP CHECKSUM DECIMAL
LD C,A
LD A.D ;
GET LEAST SIGNIFICANT DIGIT
AND 00001 111B : (MASK OUT MSD)
ADD A,C u:ADD LSD TO CHECKSUM
DAA ;KEEP CHECKSUM DECIMAL
LD C,A
!NC HL
DJNZ CHDIG
AND 00001 111B :f MASK OFF SELF-CHECKING DIGIT
LD (40H),A ;J SAVE SELF-CHECKING DIGIT
HALT

8-19
A
D
C
B
E
F

Object Program:
Memory Contents Instruction
Memory Address
(Hex) (Hex) (Mnemonic)

0000 3A LD A.(41H)

0001 41
0002 00
47 LD B,A
0003
0004 OE LD CO
0005 00
0006 21 LD HL.42H
0007 42
0008 00
0009 7E CHDtG: LD A,(HL)

OOOA 57 LD D.A
OOOB IF RRA
OOOC IF RRA
GOOD IF RRA
OOOE IF RRA
OOOF E6 AND 00001 11 1B
0010 OF
0011 87 ADD A.A
0012 27 DAA
0013 81 ADD A.C
0014 27 DAA
0015 4F LD C.A
0016 7A LD A.D
0017 E6 AND 00001 11 IB
0018 OF
0019 81 ADD A.C
001 27 DAA
001 4F LD C,A
001 23 INC HL
001 10 DJNZ CHDiG
001 EA
001 £6 AND 00001 111B
0020 OF
0021 32 LD (40H).A
0022 40
0023 00
0024 76 HALT

The digits are removed by shifting and masking. Four right shifts are needed to separate
out the most significant digit

A decimal adjust (DAA) must follow each addition to produce the proper decimal result
A single DAA after a series of additions will not work (try Remember that DAA
it!).

works only on the Accumulator.


There is no problem with carries from the decimal sum, since the procedure uses only
the least significant digit of the checksum anyway.

8-20
An alternative (and superior)approach Is to use the 280 DECIMAL SHIFT
decimal shift instructionRLD. This instruction is a 4-blt INSTRUCTIONS
shift that moves the contents of the four least significant
bits of the memory location addressed by HL Into the four most significant bits of that
location, the previous contents of the four most significant bits of that location into the
four least significant bits of the Accumulator, and the previous contents of the four
least significant bits of the Accumulator into the four least significant bits of the memo-
ry location. Thus, RLD not only moves a single digit to the Accumulator, but it also
shifts the next digit so that it can be moved to the Accumulator with the next RLD.
Figure 8-1 shows an example of how RLD works; RRD is the same instruction except
that the shift is right instead of left

The Double Add Double Mod 10 algorithm can be implemented as follows using RLD:
Source Program:
LD A,(41H) :COUNT =LENGTH OF STRINGS (IN BYTES)
LD B,A
LD CO CHECKSUM =0
LD HL42H POINT TO START OF STRING OF DIGITS
CHDIG: SUB A ;CLEAR MSD
RLD GET MSD FROM STRING
ADD A,A DOUBLE MSD
DAA MAKE DOUBLED MSD DECIMAL
ADD A,C ADD DOUBLED MSD TO CHECKSUM
DAA KEEP CHECKSUM DECIMAL
LD C,A
SUB A :. CLEAR MSD
RLD :GET LSD FROM STRING
ADD A.C :ADD LSD TO CHECKSUM
DAA ;KEEP CHECKSUM DECIMAL
LD C.A
INC HL
DJNZ CHDIG
AND 00001 111B ;MASK OFF SELF-CHECKING DIGIT
LD (40H),A ;SAVE SELF-CHECKING DIGIT
HALT

8-21
A
D
C
BF
E

Object Program:
Memory Address Memorv Contents instruction

(Hex) (Hex) (Mnemonic)

0000 3A LD A,(41H)

0001 41
0002 00
47 LD B,A
0003
0004 OE LD CO
0005 00
0006 21 LD HL42H
0007 42
0008 00
0009 97 CHDIG: SUB
OOOA ED RLD
OOOB, 6F
OOOC 87 ADD A.A
OOOD 27 DAA
OOOE 81 ADD A.C
OOOF 27 DAA
0010 4F LD C,A
0011 97 SUB A
0012 ED RLD
0013 6F
0014 81 ADD A.C
0015 27 DAA
0016 4F LD C,A
0017 23 !NC HL
0018 10 DJNZ CHDIG
0019 EF
001 E6 AND 00001 11 IB
001 OF
001 32 LD (40H).A

001 40
001 00
001 76 HALT

improve this program even further (it is already shorter than the previous
ver-
We coutd
most significant digit at the end anyway, there is no
sion). Since we are dropping the
reason to clear it out each time with the SUB A instruction.

8-22
Initial Conditions

(HU=4000
(A) = 7F

(4000) ^ 12

After RLD
(A) - 71

(4000) = 2F

Before

Accumulator Memory Accumulator Memory

1
'

\
\
F

V,..,.
1
1 2
] H F

High-order bit =0, setS to •«


* Non-zero result,
4 ones, set P/0 to 1
set 2 to

(A) =72
14000) = F

Before After

Accumulator

T TH
High -order bit = 0. set S to •^<- Non-zero result,
4 ones, set P/0 to 1
set Z to

Figure 8-1. Examples of the Z80 Digit Shifts

You can double a decimal number (in the Accumulator) by DOUBLING


adding it to itself and then performing a decimal correction, AND HALVING
I.e.,
BINARY
ADD ;DOUBLE NUMBER NUMBERS
DAA ;AND MAKE RESULT DECIMAL
Remember that the Accumulator can ho!d only valid decimal digits in the range 0-99,
You cannot use SLA A (Shift Left Arithmetic A) because that instruction always clears
the Half-Carry (only Add and Subtract instructions set H properly).
You can number by two simply by shifting it right logically and then
divide a decimal
subtracting three from any digit that is eight or larger (since 10 BCD is 16 binary). The
following program divides a decimal number in memory location 0040 by two and
places the result into memory location 0041.

8-23
LD A.(40H) GET DECiMAL NUMBER
SRL A D!V1DE BY 2 !N BINARY
BIT 3,A IS LEAST SIGNIFICANT DIGIT 8 OR MORE?

JR Z.DONE
SUB 3' ;YES. SUBTRACT 3 FOR DECIMAL CORRECTION
DONE; LD (41H).A ;STORE NUMBER DIVIDED BY 2
HALT
30. and 37 Do you un
Try this program and the method on the decimal numbers 28,
derstand why tt works?

Rounding is simple whether the numbers are binary or decimal A BINARY


binary number can be rounded as follows: ROUNDING
If the most significant bit to be dropped is 1.

add 1 to the remaining bits. Otherwise, leave


the remaining bits alone.

This rule works because 1 is halfway between and 10 in binary, much as 5 ts halfway

in decimal (note that 0.5 decimal = 0,1 binary).

So, the following program will round a 16-bit number in memory locations 0040 and
0041 (MSBs in 0041) to an 8-bit number in memory location 0041.

LD HL.40H
BIT 7,(HL) :!S MSB OF EXTRA BYTE 1 ?

JR Z,DONE
tNC HL ;N0, ROUND UP
INC (HL)
DONE; HALT
If the number is longer than 16 bits, the rounding must ripple through the other bytes
as needed.

Decimal rounding is a bit more difficult because the crossover DECIMAL


point ts now BCD 50 and the rounding must produce a decimal ROUNDING
result The rule is:

If the most significant digit is to be dropped


IS 5 or more, add 1 to the remaining digits.

The following program will round a 4-digit BCD number in memory locations 0040 and
0041 (MSBs m 0041) to a 2-digit BCD number in memory location 0041.
LD HL,40H
LD A.(HL) :IS BYTE TO BE DROPPED 50 OR MORE?
CP 50H
JR C.DONE
INC HL ;YES, ROUND MSB'S UP
LD A.iHU
ADD A.1
DAA :KEEP DIGITS DECIMAL
LD (HU.A
DONE: HALT
Remember that the DAA instruction works only on numbers in the Accumulator, in thiS

case, we could round with the instruction INC A, since we know that the Carry is zero
(vvhy?— remember the JR instruction). Normally, we need the sequence ADD A,1

followed by DAA. since INC A does not affect the Carry.

8-24
Very often when performing muUibyte twos complement SIGN
signed arithmetic, it Is necessary to propagate the sign bit PROPAGATION
through the high-order bytes. This operation can be performed
in a straightforward manner if. as is usually the case, the
sign is in the Carry. The SBC
A.A instruction has the effect of propagating the state of the Carry throughout a word.
Since A-A always equals 0, SBC A,A is equivalent to subtracting the Carry from and
can yield only the values and FFH,

PROBLEMS
1) Multiple-Precision Subtraction
Purpose: Subtract one multiple-word number from another. The length of the num-
bers is in memory location 0040, the numbers themselves start (least signifi-
cant bits first) in memory locations 0041 and 0051, respectively, and the
difference replaces the number starting in memory location 0041. Subtract
the number starting in 0051 from the one starting In 0041.

Sample Problem:
(0040) - 04
(0041) — C3
(0042) := A7
•-
(0043) 5B
(0044) = 2F

(0051) =. B8
(0052) = 35
(0053) =: DF
(0054) = 14
esult: (0041) ~ OB
(0042) = 72
(0043) = 7C
(0044) - 1A
hat IS, 2F5BA7C3
" 14DF35B8
1A7C720B
2) Decimal Subtraction
Purpose: Subtract one muftiple-word decimal (BCD) number from another. The length
of the numbers is in memory location 0040, the numbers themselves
start
(least significant bits first) in memory locations 0041 and 0051. respectively,
and the difference replaces the number starting in memory location 0041.
Subtract the number starting in 0051 from the one starting m 0041.
Sample Problem:
(0040) - 04
(0041) - 85
(0042) = 19
(0043) - 70
(0044) - 36
(0051) - 59
(0052) = 34
(0053) = 66
(0054) - 12

8-25
Result: (0041) = 26
(0042) - 85
(0043) - 03
(0044) - 24

thatis. 36701985
12663459
24038526

3) 8-Bit by 16-Bit Binary Multiplication


Purpose: Multiply the 16-bit unsigned number in memory locations 0040 and 0041
(most significant bits m 0041) by the 8-bit unsigned number m
memory loca-
tion 0042. Store the result m memory locations 0043
through 0045. with the
most Significant bits in memory location 0045.

Sample Problemsi:
I

a. (0040) 03
(0041) = 00
(0042) 05

(0043)
„ OF
Result:
(0044) 00
(0045) 00

that IS, 3x5 -15


b. (0040) ~ 6F
(0041) 72 (29,295 decimal)
(0042) 61 (97 decimal)

Result: (0043) OF
(0044) 5C
(0045) = 2B

that IS, 29.295x97 =2,841.615

4} Signed Binary Division


Purpose: Divide the 16-bit signed number in memory locations 0040 and 0041 (most
significant bits in 0041 by the 8-bit signed number in memory location 0042.
The numbers are normalized so that the magnitude of memory location 0042
IS greater than the magnitude of memory location
0041. Store the quotient
(signed) in memory location 0043 and the remainder (always positive) in
memory location 0044.

Sample Problems:
a. (0040) - CO
(0041) = FF (-64)

(0042) - 08
Result: (0043) == F8 (-8) quotient
(0044) - 00 (0) remainder

b. (0040) = 93
(0041) - ED (-4717)
(0042) - 47 (71 decimal)

Result: (0043) - BD {-67 decimal)


(0044) - 28 (+40 decimal)
Hint: Determine the sign of the result, perform an unsigned division, and ad-
just the quotient and remainder properly.

8-26
5) Self-Checking Numbers Aligned 1, 3, 7 Mod 10
Purpose: Calculate a checksum
from a string of BCD digits. The length of the
digit
string of digits (nunnber of words) is m memory location 0041, the
string of
digits {2 BCD digits to a word) starts in memory location 0042. Calculate the
checksum digit by the Aligned 1 3, 7 Mod 1 method and store it m memory
,

location 0040.

The Aligned 1, 3. 7 Mod 10 technique works as follows:

1) Clear the checksum to start.


2) Add the leading digit to the checksum.
3) Multiply the next digit by 3 and add the result to the checksum.

4) Multiply the next digit bv 7 and add the result to the checksum.
5) Continue the process (Steps 2-4) until you have used all the digits.
6) The self-checkmg digit is the least significant digit of the checksum.

For example, if the string of digits is:

549321
the result will be:

Checksum = 5 + 3x4 + 7x9 + 3 + 3x2 + 7x1 -=96


Self-checktng digit - 6
Sample Problems:
a. {00411 = 03
(0042) = 36
(0043) = 68
(0044) = 51
Result: Checksum =3 + 3x6 + 7x6 + 8 + 3x5 + 7x1 =93
(0040) - 03
b. (0041) = 04
(0042) = 50
(0043) = 29
(0044) = 16
(0045) = 83
Result: Checksum =5 + 3x0 + 7x2 + 9 + 3x1 +7x6 + 8
+
3 x 3 = 90
(0040) = 00

Hint: Note that 7=2x3 + 1 and 3 = 2x1+1. so the formula


Mj = 2 X Mj,-} + 1 can be used to calculate the next multiplying factor.

8-27
REFERENCES
Several multiplication algorithms are described in T. Dolihoff, "Microprocessor

Software: Optimize Timing and Memory Usage. Part Four. Techniques for
How to
the Zilog Z80/' Digital Design February 1977, pp. 44-51.
.

Some microprocessors (such as the 9900, 8086, and Z-8000) have hardware
multiplication instructions that are somewhat faster, but maximum speed
requires

the addition of external hardware.

Other methods for implementing multiplication, division, and other arithmetic tasks
are discussed in:

Geist D, J.. "MOS Processor Picks up Speed with Bipolar Multipliers." Electronics .

July 7, 1977. pp. 113-115.

Kolodzmski. A. and D. Wainland. "Multiplying with a Microcomputer," Electronic


Design January 18. 1978, pp. 78-83.
,

Mick. J. R, and J. Springer, "Single-chip Multiplier Expands Digital Role in Signal

Processing," Electronics , May 13, 1976. pp. 103-108.

Parasuraman. B., "Hardware Multiplication Techniques for Microprocessor


Systems," Computer Design April 1977, pp. 75-82. ,

Tao, T. F. et al.. "Applications of Microprocessors in Control Problems," 1977 Joint


1 977.
Automatic Control Conference Proceedings. San Francisco, CA,. June 22-24,

Waser, S., "State-of-the-art in High-Speed Arithmetic Integrated Circuits," Com-


puter Design. July 1978. pp. 67-75.

Weissberger, A. J. and T. Toal, "Tough Mathematical Tasks Are Child's Play for
Number Cruncher." Electronics February 17, 1977, pp. 102-107.
,

See J. R. Herr, "Self-Checking Number Systems," Computer Design. June 1974.


pp. 85-91.

8-28
Chapter 9
TABLES AND LISTS
Tables and lists are two of the basic data structures
used with all computers. We have
already seen tables used to perform code conversions and
arithmetic. Tables may
also
be used to identify or respond to commands and instructions, linearize data, provide ac-
cess to files or records, define the meaning of keys or switches, and choose among
alternate programs. Lists are usually less structured than
tables. Lists may record tasks
that the processor must perform, messages or data that
the processor must record, or
conditions that have changed or should be monitored. Tables are
a simple way of mak-
ing decisions or solving problems, since no
computations or logical functions are
necessary. The task. then, reduces to organizing the table so
that the proper entry ts
easy to allow the execution of sequences of tasks, the preparation of
find. Lists
sets of
results, and the construction of interrelated data files
(or data bases). Problems include
how to add elements to a list and remove elements from it

EXAMPLES
Add Entry to List
Purpose: Add the contents of memory location 0040 to a list if it is not already
pre-
sent inthe list. The length of the list is in memory location 0041 and the list
Itself begins in memory location 0042.

Sampie Problems:
(0040) = 6B
(0041) = 04
(0042) = 37
(0043) = 61
(00441 = 38
(0045) = ID
Result: (0041) =, 05
(0046) = 6B
The entry is added to the list since
since it is not already present The length of the list is in-
creased by 1.

(0040) = 6B
(00411 = 04
(0042) = 37
(0043) = 68
(0044) ^ 38
(0045) = ID
Result: No change, since the entry is already m the list

9-1
Flowchart:

start
i J

Entry = (40)

Count = (41)

Pointer = 42

{Pointer! = Entry

{41} = (41) + 1

C J
Source Program:
LD HL40H POINT TO ENTRY
LD A,(HL) GET ENTRY
INC HL POINT TO COUNT
LD B.(HU COUNT = LENGTH OF LiST
INC HL POINT TO START OF LIST
SRLST CP (HL) IS ENTRY = ELEMENT IN LiST?

JR Z,DONE YES, THROUGH


INC HL NO, GO ON TO NEXT ELEMENT
DJNZ SRLST
LD (HU.A ADD ENTRY TO LIST
LD HL41H .ADD 1 TO LiST LENGTH
INC (HL)
DONE: HALT

9-2
Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex) (Mnennonid |

0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A.(HL)
0004 23 fNC HL
0005 46 LD B,(HL)
0006 23 iNC HL
0007 BE SRLST: CP (ML)
0008 28 JR Z.DONE
0009 08
OOOA 23 INC HL
OOOB 10 DJNZ SRLST
OOOC FA
OOOD 77 ADELM: LD (HL),A
OOOE 21 LD HL41H
OOOF 41
0010 00
0011 34 tNC (HL)
0012 76 DONE: HALT
We could also use the block search instruction CPIR in our example, as follows:
Source Program:
LD HL.40H POINT TO ENTRY
LD A,(HU :GET ENTRY
INC HL POINT TO COUNT
LD B,0 COUNT - LENGTH OF LIST (16 BITS)
LD C,{HU
INC HL POINT TO START OF LIST
CPIR LOOK FOR ENTRY IN LIST
JR Z.DONE : DONE IF ENTRY FOUND
LD (HU.A : OTHERWISE, ADD ENTRY TO LIST
LD HL41H ; ADD 1 TQ LIST LENGTH
DONE: HALT

9-3
Object Program:
Memory Contents Instruction
Memory Address
(Hex) (Mnemonic)
(Hex)

0000 21 LD HL40H
0001 40
0002 00
0003 7E LD A,(HL)

23 !NC HL
0004
0005 06 LD B.O

0006 00
0007 4E LD C,(HL)

23 tNC HL
0008
ED CPIR
0009
OOOA B1
28 JR Z.DONE
OOOB
OOOC 05
OOOD 77 LD (HL),A

OOOE 21 LD HL41H
OOOF 41
0010 00
0011 34 iNC (HL)

0012 76 DONE: HALT

basic Search mstruction untii either BC


Remember that CPIR automatically repeats the
true comparison occurs (i.e.. A - (HD).
Is decremented to zero or a

careful of the following slight differences from


the previous version:
Be
1) BC is a 16-bit counter. Thus. CPIR can handle strings longer than 256 bytes.
cleared if BC is decremented to zero, and
set other-
2) The Panty/Overflow btt (P/0) is

wise.

of adding elements is ven/ inefficient


if the list HASHING
Clearly, this method
We could improve the procedure by limiting the search to
is long
limit the search by using the entry to get
part of the list or by ordering the list We could
"hashing", and ts much like selecting a
a starting point in the list This method is called

starting page in a dictionary or directory on


the basts of the first tetter m an entry. We
could then end when the list values
could order the list by numerical value. The search
went beyond the entry (larger or smaller, depending on the ordering technique used). A
properly, and all the other entries would have to be
new entn/ would have to be inserted
moved down in the list

a starting
The program could be restructured to use two tables. One table could provide
point could be based on the most or
point in the other table; for example, the search
least significant 4-bit digit in the entry.

9-4
The program does not work if the length of the list coutd be zero
(what happens?). We
could avoid this problem by checking the length initlaitv. The initialization
procedure
for the first program would then be:

LD HL40H POINT TO ENTRY


LD A,(HL) GET ENTRY
INC HL POINT TO LENGTH
LD B.iHL) COUNT - LENGTH OF LIST
INC HL POINT TO START OF LIST
INC B IS COUNT zero;*
DEC B
JR Z.ADELM ;YES. GO ADD ENTRY TO LIST

ADELM; LD (HU,A ;ADD ENTRY TO LIST


Note that the sequence INC, DEC is an easy way to check for a zero value in a register
without using the Accumulator or changing the value in the register.

The procedure:
LD HLADDR
INC (HL)

is a quick wayadd 1 to a counter in memon/ location ADDR without using the Ac-
to
cumulator. You can use DEC (HL) in a similar manner to subtract 1 from the counter. LD
(HL), CONST can place a starting value (such as zero) In the counter.
Memory locations
should, of course, be used for counters only when no readily accessible registers are
available.

If each entry were longer than one word, a pattern-matching program would be necess-
an/. The program would have to proceed to the next entry if a match failed: that is, skip
over the last part of the current entry once a mis-match was found.
Check an Ordered List
Purpose: Check the contents of memory location 0041 to see if it Is in an ordered list
The length of the list is in memory location 0042: the list itself begins In
memory location 0043 and consists of unsigned binary numbers In increas-
ing order. If the contents of location 0041 is in the list clear memon/ loca-
tion 0040; otherwise, set memon/ location 0040 to FF (hex).

Sample Problems:
(0041) - 6B
(0042) = 04
(0043) = 37
(0044) = 55
(0045) = 7D
(0046) = AI
Result: (0040) - FF, since 68 is not in the list

(0041) = 6B
(0042) = 04
(0043) - 37
(0044) = 55
(0045) = 6B
(0046) = A1
Result: (0040) - 00. since 68 is in the list

9-5
Flowchart:

The searching process is a bit different here since the elements are ordered. Once we

findan element larger than the entry, the search is over, since subsequent elements will
be even larger. You may want to tn/ an example to convince yourself that the procedure
works.

As In method that could


the previous problem, a table or other SEARCHING
choose good starting point would speed up the search. One
a METHODS
method would be to start in the middle and determme which half
of the list the entry was in, then divide the half into halves, etc. This method is called a
binary search, since it divides the remaining part of the list in half each time.^

9-6
Source Program:
LD HL41H POINT TO ENTRY
LD A,(HL) GET ENTRY
iNC HL POINT TO LENGTH
LD B.(HL) COUNT - LENGTH OF LIST
LD CO MARK -ZERO FOR IN LIST
INC HL POINT TO START OF LIST
SRLST: CP (HL) IS ENTRY - ELEMENT IN LIST?
JR Z.DONE YES SEARCH COMPLETED
JR C.NOTIN ENTRY NOT IN LIST IF LESS THAN ELEMENT
INC HL
DJNZ SRLST
NOTIN: LD C.OFFH :MARK = FFFORNOTIN LIST
DONE: LD A.C :SAVE MARK
LD (40H),A
HALT
Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex) (Mnemonic) |

0000 21 LD HL41H
0001 41
0002 00
0003 7E LD A.(HL)
0004 23 INC HL
0005 46 LD B,(HU
0006 OE LD CO
0007 00
0008 23 INC HL
0009 BE SRLST: CP (HU
OOOA 28 JR Z,DONE
0008 07
OOOC 38 JR CNOTIN
GOOD 03
OOOE 23 INC HL
OOOF 10 DJNZ SRLST
0010 F8
0011 OE NOTIN: LD C.OFFH
0012 FF
0013 79 LD A.C
0014 32 LD (40H).A
0015 40
0016 00
0017 76 HALT

The Z80 block search instructions are not as useful here as in the previous example
because we want to do more than a simple search. Now we also want to check to see if
we have examined the relevant part of the list (i.e.. the part where the elements are less
than or equal to the entry). Try rewriting the program to use CPI. Remember that you
must use the Parity/Overflow flag to determine if the byte counter has been decre-
mented to zero.

9-7
Remove Element from Queue
Purpose: Memory locations 0042 and 0043 contain the address of the head of the
queue (MSBs in 0043). Place the address of the first elennent (head) of a
queue into memorv locations 0040 and 0041 (MSBs in 0041) and update
the queue to remove the element Each element (n the queue is two bytes
long and contains the address of the next two-byte element in the queue.
The last element in the queue contains zero to indicate that there is no next
element
Queues are used to store data in the order in which it will be used, or tasks in the order
m which they will be executed. The queue is a first-in, first-out data structure: i.e.. ele-
ments are removed from the queue in the same order in which they were entered.
Operating systems place tasks in queues so that they will be executed in the proper
order. I/O drivers transfer data to or from queues so that it wilt be
transmitted or

handled in the proper order. Buffers may be queued so that the next available one can
easily be found and those that are released can easily be added to the
available storage.

Queues may also be used to link requests for storage, timing, or I/O so that they can be
satisfied in the correct order.

In realapplications each element in the queue will typically contain a large amount of
information or storage space besides the address required to link the element to the
next one.

Sample Problems:
(0042) element queue
^^1 address of first in
(0043)
(0046) queue
^^i address of second element in
(0047)
(004D) queue
zzi end of
(004E)

Result: (0040) element removed from queue


t^\ address of
(0041) oof
(0042) new element queue
I address of first in
(0043) oof
(0042) = 00
empty queue
(0043) = 00 \
Result: (0040) available from queue
92\ no element
(0041)

9-8
Flowchart:
f Start
J

Pointer = (42 and 43)


(40 and 41) = Pointer

(42) = (Pointer)
(43) = (Pointer + 1)

I
C End
J
Source Program:
LD HL,(42H) GET ADDRESS OF HEAD OF QUEUE
ID (40H),HL REMOVE HEAD OF QUEUE
LD A.H IS QUEUE EMPTY?
OR L
JR Z,DONE ;YES, DONE
LD E,(HU :N0, GET ADDRESS OF NEXT ELEMENT
INC HL
LD D.(HU
LD (42H),DE :MOVE NEXT ELEMENT TO HEAD OF QUEUE
DONE: HALT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 2A LD HL(42H)
0001 42
0002 00
0003 22 LD (40H).HL
0004 40
0005 00
0006 7C LD A,H
0007 B5 OR L
0008 28 JR Z.DONE
0009 07
OOOA 5E LD E,(HL)
OOOB 23 INC HL
OOOC 56 LD D,(HL)
OOOD ED LD (42H).DE
OOOE 53
OOOF 42
0010 00
0011 76 DONE: HALT

9-9
Queuing can handle lists that are not in sequential nnemory locations. Each
elennent

must contajn the address of the next eiement Such lists allow you to handle data or
tasks in the proper order, change variables, or fili m definitions in a program.
Extra
deleted from it
Storage iS required, but elements can easily be added to the queue or

Note the use of the sequence:

LD A,H
OR L

zero. Remember that INC and


to determine if the contents of a 16-bit register pair is
DEC do not affect anv flags when applied to a register pair. Try to devise some other se-
quences that could handle this problem —
it obviously occurs whenever vou use a
1
6-

bit counter rather than the 8-bit counter that we have used most of the examples. m
One problem is that there is no instruction that loads a register pair using the address in

a register pair. A sequence of instructions is necessary whenever a register pair must be


loaded directly.

it may be useful to maintain pointers to both ends of the queue rather than just to its

head. The data structure may then be used in either a first-in, first-out manner or in a

manner, depending on whether new elements are added to the head or


iast-m. first-out
the tail you change the program example so that memon/ locations 0044
How would
and 0045 contain the address of the last element (tail) of the queue?

Ifthere are no elements in the queue, the program clears memory locations 0040 and
0041. A program that requested an element from the queue would then have to check
those memory locations to see if its request had been satisfied. Can you suggest other
ways to provide this information?

8-Bit Sort
Purpose: Sort an array of unsigned binary numbers into descending order. The length
of the array is in memory location 0040 and the array itself begins in memo-
ry location 0041.

Sample Problem:
(0040) = 06
(0041)
_ 2A
(0042) := B5
(0043) ==; 60
(0044) = 3F
(0045) rr D1
(0046) = 19

Result: (0041) = D1
(0042)
_ 85
(0043) = 60
(0044) =r 3F
(0045) == 2A
(0046) = 19

A simple sorting technique works as follows: SIMPLE


SORTING
Step 1) Clear a flag INTER.
ALGORITHM
Step 2) Examine each consecutive pair of numbers In the array. If

any are out of order, exchange them and set INTER.


Step 3) If INTER = 1 after the entire array has been examined, return to Step 1,

9-10
INTER win be set if any consecutive pair of nunnbers is out of order. Therefore, if IN-
TER = at the end of a pass through the entire array, the array is in proper order.

This sorting nnethod is referred to as a "bubble sort" it is an easy algorithm to imple-


ment. However, other sorting techniques should be considered when sorting long lists
where speed is important^
The technique operates as follows in a simple case. Let us assume that we want to sort
an array into descending order; the array has four elements — 12, 03, 15, 08.

1st Iteration:

Step 1) INTER =
Step 2) Final order of the array is;

12
15
08
03
since the second pair (03.15) is exchanged and so is the third pair (03,08).
INTER = 1.

2nd Iteration:

Step 1) INTER -0
Step 2) Final order of the array is:

15
12
08
03
since the first pair (12.15) is exchanged. INTER = 1,

3rd Iteration:

Step 1) INTER -0
Step 2) The elements are already in order, so no exchanges are necessary and INTER
remains zero.

9-11
Flowchart:

Temp = (Pointer)

{Pointer!= iPointer+1)
(Pointer +1) = Temp
Inter = 1

^_
Pointer = Pointer +1
Ckjunt == Count - 1

9-12
Source Program:
SORT: LD CO ;CLEAR INTERCHANGE FLAG
LD HL40H :COUNT - LENGTH OF ARRAY
LD B.{HL)
DEC B NUMBER OF PAIRS - COUNT-1
INC HL POINT TO START OF ARRAY
PASS1; LD A,(HL) GET ELEMENT FROM ARRAY
iNC HL
CP (HL) :IS IT LESS THAN NEXT ELEMENT?
JR NCCNT :N0, NO INTERCHANGE NECESSARY
LD D.(HL) :YES, INTERCHANGE ELEMENTS
LD (HU.A
DEC HL
LD (HL),D
INC HL
LD C.I ;SET INTERCHANGE FLAG
CNT: DJNZ PASS1
DEC C ;WAS INTERCHANGE FLAG SET?
JR Z,SORT ;YES, DO ANOTHER PASS
HALT
Object Program:
Memory Address Memory Contents instruction
(Hex) (Hex) (Mnemonic)
0000 OE SORT; LD ao
0001 00
0002 21 LD HL40H
0003 40
0004 00
0005 46 LD 8.(HL)
0006 05 DEC B
0007 23 INC HL
0008 7E PASS1: LD A,(HL)
0009 23 INC HL
OOOA BE CP (HL)
OOOB 30 JR NC.CNT
OOOC 07
OOOD 56 LD D.(HL)
OOOE 77 LD (HL),A
OOOF 28 DEC HL
0010 72 LD (HL),D
0011 23 INC HL
0012 OE LD CI
0013 01
0014 10 CNT: DJNZ PASS1
0015 F2
0016 OD DEC C
0017 28 JR Z.SORT
0018 E7
0019 76 HALT
The case where two elements the array are equal is very important here. The program
in
should not perform an interchange in that case, since that interchange would occur in
every pass. The result would be that every pass would set the interchange flag, thus
producing an endless loop.

9-13
.

The program must reduce the counter by 1. since the number of consecutive
pairs r
Before start
one less than the number of elements (the last element has no successor).
ing each sorting pass, we must be careful to reinitialize
the counter, pointer, and m

terchange flag.

There are many possible minor variations on this program. For example, we
could use

RES O.C and SET O.C to clear and set the interchange flag instead of LD CO and ID C,1
We could also use the sequence MOV B,C followed by DJNZ SORT to check the in-
terchange flag.
counter is decre-
Note that Register 8 should be used for the inner counter, since that
mented most frequently. This allows us to take maximum advantage of the
DJNZ in-
struction,
ZSO's index
indexing would be a convenient way to perform the interchange if the
registers were more accessible. Try rewriting the program so as to
use one of the index
registers and compare the execution time and memory usage of
the rewritten program

to those of the onginal program.

Using an Ordered Jump Table


Purpose: Use the contents of memon/ location 0040 as an index to a jump table start-
ing in memon/ location 0041 Each entry
. in the jump table contains a 1 6-bit

address with LSBs in the first word. The program should transfer control to
the address with the appropriate index; that is, if the index is 6. the pro-
gram jumps to address entry #6 m the table. Assume that the table has
fewer than 128 entries.

Sample Problem:
(0040) = 02
(0041) = 48
(0042) = 00
(0043) = 4C
(0044) = 00
(0045) = 50
(0046) = 00
(0047) = 54
(0048) = 00
Result: (PC) = 0050, since that is entry #2.
(starting from zero) in the jump table.

Flowchart:

r Start
1
index = (40) > 2

Base = 41

1
JELEM =
Base •§-
Index

t
(PC) =
(JELEM) (JELEM -t 1)

9-14
The last box results in a transfer of control to the address obtained from the table.

Source Program:
LD HL.40H ;POINTTO INDEX
LD A.(HL) ;GET INDEX
ADD A.A :DOUBLE INDEX FOR 2-BYTE TABLE
LD E.A
LD D,0 ;EXTEND INDEX TO 16 BITS
INC HL :BASE ADDRESS OF JUMP TABLE
ADD HLDE ;tNDEX INTO JUMP TABLE
LD E,{HL) ;GET LSB'S OF DESTINATION ADDRESS
INC HL
LD D,(HL) :GET MSB'S OF DESTINATION ADDRESS
EX DE.HL
JP (HL) :TRANSFER CONTROL TO DESTINATION
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
0000 21 LD HL.40H
0001 40
0002 00
0003 7E LD A,(HL)
0004 87 ADD A.A
0005 5F LD E,A
0006 16 LD 0,0
0007 00
0008 23 INC HL
0009 19 ADD HLDE
OOOA 5E LD E.(HL)
OOOB 23 INC HL
OOOC 56 LD D.(HL)
OOOD EB EX DE,HL
OOOE E9 JP (HL)

Jump tables are very useful in situations where one of several routines must be
selected. Such situations arise in decoding commands,
selecting test programs, choos-
ing alternate methods, or selecting an I/O configuration.

The jump table replaces a whole series of conditional jump operations. The program
that accesses the jump table could be used to access several different tables merely by
changing the starting address.^
The data must be multiplied by two to give the correct index, since each entry in the
jump table is a two-byte address.
The instruction JP (HL), which transfers the contents of Register INDIRECT
PairHL to the Program Counter, is an indirect jump that is very JUMPS
handy in jump tables and monitor programs. Note that JP (HL) Is a
Jump instruction, since it places a new value into the Program Counter; however, it
allows us to place a variable address directly into the Program Counter. All of the Condi-
tional Jump instructions (and the Cati instructions) use fixed addresses. The only Jump
instructions with similar flexibility are the two-word instructions JP (IX)and JP (lY).
No ending operation is necessary, since JP (HL) transfers control to the address ob-
tained from the jump table.

9-15
PROBLEMS
1) Remove an Entry From a List
Purpose: Remove the contents of memory location 0040 from a list if is present it

The length of the list is in memory location 0041 and the list itself begins in
memory location 0042. Move the entries below the one removed up one
position and reduce the length of the list by 1.

Sample Problems:
a. (0040) - 6B
(0041) = 04
(0042) = 37
(0043) = 61
(0044) = 28
(0045) = ID

Result: No change, since the entry is not in the list.

b. (0040) = 6B
(0041) - 04
(0042) = 37
(0043) - 6B
(0044) = 28
(0045) = 1D
Result: (0041) = 03
(0042) = 37
(00431 = 28
(0044) - ID

The entry is removed from the list and the ones below It are moved up one position. The
length of the list ts reduced by 1.

9-16
2) Add an Entry to an Ordered List
Purpose: Place the contents of nnemory location 0040 into an ordered list if It is not
already there. The length of the list is in memorv location 0041 and the list ,

itself begins in memory location 0042, which consists of unsigned binary


numbers in increasing order. Place the new entry in the correct position m
the list, adjust the elements below it down, and increase the length of the
list by 1.

Sample Problems:
(0040) = 6B
(0041) = 04
(0042) z^ 37
(0043) = 55
(0044) = 7D
(0045) = A1
Result: (0041) = 05
(0044) = 6B
(0045) = 7D
(0046) = A1
(0040) = 6B
(0041) =. 04
(0042) = 37
(0043) == 55
(0044) = 68
(0045) = A1
Result: No change, since the entry is already in the list

3) Add an Element to a Queue


Purpose: Add the address in memory locations 0040 and 0041 (MSBs in 0041) to a
queue. The address of the first element of the queue is In memory locations
0042 and 0043 (MSBs in 0043). Each element in the queue contains either
the address of the next element in the queue or zero if there is no next ele-
ment; ail addresses are 16 bits long with the most significant bits in the
second word of the element. The new element goes at the end (tail) of the
queue; its address will be m the element that was at the end of the queue
and it will contain zero to Indicate that it is now the end of the queue.
Sample Problem:

f^^w slsf^^nt to be added to queue


0041) =00)
= Ool P^*"^®"* ^^ ^^^^ °^ ^^^^^
(0043)

^^'^ ^^^"^^"^ '" "^"^^"^^


lo047) - ool
Result: (0046) ^ 4D) old last element points to
(0047) = OOj new last element
(004D) = 00
new last element in queue
(004E} - 00

How would you add an element to the queue if memory locations 0044 and 0045 con-
tained the address of the tail (last element} of the queue?

9-17
4) 16-BitSort
Purpose: Sort an array of unsigned 16-bit binary numbers into descending order. The
length of the array is in mennory location 0040 and the array itself begins in
memory iocation 0041. Each 16-bit number is stored with the least signifi-
cant bits in the first word.

Sample Problem:
(0040) r= 03
(0041) = D1
(0042) ^ 19
(0043) =r 60
(0044) = 3F
(0046) = 2A
(0046) = B5
Result: (0041) 2A
=;=

(0042) = 85
(0043) = 60
(0044) = 3F
(0045) = D1
(0046) = 19
The numbers are B52A, 3F60, and . 19D1

5) Using a Jump Table With a Key


Purpose: Use the contents of memory location 0040 as the key to a |ump table start-
ing in memory location 0041. Each entry in the jump table contains an 8-bit
key value followed by a 16-bit address (MSBs in second word) to which the
program should transfer control if the key is equal to that key value.
Sample Problem:
(0040) = 38
(0041) = 32
(0042) = 48
(0043) = 00
(0044) = 35
(0045) = 4D
(0046) = 00
(0047) = 38
(0048) = 4F
(0049) = 00
Result; (PC) = 004F, since that address corresponds
to key value 38.

Tn/ writing the program with and without the CPIR instruction. Can you think of a way
to simplify the version that uses the CPIR instruction? Hint: place all the corresponding
8-bit words into separate tables so that the program only has to add 1 to the table
pointer to move from one key value to the next'^

9-18
REFERENCES
Knuth describes other searching techniques in his book The Art of Computer Pro-
gramming, Volume III: Sortin g and Searchin g. Addison-Wesley, Reading, Mass.,
1978. Knuth also has discussed searching and hashing in a more elementan/ way
in an article entitled "Algorithms" (see the April 1 977 issue of
Scientific American) .

There are many sorting algorithms that van/ widely in efficiency. Knuth describes
some in the book mentioned above (The Art of Computer Pro gramming Volume .

HI: Sortin g and Searchin g). Sorting and searching


algorithms are also discussed in
K. A. Schember and J. R. Rumsey, "Minimal Storage Sorting and
Searching Techni-
ques for RAM Applications, a Tutorial", Computer June 1977, pp. 92-100.
.

There are additional examples of the use of jump tables in L A. LeventhaL "Cut
Your Processor's Computation Time", Electronic Desig n. August 16, 1977, pp.
82-89. and in Chapter 7 of J, B. Peatman, Microcomputer-Based Desi gn. McGraw-
Hill, New York, 1977.

This method is discussed by T. Dotlhoff in "Microprocessor Software: How to Op-


timize Timing and Memory Usage: Part Four: Techniques for the ZItog Z80".
Dig ital Desi gn. February 1977, pp, 48-49.

9-19
Chapter 10
SUBROUTINES
None of the examples that we have shown so far is tvpicaiiy a program a!! by itseif.
Most real programs perform a series of tasks, many of which may be the same or may
be common to several different programs. We need a way to formulate these tasks
once
and make the formulations conveniently available both in different parts of the current
program and m other programs.
The standard method is to write subroutines that perform particu-
ISUBROUTrtMEl
lar tasks. The resulting sequences of instructions
can be written LIBRARY j
once, tested once, and then used repeatedly. They can form a
subroutine library that provides documented solutions to common problems.

Most microprocessors have special instructions for transferring SUBROUTINE


control to subroutines and restoring control to the mam pro- INSTRUCTIOMS
gram. Weoften refer to the special instruction that transfers
control to a subroutine as Call, Jump-to-Subrouttne, Jump and Mark Place, or Jump
and Link. The special instruction that restores control to the main program is usually
called Return. On the Z80 microprocessor, the Call instruction (CALL) saves the old
value of the Program Counter in the RAM Stack before placing the starting address
of
the subroutine into the Program Counter: the Return instruction (RET)
gets the old
value from the Stack and puts it back in the Program Counter, The effect is
to transfer
program control, first to the subroutine and then back to the mam program. Clearly the
subroutme may itself transfer control to a subroutine, and so on.
In order to be really useful, a subroutine must be
general. A routine that can perform
only a specialized task, such as looking for a particular letter in an input string
of fixed
length, will not be very useful. If, on the other hand, the subroutine can
look for any let-
ter in strings of any length, it will be far more helpful. We
call the data or addresses that
the subroutine allows to vary "parameters". An important part of wnting
subroutines is
deciding which variables should be parameters.

One problem is transferring the parameters to the subroutine; this PASSiNG


process is called passing parameters.
The simplest method is for PARAMETERS
the main program to place the parameters Into registers. Then the
subroutine can simply assume that the parameters are there. Of course, this technique
Is limited by the number of registers that are
available. The parameters may. however,
be addresses as well as data. For example, a sorting routine could begin with the
start-
ing address of an array in Register Pair HL.

Other methods are necessary when there are more parameters. One possibility is to use
the Stack. The main program can place the parameters into the Stack
and the
subroutine can retrieve them. The advantages of this method are that the Stack is es-
sentially unlimited m size, and that data in the Stack is not lost even if the Stack
is used
again.

The disadvantages are few Z80 instructions use the Stack, and the Call instruction
that
also stores the return address m the Stack. Another method is to use an area of memory
for parameters. The main program can place the address of the area
into Register Pair
HL or into one of the Index registers and the subroutine can retrieve the data as needed.
However, this procedure is awkward if the parameters themselves are addresses.

10-1
Sometimes a subroutine must have special characteristics. A j
RELOCATION [
subroutine is relocatable if it can be placed anywhere in memon/.
You can use such a subroutine easily, regardless of the placement of other programs or
the arrangement of the memory. A strictly relocatable program can use no absolute ad-
dresses; all addresses must be relative to the start of the program. A relocating loader
IS necessary to place the program in memory properly;
the loader will start the program
to all ad-
after other programs and will add the starting address or relocation constant
dresses in the program.

A subroutine is reentrant if it can be interrupted and called by the REENTRANT


interrupting program and stilt give the correct results for both the SUBROUTINE
interrupting and interrupted programs. Reentrancy is important for
service
standard subroutines m an interrupt-based system. Otherwise the interrupt
Microprocessor
routines cannot use the standard subroutines without causing errors.
subroutines are easy to make reentrant, since the Call instruction uses the Stack and
that procedure is automatically reentrant. The only remaining
requirement is that the
subroutine use the registers and Stack rather than fixed memory locations for
tempor-
ary storage. This is a bit awkward, but usually can be done .if necessary.

A subroutine is recursive if it calls itself. Such a subroutine clearly must also be re-

entrant. However, recursive subroutines are uncommon in microprocessor applications.

Most programs consist of a main program and several subroutines. This is advan-
tageous because you can use proven routines and debug and test the other subroutines
separately. You must however, be careful to use the subroutines properly and remem-
ber their exact effects on registers and memory locations.

SUBROUTINE DOCUMENTATION
Subroutine listings must provide enough information so that DOCUMENTING
users need not examine the subroutine's internal structure. SUBROUTINES
Among the necessary specifications are;
• A description of the purpose of the subroutine.
• A list of input and output parameters.
• Registers and memory locations used.
• A sample case.

If these guidelines are followed, the subroutine will be easy to use.

EXAMPLES
It is important to note that the following examples all reserve an area of memory for the
RAM Stack. If the monitor in your microcomputer establishes such an area, you may use
it instead, if vou wish to try establishing your own Stack area
remember to save and
restore the monitors Stack Pointer in order to produce a proper return at the end of
your main program.

To save the monitor Stack Pointer, use the instruction LD {addr),SP. To restore the
monitor Stack Pointer, use the instruction LD SP.faddr). Both of these instructions re-
quire a two-bvte operation code (ED 7B for loading the Stack Pointer. ED 73 for storing
it) in addition to the two bytes of address.

We have used address 0080 You may have to


(hex) as the starting point for the Stack,
more suitable for your configuration. You
consistently replace that address with one
should consult your microcomputer's manual to determine the required changes.

10-2
Hex to ASCII
Purpose: Convert the contents of the Accunnulator to an
ASCII character. Place the
result in the Accumulator. Assume that the
Accumulator contains a single
hexadecimal digit
Sample Problems:
a. (A) = OC
Result: (A) = 43
b. (A) - 06
Result: (Al = 36 '6'

Flowchart:

(A) = (A) +-ASC!! A


ASCII 9 - 1

(A) = (A) + ASCII

CIEID
Source Program:
The calling program starts the Stack at memory location 0080. gets the
data from
memory location 0040. calls the conversion subroutine, and
stores the result in memory
location 0041,

ORG
ID SP,80H START STACK AT LOCATION 0080
LD A.{40H) GET DATA
CALL ASDEC CONVERT DATA TO ASCII
LD (41HU STORE RESULT
HALT
The subroutine converts a hexadecimal digit to ASCII.

ORG 20H
ASDEC: CP 10 :1S DATA A DECIMAL DIGIT?
JR CASCZ
ADD A;A'-'9'-1 :N0, ADD OFFSET FOR LETTERS
ASCZ: ADD A/O' ;CONVERT DATA TO ASCII
RET

10-3
Subroutine Documentation:

: SUBROUTINE ASDEC

: PURPOSE; ASDEC CONVERTS A HEXADECIMAL


DiGtT IN THE ACCUMULATOR TO AN
ASCI! DIGIT IN THE ACCUMULATOR

; INITIAL CONDITIONS: HEX DIGIT IN A

: FINAL CONDITIONS: ASCII CHARACTER IN A

. REGISTERS USED: A

. SAMPLE CASE
INITIAL CONDITIONS: 6 IN ACCUMULATOR
; FINAL CONDITIONS: ASCI! 6 (HEX 36)

IN ACCUMULATOR

Object Program:
Memory Contents Instruction !
Mennorv Address
(Hex) (Hex) (Mnemonic) 1

1) Calling program
0000 31 LD SP,80H
0001 80
0002 00
0003 3A LD A.(40H)
0004 40
0005 00
0006 CD CALL ASDEC
0007 20
0008 00
0009 32 LD (41H),A
OOOA 41
OOOB 00
OOOC 76 HALT

2) Subroutine

0020 FE ASDEC: CP 10
0021 OA
0022 38 JR CASCZ
0023 02
0024 C6 ADD A;A'-'9'-1

0025 07
0026 C6 ASCZ: ADD a;o'
0027 30
0028 C9 RET

The LD SP.80H
instruction starts the Stack at memory location UUbU. HememDer that

the Stack grows downward (to lower addresses). We usually place the Stack at the high

10-4
end of RAM (I.e., the highest address) so that it will not interfere with other temporary
storage.

The Call instruction places the subroutine starting address {0020 hex) into the Program
Counter and saves the old Program Counter (0009 hex) in the Stack. The procedure is:
STEP 1 —Decrement Stack Pointer, save MSBs of old Program Counter in Stack.
STEP 2 — Decrement Stack Pointer, save LSBs of old Program Counter in Stack.
Note that the Z80 Stack Pointer always contains the address of the last occupied Stack
location.

The result in this case is:

(007F) = 00
(007E) = 09
(SP) = 007E
The value saved is the value of the Program Counter after the processor has
that is

fetched the entire Call instruction from memory. Note that the address ends
up stored
just like other Z80 addresses, with the least significant bits in
the lower address.
The Return instruction loads the Program Counter with the contents of the bottom two
memory locations in the Stack. The procedure is:
STEP 1 —Load eight bits from Stack into LSBs of Program Counter. Increment Stack
Pointer.

STEP 2 — Load eight bits from Stack into MSBs of Program Counter. Increment Stack
Pointer.

The result in this case is:

(PC) = (007F) and (007E)


- 0009
(SP) = 0080
This subroutine has a single input parameter and produces a single result. The Ac-
cumulator IS the obvious place to put both.

The calling program involves three steps; placing the data mto the Accumulator, call-
ing the subroutine, and storing the result. The overall initialization must also place the
Stack in the appropriate area of memory.

The subroutine is reentrant, since it uses no data memory; it is relocatable, since the
address ASCZ is relative.

Note that the CALL instruction results m the execution of four or five instructions taking
36 or 38 clock cycles. A subroutine call can take a long time even though it appears to
be a single instruction in the program.

If you plan to use the Stack for parameters,


remember that CALL places the return ad-
dress at the top of the Stack. You can increment the Stack Pointer twice (INC SP)
to get
past the return address, but you must also remember to adjust the Stack Pointer
pro-
perly before returning. You can also move the Stack Pointer to Registers H and L
with
the sequence:

LD HLO
ADD HLSP ;MOVE STACK POINTER TO ADDRESS REGISTER
Now you can use implied memory addressing with H and L to access data In the Stack.
Another alternative is to move the Stack Pointer to an index register (say IX) with the se-
quence;

LD IX.O
ADD IX.SP ;MOVE STACK POINTER TO INDEX REGISTER

10-5
This alternative has the advantage that you can now access data
and addresses in the
Stack v^ith indexed offsets. Furthermore, Register Pair HL is
immediatelv available for
use in the subroutme. Note that you can use the instructions
LD SP.HL or LD SP.IX to
return an adjusted value to the Stack Pointer.

Length of a String of Characters


starting address of
Purpose: Determine the length of a string of ASCII characters. The
is marked by a carnage
the stnng is tn Register Pair HL. The end of the string
the
return character (CR. hex OD), Place the length of the string (excluding
carriage return) into the Accumulator.

Sample Problems:
a. (HL) - 0043
(0043) = OD
Result: (A) = 00

b. (HL) = 0043
(0043) - 52 'R'

(0044) - 41 'A'

(0045) = 54 'T'

(0046) = 48 'H'

(0047) = 45 'E'

(0048) - 52 'R'

(0049) - OD CR
Result: (A) = 06
Flowchart:

f Start
J

Pointer HL
Count

Count Count + 1

Pointer Pointer + 1

C D

10-6
Source Program:
The cafling program starts the Stack at memory location 0080, gets
the starting address
of the string from memory locations 0040 and 0041. calls the string
length subroutine
and stores the result in memory location 0042.

LD SP.80H :START STACK AT LOCATION 0080


LD HL(40H) ;GET STARTING ADDRESS OF STRING
CALL STLEN :DETERMINE STRING LENGTH
LD (42H).A ;STORE STRING LENGTH
HALT
The subroutine determines the length of a stnng of ASCII characters and places the
length into the Accumulator.

ORG 20H
STLEN: LD B.O STRING LENGTH -ZERO
LD A.ODH GET ASCII CARRIAGE RETURN
CHKCR: CP (ML) IS CHARACTER A CARRIAGE RETURN?
JR Z.DONE YES. END OF STRING
INC B NO, ADD 1 TO STRING LENGTH
INC HL
JR CHKCR
DONE: LD A.B
RET
Subroutine Documentation:

;SUBROUTINE STLEN

;PURPOSE: STLEN DETERMINES THE LENGTH OF A


STRING {NUMBER OF CHARACTERS BEFORE
; A CARRIAGE RETURN)

:INITIAL CONDITIONS; STARTING ADDRESS OF


STRING IN REGISTER PAIR HL

;REGISTERS USED: A.B.H.L

:SAMPLE CASE;
STARTING CONDITIONS: (HL) - 0043
(0043) = 35. (0044) - 46, (0045) - OD
FINAL CONDITIONS; (A) - 02

10-7
Object Program:
Memory Address Memorv Contents Instruct ion 1

(Hex) (Hex) (Mnemonic) 1

1) Calling program
0000 31 LD SP.80H
0001 80
0002 00
0003 2A LD HL(40H)
0004 40
0005 00
0006 CD CALL STLEN
0007 20
0008 00
0009 32 LD (42H).A
OOOA 42
OOOB 00
OOOC 76 HALT
2) Subroutine

0020 06 STLEN: LD B.O

0021 00
0022 3E LD A.ODH
0023 OD
0024 BE CHKCR: CP (ML)

0025 28 JR Z.DONE
0026 04
0027 04 INC 8
0028 23 INC HL
0029 18 JR CHKCR
002A F9
002B 78 DONE: LD A.B
002C C9 RET

calling program involves four steps: initializing the Stack Pomter, placing the
start-
The
ing address of the string into Register Pair HL, calling the subroutine, and stonng the
result

The subroutine is reentrant since it does not change the contents of any memory loca-

tions, tt is relocatable, since all the Jump instructions use relative addresses.

The subroutine changes Register 8 and the address in Register Pair HL as well as the
Accumulator. The programmer must be aware that data previously stored in Register B
and the address previously loaded into HL will be lost; the subroutine documentation
must describe what registers are used.
An alternative to destroying register contents in the subroutine is to save them in the
Stack and then restore them before returning. This approach makes the calling routine
simpler, but costs extra time and memory (in the program and in the Stack).

This subroutine has a single input parameter, which is an address. The best way to pass
this parameter ts through a register pair and. since the HL pair is certainly the most flex-
ible as far as addressing options are concerned, it is the obvious choice.

The subroutine contains an unconditional Jump instruction, JR CHKCR. By altering the

initial conditions prior to entering the subroutine's loop, can you eliminate this jump?

if the terminating character were not always an ASCII carriage return, we could make
that character into another parameter. Now the calling program would have to place

10-8
the terminating character into the Accumulator and the starting
address of the string
into Register Pair HL before calling the subroutine.

One way to pass parameters that do not depend on vanable data


is to place the values
m program memorv immedlatelv after the Call instruction. You can use the old
Program
Counter (saved at the top of the Stack) to access the data, but you must
adjust its value
properly before returning control to the mam program. For
example, we could pass the
value of the terminating character this way. The main program
and subroutine would

Calling program:

ORG
LD SP.80H ;START STACK AT LOCATION 0080
LD (HU.40H :GET STARTING ADDRESS OF STRING
CALL STLEN iOETERMINE STRING LENGTH
DEFB TERMINATOR - ASCII PERIOD
LD (42H),A ;STORE STRING LENGTH
HALT
Subrout me:

ORG 20H
STLEN: POP DE GET START OF PARAMETER LIST
LD A,(DE) GET TERMINATING CHARACTER
INC DE ADJUST RETURN ADDRESS
PUSH DE
LD B.O STRING LENGTH - ZERO
CHKCR: CP (HL) IS CHARACTER TERMINATOR?
JR Z.DONE YES. END OF STRING
INC B NO. ADD 1 TO STRING LENGTH
INC HL
JR CHKCR
DONE; LD A,B
RET
This subroutine is longer and uses Register Pair DE, but
the calling program need not
load the terminating character into a register. The INC DE
instruction is necessary to
force a return to the next instruction, rather than to the parameter
list."'

PUSH and POP transfer the contents of register pairs or index registers to and
from the
RAM Stack. The eight
least significant bits are removed first and stored last
to retain
consistency with the ZSO's upside-down method of stonng 16-bit addresses.
Remem-
ber that the RAMStack grows downward (to lower addresses).

Add Even Parity to ASCI! Characters


Purpose: Add even parity to a string of 7-bft ASCII characters. The length of
the stnng
IS in the Accumulator and the starting address
of the string is in Register Pair
HL. Place even parity in the most significant bit of each character,
i.e., set the
most significant bit to 1 if that makes the to.tal number of 1 bits in the wore
even.

10-9
Sample Problem:
(A) = 06
(HL) = 0041
(0041) = 31
(0042) - 32
(0043) = 33
(0044) = 34
(0045) = 35
(0046) = 36
Result: (0041) - B1
(0042) = B2
(0043) = 33
(0044) - 84
(0045) = 35
(0046) - 36

Flowchart:

(Pointer) — (Pointeri

OR 10000000B

3
(Set Pantv Bit)

Pointer = Pointer + 1

Count = Count - 1

10-10
Source Program:
The calling program starts the Stack at memory location 0080, sets
the starting address
of the string to 0041, gets the string length from memory location 0030,
and calls the
even parity subroutine.

ORG
LD SP.80H START STACK AT LOCATION 0080
ID HL41H GET STARTING ADDRESS OF STRING
LD A,(30H) ;GET STRING LENGTH
CALL EPAR
HALT
The subroutine adds even parity to a string of ASCII characters.

ORG 20H
EPAR: LD B,A
LD CJOOOOOOOB GET PARITY BIT OF 1
SETPR: LD A.{HU GET A CHARACTER
OR C :SET PARITY BIT TO 1
JP PO.CHCNT IS PARITY NOW EVEN?
LD (HD.A YES. SAVE CHARACTER WITH EVEN PARITY
CHCNT: INC HL
DJNZ SETPR
HALT
Subroutine Documentation:

;SUBROUTINE EPAR

:PURPOSE: EPAR ADDS EVEN PARITY


: TO A STRING OF 7-BIT ASCI!
: CHARACTERS

.'INITIAL CONDITIONS: STARTING ADDRESS


: OF STRING IN HL LENGTH OF STRING
; IN A

:FINAL CONDITIONS: EVEN PARITY IN


.; MSB OF EACH CHARACTER

:REGISTERS USED: A,B,C.H,L

;SAMPLE CASE:
; INITIAL CONDITIONS: (HU^0041
: (A) (00411 = 32, (0042) = 33
= 2.

; FINAL CONDITIONS; (0041) = B2, (0042) = 33

This subroutine has two parameters, an address and a


number Register Pair HL ts used
to pass the address and the Accumulator to pass
the number. No explicit results are
returned, smce the subroutine affects only the MSB
of each character in the string

10-11
Pair HL
program must place thestarting address of the string into Register
The calling
Accumulator before transferring control to the
and the length of the string into the
subroutine.
Registers A. H. and L and uses Registers B and C
The subroutine changes the values in

temporary storage. It is reentrant, since it does not use any fixed memory locations
for
for temporary storage.

Object Pfogram:
Memory Contents Instruction
Memory Address
(Hex) {Hex} (Mnemonic)

1) Calling program
31 LD SP,80H
0000
0001 80
0002 00
0003 21 LD HL41H
0004 41
0005 00
0006 3A ID A.(30H)

0007 30
0008 00
0009 CD CALL EPAR
OOOA 20
OOOB 00
OOOC 76 HALT

2) Subroutine
47 EPAR: LD B.A
0020
0021 OE LD CIOOOOOOOB
0022 80
0023 7E SETPR: LD A,(HL)

0024 Bl OR Q
0025 E2 JP POXHCNT
0026 29
0027 00
0028 77 LD (HU.A
0029 23 CHCNT; INC HL
002A 10 DJNZ SETPR
002B F7
002C C9 RET

Pattern Match
Purpose: Compare two strings of ASCII characters to see if they are the same. The
length of the strings is in the Accumulator. The starting
address of one strmg
the starting address of the other is in Register Pair DE.
IS in Register Pair HL:
If the two strings match, clear the Accumulator; otherwise, set the Ac-
cumulator to FF (hex).

10-12
1

Sample Problems:
a. (A) 03
(DE) 50
(HL) 60
(0050) 43
(0051) - 41 ^A'
(0052) 54 T'

(0060) 43 'C
(0061) = 41 'A'
(0062) 54
Result: (A) = 0. since the strings are the same
b. (A) = 03
(DE) 50
(HL) 60
(0050) = 52 'R'

(0051) - 41 'A'
(0052) = 54 'T'

(0060) = 43 'C
(0061) = 41 'A'
(0062) = 54 T
Result: (A) FF (hex), since the first characters differ.

Flowchart:
f Start
J

Pointer 1 = (DE)
Pointer 2 = (HU
Courjt = (A)

Pointer 1
Pointer t + 1
Pointer 2 1
{A) = FF (hex)
Pointer 2 + l|
Count = Count - l|

10-13
Source Program:
The caiNng program starts the Stack at memory location 0080. sets the starting ad-

dresses of the stnngs to 0050 and 0060, respectively, gets the string length from

memon/ location 0040, calls the pattern match subroutine, and places the result into

memory location 0041.

ORG
LD SP.80H START STACK AT LOCATION 0080
LD DE,60H GET STARTING ADDRESS OF STRING 1

LD HL50H GET STARTING ADDRESS OF STRING 2


LD A,(40H) GET STRING LENGTH
CALL PMTCH CHECK FOR MATCH
LD {41H),A SAVE MATCH INDICATOR
HALT
utine determines if t

ORG 20H
PMTCH: LD 8.A COUNT = STRING LENGTH
LD COFFH MARK = FF (HEX) FOR NO MATCH
CHCAR: LD A.(DE) GET CHARACTER FROM STRING 1

CP (HU ;1S THERE A MATCH WITH STRING 2?

JR NZ.DONE NO. DONE — STRINGS D.O NOT MATCH


INC DE
INC HL
DJNZ CHCAR
LD CO :MARK -ZERO. STRINGS MATCH
DONE: LD A.C
RET
Subroutine Documentation:

ISUBROUTINE PMTCH

:PURPOSE: PMTCH DETERMINES IF TWO


: STRINGS ARE EQUIVALENT

:INITIAL CONDITIONS: STARTING ADDRESSES


: OF STRINGS IN DE AND HL
; LENGTH OF STRINGS IN ACCUMULATOR

;FINAL CONDITIONS: IN A IF

; STRINGS MATCH, FF IN A OTHERWISE

:REGISTERS USED: A.B.D.E.H.L

:SAMPLE CASE:
; STARTING CONDITIONS: (HU - 0050,
: (DE) - 0060, (A) - 2
; (0050) =36, (00511=39
: (0060) =36, (0061) = 39
: FINAL CONDITIONS: (A) - SINCE THE STRINGS MATCH

10-14
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
1) CaNing program

0000 31 LD SP,80H
0001 80
0002 00
0003 11 LD DE,60H
0004 60
0005 00
0006 21 LD HL50H
0007 50
0008 00
0009 3A LD A,(40H)
OOOA 40
OOOB 00
OOOC CD CALL PMTCH
OOOD 20
OOOE 00
OOOF 32 LD (41H),A
0010 41
0011 00
0012 76 HALT
1
2) Subroutine
0020 47 PMTCH; LD B,A
0021 OE LD C.OFFH
0022 FF
0023 1A CHCAR: LD A,{DE)
0024 BE CP (HL)
0025 20 JR NZ.DONE
0026 06
0027 13 INC DE
0028 23 INC HL
0029 10 DJNZ CHCAR
002A F8
0028 OE LD CO
002C 00
002D 79 DONE; LD A.C
002E C9 RET

This subroutine, like the preceding ones, changes all of the flags. You should generally
assume that a subroutine call changes the flags unless it is specifically stated other-
wise. If the main program needs the old flag values (for later checking), it must save
them in the Stack prior to calling the subroutine. This is accomplished with the PUSH
AF instruction.

The subroutine is reentrant and changes all the main registers except C.

This subroutine has three parameters —


the two starting addresses and the length of
the strings. These parameters use five general-purpose registers.

10-15
Multiple-Precision Addition
Purpose: Add two muttipte-byte binary numbers. The length of the numbers in bytes
is In the Accumulator. The starting addresses of the numbers are
in Register

Pairs DE and HL. The starting address of the result is in Index Register IX. AH
the numbers begin with the least significant bits.

Sample Problem:
(A) = 04
(DE) =r 51
(HU = 61
(IX) = 71

(0051) = C3
(0052) = A7
(0053) = 58
(0054) = 2F
(0061) == 88
(0062) = 35
(0063) == DF
(0064) = 14

Result: (00711=78
(0072) = DD
(0073) = 3A
(00741=44
i.e. 2F5BA7C3
+ 14DF35B8
443ADD7B
Flowchart:

J
Count "^n^T"
Pointer 1 = (DE)
Pointer 2 = (HU
Pointer 3 = {IX)'
Carry
.^«i™
(Pointer 3) -
(Pointer 1)
+ (Pointer 2)
+ Carrv
(Ihis step also produces new Carry)

Pointer 1=^ Pointerl +1


Pointer 1^ Po!nter2 + 1

Pointer 3= Pointers +i
Count =r Count - 1

10-16
Source Program:
The calling program starts the Stack at memory location 0080, sets the starting ad-
dresses of the vartous numbers to 0050. 0060. and 0070, respectively, gets the length
of the numbers from memory location 0040. and calls the multiple-precision addition
subroutine.

ORG
LD SP.80H START STACK AT LOCATION 0080
LD HL50H GET STARTING ADDRESS OF FIRST NUMBER
LD DE.60H GET STARTING ADDRESS OF SECOND NUMBER
LD 1X.70H GET STARTING ADDRESS OF RESULT
LD A.(40H) GET LENGTH OF NUMBERS IN BYTES
CALL MPADD MULTIPLE-PRECISION ADDITtON
HALT
The subroutine performs multiple-precision binary addition.

ORG 20H
MPADD: LD B.A COUNT = LENGTH OF NUMBERS IN BYTES
AND A CLEAR CARRY TO START
ADDW: LD a,{de; GET WORD FROM FIRST NUMBER
ADC A.iHU ADD WORD FROM SECOND NUMBER
LD (IX),A STORE ONE WORD OF RESULT
INC DE
INC ML
INC IX
DJNZ ADDW
RET
Subroutine Documentation:

SUBROUTINE MPADD

PURPOSE; MPADD ADDS TWO


MULTIPLE-BYTE BINARY NUMBERS

INITIALCONDITIONS: STARTING ADDRESSES


OF NUMBERS iN D AND E. H AND L:
STARTING ADDRESS OF RESULT IN IX,
LENGTH OF NUMBERS IN A

REGISTERS USED: A.B.D,E.H.LiX

SAMPLE CASE:
STARTING CONDITIONS: {HU = 0050.
(DE)=0060. (tX)=0070, (A) = 2.
(0050) = C3. (0051) = A7. (0060) = B8. (0061) = 35
FINAL CONDITIONS: (0070) - 7B. (0071) = DD

10-17
Object Program:
Memory Address Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

1) Catling program
0000 31 LD SP.80H
0001 80
0002 00
0003 21 LD HL,50H
0004 50
0005 00
0006 11 LD DE.60H
0007 60
0008 00
0009 DD LD IX.70H
OOOA 21
OOOB 70
OOOC 00
OOOD 3A LD A,(40H)
OOOE 40
OOOF 00
0010 CD CALL MPADD
0011 20
0012 00
0013 76 HALT
2) Subroutine

0020 47 LD B.A
0021 A7 AND A
0022 1A LD A,{DE)
0023 8E ADC A,(HL)
0024 DD LD (iXl.A

0025 77
0026 00
0027 13 INC DE
0028 23 INC HL
0029 DD INC IX

002A 23
002B 10 DJNZ ADDW
002C F5
002D C9 RET

We use Index Register IX to hold the result address. Try changing the program to use
Register Pair BC for this purpose. What happens to the counter?
We could also place the result address at the top of the Stack. The instruction EX
(SP),HL exchanges the top of the Stack and Register Pair HL Change the program so
that it uses this instruction, but remember to increment all three pointers after each
Iteration.

This subroutine has four parameters — three addresses and the length of the numbers.
Six 8-bit registers and the 16-bit Index Register IX are used for passing parameters.

10-18
PROBLEMS
Note that you are to write both a calling program for the sample problem and a property
documented subroutine.

1) ASCII to Hex
Purpose: Convert the contents of the Accumulator from the ASCII representation of a
hexadecimal digit to the 4-bit binary representation of the digit. Place the
result into the Accumulator.

Sample Problems:
(A) 43 'C
Result: (A) OC
(A) 36 '6'

Result: (A) 06

2} Length of an ASCII Message


Purpose: Determine the length of an ASCil-coded message. The starting
address of
the stnng of characters in which the message Is located is in Register Pair
HL The message Itself starts with an ASCII STX character (hex 02) and ends
with ASCII ETX (hex 03). Place the length of the message (the number of
characters between the STX and the ETX) Into the Accumulator.

Sample Problem:
(HL) = 0041
(0041) = 49
(0042) = 02 STX
(0043) = 47 'G*
(0044) = 4F '0'

(0045) = 03 ETX
Result: (A) = 02

3) Check Even Parity in ASCII Characters


Purpose: Check the even parity of a stnng of ASCII characters. The length of the string
is m the Accumulator and the starting address of the stnng is in Register Pair

HL. If the parity of all the characters in the stnng is correct clear the Ac-
cumulator: otherwise, set the Accumulator to FF hex (al! ones).

Sample Problems:
a. (A) 03
(HL) 0042
(0042) 81
(0043) 82
(0044) 33
Result: (A) 00, since all the characters have even panty

(A) 03
(HL) 0042
(0042) 81
(0043) 86
(0044) 33
Result: (A) FF, since the character m memory location 0043
does not have even parity

10-19
4) String Comparison
Purpose: Compare two strings of ASCII characters to see which is larger {I.e., which
would follow the other in alphabetical' ordering).

The length of the strings Is m the Accumulator; the starting address of


string 1 is in Register Pair HL and the starting address of string 2 is m
Register Pair DE, If string 1 is larger than or equal to string 2. clear the Ac-
cumulator; otherwise, set the Accumulator to FF hex (all ones).

Sample Problems:
a, (A) - 03
(DE) = 0060
(HL) = 0050
(0050) = 43 'C
(0051) = 41 'A'

(0052) = 54 T'

(0062) - 42 'B'

(0063) = 41 'A'

(0064) = 54 T'

Result = (A) = 00, since CAT is 'larger than BAT


(A) = 03
(DE) = 0060
(HL) r= 0050
(0050) = 44 'D'

(0051) = 4F '0'

(0052) = 47 'G'

(0060) =r 44 'D'
'0'
(0061) =r 4F
(0062) = 47 'G'

Result = (A) = OC since the two strings are equal

(A) :=03
(DE) = 0060
(HL) = 0050
(0050) = 43 'C
(0051) = 41 'A'

(0052) = 54 T
(0060) = 43 'C
(0061) - 55 'U'

(0062) = 54 T'

Result = (A) = FF (hex), smce CUT is 'larger' than CAT

5) Decimal Subtraction
Purpose: Subtract one multiple-digit decimal (BCD) number from another. The length
of the numbers (in bytes) is in the Accumulator and the starting addresses of
the numbers are in Register Pairs DE and HL Subtract the number with the
starting address in HL from the one with the starting address m DE. The
starting address of the result is in Index Register IX. All the numbers begin
with the least significant digits. The sign of the result is returned in the Ac-
cumulator —
zero if the result is positive, FF (hex) if it is negative.

10-20
Sample Problem:
(A) = 04
(DE) - 0050
(HU = 0060
(IX) = 0070
(0050) = 85
(0051) = 19
(0052) = 70
(0053) = 36
(0060) = 59
(0061) = 34
(0062) = 66
(0063) = 12

Result: (A) = 00 (positive)


(0070) = 26
(0071) = 85
(0072) = 03
(0073) = 24
I.e. 36701985
-
12663459
4- 24038526

10-21
REFERENCES
1 . Other examples of this technique {for the 8080 microprocessor) are in S. Mazor and
C. Pitchford, "Develop Cooperative Microprocessor Subroutines," Eiectronic
Design. June 7, 1978. pp. 116-118.

10-22
1

Chapter 1
INPUT/OUTPUT
There are two problems in the design of input/output sections: one how
is to interface
peripherals to the computer and transfer data, status, and control signals: the other is
how to address I/O devfces so that the CPU can select a particular one for a data
transfer. Clearly, the first problem is both more complex and more interesting. We will
therefore discuss the interfacing of peripherals here and leave addressing
to a more
hardware-oriented book.

In theory, the transfer of data to or from an I/O device is similar to AND


I/O
the transfer of data to or from memory. In fact, we can consider
the MEMORY
memory as just another i/0 device. The memory is, however,
special for the following reasons:

1) !t operates at almost the same speed as the processor.


2) Ituses the same type of signals as the CPU. The only circuits usually needed
to in-
terface the memory to the CPU are drivers, receivers, and level
translators.
3) It requires no special formats or any control signals besides a Read/Write
pulse.
4) It automatically latches data sent to it.

5) Its word length is the same as the computer's.

Most do not have such convenient features. They may operate at speeds
I/O devices
much slower than the processor: for example, a teletypewriter can transfer
only 10
characters per second, while a slow processor can transfer 10,000
characters per sec-
ond. The range of speeds is also very wide —
sensors may provide one reading per
minute, while video displays or floppy disks may transfer 250,000
bits per second.
Furthermore, I/O devices mav require continuous signals (motors or thermometers), cur-
rents rather than voltages (teletypewriters), or voitages at far different
levels than the
signals used by the processor (gas-discharge displaysK I/O devices
may also require
special formats, protocols, or control signals. Their word lengths
may be much shorter
or much longer than the word length of the computer. These
variations make the
design of I/O sections difficult and mean that each peripheral presents its own
special
interfacing problem.

We may, however, provide a general description of devices and in- I/O


terfacing methods. We may roughly separate devices into three CATEGORIES
categories, based on their data rates:

1) Stow devices that change state no more than once per second. Changing their
states typically requires milliseconds or longer. Such devices include lighted
dis-
plays, switches, relays, and manv mechanical sensors and actuators,

2) Medium-speed devices that transfer data at rates of 1 to 10,000 bits per second
Such devices include keyboards, printers, card readers, paper tape readers and
punches, cassettes, ordinary communications lines, and many analog data acquisi-
tion systems.

3) High-speed devices that transfer data at rates of over 10.000 bits per second. Such
devices include magnetic tapes, magnetic disks, high-speed line printers, high-
speed communications lines, and video displays.

11-1
The interfacing of slow devices is simple. Few control signals
INTERFACINQ
are necessary unless the devices are multiplexed i.e.. several
DEVICES Stow
11-4.
are handled from one port, as shown in Figures 11-1 to
for a long time
input data from slow devices need not be latched since it remains stable
interval. Outputdata must of course, be latched. The onlv problems with input are
transitions that occur white the computer is reading the data. One-shots, cross-coupled
latches, or software delay routines can smooth the transitions.

single port can handle several slow devices. Figure 11-1 shows a
A demultipiexer that
opera-
automatically directs the next output data to the next device by counting output
tions. Figure 1 1-2 shows a control port that provides select
inputs to a demultiplexer.

The data outputs here can come in any order, but an additional output Instruction is
necessary to change the state of the control port. Output demultiplexers are commonly
used to drive several displays from the same output port. Figures 11-3 and 11-4 show
the same alternatives for an input multiplexer.

Note the differences between input and output with slow devices:

Input data need not be latched since the input device holds the data for an
enor-
1)

mous length of time by computer standards. Output data must be latched, since
the output device will not respond to data that is present for only a few
CPU clock
cycles.

2) Input transitions cause problems because of their duration; brief output transitions
cause no problems because the output devices (or the observers) react slowly.
3) The major constraints on input are reaction time and responsiveness, the major
constraints on output are response time and observability.

Medium-speed devices must be synchronized in some way to INTERFACING


the processor clock. The CPU cannot simply treat these devices MEDIUM-SPEED
as if they held their data forever or could receive data at any DEVICES
time. Instead the CPU must be able to determine when a
device has new input data or is ready to receive output data. !t must also have a way of
telling a device that new output data is available or that the previous
input data has

been accepted. Note that the peripheral may be or contain another p rocessor.
The standard unclocked procedure the handshake. Here the
is | HANDSHAKE |

sender indicates the data to the receiver and


availability of
transfers the data: the receiver completes the handshake by acknowledging the recep-
tion of the data. The receiver may control the situation by initially requesting the data or
by indicating its readiness to accept data; the sender then sends the data and com-
pletes the handshake by indicating that data is available. In either case, the sender
knows that the transfer has been completed successfully and the receiver knows when
new data is available.

11-2
Data Outputs

uata ous
Output Data i'
Port i> Inputs

Data Outputs t

:>
Port Selection Logic H
Demultiplexer
Data Outputs 2

i>
Select
Data Outputs 3
Inputs

The Counter controls where the Demultiplexer sends the data.

Figure 11-1. An Output Demultiplexer Controlled by a Counter

Data Outputs

Data Data
:>
rTO Port t> inputs

Data Outputs 1

i>
Demultiplexer
Data Outputs 2

i>

^ Control
Port
Select

Inputs
Data Outputs 3

i>

The CPU sends control information to the Control Port; that port determines

where the Demultiplexer sends the data.

Figure 1 1-2. An Output Demultiplexer Controlled by a Port

11-3
Data Inputs

Data
Outputs
IC=3
Port
Data inputs 1

Port Selection Logsc


c
-filM Mut^texef
Datff inputs 2

c
Countra^ Data Inputs 3
Inputs

The CoimM' controb which mput tfw Whrttiptexer gates to ttw Input Ptfft.

Figure 11-3. An Input Multiplexer Controlled by a Counter

Data inputs

tr^pHit Data&is

c Data
PCHt c Data
Outputs

Data thputs 1

Multiplexer

Data Inputs 2

r
Output Data l^is

Contrtrf
Data Inputs 3
Port

the control inftHmatton wMch the CPU sends to the Ctrntml Port (with an output operation)

datenmies vtrfsch input the Mtrit^xer routes to the Data PcKt.

Figure 11-4. An Input Multiplexer Controlled by a Port

11-4
Figures 11-5 and 11-6 show typical input and output operations using the handshake
method. The procedure whereby the CPU checks the readiness of the peripheral before
transferring data is called "polling" Clearly, polling can occupy a targe amount of pro-
cessor time if there are many I/O devices. There are several ways of providing the
handshake signals. Among these are:

' Separate dedicated I/O lines. The processor may handle these as additional I/O ports
or through special lines or interrupts. The Z80 processor does not have serial !/0 lines,
but the Z80 Parallel input/Output device- (or PIO) does.
• Special patterns on the I/O lines. These may be single start and stop bits or entire
characters or groups of characters. The patterns must be easy to distinguish from
background noise or inactive states.

We often call a separate I/O line that indicates the availability of [STROBE (
data or the occurrence of a transfer a "strobe". A strobe may. for
example, clock data into a latch or fetch data from a buffer.

Many peripherals transfer data at regular intervals; synchronously. Here the only
i.e.,

problem is starting the process by lining up marking the first output


to the first input or
In some cases, the peripheral provides a clock input from which the processor can ob-
tain timing information.

Transmission errors are a problem with medium-speed devices. REDUCINQ


Several methods can lessen the likelihood of such errors; they TRANSMISSION
include: ERRORS
• Sampling input data at the center of the transmission interval
in order to avoid edge effects; that is, keep away from the edges where the data is

changing.
• Sampling each input several times and using majority logic such as best three out of
five.^

• Generating and checking parity; an extra bit is used that makes the number of 1 bits
in the correct data even or odd.

• Using other error detecting and correcting codes such as checksums, LRC
(longitudinal redundancy check), and CRC (cyclic redundancy check).2
High-speed devices that transfer more than 10,000 bits per INTERFACING
second require special methods. The usual technique is to con- HIGH-SFEED
struct a special-purpose controller that transfers data directly DEVICES
between the memory and the I/O device. This process is called
DIRECT
direct memory access (DMA). The DMA controller must force
the CPU off the busses, provide addresses and control signals
MEMORY
memory, and
ACCESS
to the Such a controller will be
transfer the data.
fairly complex, typically consisting of 50 to 100 chips,
although LSI devices are now available.^ The CPU must initially load the Address and
Data Counters in the controller so that the controller wilt know where to start and how
much to transfer.

11-5
input

Acknowledge

c I/O
Section c
Data Ready
Peripheral

a) Peripheral provides data and Data Ready signal to computer I/O section.

Input
Acknowledge
^
Data
1/0
CPU
c Section c
Data Ready
Peripheral

b) CPU reads Data Ready signal from I/O section {this may be a hardware interrupt connection).

Input

Acknowledge

Data

c , I/O
Section c Peripheral

Data Ready
^

cl CPU reads data from I/O section.

Input
Acknowledge

Data

^ I/O
Section cData Ready
Peripheraf

d} CPU sends Input Acknowledge signal to I/O section, which then provides Input Acknowledge signal

to Peripheral (this may be a hardware connection).

Figure 1 1-5. An Input Handshake

11-6
Output Ready

I/O

c Section
^ Peripheral

Peripheral Ready

a) Penphera! provides Penphera! Ready signal to computer I/O section.

Output Ready

1/0

C Section

Penpheral Ready
t'
Penpheral

b) CPU reads Penpheral Ready signal from I/O section {this may be a hardware interrupt connection).

Output Ready

I/O

^ Section !> Peripheral

Peripheral Ready

c) CPU sends data to Penpheral.

Output Ready

Data
I/O
CPU > Peripheral
:> Section

Penphera! Ready

d) CPU sends Output Ready signal to Penpheral (this may be a hardware connection).

Figure 11-6. An Output Handshake

11-7
TIMING INTERVALS (DELAYS)
One problem we will face throughout the discussion of In-
that US£S OF
put/output the generation of timing intervals with specific
is TIMING
lengths. Such intervals are necessary to debounce mechanical | INTERVALS

switches (to smooth their irregular transitions), to provide pulses


with specified lengths and frequencies for displays, and to provide timing for devices
that transfer data regularly (for example, a teletypewriter that sends or receives one bit
even/ 9.1 ms).

We can produce timing intervals in several ways: METHODS


FOR
1) In hardware with one-shots or monostable multivibrators.
PRODUCINQ
These devices produce a single pulse of fixed duration in
TIMING
response to a pulse input
INTERVALS
2) In acombination of hardware and software with a flexible pro-
grammable timer such as the Z80 Counter-Timer Circuit (or
CTC) for Z80 based microcomputers, as described in An introduction to Microcom-
puters: Volume 2 —
Some Real Microprocessors. The CTC can provide timing in-
tervals of various lengths with a variety of starting and ending conditions.
3) In software with delay routines. These routines use the processor as a counter This
is possible since the processor has a stable clock reference, but it clearly under-util-

izes the processor However, delay routines require no additional hardware and
often use processor time that would othenA/ise be wasted.

The choice among these three methods depends on your applica- CHOOSING
tion. The software method is inexpensive but may overburden the A TIMING
processor. The programmable timers are relatively expensive, but METHOD
are easy to interface and may be able to handle many complex
timing tasks.

DELAY ROUTINES
A simple delay routine works as follows: BASIC
SOFTWARE
Step 1) Load a register with a specified value.
DELAY
Step 2) Decrement the register.

Step 3) if the result of Step 2 is not zero, repeat Step 2.

This routine does nothing except use time. The amount of time used depends upon the
execution time of the various instructions. The maximum length of the delay is limited
by the size of the register; however, the entire routine can be placed mside a similar
routine that uses another register, and so on.

The following example uses Register C and the Accumulator to TRANSPARENT


provide delays as long as 255 ms. The choice of registers is ar- DELAY
bitrary. You may, in fact find the use of a register pair (e.g.. BC) j ROUTINE

more convenient. A PUSH BC instruction at the start of the


delay routine and a POP BC at the end will result in a routine that does not affect any
registers at all. Such a routine is said to be "transparent" to the calling program. Note
that the PUSH and POP instructions must be included in the time budget.

11-8
EXAMPLE
Delay Program Using Accumulator
Purpose: The program provides a delay of 1 ms times the contents of Accumulator.

Flowchart:

f Start
j

Count = MSCNT

±
Count = Count - t

(A) = (A} - 1

The value of MSCNT depends on the speed of the CPU and the memory cycle.

11-9
Source Program:
DELAY: LD CMSCNT GET COUNT FOR 1 MS DELAY
DLY1: DEC C COUNT = COUNT -1

JR NZ.DLY1 CONTINUE UNTIL COUNT = ZERO


DEC A DECREMENT NUMBER OF REMAINING MS
JR NZ.DELAY CONTINUE UNTIL NUMBER OF MS - ZERO
RET
Object Program:

Memory Location Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0030 OE DELAY: LD CMSCNT
0031 MSCNT
0032 OD DLY1: DEC C
0033 20 JR NZ.DLY1
0034 FD
0035 3D DEC A
0036 20 JR NZ.DELAY
0037 F8
0038 C9 RET

Time Budget:

Instruction Number of Times Executed


LD C.MSCNT (A)
DEC C (A) x MSCNT
JR NZ,DLY1 (A) x MSCNT
DEC A (A)
JR NZ,DELAY (A)
RET

The total time used should be (A) x 1 ms. If the memory is operating at full speed, the
instructions require the following numbers of clock cycles.

LD CMSCNT 7
DEC C or DEC A 4
JR NZ 7 or 12
RET 10

The alternative times for JR are for the condition being met (12) or not met (7).

Ignoring the CALL and RET instructions (which occur only once), the program takes:
(A) X (7+16 X MSCNT - 5 + 16) - 5
clock cycles. The -5's are caused by the fact that JR takes less time during the final
Iteration when the condition is not met.

So, to make the delay 1 ms.


13+ 16 X MSCNT = Nc
where Nq is the number of clock cycles per millisecond. At the Z80 DELAY
standard 4 MHz Z80 clock rata N^ = 4000. so: LOOP
16 X MSCNT = 3987 CONSTANT
I
MSCNT = 249 (hex F9) at a Z80 clock rate of 4 MHz]

11-10
SIMPLE I/O DEVICES
THE 280 PARALLEL INPUT/OUTPUT CIRCUIT (PIO)
The keyetennent in mostZSO input/output sections is the Z80 Parallel Input/Output Cir-
cuit or PIO. This devicecombines latches, buffers, flip-flops, and other logic circuits
needed for handshaking and other sinnpte interfacing techniques. The PIO contains
many logic connections, certain sets of which can be selected according to the con-
tents of programmable registers. Thus, the designer has the equivalent of a Circuit
Designer's Casebook under his control. The initialization phase of the program places
the appropriate values into registers to select the required logic connections. An in-
put/output section based on PIOs can handle many different applications, and changes
or corrections can be made in software rather than by rewiring.

Figure 11-7 the block diagram of a PIO. The device contains two nearly identical 8-blt
is

ports — A. which
Is usually an input port and B. which is usually an output port. Each

port (see Figure 11-8) contains:

• An 8-bit Data Output register P!0 REOiSTEBS


• An 8-bit Data Input register AND
• A 2-bit Mode Control register, which indicates whether the
CONTROL LINES
port is in an output input bidirectional, or control mode
• An 8-bit Input/Output Control register, which determines whether the corresponding
data pins are inputs (1} or outputs (0) in the control mode
• Two control lines (STB and RDY) that are configured by the Mode Control register.
These lines can be used for the handshaking signals shown in Figures 1 1 -5 and 1 1 -6.
• A 2-bJt Mask Control register (used only in the control model that determines the ac-
tive polarity of the inputs and whether they will be (ogicaily ORed or ANDed to form
an interrupt signal
• An 8-bit Mask register (used only in the control mode) that determines which port
lines will be monitored to form the interrupt signal
• An 8-btt Vector Address register used with the interrupt system

For now, we
be concerned only with the Mode Control registers, the Input/Output
will
Control registers, and the control lines. We wit! discuss the interrupt-related features of
the PIO in Chapter 12.

The meanings of the bits in the various control and mask registers are related to the un-
derlying hardware and are entirely arbitrary as far as the assembly language program-
mer is concerned. You must either memorize them or look them up In this chapter and
in Chapter 12.

Each PIO occupies four input port addresses and four output port PIO
addresses. The B/A SEL (Port B or A select) and C/D SEL (Control |A0PRESSES
or Data Select) lines choose one of the four ports as described in
Table 11-1. Most often, designers attach address bit Aq to the 8/A SEL input and ad-
dress bit A-j to the C/D SEL input The PIO then occupies four consecutive port ad-
dresses as described in the last column of Table 11-1.

Clearly there are far more internal control registers than there are port addresses for
them. fact all the control registers for each port occupy one address according to the
In
C/D SEL connection. So some of the data bits sent to a control register are actually used
for addressing purposes. Note the following situations (see Table 1 1-2):

Do = means that the remaining data bits are loaded into the Interrupt Vector register.

11-11
? ft Peripheral

Interface

Internal Data or
Control Control

LogfC

77 o Port
I/O
A

Data or

^^
Control

Port B
I/O

interrupt

Control

T
Interrupt

Control Lines

Figure 11-7 PIO Block Diagram


(Courtesy of Ziiog)

11-12
Mode tnput/Output
Control Reg
(2 Bits!
1^ Select
{8 Bits)
Reg

7\
\7

B-Bit
Data Output

^ Reg
(8 Bits}
ihv

"^r
Peripheral

Data or
Control Bus

AZ.

Mask
Mask
C Data Input
Control
Reg
(2 Bits)
Reg
(2 Bitst
Input

Data
Reg
(8 Bits)
cJ
c
Handshake
f Handshake
interrupt Requests -
Control
STROBE /Lines
Logic
^ )

Figure 11-8. Block Diagram of PIO Port


(Courtesy of Zilog)

11-13
Table 11-1. PtO Addresses

CONTROL OR PORT B OR A REGISTER PORT ADDRESS


DATA SELECT SELECT ADDRESSED (STARTING WITH PIOADD)

Data Register A PIOADD


1 Data Register B PIOADD+I
1 Control A PiOADD+2
1 1 Control B PtOADD+3

The port addresses assume that C/D SEL is tied to Ai and B/A SEL to Aq. |

Table 11-2. Addressing of PIO Control Registers

REGISTER ADDRESSING

MODE CONTROL 03 = 02 = 0-! =Do = 1


INPUT/OUTPUT CONTROL NEXT WORD AFTER MODE CONTROL
SETS MODE 3
MASK CONTROL REGISTER ^3 ^ 0' D2 = Di = Do = 1
INTERRUPT MASK REGISTER NEXT WORD AFTER MASK CONTROL
REGISTER ACCESSED WITH D4 = 1
INTERRUPT ENABLE D3 = D2=0, Di =Do = 1

INTERRUPT VECTOR Do = 1

D3 = 0, D2 = D-} = Do = 1 means that the remaining data bits are loaded into the Mask
Control register. If D4- 1. the next control word is loaded into the Interrupt Mask
register. Interrupts can be enabled or disabled with D3 = D2 =0, D-] =Do = 1.

D3 = D2 = Di = Do = means that the remaining data bits are loaded into the Mode
1

Control register. D7 = De - (control mode), the next control word is loaded into the
If 1

Input/Output Control register.

This sharing of an external address means that:

1) The programmer must be very careful of the order of operations. The meaning of a
particular Output instruction depends on the sequence in which it occurs.

2) The programmer should document the PIO configuration in detail. The device is
complex, and a reader is unlikely to be able to make much sense out of the se-
quence of operations that configures it
We should note that one usually configures the control registers of the PIO just once in
the initialization phase of the program. The rest of the program then uses only the PIO
data registers.

11-14
PIO MODE CONTROL
The mode of operation of a PIO Is established by writing a control PIO
word to the PIO in the form shown in Figure 11-1. Table 11-3 de- MODES
scribes the meanings of the various modes and the control words
required to establish them. Note that bits D5 and D4 are not used. When power is
turned on. the PIO comes up in mode 1 (input).

We may summarize the modes as follows:

1) Mode — OUTPUT PIO


Writing data into the port Output register latches the data and OUTPUT
causes it to appear on the port Data Bus. The READY (RDY) MODE
linegoes high to indicate Data Ready; it remains high until the
peripheral sends a rising edge on the STROBE (STB) line to indicate Data Accepted
or Device Ready. The rising edge of STB causes an interrupt if the interrupt has
been enabled.
2) Mode 1 —INPUT
The peripheral latches data into the port Input register using
the STROBE signal. The rising edge of STB causes an interrupt
(ifenabled) and deactivates RDY. When the CPU reads the
data, RDY goes high to indicate Data Accepted or Input Register Empty. Note that
the peripheral can strobe data into the register regardless of the state of RDY. The
programmer must thus handle the problem of overrun, i.e., new data being placed
into the register before the old data is read.

3) Mode 2 —
BIDIRECTIONAL PIO
This mode uses all four handshake ines so it is allowedl ,
BIDIRECTIONAL
only on Port A. The Port A RDY and STB signals are used MODE
for output control and the Port B RDY and STB signals are
used for input control. The only difference between this mode and a combination of
modes and 1 is tha t data from the Port A Output register is enabled onto the port
Data Bus only when A STB s active This allows the Port A bus to be u sed bidirec-
i .

tionaliy under the control of A STB (Output Data Request) and B STB (Input Data
Available). Note that the B side control signals are governed by Input Register A in
this mode.

4) Mode 3 —
CONTROL PIO
Thismode does not use the RDY and STB signals. It is in- CONTROL
tended for status and control applications in which each MODE
bit has an individual meaning. When mode 3 is selected,
PIO
the next control word sent to the PIO defines the directions
DIRECTIONS IN
of the port data bits (Figure 11-9). A 'V in a bit position
CONTROL MODE
makes the corresponding bus line an input while a '0'
makes it an output.

11-15
'

Sat Mode

Ml MO Mode [ Ml MO X X
I I I

Output
When selecting Mode 3, the next word must
t Input
set the !/0 Register:
1 Bidirectional
1 1 Bit Control J/O? !/06 f/Osjl/CMJl/OS l/Ozjf/Oljt/Ool

\/0 " 1 Sets bit to Input

I/O =0 Sets bit to Output

PiO Mode Meaning . Control Word

(Binary) (Hex}

Output 00001111 OF
t Input 01001111 4F
2 Bidirectional 10001111 8F
3 Control 11001111 CF

Note that bits 4 and 5 are not used and could


have any values.

Figure 1 1-9. Mode Control for the Z80 PiO

Note the following features of the PIO modes: FEATURES OF


P\0 MODES
1) Innnodes 0,1. and 2 the peripheral indicates Data Ready,
Dev ice Ready, or Data Accepted with a rising edge on the
STB line. This edge also causes an interrupt if the interrupt is enabled.

2) !n modes 0,1. and 2 the PIO indicates Data Ready. Input Buffer Empty, or Data Ac-
cepted by sending RDY high. This signal remains high until the next rising edge on
STB.
3) Only Port A can be used bidirecttonally. !f Port A is in mode 2 (bidirectional). Port B
can only be in mode 3 (control) since no handshake lines are available.
4) The control mode (3) is the only mode in which the Input/Output Control register is

used. Otherwise, the entire port is used for either input or output

5) There is no way determine if a pulse has occurred on STB if in-


for the processor to
terrupts are not being used. The PIO
is designed for use in interrupt-dnven rather

than polling systems (see Chapter 12). STB should be tied low if it is not being
used.
6) The processor cannot directly control the RDY lines. The RDY line on a port goes
high when data is transferred to or from the port and goes low on the rising edge of
STB.
7) The contents of the data Output
can be read if the port is in the output or
register
bidirectional mode. If the port Is m
the control mode, the output register data from
the lines assigned as outputs can be read. The contents of control registers cannot
be read.

8) If RDY output is tied to the STB input on a port in the output mode, RDY wit! go
the
high for one clock period after each output operation. This brief pulse can be used
to multiplex displays as shown in Figure 11-1.

11-16
CONFIGURING THE PIO
The program must select the iogic connections in the PIO before transferring data to or
from it. This selection (or configuration) is usually part of the startup routine. Note that
the PIO comes up in the input mode with all interrupts disabled and inhibited and con-
trotsignals deactivated (low) when power is turned on. However, the PIO does not have
a RESET Input and does not necessarily return to the reset state when the CPU is reset
The steps in PIO configuration are:
1) Establish the mode of operation by writing the ap- STEPS IN
propriate control words to the Mode Control register. C0NFI6URINQ A
Interrupt control as welt as I/O mode information may PIO
have to be sent
2) If in mode 3, establish the directions of the I/O pins by writing a control word to the
Input/Output Control register. This word must follow the control word that selected
mode 3.

Let us now look at some examples of configuring a PIO without interrupts:


1) OUTPUT PORT
LD A,00001111B ;MAKE PORT B OUTPUT
OUT (PIOCRBl.A

2) INPUT PORT
LD A.01001111B :MAKE PORT A INPUT
OUT (PIOCRA).A

3) BIDIRECTIONAL PORT
LD A.10001111B ;MAKE PORT A BIDIRECTIONAL
OUT (P!OCRA),A

Remember that only Port A can be bidirectional and that Port B must then be a control
port

4) CONTROL PORT. ALL INPUTS


LD A,11001111B :MAKE PORT A CONTROL
OUT (PIOCRA),A
LD A.OFFH :ALL BITS INPUTS
OUT (PIOCRA).A

5) CONTROL PORT. ALL OUTPUTS


LD A.11001111B :MAKEPORTB CONTROL
OUT (PIOCRB).A
SUB A :ALL BITS OUTPUTS
OUT (P!OCRB),A

6) CONTROL PORT. LINES 1.5,6 INPUTS; LINES 0,2,3.4.7 OUTPUTS


LD A.1 1001 1 11B :MAKE PORT A CONTROL
OUT (PIOCRA).A
LD A,01100010B ;LINES 1.5,6. INPUTS —0,2,3.4,7 OUTPUTS
OUT (PIOCRA).A

11-17
Z80 INPUT/OUTPUT iNSTRUCTIONS
The Z80 microprocessor has an extensive set of Input/Output Z80 I/O
instructions. Ait 1/0 instructions use 8-bit device addresses, INSTRUCTIONS
thus allowing up to 256 input ports and 256 output ports. But
remember that each PIO occupies four output port addresses and four input port ad-
dresses.

The I/O instructions can be grouped as follows:

1) Instructions that use absolute addressing. IN A,{portl and OUT (port),A transfer
eight bits of data between the Accumulator and the port addressed by the second
byte of the instruction.
2) Single-byte instructions that use register indirect addressing. IN reg,(C) and OUT
(O.reg transfer eight bits of data between the specified register and the port ad-
dressed by Register C.
3) Block i/O instructions. INI and OUTI transfer eight bits of data between the memory
location addressed by Register Pair HL and the port addressed by Register C. Both
instructions then increment Register Pair HL and decrement the byte counter in
Register B. The Z flag is set if B is decremented to zero and reset otherwise. IND and
OUTD are the same instructions except that they decrement Register Pair HL in-
stead of incrementing it

4) Repeated. Block I/O instructions. INIR and OTIR repeat the effects of INI and OUTI,
respectively, until B is decremented to zero. INDR and OTDR have the same rela-
tionship to IND and OUTD.
You should note the following features of each group of instructions:

1) instructions with absolute addressing. I/O


INSTRUCTIONS
• Data is always transferred to or from the Accumulator.
WITH ABSOLUTE
• No flags are affected. ADDRESSIN6
• The port address is part of the program memory and
cannot be changed if that memory is read-only.

2) Singte-byte instructions with register indirect addressing. I/O


INSTRUCTIONS
• Data can be transferred to or from any of the primary 8-
WITH INDIRECT
bit registers {A.B,C.D,E,H,L). However, remember that
ADDRESSING
Register C contains the port address.

• IN reg,(C) sets the Sign (S), Zero (Z), and Parity {P/O}
flags according to the value of the input data. The Carry flag (C) is not modified,
but the Half Carry (H) and Negative (N) flags are reset. OUT (C).reg does not
affect any flags.

• The port address is always in Register C. This address is not | I/O PRIviRj
part of the program memory and could be a parameter for
an I/O subroutine (or I/O driver!. One I/O driver could thus be used in several
different applications or with several similar 1/0 devices in the same application.

11-18
3) Block I/O instructions. BLOCK t/0
• Data is always transferred to or from the memorv location
INSTRUCTIONS
addressed by Register Pair HL
• The Z (Zero) flag is set if Register B is decremented to zero and cleared other-
wise. The S (Sign), P/0 (Panty), and H (Half Carry) flags are affected, but their
final values are uncertain.
• The port address Is always in Register C. Here again, this address coutd be a
parameter for an I/O driver.

• Register B an 8-bit counter. Thus, the repeated Block I/O instructions can
is

transfer a maximum
of 256 bytes. This differs from the Block Move and Block
Compare instructions, which use Register Pair BC as a 16-bit counter and can
handle up to 65K bytes.

Some examples of the various I/O instructions (without any I/O


timing considerations) are: INSTRUCTION
1) Load the Accumulator from Input Port 2.
EXAMPLES
a. Using absolute addressing
IN A, (2)

b. Using register indirect addressing


LD C,2
IN A,(C)

2) Store the contents of the Accumulator in Output Port 5.

a. Using absolute addressing


OUT (5}.A

b. Using register indirect addressing


LD C,5
OUT (C),A

3) Load memory location 0040 from Input Port 2.

a. Using absolute addressing


IN A,(2) ;GETDATA
LD (40H).A STORE DATA
;

b. Using register indirect addressing


LD C,2 :GET PORT NUMBER
IN A,(C) ;GET DATA
LD (40H),A :STORE DATA
c. Using block I/O
LD C.2 ;GET PORT NUMBER
LD HL,40H :GET MEMORY DESTINATION
INI ;GET DATA

11-19
4) Store the contents of memory location 0040 in Output r^ort 5.

a. Using absolute addressing


LD A,{40H) :GETDATA
OUT (5).A :SEND DATA

b. Using register indirect addressing


LD C,5 ;GET PORT NUMBER
LD A,(40H) : GET DATA
OUT (C),A

Using block I/O


LD C.5 :GET PORT NUMBER
LD HU40H ;GET MEMORY SOURCE
OUT! :SEND DATA
5) Load memory locations 0040 through 0047 from input Port 2.

a. Using absolute addressing


LD HL40H ;GET STARTING ADDRESS OF DATA
LD B.8 ;BYTE COUNTER =8
INBYTE; IN A. (2) ;FETCH DATA BYTE
LD (HU.A ;STORE BYTE IN MEMORY
INC HL
DJNZ INBYTE
b. Using block I/O
LD HL,40H GET STARTING ADDRESS OF DATA
LD B,8 BYTE COUNTER = 8
LD C2 GET PORT NUMBER
INBYTE: INI
JR NZJNBYTE
c. Using repeated block I/O
LD HL40H GET STARTING ADDRESS OF DATA
LD B,8 BYTE COUNTER = 8
LD C,2 GET PORT NUMBER
!NIR MOVE INPUT BYTES TO MEMORY

11-20
6) Send the contents of memory locations 0040 through 0047 to Output Port 5.

a. Using absolute addressing


LD HL40H :GET STARTING ADDRESS OF DATA
LD B,8 :GET BYTE COUNTER
OTBYTE; LD A,{HL) ; FETCH BYTE FROM MEMORY
OUT (5),A : OUTPUT BYTE
INC HL
DJNZ OTBYTE
b. Using block I/O
LD HL,40H GET STARTING ADDRESS OF DATA
LD B,8 GET BYTE COUNTER
LD 0,5 GET PORT NUMBER
OTBYTE: OUTl OUTPUT BYTE FROM MEMORY
JR NZ.OTB>
c. Using repeated block I/O
LD HL.40H :GET STARTING ADDRESS OF DATA
LD B.8 ;GET BYTE COUNTER
LD C,5 ;GET PORT NUMBER
OTIR :OUTPUT BYTES FROM MEMORY
Note that the repeated Block I/O instructions operate con- USING BLOCK
tinuously. You cannot provide any timing between I/O INSTRUCTIONS
transfers. Thus, these instructions cannot be used unless
the peripheral operates at the same speed as the processor or timing is handled sepa-
rately in hardware. Ways to handle timing in hardware include forcing the processor
into Wait states or buffering the data. Note that the Block I/O instructions all p(ace the
contents of the byte counter (Register 8) on the top half of the Address Bus during the
actual I/O transfer. In output operations. Register B is decremented first. The byte
counter value is then available to external circuitry.

An obvious application for Block I/O instructions is the configuration of PtOs. Several
words must often be sent to a control register to determine operating mode, select pin
directions, and establish the interrupt system. No timing problems occur, since PtOs
operate at the same speed as the CPU. We will discuss the configuration of Z80 PIOs
and serial interfaces (SIOsl with Block I/O instructions later in this chapter and in
Chapter 12.
In subsequent I/O examples, we will use mainly the instructions with absolute address-
ing. You can easily substitute the instructions with register indirect addressing as long
as you remember to initialize Register C. We will occasionally indicate applications for
the Block I/O instructions.

11-21
+ 5V
o

^
""-lo

Figure 11-10. A Pushbutton Circuit

EXAMPLES
A Pushbutton Switch
Purpose: To interface a single pushbutton switch (or a single-pole, single-throw (SPST)
switch) to a Z80 microprocessor, The pushbutton is a mechanical switch that
provides a smgle contact closure (i.e., a logic zero) while pressed.

Circuit Diagram:

Figure 11-10 shows the (t uses one bit of


circuitry required to interface the pushbutton,
a Z80 PIO that acts as a buffer; needed, since the pushbutton remains
no latch is

closed for many CPU clock cycles. Pressing the button grounds the PIO input bit The
puliup resistor ensures that the input bit is one if the button is not being pressed.

Programming Examples:
We will perform two tasks with this circuit They are:

a) Set amemory location based on the state of the button.


b) Count the number of times that the button is pressed.

Task 1: Determine switch closure.

Purpose: Set memory location 0040 to one if the button is not being pressed, and to
zero if it is being pressed.

Sample Cases:
1) Button open (i.e., not pressed)

Result = (0040) =01


2) Button closed (i.e., pressed)

Result = (0040) =00

11-22
Flowchart:

c Start
:>

(0040) =

input and mask


pushbutton
data

i0040) = 1

f End
J

Source Program:
LD A,01001111B ;MAKE PORT A iNPUT
OUT (PIOCRA).A
LD HL,40H ;MARKER=0
LD {HL),0
!N A.(P!ODRA) READ BUTTON POSITION
AND MASK IS BUTTON CLOSED (0)?
JR Z.DONE YES, DONE
!NC (HU NO, MARKER = 1

DONE; HALT

11-23
Object Program:

Memory Contents instruction


Memory Locatron
(Hex) (Hex) (Mnemonic)

0000 3E LD A.01001111B
0001 4F
0002 D3 OUT (PiOCRA),A
0003 PIOCRA
0004 2-1 LD HL40H
0005 40
0006 00
0007 36 LD (HL),0

0008 00
0009 DB IN A, (PIODRA)

OOOA PIODRA
0008 E6 AND MASK
OOOC MASK
GOOD 28 JR Z,DONE
OOOE 01
OOOF 34 INC (HL)

0010 76 HALT

The port addresses PIOCRA and PIODRA depend on how the PIO is
connected in your
microcomputer. The PiO control lines are not used in this example. In fact we
could

place the A side of the PIO in the control mode with the starting sequence:

LD A,110011 lis :MAKE PORT A CONTROL


OUT (PIOCRA).A
LD A.OFFH ;ALL BITS INPUTS
OUT (P!OCRA).A

MASK depends on the bit to which the pushbutton Is connected; ft has a one m the

button position and zeros elsewhere.

Button Position Mask 1

(Bit Number) Binary Hex

00000001 01
1 00000010 02
2 00000100 04
3 00001000 08
4 00010000 10
5 00100000 20
6 01000000 40
7 10000000 80

If the button is attached to bit or bit 7 of the input port the program can use a Shift
instruction to set the Carry and thereby determine the button's state. For example.

Bit 7
IN A. (PIODRA) :READ BUTTON POSITION
RLA :IS BUTTON CLOSED (ZERO)?
JR NCDONE ;YES. DONE
BitO
IN A, (PIODRA) :READ BUTTON POSITION
RRA :IS BUTTON CLOSED (ZERO)?
JR NCDONE :YES. DONE

11-24
The procedure for bit 7 is even simpler if we have the address of the PIO data register in
Register C. This is because the input instructions using register indirect addressing
(e.g., IN A,(C)) affect the Sign flag. The required sequence is:

Bit 7 (PIODRA in Register C)


iN A,(C) ;READ BUTTON POSITION
JP P.DONE ;DONE IF BUTTON CLOSED (ZERO)
If the button is attached to bits 6 or
7 of the input port the program can use the Sign bit
to determine the button's state. For example.

Bit 7
IN A.(PIODRA) ;READ BUTTON POSITION
AND A :IS BUTTON CLOSED (ZERO)?
JP P.DONE ;YES. DONE
IN A,(port} does not affect the flags; therefore, we must use the AND A instruction to
set the flags without changing the Accumulator.

Bite
IN A,(PIODRA) :READ BUTTON POSITION
ADD A.A :IS SUTTON CLOSED (ZERO)?
JP P.DONE :YES, DONE
RLA cannot be used because it does not affect the Sign bit.

11-25
Task 2: Count switch closures.
iocation 0040
Purpose: Count the number of button closures by mcrementmg memon/
after each closure.

Sample Case:
give
Pressing the button ten times after the start of the program shouid
(0040) - OA
Note: in order to count the number of times that the button has
SWITCH
been pressed, we must be sure that each closure causes a single
BOUNCE
transition. However, a mechanical pushbutton does not
produce a
single transition for each closure, because the mechanical contacts
bounce back and
forth before settling into their final positions. We can use
a one-shot to eliminate the

bounce or we can handle it m software.

The program can debounce the pushbutton by watting after it DEBOUNCINQ


finds a closure. The required delay is called the debouncing
IN SOFTWARE
time and is part of the specifications of the pushbutton. It is

typically afew milliseconds long. The program should not examine the pushbutton dur-
ing this period, because it might mistake the bounces for new closures. The program
may either enter a delay routine like the one described previously or may simply per-
form other tasks for the specified amount of time.

Even debouncing, the program must still wait for the present closure to end before
after
looking for a new closure. This procedure avoids double counting.
The following pro-
gram uses a software delay of 1 ms to debounce the pushbutton. You may want to try
this program,
varying the delay or eliminating it entirely to see what happens. To run
must enter the delay subroutine into memon/ starting at location 0030.
you also

Flowchart:

Count = Count + 1

Debounce button
with 1 ms wait

11-26
A

5 Program:
LD A.01001111B :MAKE PORT A INPUT
OUT (PIOCRA),A
LD HL40H
LD (HU.O CLOSURE COUNT = ZERO
: IN A,(PIODRA) READ BUTTON POSITION
AND MASK IS BUTTON BEING PRESSED (0)?
JR NZ,CHKCL NO, WAIT UNTIL IT IS
!NC (HU YES. INCREMENT CLOSURE COUNT
CALL DELAY ;WAIT 1 MS TO DEBOUNCE
: m A,(P!ODRA) READ BUTTON POSITION
AND MASK IS BUTTON STILL BEING PRESSED (0)?
JR Z,CHKOP YES. WAIT FOR RELEASE
JR CHKCL NO, LOOK FOR NEXT CLOSURE
Object Program:

Memory Location Memorv Contents instruction


(Hex) (Hex) (Mnennonic)
0000 3E LD A.01001111B
0001 4F
0002 D3 OUT (P!OCRA),A
0003 PIOCRA
0004 21 LD HL40H
0005 40
0006 00
0007 36 LD (HU.O
0008 00
0009 DB CHKCL; IN A, (PIODRA)
OOOA PIODRA
OOOB E6 AND MASK
OOOC MASK
OOOD 20 JR NZ,CHKCL
OOOE FA
OOOF 34 INC (HL)
0010 CD CALL DELAY
0011 30
0012 00
0013 DB CHKOP: IN A,(PIODRA)
0014 PIODRA
0015 E6 AND MASK
0016 MASK
0017 28 JR Z,CHKOP
0018 FA
0019 18 JR CHKCL
001 EE

The three instructions beginning with the label CHKOP are used to determine when the
switch reopens.

Clearly we do not really need a PIO for this simple interface. An addressable tri-state
buffer would do the job at far lower cost

11-27
A Toggle Switch
switch to a Z80
Purpose: To interface a single-poia double-throw (SPOT) toggle
microprocessor. The toggle is a mechanical device that is either m
the nor-

mally closed (NO position or the normally open (NO) position.

Circuit Diagram:

Figure 11-11 shows the circuitry required to interface the


DEBOUNCING
switch. Like the pushbutton, the switch uses one bit of a Z80
WITH
PiO that serves as an addressable buffer. Unlike the button, the
CROSS-COUPLED
switch may be left in either position. Typical program tasks are
NAND GATES
position has
to determine the switch position and to see if the
or a pair of cross-
changed. Either a one-shot with a pulse length of a few miiiiseconds
coupled NAND gates (see Figure 11-12) can debounce a mechanical
switch.

The circuits will produce a single step or pulse in response to a change in switch posi-
tion even if the switch bounces before settling into its new position.

Programming Examples:
We will perform two tasks involving this circuit. They are:

1) Set a memory location to one when the switch is closed.

2) Set a memory location to one when the state of the switch changes.

Task 1: Wait for switch to close.

Purpose: Memory location 0040 is zero until the switch is closed and then is set to

one; that the processor clears memory location 0040. waits for the switch
is.

to be closed, and then sets memory location 0040 to one.

The switch could be marked Run/HiE since the processor will not proceed until the
switch is closed.

Flowchart:

C )
^T*

(0040) =

11-28
Debounce
Circuit

Figure 11-11. A Toggle Switch Circuit

Figure 11-12. A Debounce Circuit Based on Cross-coupled NAND Gates

11-29
Source Program:
LD A,01001111B :MAKE PORT A INPUT
OUT (PIOCRA).A
LD HL40H
LD (HU,0 MARKER = ZERO
WAITC: !N A.(PiOORA) READ SWITCH POSITION
AND MASK IS SWITCH CLOSED (ZERO)?

JR NZ,WA1TC NO, WAIT FOR SWITCH TO CLOSE


INC (HU YES. MARKER = 1

HALT
Object Program:

Memorv Location Memory Contents Instruction |

(Hex) (Hex) (Mnemonic)

0000 3E LD A.010011118
0001 4F
0002 D3 OUT (PIOCRA),A
0003 PIOCRA
0004 21 LD HL40H
0005 40
0006 00
0007 36 LD (HL),0

0008 00
0009 DB WAITC: iN A.(P!ODRA)
OOOA PIODRA
OOOB E6 AND MASK
OOOC MASK
OOOD 20 JR NZ,WAITC
OOOE FA
OOOF 34 INC (HL)

0010 76 HALT

11-30
Task 2: Wait for switch to change.

Purpose: Memory location 0040 remains zero until the switch position changes; i.e.,

the processor waits until the switch changes, then sets memory location
0040 to 1.

Flowchart:

c J
(40)=

c J
Source Program:
ID A,01001111B :MAKE PORT A INPUT
OUT (PIOCRAi.A
LD HL,40H
ID (HU.O ;MARKER-ZERO
!N A.(PIODRA) :GET OLD SWITCH POSITION
AND MASK
LD B.A
SRCH: m A,(P!ODRA| :GET NEW SWITCH POSITION
AND MASK
CP B ;ARE NEW AND OLD POSITIONS THE SAME?
JR Z,SRCH ;YES, WAIT
!NC (HU :N0, MARKER = ONE
HALT

11-31
Object Program:
Memory Location Memory Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 3E LD A,01001111B
0001 4F
0002 D3 OUT (PIOCRA),A
0003 PIOCRA
0004 21 LD HL40H
0005 40
0006 00
0007 DB IN A,(PIODRA)
0008 PIODRA
0009 E6 AND MASK
OOOA MASK
OOOB 47 LD 8,A
OOOC DB SRCH: IN A. (PIODRA)

GOOD PIODRA
OOOE E6 AND MASK
OOOF MASK
0010 B8 CP 8
0011 28 JR Z.SRCH
0012 F9
0013 34 INC (HU
0014 76 HALT

A Subtract or Exclusive OR coutd replace the Compare in the program. Either of these
instructions would, however, change the contents of the Accumulator. The Exclusive
OR would be useful if several switches were attached to the same PiO. since it would
produce a one bit for each switch that changed state. How would you rewrite this pro-

gram so as to debounce the switch in software?

11-32
o-
^
o

Figure 11-13. A Multiple-Position Switch

A Multiple-Position (Rotary, Selector, or Thumbwheel) Switch


Purpose: To interface a nnultipie-position switch tea microprocessor. The
lead corres-
ponding to the switch position is grounded, while the other leads are high
(logic ones).

Circuit Diagram:

Figure 11-13 shows the circuitrv required to interface an 8-position switch. The switch
uses alt eight data bits of one side of a P!0. Typical tasks are to determine
the position
of the switch and to check whether or not that position has changed. Two special situa-
tions must be handled:
1) The switch is temporarily between positions so that no leads are grounded.
2) The switch has not yet reached its final position.

The these situations can be handled by watting until the input is not all ones, i.e..
first of

until a switch lead is grounded. We


can handle the second situation by examining the
switch again after a delay (such as 1 or 2 seconds) and only accepting
the input when
It remains the same. This delay will
not affect the responsiveness of the system to the
switch. We
can also use another switch (i.e., a Load switch) to tell the processor when
the selector switch should be read.

Programming Examples:
We will perform two tasks involving the circuit of Figure 11-13. These are:
a) Monitor the switch until in a
definite position, then determine the position
it is
and
store Its binary value in a memory location.
b) Walt for the position of the switch to change, then store the new position in a
memory location.

If the switch IS in a position, the lead from that position is


grounded through the com-
mon line, Pullup resistors on the input lines avoid problems caused by
noise.

11-33
Table 11-3, Data Input vs. Switch Position

Data Input |

Switch Position Hex


Binary

11111110 FE
1 11111101 FD
2 11111011 FB
3 11110111 F7
4 11101111 EF
5 11011111 DF
6 10111111 BF
7 01111111 7F

Task 1: Determine switch position.

Purpose: The program waits for the switch to be m a specific position and then places

the number of that position into memory location 0040.

Table 11-3 contains the data inputs corresponding to the various switch positions.

This scheme is inefficient since it requires eight bits to distinguish among eight

different positions.

A TTL or MOS encoder could reduce the number of bits needed. USING
Figure 11-14 shows a circuit using the 74LS148 TTL 8-to-3 en- A TTL
coder."^ We
attach the switch outputs in inverse order, since the ENCODER
74LS148 device has active-low inputs and outputs. The output of
the encoder circuit is a 3-bit representation of the switch position. Many switches
in-

clude encoders so that their outputs are coded, usually as a BCD digit (in negative
logic).

The encoder produces active-low outputs, so. for example, switch position 5, which is
attached to input produces an output of 2 in negative logic (or 5 in positive logic).
2.

You may want to verify the double negative for yourself.

Oi

741S148
8-to-3
Encoder Ao

Figure 11-14. A Multiple-Position Switch with an Encoder

11-34
Flowchart:

r Start I

Data =
switch position

Position =
ftj^tton + 1
(0040) = Position

C J
Source Program:
LD A.01001 1 1 1 B ;MAKE PORT A INPUT
OUT (PIOCRA).A
CHKSW: IN A,(PIODRA) GET SWITCH DATA
CP OFFH IS SWITCH IN A POSITION?
JR Z.CHKSW NO. WAIT FOR A POSITION
LD B,0 SWITCH POSITION - ZERO
CHPOS: RRA IS NEXT BIT GROUNDED POSITION?
JR NC.DONE YES. SWITCH POSITION FOUND
INC B NO. INCREMENT SWITCH POSITION
JR CHPOS
DONE; LD HL40H ;STORE SWITCH POSITION
LD (HL),B
HALT

11-35
Object Program:
Memory Contents Instruction
Memory Location
(Hex) (Hex) (Mnemonic)

0000 3E LD A.01001111B
0001 4F
0002 D3 OUT (PIOCRA).A
0003 PtOCRA
0004 D8 CHKSW: IN A,(PIODRA)
0005 PIODRA
0006 FE CP OFFH
0007 FF
0008 28 JR Z.CHKSW
0009 FA
OOOA 06 LD B.O
0008 00
OOOC 1F CHPOS; RRA
OOOD 30 JR NC.DONE
OOOE 03
OOOF 04 INC B
0010 18 JR CHPOS
0011 FA
0012 21 DONE: LD HL,40H
0013 40
0014 00
0015 70 LD (HL).B

0016 76 HALT

that a faulty switch or defective PiO results in the input


always being OFFie-
Suppose
could you change the program so that it would detect this
error?
How
There is an unconditional jump, JR CHPOS, in the source program. Can you change the
initial conditions so as to make this instruction unnecessary?

This example assumes that the switch is debounced in hardware.


How would you
change the program to debounce the switch in software?

11-36
Task 2: Wait for switch position to change.

Purpose: The program waits for the switch position to change and piaces the new
position (decoded) tnto memory location 0040. The program waits until the
switch reaches its new position.

Flowchart:

f Start
J

Okl data =
Switch position

Shift data right 1 bit

New data = Position =

Switch position

{0040} = Position

C D

11-37
Source Program:
LD A,01001111B ;MAKE PORT A INPUT
OUT (PIOCRA),A
CHFST; IN A.(P10DRA) GET SWITCH DATA
CP OFFH IS SWITCH IN A POSITION?
JR Z,CHFST NO, WAIT UNTIL IT IS
LD B.A
CHSEC: IN A,(PIODRA} GET NEW SWITCH DATA
CP OFFH IS SWITCH IN A POSITION?
JR Z.CHSEC NO, WAIT UNTIL IT IS
CP B IS POSITION SAME AS BEFORE?

JR Z,CHSEC YES, WAIT FOR IT TO CHANGE


LD B.OFFH SWITCH POSITION =-1
CHPOS. INC B INCREMENT SWITCH POSITION
RRA IS NEXT BIT GROUNDED POSITION?

JR C.CHPOS NO, KEEP LOOKING FOR GROUNDED POSITION


LD HL40H STORE SWITCH POSITION
LD (HU.B
HALT

11-38
A
D
C
B
E

Object Program:

Memory Location Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A.01001111B
0001 4F
0002 D3 OUT (P!OCRA),A
0003 PIOCRA
0004 DB CHFST; IN A,(PIODRA)
0005 PIODRA
0006 FE CP OFFH
0007 FF
0008 28 JR ZXHFST
0009 FA
OOOA 47 LD B,A
0*008 DB CHSEC; IN A.(PIODRA)
OOOC PIODRA
OOOD FE CP OFFH
OOOE FF
OOOF 28 JR Z.CHSEC
0010 FA
0011 88 CP B
0012 28 JR Z.CHSEC
0013 F7
0014 06 LD B.OFFH
0015 FF
0016 04 CHPOS: INC 8
0017 IF RRA
0018 38 JR CCHPOS
0019 FC
001 21 LD HL.40H
001 40
001 00
001 70 LD (HL),B
001 76 HALT

An alternative method for determining If the switch is in a position is:

CHKSW: IN A.(PIODRA)
!NC A
JR Z,CHKSW
Why does this work? What happens to the input data?

11-39
A Single LED
Purpose: To interface a single light-emitting diode to a Z80 microprocessor. The LED
can be attached so that either a logic zero or a logic one turns it on.

Circuit Diagram:

Figure 11-15 shows the circuitry required to interface an LED. The LED
LED lights whenits anode Is positive with respect to its cathode CONTROL
(Figure 11-1 5a). Therefore, vou can either light the LED by ground-
11 -15b) or
ing the cathode and having the computer supply a one to the anode (Figure
by connecting the anode to +5 volts and having the computer supply a zero to the
cathode (Figure 1 1-1 5c). Using the cathode is the most common approach. The LED is
brightest when it operates from pulsed currents of about 10 or 50 mA applied a few
hundred times per second. LEDs have a very short turn-on time (in the microsecond
range) so they are well suited to multiplexing (operating several from a single port). LED
circuits usually need peripheral or transistor drivers and current-limiting resistors. MOS
devices normally cannot drive LEDs directly and make them bright enough for easy
viewing.

Note: The PIO has an output latch on each port However, the B port is normally used
for output, since it has somewhat more drive capability. In particular, the 8 port outputs
are capable of driving Darlington transistors (providing 1.5 mA minimum at 1.5 V).
Darlington transistors are high-gam transistors capable of switching targe amounts of
current at high speed; they are useful in driving solenoids, relays, and other devices.

Task: Turn the light on or off.

Purpose: The program turns a single LED either on or off.

A. Send a Logic One to the LED (turn a positive display on or a negative display off).

Source Program:
(form data initially)

LD A.00001111B :MAKE PORT B OUTPUT


OUT (PIOCRB),A
LD A.MASKP :GET DATA FOR LED
OUT (PIODRB),A ;SEND DATA TO LED
HALT
An alternative using the control mode is:
LD A.1 1001 1118 :MAKE PORT B CONTROL
OUT (PIOCRB),A
SUB A :MAKE ALL B LINES OUTPUTS
OUT (PIOCRB),A
LD A.MASKP :GETDATA FOR LED
OUT (PIODRB),A :SEND DATA TO LED
HALT
(update data)
IN A,(P10DRBI GET OLD DATA
SET LED.A TURN ON LED BIT
OUT (PIODRB),A SEND DATA TO LED
HALT
MASKP has a one bit in the LED position and zeros elsewhere. Note that we can read
the PIO Data Output register when the PIO is in the output mode. We can also read any

combination of input data and output register data when the PIO is In the control
mode; the combination is defined by the assignment of inputs and outputs.

11-40
Anode -^^Cathode
^5VO- -VSAh-

a) Basic LED orcuitrv. The ressstor R should limit the maxtmum current to 50 mA and
the average current to 10 mA.

C=> —^ (g) I

b) Interfacing an LED with positive logic. A logic T from the CPU turns the LED on.

?•'

i=> #-J

ci interfacing an LED with negative logic. A logic '0'


from the CPU turns the LED on. The driver or the CPU
may invert the logic levels.

Figure 11-15. Interfacing an LED

11-41
Object Program:

Memory location Memory Contents Instruction


(Hex) (Hex) (Mnemonic)

(form data initially)

0000 3E LD A,00001111B
0001 OF
0002 D3 OUT (PIOCRB),A
0003 PIOCRB
0004 3E LD A.MASKP
0005 MASKP
0006 D3 OUT (PIODRB),A
0007 PIODRB
0008 76 HALT
(update datal
0009 DB IN A, (PIODRB)
OOOA PIODRB
OOOB CB SET LED.A
OOOC LED
OOOD 03 OUT (PIODRB),A
OOOE PIODRB
OOOF 76 HALT

Send a Logic Zero to the LED (turn a positive display off or a negative display on).

The differences are that MASKP logical complement


must be replaced by its

MASKN and SET LED.A must be replaced by RES LED.A. Note that the second byte
of the object code for SET LED.A and RES LED.A depends on the actual bit position
to which the name LED refers.

MASKN has a zero bit in the LED position and ones elsewhere.

11-42
^ g

B5 ^ f

„ Mn^
From. CPU 84

PIO 83 ^ Dnvers ci Display

B2

^b
Bo Common

i 1

"S" + 5V
{Common- (Common-
87 may be used for decimal posnt LED. Cathode) Anode}

Figure 11-16. interfacing a Seven-Segment Display

Seven-Segment LED Display


Purpose: To interface a seven-segment LED display to a Z80 microprocessor. The dis-
play may be either common-anode (negative logic) or common-cathode
(positive logic}.

Circuit Diagram:

Figure 11-16 shows the circuitry required to interface a COMMOiM-ANODE


seven-segment display. Each segment may have one, two, OR
or more LEDs attached in the same way. There are two COMMON-CATHODE
ways of connecting the displays. One is tying all the DISPLAYS
cathodes together to ground (see Figure 11-17a); this is a
"common-cathode" display. Tying all the anodes together to a positive voltage supply
(see Figure 1 1-1 7b) is a "common-anode" display, and a logic zero at a cathode lights a
segment So the common-cathode display uses positive logic and the common-anode
display negative logic Either display requires appropriate dnvers and resistors.

The Common line from the display is tied either to ground or to +5 volts. The display
segments are customarily labelled:

11-43
a) Common-cathode

g O AAAf #
f

eO
O ^AA^

AAA^—
^
—^•H-

c o 'VAA*-

bo —WSr-

b) Common-anode + 5V

g O ^ ^^r^

fO ^AAr-

eO ^^r-

dO ^AAr-

cO W\r
bO 'WAr-

a o——^-^— AAAr-
^8^
Figure 11-17. Seven-Segment Display Organization

11-44
Table 11-4. Seven-Segment Representations of Decima! Nunnbers

Hexadecimal Representation ]
Nunnber
Common-cathode Common-anode
3F 40
1 06 79
2 5B 24
3 4F 30
4 66 19
5 6D 12
6 7D 02
7 07 78
8 7F 00
9 67 18

Bit 7 is always zero and the others are g, f. a d, a b, and a in decreasing order of
significance.

Note: The seven-segment display is wrdejy used because it SEVEN-SEGMENT


contains the smallest number of separately controlled seg- REPRESENTATIONS
ments that can provide recognizable representations of all
the decimal digits (see Figure 11-18 and Table 11-4). Seven-segment displays can also
produce some letters and other characters (see Table 11-6). Better representations re-
quire a substantially larger number of segments and more circuitry.^ Since seven-seg-
ment displays are so popular, low-cost seven-segment decoder/drivers have become
widely available. The most popular devices are the 7447 common-anode driver and the
7448 common-cathode driver^: these devices have Lamp Test inputs (that turn all the
segments on) and blanking inputs and outputs (for blanking leading or trailing zeros).

11-45
0: Segments f, e, d, c, b. a on 3: Segments g, d, c, b, a on

1: Segments c, b on 4: Segments g, f, c, b on

2: Segments g, e, d, b, a cm 5: Segments g, f, d, c, a on

Figure 11-18. Seven-Segment Representations of Decimal Digits

11-46
6: Segments g, f. e, d, c, 3 on 8; Segments g. f, e. d, c, b, a on

a a

f f b

9 9

e c e c

d d
Note that the alternate representation with a^off may This Is the same as LAMP TEST.
l>e rewrved for the lower case letter 'b'.

7: Segments c, b, a on 9: Segments g, f, c, b, a on
a a

b f b

c c

An alternate has segment d on also.

Figure 11-18. Seven-Segment Representations of Decimat Digits


(Continued)

11-47
Table 11-5. Seven-Segment Representations of Letters and Symbols

Upper-case Letters

Hexadecimal Representation J
Letter
Common-cathode Common-anode
A 77 08
C 39 46
E 79 06
F 71 OE
H 76 09
i 06 79
J 1E 61
L 38 47
3F 40
P 73 OC
U 3E 41
Y 66 19

Lower-case Letters and Special Characters

Hexadecima! Representation |
Character
Common-cathode Common-anode
b 7C 03
c 58 27
d 5E 21
h 74 OB
n 54 2B
5C 23
r 50 2F
u 1C 63
40 3F
? 53 2C

11-48
Task 1: Display a decimal digit
Purpose: Display the contents of memory location 0040 on a seven-segment display if

it contains a decimal digit Otherwise, blank


the display.
Sample Problems:
a, (0040) - 05
Result is 5 on display
b. (0040) = 66
Result is a blank display

Flowchart:

c J
Code = Blank
Daia = (0040}

Code ~ (SSEG
Data)

Send oKle
to display

11-49
Source Program
LD A.000011118 ;MAKE PORT B OUTPUT
OUT {PIOCRB},A
LD B.BLANK :GET BLANK CODE
LD A,(40H) :GET DATA
CP 10 ;{S DATA A DECIMAL DIGIT?

JR NCDSPLY ;N0, DISPLAY BLANKS


LD DE,SSEG :GET BASE ADDRESS OF SEVEN-SEGMENT
; TABLE
LD H.O :MAKE DATA INTO 16-BlT INDEX
LD LA
ADD HLDE ;ACCESS ELEMENT IN TABLE
LD B,(HL) :GET SEVEN-SEGMENT CODE
DSPLY: LD A.B
OUT (PIODRB).A :SEND CODE TO DISPLAY
HALT
BLANK is 00 for acommon-cathode display. FF for a common-anode display. An alter-
native procedure would be to put the blank code at the end of the table and replace all
improper data values with 10. i.e..

LD A,(40H) GET DATA


CP 10 IS DATA A DECIMAL DIGIT?
JR CCNVRT YES. CONVERT DIRECTLY TO SEVEN-SEGMENT
LD A,10 NO, GET INDEX FOR BLANK CODE
CNVRT: LD DESSEG
DE.SSEG :GET BASE ADDRESS OF SEVEN-SEGMENT TABLE

Table SSEG is either the common-cathode or common-anode representation of the


decimal digits from Table 11-4. r

11-50
Object Program:

Memory Location Memorv Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A.00001111B
0001 OF
0002 D3 OUT (PIOCRB).A
0003 PtOCRB
0004 06 LD B.BLANK
0005 BLANK
0006 3A LD A,(40HI
0007 40
0008 00
0009 FE CP 10
OOOA OA
OOOB 30 JR NCDSPLY
OOOC 08
GOOD 11 LD DE.SSEG
OOOE 20
OOOF 00
0010 26 LD H.O
0011 00
0012 6F LD LA
0013 19 ADD HLDE
0014 46 LD B.(HU
0015 78 DSPLY: LD A.B
0016 D3 OUT (P!ODRB),A
0017 PIODRB
0018 76 HALT
0020-0029 SSEG; (seven-segment code |

table)

Several displays may be multiplexed, as shown in Figure 11-19. A brief strobe on the B
RDY lineclocks the co unter and directs data to the next display. Note that B RDY is tied
directly back to B STB, i.e.. the ready line essentially provides its own acknowledgment.
The timing of the PIO is such that this connection results in a strobe with a duration of
one clock period. Such a brief strobe is exactly what the counter requires. RESET starts
the decimal counter at nine so that the first output operation clears the counter and
directs data to the first display.

The following program uses the delay routine to pulse each of ten common-cathode
displays for 1 ms.

11-51
D. C. B, and A |D most stgnificant. A
least significant} are the 4-bit output

from the counter. These 4 bits actrvate

the cormspondingiy numbered output


from the decoder, and hence the cor-
respondingly numbered display.

Figure 11-19. Multiplexed Seven-Segment Displays

11-52
Task 2: Display ten decimal digits.

Purpose: Display the contents of mennon/ locations 0040 through 0049 on ten 7-seg-
ment displays that are multiplexed with a counter and a decoder.
Sample Problem:
(0040) = 66
(0041) = 3F
(0042) = 7F
(0043) = 7F
(0044) = 06
(0045) = 5B
(0046) = 07
(0047) = 4F
(0048) = 6D
(0049) - 7D
Display reads 4088127356

Source Program:
ID A. 00001 11 1B MAKE PORT B OUTPUT
OUT (PIOCRB).A
DRUN: LD HL.40H POINT TO START OF DATA
LD B.10 NUMBER OF DISPLAYS = 10
LD CPIODRB GET PORT NUMBER
DSPLY: 0UT1 SEND DATA TO DISPLAY
CALL DELAY WAIT MS1

JR NZ,DSPLY COUNT DISPLAYS


JR DRUN START ANOTHER SCAN
: Here we must select the PIO output mode, since the circuit uses the handshake signals.

Note that OUTI sends the data to the output port addressed by Register C, increments
the address in Register Pair HL, and decrements the counter in Register B. We have
assumed that subroutine DELAY does not affect the Z flag so that it can be used after-
wards for a conditional branch.

11-53
Object Program:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)

0000 3E LD A,00001111B
0001 OF
0002 D3 OUT {PtOCRB),A
0003 PIOCRB
0004 21 DRUN: LD HL,40H
0005 40
0006 00
0007 06 LD B,10
0008 OA
0009 OE LD CPiODRB
OOOA PIODRB
OOOB ED DSPLY; OUTI
OOOC A3
OOOD CD CALL DELAY
OOOE 30
OOOF 00
0010 20 JR NZ,DSPLY
0011 F9
0012 18 JR DRUN
0013 FO

11-54
PROBLEMS
1) An On-Off Pushbutton
Purpose: Each closure of the pushbutton complements (inverts) all the bits in memory
location 0040. The location initiallv contains zero. The program should con-
tinuously examine the pushbutton and complement location 0040 with each
closure. You may wish to complement a display output port instead, so as to
make the results easier to see.

Sample Case:
Location 0040 initially contains zero.

The pushbutton closure changes location 0040 to FF (hex), the second changes it
first

back to zero, the third back to FF (hex), etc. Assume that the pushbutton is debounced
in hardware. How would you include debouncing in your program?

2) Debouncing a Switch in Software


Purpose: Debounce a mechanical switch by waiting until two readings, taken a de-
bounce time apart, give the same result. Assume that the debounce time (in
ms) is in memory location 0040 and place the switch position into memory
location 0041.

Sample Problem:
(0040) - 03 causes the program to wait 3 ms between readings.

3) Control for a Rotary Switch


Purpose: Another switch serves as a Load switch for a four-position unencoded rotary
switch. The CPU waits for theLoad switch to close (be zero), and then reads
the position of the rotary switch. This procedure allows the operator to move
the rotary switch to its final position before the CPU tries to read it The pro-
gram should place the position of the rotary switch into memory location
0040. Debounce the Load switch in software.

Sample Problem:
Place rotary switch in position 2. Close Load switch.
Result: (0040) = 02

11-55
4} Record Switch Positions on Lights
Purpose: A set of eight switches should have their positions reflected in eight LEDs.
That is to say, if the switch is closed (zero), the LED should be on, otherwise
the LED should be off. Assume that the CPU output port is connected to the
cathodes of the LEDs.

Sample Problem:
SWITCH CLOSED
SWITCH 1 OPEN
SWITCH 2 CLOSED
SWITCH 3 OPEN
SWITCH 4 OPEN
SWITCH 5 CLOSED
SWITCH 6 CLOSED
SWITCH 7 OPEN
Result:

LED ON
LED 1 OFF
LED 2 ON
LED 3 OFF
LED 4 OFF
LED 5 ON
LED 6 ON
LED 7 OFF
How would you change the program so that a switch attached to bit 7 of Port A of PiO
#2 determines whether or not the displays are active (i.e.. if the control switch is

closed, the displays attached to Port B reflect the switches attached to Port A; if the
control switch is open, the displays are always off)? A control switch is useful when the
displays may distract the operator, as in an airplane.

How would you change the program so as to make the control switch an on-off
pushbutton; that each closure reverses the previous state of the displays? Assume
is,

that the displays start in the active state and that the program examines and debounces
the pushbutton before sending data to the displays.

5} Count on a Seven-Segment Display


Purpose: The program should count from to 9 continuously on a seven-segment dis-

play, starting with zero.

Hint: Try different timing lengths for the displays and see what happens. When does
the count become visible? What happens if the display is blanked part of the time?

11-56
)

MORE COMPLEX 1/0 DEVICES


More complex I/O devices differ from simple keyboards, switches, and displays m that:

1) They transfer data at higher rates.


2) They may have their own mternal clocks and timing.
3) They produce status information and require control information, as well as
transferring data.

Because of their high data rates, you cannot handle these I/O devices casually. If the
processor does not provide the appropriate service, the system may miss input data or
produce erroneous output data. You are therefore working under much more exacting
constraints than in dealing with simpler devices. Interrupts are a convenient method
for handling complex I/O devices, as we shall see in Chapter 12.

Peripherals such as keyboards, teletypewriters, cassettes, SYNCHRONIZING


and floppy disks produce their own mternal timing. These WITH I/O
devices provide streams of data, separated by specific tim- DEVICES
ing intervals. The computer must synchronize the initial in-
put or output operation with the peripheral clock and then provide the proper interval
between subsequent operations. A simple delay loop like the one shown previously can
produce the timing interval. The synchronization may require one or more of the follow-
ing procedures:

1 Looking on a clock or strobe line provided by the peripheral for tim-


for a transition
ing purposes. A
simple approach would be to tie the strobe to a PIO STB input and
look for a change in the interrupt (INT) output. However, there is no way to directly
address the INT output (and thus determine its value) and no way to clear it other
than through an interrupt service routine. Thus, to use the PIO in a polling system,
one must make the strobe available at an input port and latch it if necessary, if the
strobe must be latched, a circuit must also be provided to clear the latch as part of
the subsequent input or output transfer.
2) Finding the center of the time interval during which the data is stable. We would
prefer to determine the value of the data at the center of the pulse rather than at
the edges, where the data may be changing. Finding the center requires a delay of
one-half of a transmission interval (bit time) after the edge. Sampling the data at
the center also means that small timing errors have little effect on the accuracy of
the reception.
3) Recognizing a special starting code. This is easy if the code is a single bit or if we
have some timing information. The procedure is more complex if the code is long
and could start at any time. Shifting will be necessary to determine where the
transmitter is starting its bits, characters, or messages (this is often called a search
for the correct "framing").

4) Sampling the data several times. This reduces the probability of receiving data in-
correctly from noisy lines. Majority logic (such as best 3 out of 5 or 5 out of 8) can
be used to decide on the actual data value.

Reception is, of course, much more difficult than transmission, since the peripheral con-

trolsthe reception and the computer must interpret timing information generated by
the peripheral. In transmission, the computer provides the proper timing and formatting
for a specific peripheral.

Peripherals may require or provide other information besides CONTROL


data and timing. We
refer to other information transmitted by AND STATUS
the computer as "control information", it may select modes of INFORMATION
operation, start or stop processes, clock registers, enable
buffers, choose formats or protocols, provide operator displays, count operations, or

11-57
identify the type and priority of the operation. We refer to other information transmitted
by the peripheral as "status information"; it may indicate the mode of operation, the
readiness of devices, the presence of error conditions, the format of protocol in use, and
other states or conditions.

The computer handles control and status information just like data. This information
seldom changes, even though actual data may be transferred at a high rate. The control
or status information may be single bits, digits, words, or multiple words. Often single
bits or short fields are combined and handled by a single input or output port

Combining status and control information into bytes reduces the total number of 1/0
port addresses required by the peripherals. However, the combination does mean that
individual status input bits must be separately interpreted and control output bits must
be separately determined. The procedures for isolating status bits and setting or reset-
ting control bits are as foHows:

Separating Out Status Bits SEPARATING


STATUS
Step 1) Read status data from the peripheral INFORMATION
Step 2) Logical AND with a mask (the mask has ones m bit

positions that must be examined and zeros


elsewhere)
Step 3} Shift the separated bits to the least significant bit positions

If the field is a single bit. is unnecessary since we can test the bit with the BIT in-
Step 2
struction. If the single bft the most significant, next to most significant or least sig-
is in

nificant position, we can use shift logical (AND A or OR A} instructions to determine its
value. Rememberalso that the input instructions with register indirect addressing (e.g..
IN A,(C)) affect the Sign flag.These somewhat more accessible bit positions are often
reserved for the most frequently used status information. You should try to write the re-
quired instruction sequences for the Z80 processor.

Step 3 is unnecessary if the fieldis a single bit since the Zero flag will contain the com-

plement of that bit after Step 2 (try Itl). A Shift or Load instruction can replace Step 2 if
the field is a single bit and occupies the least significant most significant or next to
most significant bit position. These positions are often reserved for the most frequently
used status information. You should try to write the required instruction sequences for
the 6800 processor.

Setting and Clearing Control Bits COMBINING


CONTROL
Step 1) Read prior control information
INFORMATION
Step 2) Logical AND with mask to clear bits (mask has zeros
in bit positions to be cleared, ones elsewhere)

Step 3) Logically OR with mask to set bits (mask has ones in bit positions to be set
zeros elsewhere)
Step 4) Send new control information to peripheral

Here again the procedure is simpler If the field is a single bit and occupies a position at
the end of the word.

11-58
Some examples of separating and combining status bits are:

1) A 2 through 4
3-blt field in bit positions of a PiO data register is a scaitng factor.
Place fantnr into
Planfi that factor thp Anriimjifator
intn the Accumulator.

; READ STATUS DATA FROM INPUT PORT

IN A.(PIQDR) :READ STATUS DATA

; MASK OFF SCALING FACTOR AND SHIFT

AND 00011100B .;MASK SCALING FACTOR


RRCA ;SHIFT TWICE TO NORMALIZE
RRCA
2) The Accumulator contains a 2-bit field that must be placed into bit positions 3 and
4 of a PIO data register.

MOVE DATA TO FIELD POSITIONS

RLA :SHIFT DATA TO BIT POSITIONS 3 AND 4


RLA
RLA
AND 00011000B :CLEAR OTHER BIT POSITIONS
LD B.A :SAVE NEW FIELD VALUE

; COMBINE NEW FIELD VALUE WITH OTHER DATA

IN A.{PIODR) ;CLEAR OLD FIELD VALUE


AND 11100111B
OR B ;INSERTNEW FIELD VALUE
OUT (P!ODR),A

Documentation is a serious problem in handling control and DOCUMENTING


status information. The meanings of status inputs or control STATUS AND
outputs are seldom obvious. The programmer should
clearly in- CONTROL
dicate the purposes of Input and output operations in the com- TRANSFERS
ments, e.g.. "CHECK IF READER !S ON." "CHOOSE EVEN
PARITY OPTION." or "ACTIVATE BIT RATE COUNTER." The bit manipulation. Logical,
and Shift instructions will otherwise be very difficult to remember, understand, or
debug.

11-59
Table 11-6.Companson Between independent Connections
and Matrix Connections for Keyboards

Nunnber of Lines with Number of Lines with


Keyboard Size Matrix Connections
Independent Connections

3x3 9 6
4x4 16 8
4x6 24 10
5x5 25 10
6x6 36 12
6x8 48 14
8x8 64 16

EXAMPLES
An Unencoded Keyboard
Purpose: Recognize a key closure fronn an unencoded 3x3 keyboard and place
the

number of the key that was pressed into the Accumulator


Keyboards are just collections of switches (see Figure 1 1 -20}. Small numbers of
keys are

easiest to handle if each key is attached separately to a bit of an


input port Interfacing

the keyboard is then the same as Interfacing a set of switches.

Keyboards with more than eight keys require more than one input MATRIX
port and therefore multibyte operations. This is
particularly KEYBOARD
wasteful if the keys are logically separate, as
in a calculator or ter-

minal keyboard where the user will only strike one at a time. The number of
input lines

required may be reduced by connecting the keys into a matrix, as


shown in Figure
11 -21. Now each key represents a potential connection between a row and a column.
The keyboard matrix requires n + m external lines, where n is the number of rows and
m
m is the number of columns. This compares to n x external lines if each key Is sepa-
rate. Table 11-6 compares the number of keys required
by typical configurations.

A program can determine which key has been pressed by using


the external lines from the matrix.
"keyboard scan." We ground Row
The usual procedure is a
and examine the column
lines. If any lines are grounded, a key in that row has
SCAN 3
KEYBOARD

been pressed, causing a row-to-


1

which
column connection. We can determine which key was pressed by determining
which of the input port is zero. If no column line is
column line is grounded; that is. bit

grounded, we proceed to Row 1 and repeat the scan. Note that we can check to see if
any keys at all have been pressed by grounding all the rows at once and examining the
columns.

The keyboard scan requires that the row tines be tied to an output port and the column
lines to an input port Figure 1 1-22 shows the arrangement. The
CPU can ground a par-
ticular row by placing a zero in the appropriate bit of the output port
and ones in the
other bits.

The CPU can determine the state of a particular column by examining the appropriate
bit of the input port.

11-60
Figure 11-20. A Small Keyboard

Column Column 1 Column 2

Kev

V4
1

RowO

Key 4 Keys

v<4 V4

V4
Kev 8
></'
^^-
Each key now serves to connect a row to a column. Rjr mstance, key 4 connects row 1 to column t.

Figure 11-21. A Keyboard Matrix

11-61
Column Column 1 Coiumn 2

KevO Key 1 Kev 2

y<4 y</'
1-1
% -RowO

Kev3 Key 4

y4
Key 5

y4
{from CPU)
PIO
Output
Port
^^ ^
Kev6 Kev? Keys

y4 y4

'1

PIO
Input

Port

u
Data Bus (to CPU)

Figure 11 -22, i/0 Arrangement for a Keyboard Scan

11-62
Task 1: Determine key closure,
Purpose: Wait for a key to be pressed. WAITING
The procedure is as follows:
FOR A
KEY CLOSURE
1) Ground all the rows by clearing all the output bits.

2) Fetch the column inputs by reading the input port


3) Return to Step 1 if all the column inputs are ones.

Flowchart:

C-m^ Start
1
^^
Ground di
keyix^rd TOWS

No
< any colunnns
>
C End
D
Source Program:
LD A.01001111B ;MAKE PORT A INPUT
OUT (PIOCRA),A
LD A.oooomiB :MAKE PORT B OUTPUT
OUT (PIOCRB),A
SUB A :GROUND ALL KEYBOARD ROWS
OUT (P!ODRB),A
WAITK: !N A.(P!ODRA) :GET KEYBOARD COLUMN DATA
AND 000001 11B ;MASK COLUMN BITS
CP 0000011 IB ;ARE ANY COLUMNS GROUNDED?
JR Z.WAITK ;N0, WAIT UNTIL ONE IS
HALT

11-63
Object Program:

Memory Location Memory Contents Instruction


(Hex) (Hex) (Mnemonic)

0000 3E LD A.010011118
0001 4F
0002 D3 OUT (P!OCRA),A
0003 PIOCRA
0004 3E LD A.00001111B
0005 OF
0006 D3 OUT (PIOCRB),A
0007 PIOCRB
0008 97 SUB A
0009 D3 OUT (PI0DR8).A
OOOA PiODRB
0008 DB WAITK: IN A,(P10DRA)
OOOC PIODRA
OOOD E6 AND 0000011 IB
OOOE 07
OOOF FE CP 000001118
0010 07
0011 28 JR Z.WAITK
0012 F8
0013 76 HALT

PIO Port 8 !S the keyboard output port and Port A is the mput port

Masking off the column bits eliminates any problems that could be caused by the states
of the unused input lines.

We could generalize the routine by naming the output and masking patterns;
ALLG EQU 11111000B
OPEN EQU 0000011 IB

These names could then be used in the actual program; a different keyboard would re-

quire only a change in the definitions and a re-assembly.

Of course, one port of a PIO is all that is really necessary for a 3 x 3 or 4 x 4 keyboard.
Try rewnting the program so that it uses only Port A. The PIO must be placed into the
control mode so that lines can be indiytduaily selected as inputs or outputs.

11-64
Task 2: identify key.

Purpose: identify a key closure by placing the nunnber of the key into the Accunnulator.
The procedure is as follows:

1) Set key nunnber to -1. counter to nunnber of rows, and output pattern to at! ones
except for a zero in bit 0,
2) Ground a row by sending the output pattern to the keyboard output port
3) Update the output pattern by shifting the zero bit ieft one position.
4) Fetch the column inputs by reading the input port.

5) If any column inputs ar'e zero, proceed to Step 8.

6) Add the number of columns to the key number to reach the next row.
7) Decrement counter. Go to Step 2 if any rows have not been scanned, otherwise to
Step 10.
8) Add 1 to key number. Shift column inputs nght one bit.

9) If Carn/ = 1. return to Step8.


10) End of program.

Flowchart:

f Start
J

Key Numt?er = - 1
Counter = Number
„ „ of rows
Scan Pattern =
11111110

Ground row by
output of
Scan Pattern

Update Scan Pattern Key Number -


Key Number + 1
by shifting left
Shift column inputs
circularly
nght 1 bit

Key Numbe"- =
Key Number +
Number of Columns
Counter = Counter- 1

11-65
Source Program:
LD A.01001111B ;MAKE PORT A INPUT
OUT (PIOCRAl.A
LD A.00001111B ;MAKE PORT B OUTPUT
OUT (P!0CR8),A
LD B.3 COUNT = NUMBER OF ROWS
LD CPIODRB GET OUTPUT PORT NUMBER
LD D,3 GET NUMBER OF COLUMNS
LD E,11111110B START SCAN PATTERN TO GROUND ROW
ZERO
LD H.00000111B GET KEYBOARD MASKING PATTERN
LD L.OFFH KEY NUMBER =-1
FROW: OUT (O.E SCAN A ROW
RLC E UPDATE SCAN PATTERN FOR NEXT ROW
IN A,(Pi0DRA) GET KEYBOARD COLUMN DATA
AND H MASK COLUMN BITS
CP H ;ARE ANY COLUMNS GROUNDED?
JR NZ,FCOL YES, GO FIND WHICH ONE
LD A.L NO, UPDATE KEY NUMBER FOR NEXT ROW
ADD A,D
LD LA
DJNZ FROW :EXAMINE NEXT ROW IF ANY LEFT

!NC L ;IDENTIFY CASE IN WHICH KEY NOT FOUND


JR DONE
FCOL: INC L ;iNCREMENT KEY NUMBER
RRA :IS THIS COLUMN GROUNDED?
JR NC.FCOL ;N0. EXAMINE NEXT COLUMN
DONE: HALT

11-66
A
D
B
F
E

Object Program:

Memory Address Memorv Contents Instruction


(Hex) (Hex) (Mnennonic)
0000 3E ID A.01001111B
0001 4F
0002 D3 OUT (PIOCRA),A
0003 PiOCRA
0004 3E ID A.00001111B
0005 OF
0006 D3 OUT (P!OCRB),A
0007 PiOCRB
0008 06 LD B.3
0009 03
OOOA OE LD C.PtODRB
OOOB PIODRB
OOOC 16 LD D.3
OOOD 03
OOOE IE LD E,11111110B
OOOF FE
0010 26 LD H,00000111B
0011 07
0012 2E LD L. OFFH
0013 FF
0014 ED FROW: OUT (a,E
0015 59
0016 CB RLC E
0017 03
0018 DB !N A,(P!ODRA)
0019 PIODRA
001 A4 AND H
001 BC CP H
001C 20 JR NZ.FCOL
001 08
001 7D LD AX
001 82 ADD A,D
0020 6F LD L.A
0021 10 DJNZ FROW
0022 F1
0023 2C INC L
0024 18 JR DONE
0025 04
0026 2C FCOL; iNC L
0027 IF RRA
0028 30 JR NCFCOL
0029 FC
002A 76 HALT
Each tinne a row scan fails, we must add the number of columns to the key number so
as to move past the present row (try it on the keyboard in Figure 1 1-22).

11-67
What is no keys are being pressed? Note the extra INC L in-
the result of the program if

struction so that the program between no keys pressed and the last key
differentiates
being pressed. What is the final value in the Accumulator for these two cases? Note
that the Zero flag could also be used to distinguish the case where no keys were
pressed. Can you explain how?

An alternative approach would be to use the PIO in its control mode so that lines could
be changed from inputs to outputs. The procedure would be:
1) Ground all the columns and save the row inputs.
2) Ground all the rows and save the column inputs.
3) Use the row and column inputs together to determine the key number from a table.

Try to write a program to implement this procedure.

This program can be generalized by making the numbe[ of rows, the number of col-
umns, and the masking pattern into named parameters with EQU pseudo-operations.

11-68
C=3 Keyboard Data Inputs

Data Bus
to CPU C
A STB * Keyboard Strobe

84

Figure 11-23. I/O Interface for an Encoded Keyboard

An Encoded Keyboard
Purpose: Fetch data, when it is avaiiable, from an encoded keyboard that provides a
strobe along with each data transfer.

An encoded keyboard provides a unique code for each key. It has internal electronics
that perform the scanning and The
tdentification procedure of the previous example.
tradeoff between the simpler software required by the encoded keyboard and the
is

lower cost of the unencoded keyboard.

Encoded keyboards may use diode matrices, TTL encoders, or MOS encoders. The
codes may be ASCII, EBCDIC, or a custom code. PROMs are often part of the encoding
circuitry.

The encoding may do more than iust encode key


circuitry | ROLLOVER |

closures. It maydebounce the keys and handle "rollover," the


also
problem of more than one key being struck at the same time. Common ways of han-
dling rollover are: "2-key rollover," whereby two keys {but not more) struck at the same
time are resolved into separate closures, and "n-key rollover," whereby any number of
keys struck at the same time are resolved into separate closures.

The encoded keyboard also provides a strobe with each data transfer. The strobe sig-
nals that a new closure has occurred. Figure 11-23 shows the interface between an en-
coded keyboard and the Z80 microprocessor. The rising edge of the strobe latches the
data into the input port We also tie the strobe to the B side of the PtO so that the CPU
can determine when edge has occurred. Of course, the B port of one PIO could
a rising
hold status signals from up to eight ports. The software would then have to determine
which ports were active with a shifting and masking operation.
We have assumed in the program that the strobe signal is long enough for the CPU to
handle it in software. If it is not the signal will have to be latched and cleared (with
RDY) when the input or output transfer occurs.
You may have to watch the polarity of the strobe, since the PIO always reacts to a rising
edge. An inverter gate may be necessary.

11-69
Task: Input from keyboard.
edge of a strobe at the 8 port of a PtO and then place the
Purpose: Wait for the rising
data from Port A into the Accumulator.

Flowchart:

c J
in a one state during reset to prevent the
The hardware must hold the control lines 1 jic

accidental setting of status flags.

Source Program:
1

LD A.01001111B ;MAKE PORT A INPUT


OUT (PIOCRA).A
LD A,11001111B ;MAKE PORT B CONTROL
OUT (PIOCRB).A
LD A.OFFH ;ALL PORT B LINES INPUTS
OUT (PIOCRB),A
SRCHL: IN A.(PIODRB) ;EXAMINE STATUS PORT
BIT STB.A :HAS STROBE LINE GONE LOW?
JR NZ,SRCHL :N0. WAIT UNTIL IT HAS
SRCHH: IN A.(PtODRB) ;EXAMINE STATUS PORT AGAIN
BIT STB^A :R!SING EDGE FOUND?
JR Z.SRCHH ;N0. WAIT UNTIL ONE OCCURS
IN A,(PIODRA) :YES, FETCH DATA
HALT

11-70
A

Object Program:

Memory Address Memorv Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A.oioomiB
0001 4F
0002 D3 OUT (PIOCRA).A
0003 PtOCRA
0004 3E LD A.11001111B
0005 CF
0006 D3 OUT (PIOCRB),A
0007 PIOCRB
0008 3E ID A.OFFH
0009 FF
OOOA D3 OUT (PIOCRB),A
OOOB PIOCRB
OOOC DB SRCHL: !N A. (PIODRB)
OOOD PIODRB
OOOE CB BIT ST8.A
OOOF STB
0010 20 JR NZ.SRCHL
0011 FA
0012 DB SRCHH: IN A. (PIODRB)
0013 PIODRB
0014 CB BIT STB.A
0015 STB
0016 28 JR Z.SRCHH
0017 FA
0018 DB IN A. (PIODRA)
0019 PIODRA
001 76 HALT

If the CPU repeats thts routine, it will not fetch another character until the next nsing
edge occurs on the strobe line. A continuing high level on the strobe line will be ig-
nored,

STB depends on which bit of Port B is 1 1-23 shows bit 4 being used, but
used. Figure
bits 0, 6, and 7 are, as usual, the easiest to examine. Try rewriting the program to use
the more accessible bit positions.

The second byte depends on the value of STB but is not equal
of the Bit instructions to
that value. For example, the second byte is 4F'j6 If STB = 1. 57-] g if STB = 2. etc.

11-71
A Digital-to-Analog Converter
Purpose: Send data to an 8-bit digitai-to-anatog converter, which has an active-low
latch enabie.

Digital-to-analog converters produce the continuous signals required by solenoids,


relays, actuators, and other electrical and mechanical output devices. Typical conver-
ters consist of switches and resistor ladders with the appropriate resistance vaiues7
The user must generally provide a reference voltage and some other digital and analog
circuitry, although complete units are becoming available at tow cost

Figure 11-24 describes the 8-bit Signetics NE5018 D/A converter, which contains an
on-chip 8-bit parallel data input latch, A low level on the_LE {Latch Enable) input gates
the input data into the latches, where it remains after LE goes high.

Figure 1-25 illustrates the interfacing of the device to a Z80 microprocessor. Here the
1

A is used to generate the Latch Ena bie s ignal. The RDY line from the PIO
side of the PIO
could be used in the mode where it is tied to the STB line to form a pulse lasting one
clock cycle. However, one clock cycle may not be long enough, since the NE5018 re-
quires a 400 ns pulse. Furthermore, the polarity is the opposite of that needed by the
NE5018.
Note that the PIO latches the output data. The data therefore remains stable during and
after the conversion. The converter typically requires only a few microseconds to pro-
duce an analog output. Thus, the converter latch could be left enabled if the port were
not used for any other purpose.

In applications where eight bits of resolution are not enough, 10- to 16-bit converters
can be used. Additional port logic is required to pass all the data bits; some converters
provide part of this logic.

The PIO here serves both as and as a serial control port Of course,
a parallel data port if

Port A is used for control, it could actually handle up to eight bits.

Task: Output to converter.

Purpose: Send data from memory location 0040 to the converter.


Flowchart:

r Start
1
^ Data
= (0040 )

*
r Send data
to converter

t
Pulse
Utch Enabie

^ t
C End
3

11-72
I

3 % D
CO -z. < O
Q Q
<>—^N-H»

2 o -_ -4 ^—A^^r-* —
-SMf-

o s
"W^-4>
D O

-AM(Mt

o
o
<
Q
00

c> "^^ M<yr o


3 :i

-WVH^

CO
"W^>

^^t^wsm;

^
BO

(H^^HM^^il

11-73
Data 8us Analog

from CPU Output


NE5018
i D/A
:> Converter

Figure 11-25. Interface for an 8-bit Digital-to-Analog Converter

Source Progrann:
LD A.11001111B :MAKE PORT A CONTROL
OUT {PIOCRA),A
SUB A ;ALL PORT A PINS OUTPUTS
OUT {PIOCRAI.A
LD A.00001111B :MAKE PORT 8 OUTPUT
OUT (PIOCRB),A
LD A,(40H) ;GET DATA
OUT (P!ODRB),A ;SEND DATA TO DAC
IN A.(PIODRA} :GET OLD CONTROL DATA
RES 4.A :BRIN6 LATCH ENABLE LOW
OUT (PIODRA).A
SET 4.A :BRING LATCH ENABLE HIGH
OUT (PIODRAl.A
HALT

11-74
A

Object Program:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A.11001111B
0001 CF
0002 D3 OUT (PIOCRA),A
0003 PiOCRA
0004 97 SUB A
0005 D3 OUT (PIOCRA),A
0006 PIOCRA
0007 3E LD A.000011118
0008 OF
0009 D3 OUT (PIOCRBl.A
OOOA PtOCRB
OOOB 3A LD A,(40H)
OOOC 40
GOOD 00
OOOE D3 OUT (PIODRB),A
OOOF PIODRB
0010 DB IN A, (PIODRA)
0011 PIODRA
0012 CB RES 4A
0013 A7
0014 D3 OUT (P!ODRA),A
0015 PIODRA
0016 CB SET 4.A
0017 E7
0018 D3 OUT (PIODRA).A
0019 PIODRA
001 76 HALT

The particular bit that must be set and reset depends, of course, on how the Latch Ena-
ble connected to the control port Bit is often convenient to use for control purposes
iS

since, if that bit is originally cleared, it can be set with an INC instruction and reset with
a DEC instruction.

We could use the automatic brief strobe from B ACK if the Latch En able we re active-
high (and if this strobe were long enough when B ACK is tied back to B STB). The pro-
gram would then be:
LD A.oooomiB :MAKE PORT B OUTPUT
OUT (P10CRB),A
LD A.(40H) :GET DATA
OUT (PIODRB),A ;SEND DATA TO DAC AND ENABLE LATCH
HALT
An inverter gate could produce an active-low signal. Note how many fewer instructions
are necessary.

11-75
Anaiog-to-0igit8i Converter
Purpose: Fetch data from an 8-bit ana(og-to-digital converter that requires an Initiate
Conversion pulse to start the conversion process and has a Data Valid line to
indicate the compietion of the process and the availability of valid data.

Analog-to-digital converters handle the continuous signals produced by various types


of sensors and transducers.^ The converter produces the digital input v\/hich the com-
puter requires.

One form of analog-to-digital converter is the successive approximation device, which


makes a direct 1-bit comparison during each clock cycle. Such converters are fast but
have little noise immunity. Dual slope integrating converters are another form of
analog-to-digital converter. These devices take longer but are more resistant to noise.
Other techniques, such as the incremental charge balancing technique, are also used.

some external analog and


Analog-to-digital converters usually require digital circuitry,
although complete units are becoming available at low cost

Figure 1 1 -26 shows the 8-bit Tetedyne Semiconductor 8703 A/D converter. The device

contains a result latch and tristate data outputs. A pulse on the initiate Conversion line
starts conversion of the analog Input; after about two milliseconds the result will go to
the output latches, and the Data Valid output will indicate this by switching first low
'0'
and then high. Data is read from the latches by applying to the ENABLE input
Figure 1-27 shows the interface for the Z80 processor and the 8703 converter.^ Port B
1

is used to provide an Initi ate Con version pulse (active-high) of sufficient length. The

Data Valid signal is tied to A STB so that Data Valid going low and then high will latch
the converted data into Port A. The Data Valid signal is also tied to a bit of Port B so that
the CPU can determine its value. The important edge on the Data Valid line is the low-
to-high edge, which indicates the completion of the conversion. As in the case of the
encoded keyboard, additional circuitry will be necessary if the pulse on Data Valid is too
short to be handled in software. Note that we are using Port 8 here for both status and
control.

11-76
1 > 1

5 ^So
CO
ft.
^5 2
Z

a
ll

?.U444^^44. '
H >^
SI 5«s.r.«o.2 ;:Ci ^ ?3 CM
1
+
CO

z
>
II
3 ti
o 5 c

/\

ii
»j
c
o
a
f) i
00
1
o
CO
Control
Ck)ck and Logic

D O
" t
111
_ ^ u,
'*
2 %
•*- o o
c>
HHi-
o.
tA J 52
s
"
^ >
i
1 1

2_C

^%
5
"
Iji.
1"'
lA —/^
II''

^ !2 2 ;S c;
r
S
^ II'
cT

HHhH
• s*. G
1'

G
iif i
^

'*
=^tt i|
to U "^
<
^i'^
2
O 1
"i
":5
\'* —
r^ 1
t
>
lO

g ffi J # S «

11-77
Data Bus Analog

CPU Input
to
Teiedyne 8703
/\ A7 A
P!0 A/D
<.,
*

Ao s Converter

A STB Data Initiate

85 B2 Valid Conversron

i\
t

Figure 1 1-27. Interface for an 8-bit Analog-to-Digital Converter

Task: Input from converter.

Purpose: Start the conversion process, wait for Data Valid to go low and then high,
and then read the data and store it in nnemorv location 0040.
Flowchart:

Read data from


data input port
(0040) ^ Data

C D
Note that here the PIO serves as a parallel data port a serial status port, and a serial

control port.

11-78
Source Program:
LD A.01001111B ;MAKE PORT A INPUT
OUT (PIOCRA),A
LD A.11001111B ;MAKE PORT B CONTROL
OUT (PIOCRB),A
LD A,00001111B ;B4-7 OUTPUT. BO-3 INPUT
OUT (PIOCRB),A
LD A.00100000B ;SEND INITIATE CONVERSION HIGH
OUT (PiODR8),A
SUB A ;SEND INITIATE CONVERSION LOW
OUT (PIODRBl.A
WTLOW: IN A.(PIODRB) :HAS DATA VALID GONE LOW?
BIT 2,A
JR NZ, WTLOW :N0, WAIT
WTHI: IN A,(PIODRB) ;IS DATA AVAILABLE?
BIT 2,A
JR Z, WTLOW :N0, WAIT
IN A,(PIODRA) ;YES. FETCH DATA FROM CONVERTER
LD (40H),A ;SAVE CONVERTER DATA
HALT

11-79
D
C
B
E
F

Object Program:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)

0000 3E LP A.01001111B
0001 4F
0002 D3 OUT (PIOCRA).A
0003 PtOCRA
0004 3E LD A.110011118
0005 CF
0006 D3 OUT (PIOCRB),A
0007 PIOCRB
0008 3E LD A,00001111B
0009 OF
OOOA D3 OUT (PtOCR8),A
OOOB PIOCRB
OOOC 3E LD A.00100000B
GOOD 20
OOOE D3 OUT (P!ODRB),A
OOOF PtODRB
0010 97 SUB A
0011 D3 OUT (PIODRB),A
0012 PIODRB
0013 DB WTLOW; !N A. (PIODRB)
0014 PIODRB
0015 CB BIT 2,A
0016 57
0017 20 JR NZ.WTLOW
0018 FA
0019 DB WTHi; IN A,(P10DRB)
001A PIODRB
001 CB BIT 2.A
001 57
001 28 JR Z,WTHI
001 FA
001 DB IN A,(PiODRA)
0020 PIODRA
0021 32 LD (40H),A
0022 40
0023 00
0024 76 HALT

One approach to configuring PIOs is to use the repeated Block Output instruction OTiR
and a table in memory containing the words to be sent to the Control register. A typical
routine would be:

LD BXENG :COUNT = NUMBER OF CONTROL WORDS


LD CPtOCR :GET CONTROL PORT NUMBER
LD HL.CTLTAB ;STARTING ADDRESS OF PIO CONTROL TABLE
OTIR ;CONFIGURE PIO
in fact another table (or the Stack) could be used to hold the number of control words
and the port number for each PIO.

11-80
Pantv Stop Stop
Bit Sit Bit

Character is ASQI 'E' with odd parity {45 hex).

Remember that the transmission order is Start bit


{'0'), bft 0, bit 1, bit 2, bit 3. bit 4, bit 5. bit 6, Parity

bit. Stop bit i'V), Stop bit i'V).

Figure 11-28. Teletypewriter Data Format

A Teletypewriter (TTY)
Purpose: Transfer data to and from a standard 10-character-per- TTY
second serial teletypewriter. INTERFACE
The common teletypewriter transfers data in an asynchronous
serial mode. The procedure is as follows:

1) The line is normally in the one state. STANDARD


2) A Start bit (zero bit) precedes each character. TTY
3) The character is usually 7-bit ASCII with the least significant CHARACTER
bit transmitted first FORMAT
4) The most significant bit is a Parity bit which may be even.
odd, or fixed at zero or one.
5) Two stop bits (logic one) follow each character.

Figure 11-28 shows the format Note that each character requires the transmission of
eleven which only seven contain information. Since the data rate is ten charac-
bits, of

ters per second; the bit rate is 10 x 1 1, or 110 Baud. Each bit therefore has a width of
1/110 of a second, or 9.1 milliseconds. This width is an average; the teletypewriter
does not maintain it to any high level of accuracy.

For a teletypewriter to communicate properly with a computer, the following pro-


cedures are necessary.

Receive (flowcharted m Figure 11-29): TTY


RECEIVE
Step 1) Look for a Start bit (a logic zero) on the data line.
MODE
Step 2) Center the reception by waiting one-half bit time, or 4.55
milliseconds.

Step 3) Fetch the data bits, waiting one bit time before each one. Assemble the data
bits into a word by first shiftingthe bit to the Carry and then circularly shifting
the data with the Carry. Remember that the least significant bit is received
first

Step 4) Generate the received Parity and check- it against the transmitted Parity. If

they do not match, indicate a "Parity error."


Step 5) Fetch the Stop bits (waiting one bit time between inputs). If they are not cor-
rect (if both Stop bits are not one), indicate a "framing error."

11-81
r Start
J

Get input data


.6.-, is pantv ==

received parity ?)

Count = 8
Wait one bit time
Data =

Wait one bit time Get input data

Get input data


Cany == Input data

Shift data nght


with Carry

End

Figure 11-29. Flowchart for Receive Procedure

11-82
Task 1 : Read data.

Purpose: Fetch data from a teletypewriter through bit 7 of a PIO data port and place
the data into nnemory location 0060. For procedure, see Figure 11-29.

Source Program:
(Assume that the serial port is bit 7 of the PIO and that no parity or framing check is
necessary)

LD A.01001111B MAKE PORT A INPUT


OUT (PIOCRA).A
WTSTB: !N A,(PIODRA) READ SERIAL LINE
RLA ISTHERE A START BIT?
JR CWTSTB NO. WAIT UNTIL THERE IS
CALL DHALF YES, DELAY HALF BIT TIME TO CENTER
LD D,10000000B . COUNT WITH BIT IN MSB
RCVB: CALL DFULL WAIT 1 BIT TIME
IN A.(PtODRA) READ SERIAL LINE
RLA MOVE BIT TO CARRY
RR D MOVE BIT TO ASSEMBLED WORD
JR NCRCVB CONTINUE IF COUNT BIT NOT IN CARRY
LD A.D
LD (60H),A
HALT
(Delay program)

ORG 30H
DHALF: PUSH DE ; SAVE OLD REGISTERS
LD D.8 : HALF BIT LENGTH COUNT
JR DLY16
DFULL: PUSH DE : SAVE OLD REGISTERS
LD D.16 ; FULL BIT LENGTH COUNT
DLY16: LD E8DH : DELAY 1/16TH BIT TIME
DLY1; DEC E
JR NZ.DLY1
DEC D
JR NZ,DLY16
POP DE ; RESTORE OLD REGISTERS
RET
Remember that bit of the data is received first.

11-83
A
C

Object Program:

Memorv Address Memorv Contents Instruction

(Hex) (Hex) (Mnemonic)

0000 3E LD A,01001111B
0001 4F
0002 D3 OUT (P!OCRA),A
0003 PIOCRA
0004 DB WTSTB: IN A. (PIODRA)

0005 PIODRA
0006 17 RLA
0007 38 JR C.WTSTB
0008 FB
0009 CD CALL DHALF
OOOA 30
OOOB 00
OOOC 16 LD 0,100000008
OOOD 80
OOOE CD RCVB: CALL DFULL
OOOF 35
0010 00
0011 DB IN A. (PIODRA)

0012 PiODRA
0013 17 RLA
0014 CB RR D
0015 1A
0016 30 JR NC.RCVB
0017 F6
0018 7A LD A,D
0019 32 LD {60H),A
001 60
0018 00
001 76 HALT
0030 D5 DHALF: PUSH DE
0031 16 LD D.8
0032 08
0033 18 JR DLY16
0034 03
0035 D5 DFULL: PUSH DE
0036 16 LD D.16
0037 10
0038 IE DLY16: LD E8DH
0039 8D
003A 1D DLY1: DEC E
0038 20 JR NZ.DLY1
003C FD
003D 15 DEC D
003E 20 JR NZ,DLY16
003F F8
0040 D1 POP DE
0041 C9 RET

11-84
This program assumes that the Stack can be used for subroutine calls, i,e., the monitor
must initialize the Stack Pointer. Otherwise you will have to initialize the Stack Pointer
as shown in Chapter 10.

The constants for the delay routine were calculated just as shown earlier in this chapter.
You might try determining them for yourself. The delays do not have to be highly accu-
rate because the reception is centered, the messages are short, the bit rate is low, and
the teletypewriter is not highly accurate itself.

How would you extend this program to check for the two stop bits? They must both be
one or a framing error has occurred.
You can extend this program to check odd parity by replacing the LD A,D instruction
with the sequence:

SUB A
AND D ;1S PARITY ODD?
JP PE.PRERR ;N0. PARITY ERROR HAS OCCURRED

11-85
1

( '- )

. Carrv = (Start bit)


Get output data
Shift data left
circulaiiv with Carry
Count = 1

r*
»"f
Semi data to

Output Port

t
Shift data nght
circularlv with Carry
Carry = 1 (Stop bit)

Wait 1 brt time

Count = Count - 1

No
^T Count
^^

C ^"^ 3

Figure 11-30. Flowchart for Transmit Procedure

Task 2: Write data.

Purpose: Transmit data to a teletypewriter through bit of a PIO data register. The
data is in memory location 0060.

Transmit (flowcharted in Figure 11-30) TTY


Step 1) Transmit a Start bit (I.e., a logic zero).
TRANSMIT
MODE
Step 2) Transmit the seven data bits, starting with the least sig-
nificant bit.

Step 3) Generate and transmit the Parity bit


Step 4) Transmit two Stop bits (i.e.. logic ones).

The transmission routine must wait one bit time between each operation.

11-
Source Program: (Assume that parity need not be generated)

: MAKE PIO INTO OUTPUT PORT

LD A.00001111B :MAKE PORT B OUTPUT


OUT {PiOCRB),A

; GET DATA AND CLEAR START BIT

LD A,(60H) GET DATA


ADD A.A SHIFT LEFT AND FORM START BIT
LD 8.11 COUNT = 1 1 BITS

: TRANSMIT A BIT AND UPDATE DATA

TBIT: OUT (PIODRB).A TRANSMIT A BIT


RRA UPDATE FOR NEXT BIT
SCF FORM STOP BIT (LOGIC ONE)

; DELAY 9.1 MS AND COUNT BITS

CALL DFULL :DELAYai MS


DJNZ TBIT :COUNTDOWN 11 BITS
HALT
The DFULL subroutine is the same as before. Remember that bit of the data must be
transferred first.

Object l*rogram:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A,00001111B
0001 OF
0002 D3 OUT (PIOCRBl.A
0003 PiOCRB
0004 3A LD A,(60H)
0005 60
0006 00
0007 87 ADD A.A
0008 06 LD 8.11
0009 OB
OOOA D3 TBIT: OUT (PiODRB),A
OOOB PIODRB
OOOC 1F RRA
OOOD 37 SCF
OOOE CD CALL DFULL
OOOF 35
0010 00
0011 10 DJNZ TBIT
0012 F7
0013 76 HALT

11-87
U

ADD A.A clears the least significant bit so that it can be used as the start bit The most

significant bit issaved in the Carry, in actual applications, the startup routine should
place a logic '1'
on the teletypewriter line after configuration since that line should nor-
mally be in the mark (one) state.

Each character consists of 1 1 bits, starting with a start bit (zero) and ending with two
stop bits (ones).

This program can easily be extended to generate 7-bit characters with odd parity in the
most significant bit The parity generation routine (to be inserted after LD A,(60H)) is:
ANA A IS PARITY ODD?
JP PO,STBIT YES, NO PROBLEM
SET 7.A NO, MAKE IT ODD BY SETTING MSB
STBiT: ADD A.A ;SHIFT LEFT AND FORM START BIT

How would you generate even parity?

These procedures are sufficiently common and complex to merit a | ART |

special LSI device: the Universal Asynchronous


UART. or
Recelver/TransmitterJQ The UART will perform the reception procedure and provide
the data in parallel form and a Data Ready signal. It will also accept data in parallel
form, perform the transmission procedure, and provide a Peripheral Ready signal when
It can handle more data. UARTs may have many other features, including:

1 1 Ability to handle various bit lengths (usually 5 to 8), parity options, and numbers of

Stop bits (usually 1, 1-1/2. and 2).

2) indicators for framing errors, parity errors, and "overrun errors" (failure to read a
character before another one is received).

3) RS-232'' compatibility: i.e., a Request-to-Send (RTS) output signal that indicates


''

the presence of data to communications equipment and a C!ear-to-Send (CTS) In-


put signal that indicates, in response to RTS, the readiness of the communications
equipment. There may be provisions for other RS-232 signals, such as Received
Signal Quality, Data Set Ready, or Data Terinlnal Ready,

4} Tristate outputs and control compatibility with a microprocessor.


5) Clock options that allow the UART to sample incoming data several times in order
to detect false Start bits and other errors,

6) Interrupt facilities and controls.

UARTs act as four parallel ports: an input data port, an output data port an input
status port and an output control port The status bits include error indicators as well
as Ready flags. The control bits select various options. UARTs are inexpensive ($5 to
$50, depending on features) and easy to use.

11-88
THE Z80 SERIAL INPUT/OUTPUT DEVICE (SIO)
The Z80 input/Output Device or S!0 (see Figure 11-31) is a complete com-
Serial
munications contrcrtler specificallv designed for use in Z80-based microcomputers.
!t
can serve a variety of communications functions, but we will only discuss its use as
a
simple asynchronous receiver/transmitter. ''2

The SIO has two complete channels (A and B) which can both FULL-
receive and transmit serial data (see Figure 11-32). Channels that DURLEX
can receive and transmit simultaneously are called full-duplex.
Alternatives include half-duplex (able to transmit and receive, but not at the same
time), receive-only, and transmit-only.

An SIO occupies four input port addresses and foui^output port SIO
addresses. The B/A (Channel B or A Select) and C/D (Control or ADDRESSES
Data Select) lipes choose one of the four ports as described in Ta-
ble 11-7. Mos^ often, designers attach address bit Aq to the B/A input and address bit
A-j to the C/D Input. The SIO then occupies four consecutive
port addresses as de-
scribed in the last column of Table 11-7.

As with the PtO, SiOs have more control registers than ad- ADDRESSING
dresses. In fact,each SIO has eight registers in each chan- SIO READ AND
nel for control and three registers for status. Figure 1 1-33 WRITE REGISTER
contains diagrams of each control or Write register: Figure
1 1-34 contains diagrams of each status or Read
register. Two transfers are required to
read or write any of the registers except Write Register 0. The first transfer (written into
Write Register contains three bits that direct the next transfer to or from the selected
0)
register. Note, in Figure 11-33, that these three bits occupy the three least significant
bit positions and that zeros in the other bit positions indicate a byte that
has no function
other than addressing.

11-89
i- 5V tiNU tp
Interna!

Control
Logic
O
Hi
7T
Discrete
Modem or
Control
Other
and
Controls
Status

iZ

internal

Control

Logic

J'
Interrupt Control

Lines

Figure 11-31. Block Diagram of the Z80 SIO

Table 11- 7 SIO Addresses

CONTROL OR CHANNEL B OR A REGISTER PORT ADDRESS


DATA SELECT SELECT ADDRESSED (STARTING WITH SIOADD)
Data Register A SIOADD
1 Data Register B SlOADD+1
1 Control A SIOADD+2
1 1 Control B SIOADD+3
The port addresses assume that C/D is tied to A-] and B/A to Aq 1

11-90
U
TxC

XMIT

CRC
Shift and
Bit Insert
c SYNC
Generator Registers

XMIT
Suffer

7^ 7%

Channel
Control
:>
7T and
Status * WAIT/RDY

iz.
REG
FIFO

CRC SYNC
Checker Detect
REC
Shift and
Bit Stnp
:>

n
RxO RxC

Figure 11-32. Block Diagram of SIO Channel

11-91
.

Writs Bsgistftrs

The Z80 SIO contains eight regtsters in each channel that am programmed (written into) by the si^em software

to configure the f uncttona! personality of each channeL All Write registers, with the exception of Write Register 0,

require two bytes to be property programmed. The first byte contains three bits that point to the sheeted register

{D0-D2); the second byte is the actual control word that is being written to that register to configure the SIO.

Write Register is RESET (either Interna! command or external input) will initialize the SIO to Write
a special case.
Register 0. All basic commands (CMD2-CMD0) and CRC controls (CRCO, CRC1) can be accessed
with a single byte

using Write Register 0.

Contained in the first byte of any Write register access are the basic commands (CMD2-CMD0} and the CRC con-
trols (CRC»,CRC1) so that maximum system control and flexibility is maintained.

Write Register D

F D8 05 04 03 02 01
3
i i i n i i i i

Register
1 Register 1

1 Register 2

1 1 Registers
1 Register 4

10 1 Registers
1 1 Registers
1 1 1 Register?

NullCode
1 Send Abort (SOLO
1 Reset External or Status Interrupts
1 1 Channel Reset
1 Reset Rx Interrupt on First Character
1 1 Reset Tx Interrupt Pending
1 1 En*or Reset

\ 1 1 Return from Interrupt (Ch-A Only)

Null Cofto

1 Reset Rx CRC Checker


1 Reset Tx CRC Generator
1 1 Reset CRC/SYNCS Sent/Sending Latch

Write Register 1

06 05 I 04 03 I 02 01

li a ii a A a
. Externa! Interrupt Enable
- Tx Intemipt Enable
- Status Affects Vector (Ch-8 Only)

Rx Interrupt 0isab!e

1 Rx Interrupt on Rrst Character Only or Ent)r

1 interrupt on All Rx Charactera (Parity Affects Vector)

1 1 Interrupt on All Rx Characters (Parity Ooes Not Affect Vector)

• WAfT/REAOY on R/T
• WArr FN/READY FN
WAIT/READY Enable

Figure 11 -33. SiO Control or Write Registers

.11-92
Write Register 2

D1

ii ii i\ i\ a i\ i\ ii

intemipt
Vector

Write Register 3

D7 D6 OS D4 D3 D2 D1 DO

Rx Enable
• SYNC Character Load Inhibit

> Address Search Mode (SDLCI


- Rx CRC Enable
" Enter Hunt Mode
- Auto Enables
Rx 5 Btts/Chsracter
Rx 6 8tts/Diaracter
Rx 7 Btts/Character
Rx 8 Bits/Character

Write Register 4

1
n SYNC Modes
1
Enable
Stop Bit/Character
Parity Enable

- Parity Even/Odd

1 t-1/2 Stop Bits/Character

1 1 2 Stop Bits/Character

8 Bit SYtsIC Oiaracter


1 18 Sit SYNC Character
1 SDLC Mode (01 11 1110 SYNC Rag)
1 1 External SYNC Mode

x1 Clock Mode
1 x16 Clock Mode
1 x32 Clock Mode
1 1 x64 Ctock Mode

Figure 11-33. SIO Control orWrite Registers (Continued)

11-93
Writs Registsr S

D3 D2 01 DO

ii ii a ii ii

Tx CRC Enable

-RTS
-SDLC/CRC-t6
-Tx Enable
-Send BREAK

Tx 5 Bits {or LessVCharacter


1 Tx 7 Bits/Character

1 Tx 6 Sits/Character
1 1 Tx 8 Bits/Character

-DTR

Write Register 6

D5 D2 D1

ii i\

'

Trn
Also SDLC Address Ret

Write Register 7

ii ii ii il ii li A
I
-SYNC Bit 8
- SYNC Bit 9
-SYNC Bit 10 I

-SYNC Bit 11 For SDLC it must be programmed


-SYNC Bit 12 to "01 11 11 10" for Rag Recognition
-SYNC Bit 13 I

-SYNC Bit 14

-SYNC Bit 15 ,

Figure 11-33. SIO Contro! or Write Registers (Continued)

11-94
B98(l Ragistars

The Z80 S!0 contains three registers that can be read to obtain the status of each channel. Status information in-
cludes error conditions, interrupt vector, and standard communication interface protocol signals.
To read the con-
tents of a selected Read register, the system software must first write out to the SIO the byte containing pointer
information iD0-D2) in exactly the same manner as a Write register operation. Then, by issuing a READ operation,
the contents of the addressed Read/Status twister can be read by the Z80 CPU.

The real power in this type of command structure is that the programmer has complete freedom, after pointing to
the selected register, of either reading or writing to initialize or test that register. 8y designing software to initialize
the Z80 SIO in a modular, structured fashion, the programmer can use the powerful Z80 Block I/O instructions to
significantly simplify and speed his software development and debug.

Read Raglster

it « « « A A A A
- Rx Character Available
- Interrupt Pending (Ch-A Only)
-Tx Buffer Empty
-DCD
- SYNC/HUNT
- CIS
• CRC/SYNCS
Sending
• SREAK/ABORT

Read Register 1

i^ i^ ii ii ii ii a k
- An Sent

l-Re!d Bits l-Re!d Bits in


in Previous Second Previous
Byte Byte

Residue Data for


8 Rx Bits/Character
R-ogrammed

Parity Error
Special Rx
- Rx Ovenain Enror
Condition
• CRC/Frammg En-or
Interrupts
" Bid of Frame (SDLC)

Figure 11-34. SIO Status or Read Registers

11-95
Read Register 2 (Channel B Oniy}

D2 DO

ii ii a ii

I >

(ntemipt
Vector

Figure 11-34. SIO Status or Read Registers (Continued)

11-96
Note the foNowing special features of the SIO:

1) Input and output instructions address physicaliy distinct SPECIAL


registers. There is no way to read the contro! registers or write FEATURES
into the status registers,
OF SIO
2) AN control registers for a channel share a single port address.
Thus two bytes are required to change the contents of any control register except
Register 0.

3) RESET initializes the SIO to Write Register 0. It also disables SIO


both receivers and transmitters, deactivates all control sig- RESET
nals,and disables all interrupts. We wilt discuss the SIO inter-
rupt system in Chapter 12.
4) The SIO must be configured before it can be used. The easiest way to do this is
by
placing the required bytes into a table and using the repeated Block I/O
instruction.
The table must include both the bytes needed to address the various registers and
the data that must be placed into them. A typical routine would be:

LD B.LENG OF WORDS IN TABLE


:NU!VIBER
LD CSIOCRA PORT NUMBER
LD HLCTLTAB START OF CONTROL TABLE
OTIR CONFIGURE SIO
5) The RS-232 signals are all active-low. However, the SIO control bits for these sig-
nals are active-high (i.e., a logic '1'
in a control bit sends an RS-232 signal low).

6) The SIO requires an external dock. In asynchronous communications at 110 Baud,


1 760 Hz is usually supplied and
the XI 6 mode is used. The SIO will sample the bits
at the clock frequency for synchronization and to avoid false start bits caused by
noise on the line.

7) The Data Ready (Rx Character Available) flag is bit of Read Register 0. The Periph-
eral Ready (Tx Buffer Empty) flag is bit 2 of Read Register 0.

8) Error status bits (parity, overrun, and framing) are in Read Register 1.

11-97
B

EXAMPLES
Teletypewriter I/O via a USART
Task 1: Read from teletypewriter through SIO
Putpose: Receive data from a teletypewriter through an SIO and place the data into

memory location 0040. The data is 7-bit ASCII with odd parity.
Source Program:
LD A,4 :ACCESS WRITE REGISTER 4
OUT (SIOCRA).A
LD A,01 000001 ;X16 CLOCK MODE. ODD PARITY
OUT (S!OCRA),A
LD A.3 :ACCESS WRITE REGISTER 3
OUT (SIOCRA),A
LD A,01 000001 ;7 BIT CHARACTERS. ENABLE RECEIVER
OUT (SiOCRA).A
SUB A :ACCESS READ REGISTER
OUT (SiOCRA).A
WAITD: IN A.(SIOCRA) :GET STATUS
RRA :ISDATA AVAILABLE?
JR NCWAITD ;N0, WAIT
IN A.(SIODRA) :YES. GET DATA
LD (40H),A :SAVE DATA IN MEMORY
HALT

11-98
A
D
C B

Object Program:

Memory Address Memory Contents Instruction


(Hex) (Hex) (Mnemonic)
0000 3E LD A.4
0001 04
0002 D3 OUT (SIOCRA).A
0003 SIOCRA
0004 3E LD A.01 000001
0005 41
0006 D3 OUT; (SIOCRA).A
0007 SIOCRA
0008 3E LD A.3
0009 03
OOOA D3 OUT (SIOCRAl.A
OOOB SIOCRA
OOOC 3E LD A.01 0000018
OOOD 41
OOOE D3 OUT (SIOCRA),A
OOOF SIOCRA
0010 97 SUB A
0011 D3 OUT (SIOCRAl.A
0012 SIOCRA
0013 DB WAITD: IN A.(SIOCRA)
0014 SIOCRA
0015 IF RRA
0016 30 JR NCWAITD
0017 FB
0018 DB IN A, (SIODRA)
0019 SIODRA
001 32 LD (40H),A
0018 40
001 00
001 76 HALT

11-99
The program establishes Write Register 4 as follows:

Bits 7 and 6 =^ 01 to select XI 6 clock mode (1 760 Hz EXAMPLE


must be supplied) OFSIO
Sit 1 =0 to select odd parity CONFIQURATION
Bit = 1 to enable parity checking

The program establishes Write Register 3 as follows:

Bits 7 and 6 = 01 for 7 bits per character

Bit = 1 to enable the receiver

The received data status bit is bit of Read Register 0.

Note that any errors found will be reported in Read Register 1:

Bit 6 = 1 for a framing error (no stop bi^ StO


Bit 5 = 1 for an overrun error (more data received before ERROR
previous data read) STATUS
Bit 4= 1 for a parity error

Try adding an error checking routine to the program. Set

(0061) = if no errors occurred


= 1 if a parity error occurred
= 2 if an overrun error occurred
= 3 if a framing error occurred.

Note that the receiver always checks for one stop bit.

11-100
Task 2: Write to teletype through SIO.

Purpose: Send data from memory focation 0040 to a teletypewriter through an SIO.
The data is 7-bit ASCII with odd parity.
Source Program:
ID A.4 :ACCESS WRITE REGISTER 4
OUT (SIOCRA).A
LD A.010011018 X16 CLOCK MODE, 2 STOP BITS. ODD PARITY
OUT (SIOCRA),A
LD A, 5 ACCESS WRITE REGISTER 5
OUT (SIOCRA),A
LD A.OOIOIOOOB 7 BIT CHARACTERS. ENABLE TRANSMITTER
OUT (SIOCRA).A
SUB A ACCESS READ REGISTER
OUT {SIOCRAl.A
WAITR: IN A.(SIOCRA) GET STATUS
BIT 2.A IS TRANSMITTER READY?
JR Z.WAITR NO. WAIT
LD A,(40H) YES.GET DATA
OUT (SIODRA),A AND TRANSMIT IT
HALT

11-101
A
D
C
B

Object Program:

Memory Address Memory Contents instruction


(Hex) (Hex) (Mnemonic)

0000 3E LD A,4
0001 04
0002 D3 OUT (SIOCRA).A
0003 StOCRA
0004 3E LD A,01001101B
0005 4D
0006 D3 OUT (SIOCRA),A
0007 StOCRA
0008 3E LD A.5
0009 05
OOOA D3 OUT (SIOCRA),A
OOOB StOCRA
OOOC 3E LD A,00101000B
OOOD 28
OOOE D3 OUT (StOCRA),A
OOOF SiOCRA
0010 97 SUB A
0011 D3 OUT (SIOCRA).A
0012 SIOCRA
0013 DB WAiTR: IN A, (SIOCRA)
0014 SIOCRA
0015 CB BIT 2,A
0016 57
0017 28 JR Z.WAITR
0018 FA
0019 3A LD A,(40H)
001 40
001 00
001 D3 OUT (SIODRAI.A
001 SIODRA
001E 76 HALT

The program establishes Write Register 4 as foHows:


Bits 7 and 6 === 01 to select X16 clock mode (1760 Hz must be supplied)

Bits 3 and 2 = 11 to add 2 stop bits to each character


Bit 1 =0 to select odd parity

Bit = 1 to enable parity generation

The program establishes Write Register 5 as follows:

Bits 6 and 5 = 01 for 7 bits per character


Bit 3 = 1 to enable the transmitter

The transmitter status bit is bit 2 of Read Register 1.

11-102
3

STANDARD INTERFACES
Other standard interfaces besides the TTY current-loop and STANDARD
RS-232 can also be used to connect peripherals to the microconn- INTERFACES
puter. Popular ones include:

1) The serial RS449. RS422, and RS423 interfaces. '1

2) The 8-bit parallel GeneralPurpose interface Bus, also known as IEEE-488 or =

Hewlett-Packard interface Bus (HPtB).l'^


3) The S-100 or Altair/lmsai hobbyist busJS jhis is also an 8-bit bus.
4} The Intel Multibus.^ ^ This ts another 8-btt bus that can, however, be expanded to
handle 16 bits in parallel.

PROBLEMS
6) Separating Closures from an Unencoded Keyboard
Purpose: The program should read entries from an unencoded 3x3 keyboard and
place them into an array. The number of entnes required is in memory loca-
tion 0040 and the array starts in memory location 0041.

Separate one closure from the next by waiting for the current closure to end. Remember
to debounce the keyboard (this can be simply a 1 ms wait).

Sample Problem:
(0040) = 04
Entries are 1 2. 2,
. 4
Result: (0041) = 07
(0042) = 02
(0043) - 02
(0044) = 04

7) Read a Sentence from an Encoded Keyboard


Purpose: The program should read entries from an ASCII keyboard (7 bits with a zero
Parity bit) and place them into an array until it receives an ASCII period (hex
2E). The array starts in memory location 0040. Each entry js marked by a
strobe as in the example giyen under An Encoded Keyboard.

Sample Problem:
Entries are H, E. L, L 0, ,

Result: (0040) = 48 H
(0041) = 45 E
(0042) = 4C L
(0043) - 4C L
(0044) = 4F
(0045) = 2E .

11-103
8) A Variable Amplitude Square Wave Generator
Purpose: The program should generate a square wave, as shown m the next figure,
using a D/A converter. Menriorv location 0040 contains the scaled amplitude
of the wave, memory iocation 0041 the length of a half cycle in milliseconds,
and memory location 0042 the number of cycles.
Assume that a digital output of 80i g to the converter results m
an analog output of zero
volts. In general, a digital output of D results in an analog output of VquT ^ "^REF
(D™80)/80 volts.

Sample Probiem:
(0040) = AO (hex)
(0041) = 04
(0042) = 03
Result:

Output
Voltage
^0 H
_y^^^

The base voltage is 80-jg -0 volts.


Full scale is lOOig = -^HEr volts.
So A0i6 - (A0-80)/80 X -Vrep = -Vref/4
The program produces 3 pulses of amplitude VreF^^ with a half cycle length of 4 ms.

9) Averaging Analog Readings


Purpose: The program should take four readings from an A/D converter ten millise-
conds apart and place the average in memory location 0040. Assume that
the A/D conversion time can be ignored.

Sample Problem:
Readings are (hex) 86, 89. 81, 84

Result: (0040) = 85

10) A 30 Character-per-Second Terminal


Purpose: Modify the transmit and receive routines of the example given under A
Teletypewriter to handle a 30 cps terminal that transfers ASCII data with one
stop bit and even parity. How could you write the routines to handle either
terminal depending on a flag bit in memory location 0060: e.g.. (0060) ^0
for the 30 cps terminal. (0060) = 1 for the 10 cps terminal?

11-104
REFERENCES
1. Barnes, J., and V Gregory. "Use Microcomputers to Enhance Perfornnance with
Noisy Data," EDN, August 20. 1976, pp. 71-72.

2. Swanson. "Understanding Cyclic Redundancy Codes," Computer Design


R., ,

November 1975. pp. 93-99: and McNamara. J. E.. Technical Aspects of Data
Communication Digital Equipment Corp., Maynard, Mass. 1977.
.

3. For example, the Z80 Direct Memory Access ControHer (or DMA) for Z80 based
microcomputers described
is inAn Introduction to Microcomputers: Volume 2 —
Some Real Microprocessors .

4. The TTL Data Book for Design Engineers, Texas Instruments Inc., P 0. Box 5012,
Dallas. Texas 76222. 1976,
5. Dilatush, E.. "Special Report: Numeric and Alphanumeric Displays," EDN, Febru-

ary 5. 1978. pp. 26-35.

6. See Reference 4.

7 Hnatek, E. R.. A User's Handbook of D/A and A/D Converters." Wiley. New York,
1976.

8. See Reference 7
9. See also D, Guzeman, "Marry Your ^P to Monolithic A/Ds," Electronic Design ,

January 18. 1977. pp. 82-86.

10. For a discussion of UARTs. see P Rony et aL "The Bugbook lla." E and L Instru-
ments Inc.. 61 First Street Derby. CT. 06418; or D. G. Larsen et al..
"INWAS: Interfacing with Asynchronous Serial Mode," IEEE Transactions on In-
dustrial Electronics and Control instrumentation February 1977, pp. 2-12. Also
.

see McNamara, Reference 2.

11. The official RS-232 standard is available as "Interface between Data Terminal
Equipment and Data Communications Equipment Employing Serial Binary Data
Interchange." EIA RS-232C August, 1969. You can find introductory descriptions
of RS-232 in G. Pickles. "Who's Afraid of RS-232?;' Kilobaud May 1977. pp.

.

50-54 and in C. A. Ogdin. "Microcomputer Buses Part II." Mint-Micro Systems,


July 1978. pp. 76-80. Ogdin also describes the newer RS-449 standard.

12. The SIO is discussed more completely in Volume 3 of An Introduction to


Microcomputers: the following reference describes its use as a data link con-
troller: Weissberger. A. J.. "Data-Link Control Chips; Bringing Order to New Pro-

tocols," Electronics, June 8. 1978. pp. 104-112.

13. Electronic Industries Association, "Electrical Characteristics of Balanced Voltage


Digital interface Circuits," EIA RS-422 April 1975. .

Electronic Industries Association. "Electrical Characteristics of Unbalanced


Voltage Digital Interface Circuits." EIA RS-423 April 1975. .

Electronic Industries Association. "General Purpose 37-Position and 9-Positton In-


terface for Data Terminal Equipment and Data Circuit Terminating Equipment
Employing Serial Binary Data Interchange," EIA RS-449 November 1977.

Morris, D.. "Revised Data Interface Standards." Electronic Design . September 1.

1977. pp. 138-141.

11-105
14. Institute of Eiectrica!and Electronics Engineers, "!EEE Standard Digital interface
for Programnnable (nstrumentation." IEEE Std 488-1975-ANSi MC 1.1- 1975.
J. B. Peatman. Microcomputer-Based Design McGraw-Hill, New York,
,

1977: Loughry. D. C. and M, S. Alien. "IEEE Standard 488 and Microprocessor


Synergism." Proceedings of the IEEE, February 1978, pp. 162-172.

15. Morrow. G., and H. Fullmer, "Proposed Standard for the S-100 Bus," Computer,
May 1978. pp. 84-89.
Smith, M. L. "Build Your Own interface," Kilobaud, June 1977, pp. 22-28.

16. Rolander. T., Multibus Interfacing."


"Intel Intel Application Note AP-28 Intel Cor-
.

poration, Santa Clara, CA.. 1977.

11-106
2 ^

Chapter 1
INTERRUPTS
Interrupts are inputs that the CPU examines as part of each instruction cycle. These in-
puts aNow the CPU to react to asynchronous events in a nrjore efficient manner than
polling each device. When interrupts are utiiized to initiate I/O. generaliy more hard-
ware than ordinary, programmed I/O is required, but this provides a faster and more
direct response.''

Why use interrupts? Interrupts allow events such as alarms, power REASONING
failure,the passage of a certain amount of time, and peripherals BEHIND
having data or being ready to accept data to get the immediate at-
tention of the CPU. The programmer does not need to poll every 8—
INTERRUPTS
-«——
device, nor need the programmer worry about the system completely missing events.
An interrupt system is like the bell on a telephone —
it rings when a call is received so

that you don't have to pick up the receiver occasionally to see if someone is on the line.
The CPU can go about its normal business (and get a lot more done). When something
happens, the interrupt rouses the CPU and forces it to service the input before resuming
normal operations. Of course, this simple description becomes more complicated (just
like a telephone switchboard) when there are many Interrupts of varying importance

and there are tasks that cannot be interrupted.


The implementation of interrupt systems vanes greatly. CHARACTERISTICS
Among the questions that must be answered to character- Of= INTERRUPT
ize a particular system are: SYSTEMS
1) How many interrupt mputs are there?
2) How does the CPU respond to an interrupt?
3) How does the CPU determine the source of an interrupt if the number of sources
exceeds the number of inputs?

4) Can the CPU differentiate between important and unimportant interrupts?


5) How and when is the interrupt system enabled and disabled?

There are many different answers to these questions. The aim of all the implementa-
tions, however, is to have the CPU respond rapidly to interrupts and resume normal ac-
tivity afterwards.

The number of interrupt mputs on the CPU chip determines the number of different
responses that the CPU can produce without any additional hardware or software. Each
input can produce a different internal response. Unfortunately, most microprocessors
have a very small number (one or two, typically) of separate interrupt inputs.

The ultimate response CPU to an interrupt must be to transfer control to the cor-
of the
and to save the current value of the Program Counter. The
rect interrupt service routine
CPU must therefore execute a Jump-to-Subroutine or Call instruction with the begin-
ning of the interrupt service routine as its address. This action will save the return ad-
dress in the Stack and transfer control to the interrupt service routine. The amount of

external hardware required to produce this response vanes greatly. Some CPUs inter-
nally generate the instruction and the address; others require external hardware to
form them. The CPU can only generate a different instruction or address for each sepa-
rate input.

12-1
»

if the number exceeds the number of in-


of interrupting devices POLLING
puts, the CPUneed extra hardware or software to identify the
wilt VECTORING
source of the interrupt In the simplest case, the software can be a
poMIng routine which checks the status of the devices that may be
interrupting. The oniy advantage of such a system over normal polling is that the CPU
knows that at least one device is active. The alternative solution is for additional hard-
ware to provide a unique d6ta input (or "vector") for each source. The two alternatives
can be mixed; the vectors can identify groups of inputs from which the CPU can iden-
tify a particular one by polling. -^»__«p««—
An interrupt system that can differentiate between important and |
PRIORITY [
unimportant interrupts is called a "priority interrupt system." In-
ternal hardware can provide as many priority levels as there are inputs. External hard-
warp can provide additional levels through the use of a Priority register and comparator.
The external hardware does not allow the interrupt to reach the CPU unless its priority
IS higher than the contents of the Priohty register. A priority interrupt system may need

a special way to handle tow-priority interrupts that may be ignored for long periods of
time.

Most interrupt systems can be enabled or disabled. In fact most ENABLING


CPUs automatically disable interrupts when a RESET is performed AND
(so that the programmer can configure the interrupt system) and DISABLING
on accepting an interrupt (so that the interrupt will not interrupt INTERRUPTS
its own service routine). The programmer may wish to disable in-

terrupts while preparing or processing data, performing a timing loop, or executing a


multi-byte operation.

An interrupt that cannot be disabled (sometimes called a "non- NON-MASKABLE


maskable interrupt") may be useful to warn of power failure, an INTERRUPT
event that obviously must take precedence over all other ac-
tivities.

The advantages of interrupts are obvious, but there are also DISADVANTAGES
disadvantages. These include: OF INTERRUPTS
1) Interrupt systems may require a large amount of extra

hardware.
2) Interrupts still require data transfers under program control through the CPU. There

is no speed advantage as there is with DMA.


3) Interrupts are random inputs, which makes debugging and testing difficult Errors
may occur sporadically, and therefore may be very hard to find.^
4) Interrupts may involve a large amount of overhead if many registers must be saved
and the source must be determined by polling.

Z80 INTERRUPT SYSTEM


The ZSO's internal response to an interrupt is fairly complex, since there are three
different operating modes. The interrupt system consists of:

1) An active-tow maskable interrupt inpu t (INT) and an active- zso


low non-maskable interrupt input (NMl). INTERRUPT
2) Two enable flip-flops (IFF1 and IFF2). IFF1 can be set or reset INPUTS
to enable or disable interrupts. 1FF2 serves as temporary
storage for IFF1 during non-maskable interrupts.

12-2
The Z80 checks the current status of the interrupt system at the Z80
end of each instruction cycie. !f an interrupt is active and enabled, INTERRUPT
the response is as foHows:^ RESPONSE
1) The CPU disables the interrupt system by clearing IFF1. IFF2,
howe_verJs left in its original state if a non-maskable interrupt has occurred. Note
that RESET clears both interrupt ffip-flops so that the system can be configured
before interrupts are enabled.
2) The CPU executes a special Interruptcycle, distinguished by the MT
Ack nowled ge
signal (operation code MREQ
(me mory r equest) inactive (so the
fetch) being active.
CPU will not perform its normal memory access), and lORQ (input/output request)
active so that an interrupt response vector can be placed on the Data Bus.

The remainder of the response depends on the interrupt mode and the source.

Note in particular that the Z80 will check for interrupts after each transfer or com-
parison in a Block Move, Block Connpare, or Repeated Block I/O Instruction.

The Z80 has the following special instructions for use with the Z80 INTERRUPT
interrupt system: INSTRUCTION
1) E! (Enable Interrupts) enables the maskable interrupt by
setting the interrupt flip-flops.
2) Dl (Disable Interrupts) disables the maskable interrupt by cleanng the interrupt flip-
flops.

3) RST (Restart) is a one-word Call instruction that saves the current value of the Pro-
gram Counter in the Stack and jumps to the address specified m the instruction.
Table 12-1 contains the various Restart instructions and their destination ad-
dresses. RST is often used in interrupt systems because it is a one-word instruction
that is easy to form and place on the Data Bus.
4) RETI (Return from Interrupt) acts exactly like a normal Return (RET) Instruction ex-
cept that Z80 peripheral chips (PIOs, SIOs, and CTCs) recognize this instruction and
use it as a notification that the current interrupt service routine has been com-
pleted.

5) RETN (Return from Non-Maskable Interrupt) acts exactly Hke a normal Return (RET)
instruction except that it loads 1FF1 from IFF2 so as to restore the original state of
the interrupt system.
6) ID AJ loads the Accumulator with the contents of the (Interrupt Vector) register.
I

This instruction (and LD A,R) also places IFF2 into the P/0 bit of the Flag register.
That flag can then be tested or saved in the Stack.
7) LD LA loads the I (Interrupt Vector) register with the contents of the Accumulator.
8) IM (Set Interrupt Mode) determines the mode m which interrupts are serviced. The
three options are 0, 1. or 2; these are described later in this chapter.

Non-Maskabie Interrupt
The non-maskable interrupt is an edge-sensitive (negative Z80
edge triggered) input. The processor therefore reacts only to NON-MASKABLE
the edge of a pulse on this line, and the pulse will not interrupt INTERRUPT
its own service routine. Non-maskable interrupts are useful for
applications thatmust respond to loss of power (i.e., must save data in a tow-power
memory or switch to a backup battery). Typical applications are communications equip-
ment that must retain codes and partial messages and test equipment that must keep
track of partially completed tests.

12-3
Table 12-1 The Restart {HiST) Instructions

RST tnstnjction Operation Code Destination Address

(Mnemonic} Hex) IHex) (Decimal)

RSTO C7 0000
RST 8 CF 0008 08
RST lOH D7 0010 16
RST t8H DF 0018 24
RST 20H E7 0020 32
RST 28H EF 0028 40
RST 30H F7 0030 48
RST 38H FF 0038 56

The Z80 responds to a non-maskable interrupt as follows:


1) It clears 1FF1, thus disabling at! interrupts (but saving the old state of IFF1 in 1FF2).

2) It ignores the next instruction fetched from memory and instead jumps to memon/
location 0066-1 g, saving the old value of the Program Counter in the Stack.

Remember that a RETN instruction at the end of the service routine will restore the old
state of IFF1 from IFF2.

We will not discuss the non-maskable Interrupt further. Henceforth, we will assume
that all Interrupt inputs are tied to INT,

Z80 Interrupt Modes


The Z80 has three interrupt modes. The programmer can choose INTERRUPT
any of these modes with the appropriate IM instruction. On reset MODES
the processor always enters Mode 0. The modes are;

Mode
in this mode, the CPU uses the data input during the Interrupt Acknowledge cycle as an
instruction. This mode is the same as the 8080 Interrupt response mode.^
The normal data input that must be provided externally is a RST instruction (see Table
12-1).

RST is useful In Interrupt systems for the following reasons: RESTART


INSTRUCTION
1) It IS a one-word Instruction and so requires only one fetch
cycle.

2) It provides eight different destination addresses or vectors.


3) its vectors are far enough apart to atlow Jump instructions to reach the actual ser-
vice routines.
4) It is easy to form, since five of the bits are always '1,' An8-to-3 encoder can provide
the other three bits quite easily.

RST has the following disadvantages:


1) It cannot provide more than eight vectors,
2) Its vectors are not far enough apart to allow space for entire interrupt service
routines,
3) Its vectors are in a fixed area of memory.
4) RST has the same destination address as the RESET input and is th erefore very
difficult to use. The system needs hardware to differentiate between RESET and
RST 0, since the two cannot be distinguished by software atone.

12-4
Remember that RST saves the old Program Counter in the Stack just as CALL does.
Model
in this mode, the CPU ignores the data input during the interrupt Acknowiedge cycle
and always executes RST 38H. thus jumping to memory location OOSS-jg and saving
the old Program Counter in the Stack. This mode is equivalent to Mode if the data in-

put is always RST 38H (FF^g).

The advantage of this mode is that no external hardware is required. Its disadvantages
are that there Is no way to directly differentiate among interrupt sources and the
destination address \s Mode 1 is useful in applications that have
fixed. only one or two
interrupt sources and m which minimum hardware cost Is essential.
Mode 2
In this mode, the CPU uses the data input as part of an address from which to get the
starting address of the interrupt service routine. When an interrupt is accepted, the
CPU:
1) Disables further interrupts by clearing IFF1 and IFF2.
2) Stores the old Program Counter in the RAM Stack.
3} Forms a pointer from the contents of Register I (eight MSBs) and the Data Bus input
dunng the interrupt Acknowledge cycle (eight LSBs). The least significant bit of
this pointer is forced to zero.
4) Fetches an address from the two memory locations starting with the one referred to
by the pointer (see Figure 12-1).
51 Transfers control to the address obtained from memory.

Interrupt response in this mode requires 19 clock cycles.

The advantage of this mode is it can provide a full page of 128 interrupt service
that
vectors located anywhere inmemory. The disadvantages of this approach are that the
interrupt response is slower and the system must be Initialized, as follows:

1) The table of vectors must be loaded into memory if it is not in ROM.


2) The I register must be loaded with the eight most significant bits (or page number)
of the table address. Note that RESET clears Register You can load with a valueI. I

as follows:

LD A.IPGNO :GET INTERRUPT PAGE NUMBER


LD I.A ;STORE IN VECTOR REGISTER
3) Interrupt Mode 2 must be set with the instruction IM 2.

Mode 2 is designed to work with Z80 PIOs, SIOs, and CTCs. PIO and StO interrupts are
described later in this chapter.

Z80/8080 INTERRUPT COMPATIBILITY


Mode for the Z80 interrupt system is, as mentioned, identical to the 8080 interrupt
response. The 8080 does not have Interrupt Mode s 1 o r 2. although Mode 1 is really just
a special case of Mode 0. The 8080 also has no NMI input.

The 8085 has additional interrupt inputs, not available on either the 8080 or the Z80.
The 8085 also has a non-maskable interrupt (call ed T RAP) that forces a call to a
different address (24-15) ^han that used by the Z80 NMI input

12-5
desired starting address
pointed to by:
Interrupt

8 Bits from 7 bits from Service


" low-order
\ Routine
1 Register Penpheral

high-order
/ Starting

Address
: Table

Figure 12-1. Forming an Interrupt Vector in Interrupt Mode 2

PIO INTERRUPTS
Most Z80 interrupt systenns involve PtOs. Each port of the P!0 has
™__
PIO
the foliowmg features for use with interrupts: INTERRUPTS
1) An 8-bit Interrupt Vector register used to hold the eight least
significant bits of the table address formed by the CPU in interrupt Mode 2.

2) An interrupt enable bit

3) An Interrupt Control register used to determine the logical operation performed and
the active poianty monitored for generating interrupts tn the control mode.

4) An Interrupt Mask register used to determine which data lines will be monitored to
generate Interrupts In the control mode.

The Interrupt Vector register in each port can be accessed by writ- PIO
mg a control word with a zero in its least significant bit as shown INTERRUPT
below (see also Table 11-2): VECTOR
D7 D6 D5 D4 D3 D2 D1 DO

E V6 V5 V4 V3 V2 V1

/
,"1

signlf esth s con trol word is an /


m lerrupt vecl or

A typical sequence to establish the value in this register is:

LD AJVECT
OUT (PIOCRI.A

where IVECT has a '0'


m its The starting address for the interrupt
least significant bit
service routine is at address IVECT on the page assigned to the table of starting ad-
dresses for service routines.

12-6
D7 D6 05 D4 D3 D2 D1 DO

Enable AND/ High/ Mask


1 1
Interrupt OR Low follows
t

used in Mode 3 only signifies interrupt contro! word

Figure 12-2. Format for a PIO Interrupt Control Word

D7 D6 D5 D4 D3 D2 D1 DO

MB7 MB6 M85 M84 MB3 MB2 MB1 MBO

0n}y those port lines whose mask bit iS zero will be monitored for generating an interrupt.

Figure 12-3. Format for a PIO Interrupt Mask


We can set the interrupt control word in each port by writing a PIO
controlword with the format shown m Figure 1 2-2. If the port is m INTERRUPT
Mode 3. bits D6, D5, and D4 have the following meanings: CONTROL
1) D6 = 1 means that all monitored I/O lines must become active
MODE
to cause an interrupt (i.e.. a logical AND), while D6 = means
that any monitored I/O line becoming active will cause an interrupt (i.e., a loaical
; OR}.

Note that an interrupt occurs only if the logical equation is true when interrupts are
enabled or if it changes from false to true while interrupts are enabled,

2) D5 defines the active polarity (high or low) of the monitored I/O lines. D5 = 1
means active high. D5 = means active low.
3) D4 = 1 means that the next control word is an interrupt mask (Figure 12-3). Only
lines With a mask bit of zero will be monitored. D4 = means that the mask does
not follow.

Bit 7 of the interrupt control word determines the value of the ENABLING AND
interrupt enable flip-flop for the port. Interrupts may be gener- DISABLING PIO
ated if the flip-flop Power~on resets this flip-flop, but
is set. INTERRUPTS
remember no RESET input. The interrupt ena-
that the PIO has
ble flip-flop may be set or reset without affecting the rest of the interrupt control word
by writing a control word with the flip-flop value in bit 7 and 001 1 in the four least sig-
nificant bits.

Setting bit 4 of the interrupt control word clears any pending interrupts. This can be

used to clear interrupts that may have occurred inadvertently during a reset.

12-7
Examples
1) interrupting output port with vector located at address
EXAMPLES OF
8O16. Remennber that the page number is in the CPU i PIO INTERRUPT
register.
CONFIGURATION
LD A.00001111B MAKE PORT B OUTPUT
OUT (PtOCRB).A
LD A.80H VECTOR ADDRESS -80 HEX
OUT (PtOCRA),A
LD A. 1 000001 1B ;ENABLEPtO INTERRUPT
OUT (PIOCRB),A

An alternative that clears pending interrupts as well as enabling interrupts from the
port is:

LD A.10010111B :ENABLE PIO INTERRUPT


OUT {PIOCRA),A

An interrupt wilt occur on the rising edge of STB.

2) Interrupting input port with vector located at address eO-jg,

LD A,01001111B MAKE PORT A INPUT


OUT (PIOCRA),A
LD A,60H VECTOR ADDRESS = 60 HEX
OUT (PIOCRA).A
LD A. 1 000001 1B ENABLE PIO INTERRUPT
OUT (PIOCRA),A

An interrupt will occur on the rising edge of STB.

3) Interrupting control port with vector located at address 48i6- An interrupt will^ be
generated if data tines A4 and Ay both go low. ^, ^

LD A.11001111B :MAKE PORT A CONTROL


OUT (PIOCRAIA
LD A.10001000B ;L!NES 47 INPUTS - OTHERS OUTPUTS
OUT (PIOCRA).A
LD A.48H ;VECTOR ADDRESS =48 HEX
OUT (PtOCRA).A
LD A,11010111B ;ENABLE PIO INTERRUPT
OUT (PIOCRA),A
LD A.01110111B ;MONITOR LINES 47 ONLY
OUT (P10CRA),A

The interrupt control word has:

bit 7 = 1 to enable the interrupt


bit 6 = 1 to generate an interrupt only if alt monitored tines are or

become active (a logical AND)


bit 5 =0 to specify that a logic '0'
is the active state to be monitored
t),t 4 = 1 to indicate that a mask word follows (and to reset pending
interrupts)

12-8
4) interrupting control port with vector located at address 2815. An interrupt wll! be
generated if any of the data lines go high.

LD A,11001111B :MAKE PORT B CONTROL


OUT (PIOCRB),A
LD A.OFFH :ALL LINES INPUTS
OUT (P!OCRB).A
LD A,28H iVECTOR ADDRESS = 28 HEX
OUT (PIOCRB),A
LD A.10110111B ;ENABLE INTERRUPTS
OUT (PIOCRB).A
SUB A ;MON!TOR ALL LINES
OUT (PIOCRB),A

The interrupt control word has:

bit 7 = 1 to enable the Interrupt


bit 6 == to generate an interrupt if any monitored lines become active
(a logical OR)
bit 5 = 1 to specify that a logic 'V is the active state to be monitored
bit 4 == 1 to indicate that a mask word follows (and to reset pending
interrupts).

Obviously a repeated Block Output instruction could be used to shorten these programs
considerably.

Each PIO also has a singlejnterrupt output


and enable signals DAISY
for daisy chaining. The INT output is active-low when the PIO CHAINING
has an interrupt request The enable signals are: PIO
IE!' (Interrupt Enable In) — high if no other devices of higher
INTERRUPTS
priority are being serviced by a CPU interrupt service routine.

!E0 (Interrupt Enable Out) — high if lEI is high and the CPU is not servicing an interrupt
from this PIO

lEIand lEO can be used to form a daisy chain (see Volume 1 of An PIO DAISY
Introduction to Microcomputers in which PIOs and other devices
)
CHAIN
that are connected to the chain closer to the CPU can block inter- SIGNALS
rupt requests from devices further from the CPU. The advantages
of the daisy chain are;

1) It identifies each source uniquely. ADVANTAGES


2) It requires no other hardware, AND
3} It is easy to expand or rearrange in hardware. DISADVANTAGES
OF DAISY CHAIN
The disadvantages of the daisy chain are: INTERRUPTS
1) It can be varied or changed only in hardware.
2) It does not provide for eventual servicing of low priority in-
terrupts.

3) It requires extra time because signals must ripple through the chain.
The Z80 automatically waits long enough for the signals to ripple through a chain of up
to four devices when operating in Interrupt Mode 2. Additional hardware can be added
to allow longer chains.

12-9
Note that a particular device in the chain operates as follows: DEVICE
OPERATION
1) !t places !ts on the bus during an Interrupt
interrupt vector
IN A DAISY
Acknowledge cycle only if it has a pending interrupt re- CHAIN
quest and Interrupt Enable (n is high (indicating no higher
priority devices are being serviced). Interrupt Enable Out is
also set tow. Within a device. Port A interrupts take precedence over Port 8 inter-
rupts.

2) tt subsequently brings its Interrupt Enable Out high (enabling lower priority

devices) only if a RETI instruction is executed while its Interrupt Enable In is high.

Thus, a particular device will be serviced only when it has the highest priority request
and will block lower-pnonty requests until its service routine has been connpleted. A
higher-priority device can interrupt a lower-pnortty service routine without any
difficulty. Note that a RETI instruction at the end of the high priority routine will not be
recognized by the lower-priority device.

SIO IMTEHRUPTS
The SIO can also serve as a source for interrupts. You should note SIO
the following features of the SiO tnterrupt-based systenns:
INTERRUPTS
1) The transmitter interrupt is enabled by setting bit 1 of Write
Register 1 on each channel.
21 The interrupt vector is affected by bits 2, 3. and 4 of Write Register 1 according to
Tables 12-2 and 12-3.
3) The interrupt vector is in Write Register 2 on Channel B only. It can be read from
Read Register 2 on Channel B only.

4) Bit D1 of Read Register on Channel A is 1 if any interrupt condition is presenHf


the entire SIO. i

Withm an SIO, Channel A interrupts have priority over Channel B interrupts, receiver inr

terrupts have priority over transmitter interrupts, and transmitter interrupts have
priority over external or status interrupts.

SIOs can be used in a polling interrupt system. The CPU must POLLING
check each StO for activity by examining bit 1 of Read Register 9 INTERRUPT
on Channel A; i.e., SYSTEMS
WITH SIOs
SUB A :ACCESS READ REGISTER
OUT (S10CRA),A
IN A,(StOCRA) :GET SIO STATUS
BIT l.A ;ANY INTERRUPTS PENDING?
JR NZ,SERVE :YES, INTERRUPT ACTIVE

The important features of a Z80 polling system are:

1) The first examined has the highest priority, since the remaining interrupts
interrupt
will not be examined if the first one is active. The second interrupt has the next
highest priority, and so on.
2) The service routine must clear the SIO interrupt by reading or writing the appropri-
ate data register even if a data transfer is otherwise unnecessary.

12-10
Table 12-2. Further Vectoring of SIO Interrupts
2 of SIO Write Register 1 on Channel B is 1)
(Bit

Status Affects Vector (02) (Channel 8 OnM


tf this bit rs 1, the vector returned from an interrupt acknowledge cycfe vwH be vanable according to the foliowing:

V3 V2 VI

Ch 8 Transmit Suffer Empty


1 Ch B Externa! /Status Change
ChB
1 Ch 8 Receive Character Available
1 1 Ch 8 Special Receive Condition*

1 Ch A Transmit Buffer Empty


1 1 Ch A External /Status Change
Ch A
1 1 Ch A Receive Character Available
1 1 1 Ch A Special Receive Condition*

Panty Error or
Rx Ovemin En-or or
*Special Receive Conditions -
CBC/ Framing Error or
End of Frame (SDLC)

If this bit is 0, the fixed vector programmed in the Intenrupt Vector register is retumed.

Table 12-3. SIO Interrupt Modes


3 and 4 of Write Register 1)
(Bits

Rec Int Mode (D3). Rec int Mode 1 (04)

Receive Intemipt Mode and Receive Inten-upt Mode 1 together specify the vanous character available conditions:

D4 D3
Mode
Rec Int Rec Int

Model ModeO
Receiver interrupts disabled
1 1 Receive interrupt on first character
only error
2 1 Intemjpt on all Receive Characters-
Panty en^r affects Vector
3 1 1 Interrupt on all Receive Characters-
Parity error does not affect Vector

12-11
INTERRUPT EXAMPLES
A Startup Interrupt
Purpose: The computer waits for a PIO interrupt to occur before starting actual opera-
tions.

Many systems remain inactiv e until the operator actually starts them or a DATA READY
signal Is received. On RESET, such systems must initialize the Stack Pointe
enable the
r,

startup interrupt and execute a HALT instruction. Remember that


RESET disables the
processor interrupt and power-on disables all PIO interrupts. In the flowchart the
deci-

sion as to whether startup is active is made in hardware (i.e.. by the


CPU examining the
interrupt input internally) rather than in software.

Flowchart:

CZEZ)
Initialize Stack Pointer
Enable startup
interrupt on PiO

Enable GPU inten-upt

Source Program:
Main Program:
RESET EQU
ORG RESET
LD SP.IOOH :PUT STACK AT END OF MEMORY
LP A.01001111B ;PUT PIO IN INPUT MODE
OUT (PIOCRAi.A
LD AJ 000011 IB ;ENABLE PIO INTERRUPT
OUT (PIOCRA).A
E! :ENA8LE INTERRUPTS
HALT :AND WAIT
Interrupt Service Routine:

ORG INTRP
LD SP.100H iREINITIALiZE STACK POINTER
JP START ;START MAIN PROGRAM

12-12
Object Program:

Memory Address Memory Contents


Its Instruction
(Hex) (Hex] (Mnemonic)
Main Program:
0000 31 ID SP.100H
0001 00
0002 01
0003 3E LD A,01001111B
0004 4F
0005 D3 OUT (PIOCRA),A
0006 PIOCRA
0007 3E LD A,10000111B
0008 87
0009 D3 OUT (PIOCRA),A
OOOA PIOCRA
OOOB F8 El
OOOC 76 HALT
Interrupt Service Routine:

INTRP 31 LD SP.IOOH
lNTRP+1 00
INTRP+2 01
INTRP+3 C3 JP START
INTRP+4
!NTRP-f5 START

The main program must initialize the Stack Pointer, since the interrupt response always
stores the old Program Counter in the Stack. Here the service routine simply
reinitializes
the Stack Pointer before the actual startup routine is executed. An alternative would
be
to increment the Stack Pointer twice before jumping to the startup routine.
Remember
that the Z80 comes up rn Interrupt Mode 0. Any other mode would require the execu-
tion of an IM instruction.
The exact location of the interrupt service routine varies INTEBRUFTS ON
with the microcomputer If your microcomputer has no PARTICULAR
monitor, you can start the interrupt service routine MICROCOMPUTERS
wherever the external hardware or vector table directs the
CPU. Of course, you should place the routine so that it does not interfere with fixed ad-
dresses or with other programs.

If your microcomputer has a monitor, the


monitor will often oc- INTERRUPT
cupy the RESET and interrupt service addresses. It will then supply HANDLINO
service routines or the addresses of those routines. A typical moni- BY
tor routine initialization would be: MONITORS
MONIN: PUSH HL :SAVE OLD REGISTER CONTENTS
LD HL.USRINT ;GET USER ADDRESS FOR SERVICE
JP (HL) :JUMP TO USER SERVICE ADDRESS
You must then place the address of your service routine into memory locations USRINT
and USRINT-HI, using the normal 280 address format with the least significant bits at
the lower address. Remember that MONIN is an address in the monitor program.

12-13
You can include the loading of memon/ iocations USRINT and USRINT+1 in your nnatn
progrann; i.e.,

LD HLINTRP :GET STARTING ADDRESS OF SERVICE


, ROUTINE
LD (USRINT).HL ;STORE IT AS USER ADDRESS

These instructions conne before the enabling of the interrupts.

In this exannple, the return address that the Z80 stores in the Stack is not useful.
However, the nnain progrann must initialize the Stack Pointer so that there is a
still

definite place to put that address. You may not need the LD SP instruction if the nnoni-
tor in your nnicrocomputer manages the Stack Pointer.

The main program enables only the interrupt from the startup PIO. The PIG could, of
course, be In any mode. The interrupt is enabled by setting bit 7 of an Interrupt control
word and writing that word to the PIO control port. The PIO interrupt is enabled before
the overall interrupt system is enabled with the El instruction.

Remember that RESET and accepting an interrupt automatically disable the interrupt
system. This allows the real startup routine to configure alt the PtOs and other interrupt
sources without being interrupted.

No action is needed m the interrupt service routine, since the interrupt is automaticatly
cleared as part of the Interrupt Acknowledge cycle involving a particular PIO.
The implementations of the instructions El (Enable Interrupts) and Dl (Disable inter-

rupts) differ on the Z80. Di takes effect immediately after its execution, while El takes
effect after the execution of the following instruction. The reasoning behind this fact is
discussed in Chapter 3 under the description of the Et instruction.

A Keyboard Interrupt
Purpose: The computer waits for a keyboard interrupt and places KEYBOAFll>
the data from the keyboard into memory location 0040. INTERI^UPf
Sample Problem:
Keyboard data ~ 06
Result: (0040) = 06
Flowchart;

f Start
J

Initialize Stack Potnterj


Enable kevDoard
imarrupt on HIO
Enable CPU interrupt

12-14
Source Program:
Main Program:
RESET EQU
ORG RESET
LD SP..100H :PUTSTACK AT END OF MEMORY
LD A,01001111B :PUTPIO!N INPUT MODE
OUT {PIOCRA),A
LD A.10000111B ;ENABLE P!0 INTERRUPTS
OUT (PIOCRAl.A
El :ENABLE CPU INTERRUPTS
HERE: JR HERE :DUMMY MAIN PROGRAM
Interrupt Service Routine:

ORG INTRP
EX AF.AF' SAVE ACCUMULATOR. FLAGS
IN A,(P10DRA) GET KEYBOARD DATA
LD (40H),A SAVE KEYBOARD DATA
EX AF.AF RESTORE ACCUMULATOR. FLAGS
El RE-ENABLE INTERRUPTS
RETt

Object Program:
Mennorv Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
Main Program:
0000 31 LD SP.100H
0001 00
0002 01
0003 3E LD A.01001111B
0004 4F
0005 D3 OUT (PIOCRA).A
0006 PIOCRA
0007 3E LD A.10000111B
0008 87
0009 03 OUT (PIOCRA).A
OOOA PIOCRA
OOOB FB El
OOOC 18 HERE: JR HERE
OOOD FE

interruDt Service Routi ne:

INTRP 08 EX AF.AF
lNTRP+1 DB IN A, (PIODRA)
INTRP+2 PIODRA
lNTRP+3 32 LD (40H),A
INTRP+4 40
INTRP+5 00
INTRP+6 08 EX AF.AF
!NTRP+7 FB E!
INTRP+8 ED RETI
INTRP+9 4D

12-15
The JR HERE is an endless loop (jump-to-self) instruction that is used to represent the
main program. After interrupts are enabled in a working system, the mam program goes
about its business until an interrupt occurs and then resumes execution after the inter-

rupt service routine is completed.

The RET instruction at the end of the service routine transfers CHAtSiaiNG THE
control back to the JR you want to avoid this, you
instruction. !f RETURN
can simply increment the Program Counter in the Stack, e.g.. ADDRESS
EX (SP),HL ;GET RETURN ADDRESS
INC HL :INCREMENT RETURN ADDRESS TWICE
INC HL
EX (SP),HL :RESTORE ADJUSTED ADDRESS TO STACK

The RET instruction will now transfer control to the instruction following the JR. Note
the use of EX (SP),HL; this instruction exchanges the contents of Register Pair HL with
the contents of thememory locations at the top of the Stack. By using it we can adjust
the return address without affecting the contents of Register Pair HL

Since the Z80 does not automatically save its registers, you can use them to pass
parameters and results between the main program and the interrupt service routine. So,
you could leave the data in the Accumulator instead of in memory location 0040. Thrs
is, however, a dangerous practice that should be avoided in all but the
most trivia!
systems. In most applications, the processor is using its registers during normal pro-
gram execution; having the interrupt service routines randomly change the contents of
those registers would surely cause havoc. In general, no mterrupt service routine should
ever alter any register unless that register's contents have been saved prior to its altera-

tion and will be restored at the completion of the routine.

Note that you must explicitly re-enable the interrupts at the end of the service routine,
since the processor disables the interrupt system when it accepts an interrupt. Servic-
ing a PIO interrupt deactivates the interrupt signal so that the same interrupt is not ser-
viced again.

If interrupt service routines are never themselves interrupted (i.e.. SAVING


there is only one level of interrupts), the instructions EX AF.AF' VALUES IN
and EXX are a convenient way to save and restore the old contents PRIMED
of the user registers. EXX exchanges the contents of BC. DE. and REGISTERS
HL with the contents of their primed equivalents. The two instruc-
tions together take only two bytes of memon/ and eight clock cycles. However, this
method cannot be used if there are other interrupt levels (since there is only a single set
of primed registers) or if the primed registers are needed In either the main program or
the interrupt service routine.

A more general approach to saving and restoring registers is to use the Stack. PUSH
saves the contents of a register pair and POP restores the contents. Hov\/ever, PUSH
takes 1 1 clock cycles and POP 10. so this approach is slower. It also uses extra memory
locations in the Stack. The advantage of this method is that it can be expanded in-
definitely (as long as there is room in the Stack) since nested service routines wilt not
destroy the data saved by the earlier routines.

An alternative approach would be for the interrupt routine to FILLING A


maintain control until it received an entire line of text (e.g., a string BUFFER VIA
of characters ending with a carriage return). The main program INTERRUPTS
would be:

12-16
H

Main Program:
RESET EQU G
ORG RESET
ID SP,100H PUT STACK AT END OF MEMORY
LD A,01001111B PUT PIO IN INPUT MODE
OUT (PIOCRA},A
LD AJ0000111B ENABLE PIO INTERRUPTS
OUT (PIOCRA),A
LD HL70H INITIALIZE BUFFER POINTER
LD (40H),HL SAVE BUFFER POINTER
El ENABLE CPU INTERRUPT
HERE: JR HERE DUMMY MAIN PROGRAM
interrupt Service Routine:

ORG INTRP
EX AF.AF :SAVE A. FLAGS
EXX SAVE OTHER REGISTERS
LD HL,(40H) GET BUFFER POINTER
iN A,(PIODRA) GET KEYBOARD DATA
LD (HLl.A SAVE DATA IN BUFFER
CP CR : IS DATA A CARRIAGE RETURN?
JR Z.ENDL YES, END OF LINE
INC HL : NO, INCREMENT BUFFER POINTER
LD (40HKHL
EXX RESTORE OTHER REGISTERS
EX AF,AF' ! RESTORE A. FLAGS
El RE-ENABLE INTERRUPTS
RET!
ENDL: JP LPROC : PROCESS LINE WITHOUT INTERRUPTS
When the processor receives a carriage return, it leaves the interrupt system disabled
while It handles the line.

An alternative approach would be to fit! another buffer while han- DOUBLE


dling the first one; this approach is called double buffering. BUFFERING
The processing routine iS begun at address LPROC with inter-
line
rupts disabled, the old register contents in the primed registers, and the original return
address at the top of the Stack.

Ina real application, the CPU could perform other tasks between interrupts. It could, for
instance, edit move, or transmit a line from one buffer white the interrupt was filling
another buffer.

A Printer interrupt
Purpose: The computer waits for a printer interrupt and sends the data from memory
location 0040 to the printer.

Sample Problem:
(0040) = 51

Result: Pnnter receives a 51H (ASCII Q) when it is ready.

12-17
Flowchart:

c Start
D
I
Stack Pointer
tnitiatize
I
Enable printer
interrupt on PtO
Data =(40)

T
Enable CPU intemipt

Send data to printer

,
C End
J

Source Program:
Main Program:
RESET EQU
ORG RESET
LD SP.100H PUT STACK AT END OF MEMORY
LD A.000011118 PUT PIO IN OUTPUT MODE
OUT (PiOCRA).A
LD A, 1000011 IB ENABLE PtO INTERRUPTS
OUT (PtOCRA),A
Ei ENABLE CPU INTERRUPTS
HERE: JR HERE DUMMY MAIN PROGRAM
Interrupt Service Routine:

ORG iNTRP
EX ARAF SAVE ACCUMULATOR, FLAGS
LD A,(40Hl GET DATA
OUT (PIODRA),A SEND DATA TO PRINTER
EX AF.AP RESTORE ACCUMULATOR, FLAGS
Et RE-ENABLE INTERRUPTS
RETI

12-18
B

Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex) (Mnemonic) |

Main Program:
0000 31 ID SP.IOOH
0001 00
0002 01
0003 3E ID A.00001111B
0004 OF
0005 D3 OUT (P!OCRA),A
0006 PtOCRA
0007 3E LD A.10000111B
0008 87
0009 D3 OUT (PIOCRA),A
OOOA PtOCRA
OOOB FB El

OOOC 18 HERE: JR HERE


OOOD FE

Interrupt Service Routine:

INTRP 08 EX AF.AF'
iNTRP+1 3A LD A,(40H)
INTRP+2 40
INTRP+3 00
INTRP+4 D3 OUT (PiODRA),A
iNTRP-f5 PIODRA
INTRP+6 08 EX AF.AF
tNTRP4-7 FB El
tNTRP-l-8 ED RETl
lNTRP-f9 4D

Here, as with the keyboard,you could have the printer continue to


interrupt until it The main pro-
transferred an entire line of text EMmriNG A
gram and the service routine would be: BUFFER WITH
INTERRUPTS
Main Program:
RESET EQU
ORG RESET
LD SP.100H :PUT STACK AT END OF MEMORY
LD A.00001111B :PUT PIO IN OUTPUT MODE
OUT (PiOCRA).A
LD A. 100001 11 ;ENABLE PIO INTERRUPTS
OUT (P!OCRA),A
LD HLJOH BUFFER POINTER
:IN!TIALIZE
LD (40H).HL ;SAVE BUFFER POINTER
El :ENABLE CPU INTERRUPT
HERE: JR HERE ;DUMMY MAIN PROGRAM

12-19
)

Interrupt Servjce Routine:

ORG INTRP
EX AF.AF ; SAVE A, FLAGS
EXX SAVE OTHER REGiSTERS
LD HL,(40H) : GET BUFFER POINTER
LD A,(HL) : GET A BYTE OF DATA FROM BUFFER
OUT (PtODRA).A : SEND DATA TO PRINTER
CP CR ; !S DATA A CARRIAGE RETURN?

JR ENDL ; YES. END OF LINE


INC HL ; NO. INCREMENT BUFFER POINTER
LD (40H),HL
EXX RESTORE OTHER REGiSTERS
EX AF.AF' : RESTORE A. FLAGS
£! RE-ENABLE INTERRUPTS
RETi
ENDL: JP LCOMP : HANDLE COMPLETED UNE
Again, double buffering could be used to allow I/O and processing to occur at the same
time without ever halting the CPU

A Real-Time Clock Interrupt


Purpose: The computer waits for an interrupt from a real-time REAL-TIIME
clock. CLOCK
A The in-
real-time clock simply provides a regular series of pulses.
terval between the pulses can be used as a time reference. Real-time clock interrupts
can be counted to give any mutttple of the basic time interval. A real-time clock can be
produced by dividing down the CPU clock, by using a separate timer or a programma-
ble timer like the CTC for Z80-based microcomputers, or by using external sources such
as the AC iine frequency.

Note the tradeoffs involved in determining the frequency of the FREQUENCY


real-time clock. A high frequency (say 10 kHz) allows the crea- OF REAL-TIME
tion of a wide range of time intervals of high accuracy. On the CLOCK
other hand, the overhead involved in counting real-time clock
interrupts may be considerable, and the counts will quickly exceed the capacity of a
single 8-bit register or memory location. The choice of frequency depends on the preci-
sion and timing requirements of your application. The clock may, of course, consist
partly of hardware; a counter may count high frequency pulses and interrupt the pro-
cessor only occasionally. A program will have to read the counter to measure time to
high accuracy.

One problem is synchronizing operations with the real-time SYNCHRONIZATION


clock. Clearly, there will be some effect on the precision of WITH REAL-TIME
the timing interval if the CPU starts the measurement ran- CLOCK
domly during a clock period, rather than exactly at the
beginning. Some ways to synchronize operations are:

1 Start the CPU and clock together RESET or a startup interrupt can start the clock as
well as the CPU.
2) Allow the CPU to start and stop the clock under program control.

3) Use a high-frequency clock so that an error of less than one clock period will be
small.

4) Line up the clock (by waiting for an edge or interrupt) before starting the measure-
ment

12-20
A real-time clock interrupt should have very high priority, since PRIORITY
the precision of the timing intervals will be affected by any delay OF REAL-TIME
in servicing the interrupt The usual practice is to make the real- CLOCK
time clock the highest priority interrupt except for power failure.
The clock interrupt service routine is generally kept extremely short so that it does not
interfere with other CPU activities.

a) Wait for Real-Time Clock

Source Program:
Main Program:
RESET EQU
ORG RESET
LD SP.100H :PUT STACKAT END OF MEMORY
LD A.01001111B ;PUTPIOIN INPUT MODE
OUT (PIOCRA).A
LD A.10000111B :ENABLE PiO INTERRUPTS
OUT (PIOCRA).A
El ;ENABLE CPU INTERRUPTS
HERE: JR HERE ;DUMMY MAIN PROGRAM
Interrupt Service Routine:

ORG INTRP
HALT :END CLOCK INTERRUPT
Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex! (Mnemonic)

Main Program:
0000 31 LD SP,100H
0001 00
0002 01
0003 3E LD A.01001111B
0004 4F
0005 D3 OUT {PIOCRA),A
0006 PIOCRA
0007 3E LD A,10000111B
0008 87
0009 D3 OUT (PIOCRA),A
OOOA PIOCRA
OOOB FB El

OOOC 18 HERE: JR HERE


OOOD FE

Interrupt Service Routine

INTRP 76 HALT

The service routine does not have to do anything, since servicing the PIO interrupt auto-
matically clears it and there is no data to send or receive.

The real-time clock interrupt always occurs on* a rising edge if a PIO STROBE signal is

used for the clock input

12-21
b) Walt for 10 Beal-Tlme Clock Interrupts
Source Program:
Main Program:
RESET EQU
ORG RESET
LD SP..100H :PUT STACK AT END OF MEMO!
LD A.010011118 :PUT PIO IN INPUT MODE
OUT (P!OCRA),A
LD A.10000111B :ENABLE PIO INTERRUPTS
OUT (PIOCRA),A
LD HL40H :CLOCK COUNTER = ZERO
LD (HU.O
LD A,10 ;NUMBER OF COUNTS = 10
El :ENABLE CPU INTERRUPTS
WTTEN: CP (HL) ;HAVE TEN COUNTS ELAPSED?
JR NZ,WTTEN :N0. WAIT
HALT ;YES. DONE
Interrupt Service Routine:

ORG INTRP
EXX :SAVE USER REGISTERS
EX AF.AF :SAVE A, FLAGS
LD HL,40H :INCREMENT CLOCK COUNTER
!NC (HU
EX AF,AF ; RESTORE A, FLAGS
EXX :RESTORE USER REGISTERS
El :RE-ENABLE INTERRUPTS
RET!

12-22
Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex) (Mnemonic) |

Mam Program:

0000 31 LD SPJOOH
0001 00
0002 01
0003 3E LD A.01001111B
0004 4F
0005 D3 OUT (PIOCRAl.A
0006 PtOCRA
0007 3E LD A, 100001 118
0008 87
0009 D3 OUT (PIOCRA),A
OOOA PtOCRA
OOOB 21 LD HL.40H
OOOC 40
OOOD 00
OOOE 36 LD (HL).O
OOOF 00
0010 3E LD A,10
0011 OA
0012 FB El

0013 BE WTTEN: CP (HL)


0014 20 JR NZ,WTTEN
0015 FD
0016 76 HALT
Interrupt Service Routi ne:

INTRP U9 EXX
lNTRP-4-1 08 EX AF.AF'
lNTRP+2 21 LD HL40H
INTRP+3 40
lNTRP-f4 00
iNTRP+5 34 INC (HL)
INTRP+6 08 EX AF.AF'
lNTRP+7 D9 EXX
INTRP+8 FB El
!NTRP+9 ED RET!
lNTRP+10 4D

An aiternatiye approach uses the Stack to save and restore register values. To save H, L
and the flags requires:

PUSH HL :SAVE REGISTERS H AND L


PUSH AF :SAVE ACCUMULATOR AND FLAGS
To restore them requires the sequence:

POP AF :RESTORE ACCUMULATOR AND FLAGS


POP HL :RESTORE REGISTERS H AND L
Note that if the Stack is used, registers must be restored in the opposite order from that

inwhich they were saved. Clearly the order m which EXX and EX AF.AF' are executed
does not matter.

12-23
This interrupt service routine mereiy updates the counter m memory location 0040. It is

transparent to the mam program.

A more realistic real-time clock interrupt routine could MAINTAINSNG


maintain real time in several memory locations. For exam- REAL TIME
ple, the following routine uses addresses 0040 through 0043
as follows:

0040 - hundredths of seconds


0041 - seconds
0042 - minutes
0043 - hours

We assume that the routine is triggered by a 100 Hz clock.

Flowchart:

start
^ J
T .
Clear clock interrupt
Hundredths =
Hundredths + 1

Hundredths =
Seconds ==

Seconds + 1

No W

Seconds =
Minutes ==

Minutes + 1

Is ^**«*^^No \ f

iVRnutes 60

, Yes

(Minutes —
Hours =
Hours + 1

12-24
Source Program:
ORG INTRP
PUSH AF : SAVE REGISTERS
PUSH HL
LD HL,40H ; UPDATE HUNDREDTHS OF SECONDS
INC (HU
LD A. 100
CP (HU : IS THERE A CARRY TO SECONDS?
JR NZ.DONE ; NO.DONE
LD (HU.O ; YES.HUNDREDTHS -
INC HL : UPDATE SECONDS
INC (HL)
LD A, 60
CP (HL) : IS THERE A CARRY TO MINUTES?
JR NZ.DONE : NO. DONE
LD (HU.O ; YES, SECONDS -0
iNC HL : UPDATE MINUTES
INC (HU
CP (HU : IS THERE A CARRY TO HOURS?
JR NZ.DONE ; NO, DONE
LD (HU.O : YES.MINUTES -
INC HL : UPDATE HOURS
INC (HU
LD A.24 : DAY COMPLETED?
JR NZ.DONE : NO. DONE
LD (HU.O : YES. HOURS =
DONE; POP HL : RESTORE REGISTERS
POP AF
EI RE-ENABLE INTERRUPTS
RET!

it of 300 ms could be produ


LD HL40H ; GET PRESENT TIME (HUNDREDTHS OF SECS)
LD A,(HU
ADD A.30 : DESIRED TIME IS 30 COUNTS LATER
CP 100 : MOD 100
JR C.WT30
SUB 100
WT30: CP (HU : DESIRED TIME REACHED?
JR NZ,WT30 : NO, WAIT
Be careful in this program of the difference between INC HL and INC (HL). INC HL adds
1 to the 1 6-bit contents of Register Pair HL, while INC (HU adds 1 to the 8-btt contents
of the nnemorv location addressed by HL
Of course, the program could perform other tasks and check the elapsed time only oc-
casionally. How would you produce a delay of seven seconds?. Of three minutes?

Sometimes you may want to keep time either as BCD digits or as ASCII characters. How
would you revise the last program to handle these alternatives?
You can disable the clock interrupt (or any other Interrupt) when it DISABLING
is no longer needed m any of the following ways. INTERRUPTS
1) By executing a Dl instruction in the main program. This disa-
bles the entire interrupt system.
2) By clearing bit 7 of the interrupt control word during the service routine or during
the main program. This disables only the interrupt from one port of one PiO.

12-25
B

3) By not re-enabling the interrupt during the service routine.

Remember CPU
automatically disables interrupts upon accepting one. Thus,
that the
the interrupt system disabled unless the service routine explicitly re-enables it Note,
is

however, that you must be very careful about not re-enabling the interrupts, since the
main program would be completely unaware that interrupts were no longer allowed. In
general, alt interrupt service routines should re-enable the interrupts before return-
ing; any other policy means that the service routines are not transparent to the main
program.

A Teletypewriter interrupt
Purpose: The computer waits for data to be received from a teletypewriter and stores
the data in memory location 0040.

a) Using an SIO SiO


INTERRUPT
(7-bit characters with odd parity and 2 stop bits).
ROUTINE
Source Program:
Main Program:
RESET EQU
LD A.4 :ACCESS WRITE REGISTER 4
OUT {SIOCRA),A
LD A.01 000001 ;X16 CLOCK MODE, PARITY
OUT (StOCRA),A
LD A.3
OUT (S10CRA),A
LD A.01 000001 ;7 BIT CHARACTERS. ENABLE RECEIVER
OUT (StOCRA),A
LD A,1 ;ACCESS WRITE REGISTER 1

OUT {S10CRA),A
LD A,00011000B :ENABLE RECEIVER INTERRUPT ON ALL CHARS
OUT {SIOCRA),A
El :ENA8LE CPU INTERRUPTS
HERE: JR HERE :DUMMY MAIN PROGRAM
Interrupt Service Routine:

ORG INTRP
PUSH AF SAVE ACCUMULATOR. FLAGS
IN A.(SIODRA) READ CHARACTER FROM SIO
LD (40H).A SAVE CHARACTER IN MEMORY
POP AF RESTORE ACCUMULATOR, FLAGS
El RE-ENABLE INTERRUPTS
RETl

12-26
A B

Object Program:
Memory Address Memory Contents Instruction
(Hex) (Hex) (Mnemonic)
Main Program;
0000 3E LD A.4
0001 04
0002 D3 OUT (SIOCRA).A
0003 SiOCRA
0004 3E LD A,01 000001
0005 41
0006 D3 OUT (S!OCRA),A
0007 SIOCRA
0008 3E LD A.3
0009 03
OOOA D3 OUT (S!OCRA),A
OOOB SIOCRA
OOOC 3E LD A,01 000001
OOOD 41
OOOE D3 OUT (SIOCRA),A
OOOF SIOCRA
0010 3E LD A,1
0011 01
0012 D3 OUT (SIOCRA),A
0013 SIOCRA
0014 3E LD A.00011000B
0015 18
0016 03 OUT (SiOCRA),A
0017 SIOCRA
0018 FB El
0019 18 HERE: JR HERE
001 FE

Interrupt Service Routine:

INTRP F5 PUSH AF
INTRP+1 DB !N A. (SIODRA)
INTRP+2 SIODRA
INTRP+3 32 LD (40H).A
INTRP+4 40
iNTRP+5 00
INTRP+6 F1 POP AF
INTRP+7 FB El
INTRP+8 ED RETI
INTRP+9 40

This service routine assumes that only the receive interrupt from one channel of the SIO
has been enabled. Otherwise, either further vectoring will be required by changing con-
trol bits D2. D3, and D4 of Write Register (see the discussion of SIO interrupts earlier
in this chapter) or the routine will have to examine the status bits in Read Register 0.
The key status bits are:

Bit - Receive Character Available — 1 when at least one character is available in the
receive buffers.
Bit 1 - Interrupt pending (Channel A only) — 1 if any interrupt ts pending in the entire
SIO.

12-27
Bit 2 - Transmit Buffer Empty — 1 if the Transmit buffer iS empty.

Obviously, it would be far shorter and simpler to configure the SIO by using a table (in

ROM) and the repeated Block I/O instruction, i.e..

LD 8.6 NUMBER OF BYTES IN CONFIGURATION


LD C.SIOCRA SIO CONTROL PORT
LD HLStOTBL START OF StO CONFIGURATION TABLE
OT!R CONFIGURE SIO
This method requires 9 bytes of memory for the program and 6 bytes for the table, as

compared to the 23 bytes used m the example to configure the SIO.

The program establishes the SIO registers as follows:

WRITE REGISTER 4
Bit 7 = 0, bit 6 = 1 for X1 6 clock mode
Bit 1 =0 to select odd parity

Bit = 1 to enable parity generation

WRITE REGISTER 3
Bit 7 = 0. bit 6 = 1 to select 7-bit characters

Bit = 1 to enable the receiver

WRITE REGISTER 1

Bit 4 = 1 , bit 3 = 1 to produce an interrupt on ail received characters with parity errors
not affecting the vector.

The CPU clears the Received Character Available bit by reading a character from the
SIO Data register. The Interrupt Pending bit is cleared automatically when the interrupt
is serviced.

b) Using a PIO START BIT


INTERRUPT
(Received data tied to data bit 7 of PIO Port A).

Source Program:
Main Program:

LD A.11001111B ; MAKE PORT A CONTROL


OUT (P(OCRA),A
LD A,10000000B MAKE BIT 7 INPUT, OTHERS OUTPUTS
OUT (PIOCRA),A
LD A.10010111B ; ENABLE INTERRUPT ON START BIT (0)

OUT (PIOCRA),A
LD A.01111111B ; MASK OUT ALL OTHER BITS
OUT (PIOCRA).A
£1 ENABLE CPU INTERRUPTS
HERE: JR HERE : DUMMY MAIN PROGRAM
Interrupt Service Routine:

ORG INTRP
PUSH AF ; SAVE ACCUMULATOR, FLAGS
LD A.OOOOOniB ; DISABLE START BIT INTERRUPT
OUT (PIOCRA),A
CALL TTYRCV : FETCH DATA FROM TTY
LD A,10000111B ; ENABLE START BIT INTERRUPT
OUT (PIOCRA).A
POP AF ;
; RESTORE ACCUMULATOR. FLAGS
El RE-ENABLE INTERRUPTS
RETI

12-28
Object Program:
Memory Address Memory Contents Instruction 1

(Hex) (Hex) (Mnemonic) |

Mam Program:

0000 3E LD A11001111B
0001 CF
0002 D3 OUT (P!OCRA),A
0003 PIOCRA
0004 3E LD AJOOOOOOOB
0005 80
0006 D3 OUT (PtOCRA),A
0007 PIOCRA
0008 3E LD A.10010111B
0009 97
OOOA D3 OUT (P!OCRA),A
OOOB PIOCRA
OOOC 3E LD A.01111111B
GOOD 7F
OOOE D3 OUT (PIOCRA),A
OOOF PIOCRA
0010 FB Et

0011 18 HERE: JR HERE


0012 FE

Interrupt Service Routine:

JNTRP F5 PUSH AF
INTRP+1 3E LD A,00000111B
lNTRP+2 07
INTRP+3 D3 OUT (PIOCRA),A
INTRP+4 PIOCRA
INTRP+5 CD CALL TTYRCV
lNTRP+6 TTYRCV
!NTRP+7
INTRP+8 3E LD A.10000111B
lNTRP+9 87
INTRP+10 D3 OUT (PIOCRA).A
lNTRP+11 PIOCRA
iNTRP+12 F1 POP AF
INTRP+13 FB E!

INTRP-H14 ED RET!
INTRP+15 4D

These programs assume that the monitor initializes the Stack Pointer. Otherwise, it will

have to be loaded in the main program.

Subroutine TTYRCV is the TTY receive routine shown m the previous chapter.

The edge used to cause the interrupt Is very important here. An interrupt must occur
the data tine changes from the normal MARK or state to the SPACE or '0' state,
*1'
when
since this transition identifies the start of the transmission.

The service routine must disable the PIO interrupt since otherwise each '1'-to-'0' tran-
sition m the character will cause an interrupt Of course, you must re-enable the PIO in-
terrupt after the entire character has been read.

12-29
Note the use of the PIO in the control mode:

1) The PiO is placed in the control mode by establishing Mode 3.

2) The next control word defines which data lines are to be inputs CV) and which are
to be outputs CO'),

3) The interrupt control word has, besides the usual enable m bit 7,

bit 6 = to perform a logical OR


monitored data lines for an interrupt (not
of the
used in this case, since only one line is monitored)
bit 5 = to define the active polarity of the data lines as iow (for the start bit in this
case)
bit 4 = 1 to indicate that a mask word follows.

4} The next control word contains the interrupt masks. Only those port lines with a
mask bit of zero will be monitored for generating an interrupt

The net result is is zero or changes from one to


for an interrupt to be generated if bit 7
zero. Note that further interrupts occur only when a change occurs In the status of the
logical equation. Here again, the PIO could be configured by using a table and the re-
peated block output Instruction.

MORE GENERAL SERVICE ROUTINES


More general service routines that are part of a complete inter- TASKS FOR
rupt-dnven system must handle the following tasks: GENERAL SERVICE
ROUTIMES
1) Saving all registers that are used in the interrupt service
routine In the Stack so that the interrupted program can be
correctly resumed.

Remember that the Z80 Push instruction transfers a register pair (or an index register)
to the Stack. PUSH AF (F is the Flag register) transfers the Accumulator and flags to the
Stack.

A routine to save all the registers m the Stack would be:

PUSH AF :SAVE ACCUMULATOR. FLAGS


PUSH BC :SAVE REGISTERS B,C
PUSH DE ;SAVE REGISTERS D.E
PUSH HL SAVE REGISTERS H,L
PUSH IX SAVE INDEX REGISTER iX
PUSH lY SAVE INDEX REGISTER lY
EX AF.AF
EXX
PUSH AF SAVE PRIMED ACCUMULATOR. FLAGS
PUSH BC SAVE PRIMED REGISTERS B,C
PUSH DE SAVE PRIMED REGISTERS D.E
PUSH HL SAVE PRIMED REGISTERS H,L
Of course, only those registers that are used by the interrupt service routine must be
saved.

2) Restoring all registers from the Stack after completing the interrupt service routine.
Remember that registers must be restored in the opposite order from that in which
they were saved.
3) Enabling and disabling interrupts appropriately. Remember that the CPU automat-
ically disables Its interrupts upon accepting one.

The service routines should be transparent as far as the interrupted program is con-
cerned (i.e.. they should have no incidental effects).

12-30
Any standard subroutines that are used by an interrupt service routine must be
reentrant If some subroutines cannot be made reentrant the interrupt service routine
must have separate versions to use.^

PROBLEMS
1) A Test Interrupt
Purpose: The computer waits for a PIO interrupt to occur, then executes the endless
loop instruction:

HERE: JR HERE
until the next interrupt occurs.

2) A Keyboard Interrupt
Purpose: The computer waits for a 4-digtt entry from a keyboard and places the digits
into memory 0040 through 0043 (first one received in 0040). Each
locations
digit entry causes an interrupt The fourth entry should also result in the dis-
abling of the keyboard interrupt

Sample Problem:
Keyboard data = 04,06,01,07
Result: (0040) = 04
(0041) = 06
(0042) = 01
(0043) = 07
3) A Printer Interrupt
Purpose: The computer sends four characters from memory locations 0040 to 0043
(starting with 0040) to the printer. Each character is requested by an inter-
rupt The fourth transfer also disables the printer interrupt

4) A Real-Time Clock Interrupt


Purpose: The computer clears memory location 0040 initially and then complements
memory location 0040 each time the real-time clock interrupt occurs.
How would you change the program so that it complements memory location 0040
after every ten interrupts? How would
you change the program so that it leaves memo-
ry location 0040 at zero for ten clock periods, FF-) q for five clock periods, and so on con-
tinuously? You may want to use a display rather than memory location 0040 so that it
will be easier to see.

5) A Teletypewriter Interrupt
Purpose: The computer receives TTY data from an interrupting SIO and stores the
characters in a buffer starting m memory location 0040. The process con-
tinues until the computer receives a carriage return (OD-jg).

Assume that the characters are 7-bit ASCII with odd parity. How would you change
your program to use a PIO? Assume that subroutine TTYRCV is available, as in the ex-
ample. Include the carriage return as the final character in the buffer.

12-31
.

REFERENCES
1 You may want to review the discussion of interrupts in Volume 1 of An introduction
to Microcomputers.

2. For a discussion of designing with interrupts, see R. L Baldndge. "interrupts Add


Power, Complexity to Microcomputer System Design/' EDN, August 5, 1977, pp.
67-73.

3. See Volume 2 of An Introduction to Microcomputers.

4. See An Introduction to Microcomputers, Volume 2 and 8080A/8Q85 Assembly


Language Programming .

5. For further discussion and some real-life examples of designing Z80-based systems
with interrupts, see pp. 5-24 through 5-37 of Z80 Programming for Logic Design
and the following:
Baldridge, R. L.' "Interrupts Add Power, Complexity to Microcomputer System
Design/' EDN. August 5, 1977, pp. 67-73.

Pond, R. M., "Let Microprocessors Communicate/' Electronic Design . November 8.

1 977. pp. 88-90.

Shima, M.. and R. Btacksher, "Improved Microprocessor Interrupt Capability,"


Electronic Design April 26. 1978. pp. 96-100.
.

Weller. W. J., Practical Microcomputer Programming: the Z80 Northern Tech-


,

nology Books, Evanston. III.. 1978.

Winston. A. W.. and T. B. Smith. "Use of the Z-80 in Data Collection and Control/'
JECI '78 Proceedings - IndustriaJ Applications of Microprocessors. March 20-22.
1978, pp. 208-214.

The Proceedings of the IEEE's Industrial Electronics and Control Instrumentation


Group's Annua! Meeting on "Industriai Applications of Microprocessors" contains
many interesting articles. Volumes (starting with 1975) are available from IEEE Service
Center, CP Department, 445 Hoes Lane, Piscataway, NJ 08854.

12-32
Chapter 13
PROBLEM DEFINITION AND
PROORAM DESIGN
THE TASKS OF SOFTWARE DEVELOPMENT
!nthe previous chapters, we have concentrated on the writing of short programs in as-
sembly language. White this is an important topic, it is only a smai! part of software
development Although writing assembly language programs is a major task for the
beginner, it soon becomes simple. By now, you should be familiar with standard
methods for programming in assembly language on the Z80 microprocessor. The next
four chapters will describe how to formulate tasks as programs and how to com-
bine short programs to form a working system.

Software development consists of many stages. Figure STAGES OF


13-1 is a flowchart of the software development process. Its SOFTWARE
stages are: DEVELOPMENT
• Problem definition
• Program design
• Coding
• Debugging
• Testing
• Documentation
• Maintenance and redesign
Each of these stages is important in the construction of a working system. Note that
coding, the writing of programs in a form that the computer understands, is only one of
seven stages.

In fact coding is usually the easiest stage to define and per- RELATIVE
form. The rules for writing computer programs are easy to learn. IMPORTANCE
They vary somewhat from computer to computer, but the basic OF CODING
techniques remain the same. Few software projects run into trou-
ble because of coding; indeed, coding is not the most time-consuming part of software
development Experts estimate that a programmer can wnte one to ten fully debugged
and documented statements per day. Clearly, the mere coding of one to ten statements
is hardly a full day's effort On most software projects, coding occupies less than 25% of

the programmer's time.

Measuring progress in the other stages is difficult. You can say MEASURING
that half of the program has been written, but you can hardly say PROGRESS
that half of the errors have been removed or half of the problem IN STAGES
has been defined. Timetables for such stages as program design,
debugging, and testing are difficult to produce. Many days or weeks of effort may result
in no clear progress. Furthermore, an incomplete job m one stage may result in tremen-

dous problems later. For example, poor problem definition or program design can make
debugging and testing very difficult Time saved in one stage may be spent many times
over in later stages.

13-1
Start
J

Prc^em definition

Program design

fl>«®

Ox^

I
D^»igging

Docirniontation

I
Matnten^ceand
redesign

CZHZ)
Figure 13-1. Flowchart of Software DeveloDment

13-2
J

DEFINITION OF THE STAGES


Problem aefinitlon the formulation of the task in terms of
Is PROBIEM
the requirements that it places on the computer. For example, DEFINITION
what is necessary to make a computer control a tool, run a series
of electrical tests, or handle communications between a central controller and a remote
instrument? Problem definition requires that you determine the forms and rates of in-
puts and outputs, the amount and speed of processing that is needed, and the types of
possible errors and their handling. Problem definition takes a vague idea of building a
computer-controlled system and defines the tasks and requirements for the computer.

Program design Is the outline of the computer program which l>ROGRAM


will perform the tasks that have been defined, in the design DESIGN
stage, the tasks are described in a way that can easily be con-
verted into a program. Among the useful techniques in this stage are flowcharting,
structured programming, modular programming, and top-down design.

Coding is the writing of the program in a form that the com-


puter can either directly understand or translate. The form may
be machine language, assembly language, or a high-level language.
jCODING}
u-— —
Debugging, also called program verification, is making the pro- j DEBUGGING)
gram do what the design specified that it would do. In this
stage, you use such tools as breakpoints, traces, simulators, logic analyzers, and in-cir-
cuit emulators. The end of the debugging stage is hard to define, since you never know
when you have found the last error.

Testing, also referred to as program validation, is ensuring that {TESTING]


the program performs the overall system tasks correctly. The
designer uses simulators, exercisers, and various statistical techniques to get some
measure of the program's performance.
Documentation is the description of the program in the ( DOCUIVIENTATION j
proper form for users and maintenance personnel. Docu-
mentation also allows the designer to develop a program library so that subsequent
tasks will be far simpler. Flowcharts, comments, memon/ maps, and iibran/ forms are
some of the tools used in documentation.
ISAaintenance and redesign are the servicing, improvement, MAINTENANCE
and extension of the program. Clearly, the designer must be AND
ready to handle field problems in computer-based equipment REDESIGN
Special diagnostic modes or programs and other maintenance
tools may be required. Upgrading or extension of the program may be necessary to
meet new requirements or handle new tasks.
The rest of this chapter will consider only the problem definition and program
design stages. Chapter 14 will discuss debugging and testing- and Chapter 1 5 will dis-
cuss documentation, extension, and redesign. We will bring all the stages together in
some simple systems examples in Chapter 16.
PROBLEM DEFINITION
Typical microprocessor tasks require a lot of definition. For example, what must a pro-
gram do to control a scale, a cash register, or a signal generator? Clearly, we have a
long way to go just to define the tasks involved.

13-3
DEFINING THE INPUTS
How do we start the definition? The obvious place to begin is with the inputs. We
should begin by listing all the Inputs that the computer may receive in this applica-
tion.

Examples of inputs are:

• Data blocks from transmission lines

• Status words from peripherals


• Data from A/D converters

Then, we may ask the following questions about each input: FACTORS
IN INPUT
1) What is its form; i.e.. what signals will the computer actuallv
receive?
2) When is the mput available and how does the processor know it is available? Does

the processor have to request the input with a strobe signal? Does the input pro*
Vide !ts own clock?
3) How long is it available?

4) How often does it change, and how does the processor know that it has changed?
51 Does the Input consist of a sequence or block of data? is the order important?

6) What should be done if the data contains errors? These may include transmission
errors, incorrect data, sequencing errors, extra data, etc.

7) !s the input related to other inputs or outputs?

DEFINING THE OUTPUTS


The next step to define is the output. We must list all the outputs that the computer
must produce. Examples of outputs include:

• Data blocks to transmission lines

• Control words to peripherals


• Data to D/A converters

Then, we may ask the following questions about each output:


1) What iS Its form; i.e., what signals must the computer produce?
2) When must be it available, and how does the peripheral know It is available?

3) How long must it be available?


4) How often must it change, and how does the peripheral know that it has changed?
5) Is there a sequence of outputs? Is the order important?
6) What should be done to avoid transmission errors or to sense and recover from pe-
ripheral failures?

7) How Is the output related to other inputs and outputs?

13-4
PROCESSING SECTION
Between the reading of input data and the sending of output results is the processing
section. Here we must determine exactly how the computer must process the in-
put data. The questions are:

1) What IS the basic procedure {algorithnn) for transforming input FACTORS IN


data into output results? PROCESSING
2) What tinne constraints exist? These may include data rates,
delay times, the time constants of input and output devices, etc.
3) What memory constraints exist? Do we have limits on the amount of program
memory or data memory, or on the size of buffers?
4) What standard programs or tables must be used? What are their requirements?
5) What special cases exist and how should the program handle them?
6) How accurate must the results be?
7) How should the program handle processing errors or special conditions such as
overflow, underflow, or loss of significance?

ERROR HANDLING
An Important factqr in many applications is the handling of errors. Clearly, the
designer must make provisions for recovering from common errors and for diagnosing
malfunctions. Among the questions that the designer must ask at the definition
stage are:
1) What errors could occur? ERROR
2) Which errors are most likely? If a person operates the CONSIDERATIONS
system, human error is the most common. Following
human errors, communications or transmission errors are more common than
mechanical, electrical, mathematical, or processor errors.
3) Which errors will notbe immediately obvious to the system? A special problem is
the occurrence of errors that the system or operator may not recognize as incorrect
4) How can the system recover from errors with a minimum loss of time and data and
yet be aware that an error has occurred?
5) Which errors or malfunctionscause the same system behavior? How can these er-
rors or malfunctions be distinguished for diagnostic purposes?
6) Which errors involve special system procedures? For example, do parity errors re-
quire retransmission of data?

Another question is: How can the field technician systematically find the source of
malfunctions without being an expert? Built-in test programs, special diagnostics, or
signature analysis can helpJ

13-5
HUMAN FACTORS
Many microprocessor-based systems involve human interaction. OPERATOR
Human factors must be considered throughout the develop- INTERACTION
ment process for such systems. Among the questions that the
designer must ask are:
1) What input procedures are most natural for the human operator?
2) Can the operator easily determine how to begin, continue and end the input
operations?
3) How is the operator informed of procedural errors and equipment malfunctions?
4) What errors is the operator most tikety to make?
5} How does the operator know that data has been entered correctly?
6) Are displays in a form that the operator can easily read and understand?
7) Is the response of the system adequate for the operator?

8) Is the system easy for the operator to use?


9) Are there guiding features for an mexperlenced operator?
10) Are there shortcuts and reasonable options for the experienced operator?
11) Can the operator always determine or reset the state of the system after interrup-

tions or distractions?

Building a system for people to use is difficult. The microprocessor can make the
system more powerful, more flexible, and more responsive. However, the designer still
must a66 the human touches that can greatly increase the usefulness and attractive-
ness of the system and the productivity of the human operator.^

EXAMPLES
Response to a Switch
Figure 1 3-2 shows a simple system In which the input is from DEFINIIMG
a single SPST switch and the output is to a single LED display. SWITCH AND
In response to a switch closure, the processor turns the dis- LIGHT
play on for one second. This system should be easy to define. SYSTEM
Let us first examine the input and answer each of the questions SWITCH AND
previously presented: LIGHT INPUT
'0'
1) The input Is a single bit. which may be either (switch
'1' (switch open).
closed) or
2) The input Is always available and need not be requested.
3) The input is available for at least several milliseconds after the closure.

4) The input seldom change more than once every few seconds. The processor
will
has to handle only the bounce In the switch. The processor must monitor the
switch to determine when it is closed.
5) There is no sequence of inputs.
6) The obvious input errors are switch failure, failure in the input circuttn/. and the
operator attempting to close the switch again before a sufficient amount of time
has elapsed. We
will discuss the handling of these errors later.

7) The input does not depend on any other inputs or outputs.

13-6
^

+ 5V
O

Input

CPU
Port

X

The switch input iS a r if
\-

the switch
^/

is open, '0'
Output
Port

if the
h^
swtch is closed- The CPU applies the output to the
cathode of the LED; a 0* lights the display.

Figure 13-2. The Switch and Light System

The next requirement In defining the system is to examine the SWITCH


output. The answers to our questions are: AND LIGHT
1) The output is a single bit, which is
'0'
to turn the display oa
OUTPUTS
'1'
to turn it off.

2) There are no time constraints on the output The peripheral does not need to be in-
formed of the availability of data.
3) Ifthe display is an LED, the data need be available for only a few milliseconds at a
pulse rate of about 100 times per second. The observer will see a continuously lit
display,

4) The data must change (go off) after one second.


5) There is no sequence of outputs.

6) The possible outputerrors are display failure and failure In the output circuitry.
7) The output depends only on the switch input and time.
The processing section is extremely simple. As soon as the switch input becomes
a logic '0', the CPU turns the light on {a logic '0') for one second. No time or memo-
ry constraints exist

Let us now look at the possible errors and malfunctions. These SWITCH AND
are: LIGHT ERROR
• Another switch closure before one second has elapsed HANDLING
• Switch failure

• Display failure
• Computer failure

Surely the first error is the most likely. The simplest solution is for the processor to ig-
nore switch closures until one second has elapsed. This brief unresponsive period will
hardly be noticeable to the human operator. Furthermore, ignoring the switch during
this period means that no debouncing circuitry or software is necessary, since the
system will not react to the bounce anyway.

13-7
Clearly, the last three failures can produce unpredictable results. The display may stay

on, stay off, or change state randonniy. Some possible ways to isolate the failures would
be:

• Lamp-test hardware to check the display: i.e.. a button that turns the light on
independently of the processor
• A direct connection to the switch to check its operation
• A diagnostic program that exercises the input and output circuits

If both the display and switch are working, the computer is at fault .A field technician
with proper equipment can determine the cause of the failure.

A Switch-Based Memory Loader


Figure 1 3-3 shows a system that allows the user to enter DEFINING A
data into any memory location In a microcomputer. One in- SWITCH-BASED
put port, DPORT, reads data from eight toggle switches. MEMORY LOADER
The other input port, CPORT, is used to read control infor-
mation. There are three momentary switches: High Address, Low Address and
Data. The output is the value of the last completed entry from the data switches;
eight LEDs are used for the display.

The system will also, of course, require various resistors, buffers, and drivers.

We shall first examine the inputs. The characteristics of the switches are the same as
m the previous example; however, here there is a distinct sequence of inputs, as
follows:

1) The operator must set the data switches according to the eight most significant

bits of an address, then


2) press the High Address button. The high address bits will appear on the lights, and
the program will interpret the data as the high byte of the address.
3) Then the operator must set the data switches with the value of the least significant
byte of the address and
4) press thelow Address button. The low address bits will appear on the lights, and
the program will consider the data to be the tow byte of the address.
5) Finally, the operator must set the desired data into the data switches and
6) press the Data button. The display will now show the data, and the program stores
the data in memory at the previously entered address.

The operator may repeat the processto enter an entire program. Clearly, even in this
simplified situation, have many possible sequences to consider. How do we
we will
cope with erroneous sequences and make the system easy to use?
Output IS no problem. After each input, the program sends to the displays the
complement {since the displays are active-low) of the input bits. The output data
remains the same until the next input operation.

The processing section remains quite simple. There are no time or memory con-
The program can debounce the switches by waiting
straints. few milliseconds, and
for a
must provide complemented data to the displays.

13-8
Data Switches
-o<.
^o
^o
input
-a^o
Port
DPORT -a^o
^o
<^a
Data
Bus
-<^c.

High Address
"O o-

CPU
Input

Port -o
±o
CPORT

"O o-

I-5V

h-^ •^^^—^»

-^ ^ -VNA* — <^

-AAAf —<
O Output
Port
-®-
-^--wv-..
-VA — «>

-^ VNAr-

Figure 13-3. The Switch-Based Memory Loader

13-9
)

The most likely errors are operator mistakes. These include: MEMORY
LOADER
• Incorrect entries
ERROR
• Incorrect order HANDLING
• Incomplete entries; for example, forgetting the data

The system must be able to handle these problems in a reasonable


way. since they are certain to occur in actual operation.

The designer must also consider the effects of equipment failure. Just as before,

the possible difficulties are:

• Switch failure

• Display failure
• Computer failure

In this we must pay more attention to how these failures affect the
system, however,
system. A computer failure will presumably cause very unusual behavior by the system,
and will be easy to detect A display failure may not be immediately noticeable: here a
Lamp Test feature wilt allow the operator to check the operation. Note that we would
like to test each LED separately, in order to diagnose the case in which output lines are

shorted togethei; In addition, the operator may not immediately detect switch failure;
however, the operator should soon notice it and establish which switch is faulty by a
process of elimination.

Let us look at some of the possible operator errors. Typical errors OPERATOR
will be: ERROR
CORRECTION
• Erroneous data
IN MEMORY
• Wrong order of entries or switches LOADER
• Trying to go on to the next entry without completing the current
one
The operator will presumably notice erroneous data as soon as it appears on the dis-

plays. What is a viable recovery procedure for the operator? Some of the options are:

1 The operator must complete the entry procedure; i.e.. enter Low Address and Data
ifthe error occurs in the High Address. Clearly, this procedure is wasteful and
would only serve to annoy the operator.
2) The operator may restart the entry process by returning to the high address entry
steps. This solution is useful if the error was in the High Address, but forces the
operator to re-enter earlier data if the error was in the Low Address or Data stage.

3) The operator may enter any sequence at any time simply by setting the
part of the
Data switches with the desired data and pressing the corresponding button. This
procedure allows the operator to make corrections at any point in the sequenca

This type of procedure should always be preferred over one that does not allow immedi-
ate error correction, has a variety of concluding steps, or enters data into the system
without allowing the operator a final check. Any added complication in hardware or
software will be justified in increased operator efficiency. You should always prefer to
letthe microcomputer do the tedious work and recognize arbitrary sequences; it never
gets tired and never forgets what was in the operating manual.

A would be status lights that would define the meaning of the


further helpful feature
display. marked "High Address".. "Low Address", and "Data",
Three status lights,
would let the operator know what had been entered without having to remember which
button was pressed. The processor would have to monitor the sequence, but the a66e6
complication in software would simplify the operator's task. Clearly, three separate sets
of displays plus the ability to examine a memory location would be even more helpful to
the operator.

13-10
Keyboard Keyboai^ Strobe

Input Port

C=3 Keyboard Data

Display

X> Output Port(si :> Display

b XMIT
Output Port
Peripheral

To Centra!
Ready Strobe

Computer

h Data Strobe
RCV
Input Port
C~ 1 From Central Computer

L^ Status Light
Output Port

Figure 13-4. Block Diagram of a Verification Terminal

We should note that, although we have emphasized human interaction, machine


or system interaction has many of the same characteristics. The microprocessor
should do the work. If complicating the microprocessor's task makes error recov-
ery simple and the causes of failure obvious, the entire system will work better
and be easier to maintain. Note that vou should not watt until after the software has
been completed to consider system use and maintenance: instead, vou should include
these factors
in the problem definition stage.

A Verification Terminal
Figure 13-4 a block diagram of a simple credit-verification
is DEFINING A
terminal. Oneinput port derives data from a keyboard (see VERIFICATION
Figure 13-5); the other input port accepts verification data TERMINAL
from a transmission line. One output port sends data to a set of
displays (see Figure 13-6); another sends the credit card number to the central
computer. A third output port turns on one light whenever the terminal is ready to
accept an inquiry, and another light when the operator sends the Information. The
"Busy" light turns off when the response returns. Clearly, the input and output of
data wilt be more complex than in the previous case, although the processing is still
simple.

13-11
n
7 8 9

4 5 5 CLEAR

1 2 3 SEND

J
The digit keys aliow digit entries.

CLEAR deletes the entire entry,


SEND transmits the entry to the central computer.

Figure 13-5. Verification Termlnai Keyboard

READY BUSY

D 1

1
L_/ L_/ /_'
/ / / / /
O
*_/
'__'
/ /
'
/
11
/ /
It
1
II 1
1^1 iHi
'""'
dl

The disc lay consists of ten 7-segment displays, which may be multiplexed, controifed by a shift
register, or addressed separately. Two additional lights. READY and BUSY, are a!so present.

Figure 13-6. Verification Terminal Display

13-12
Additional displays may be useful to emphasize the meansng of the response. Many ter-
minals use a green light for "Yes", a red light for "No", and a yellow light for "Consult
Store Manager." Note that these lights will still have to be clearly marked with their
meanings to allow for a color-blind operator.

Let us look at the keyboard input. This is, of course,


first VERIFICATION
different from the switch input, since the CPU must have some TERMINAL
way of distinguishing new data. We
will assume that each key INPUTS
closure provides a unique hexadecimal code {we can code
each of the 12 keys into one digit) and a strobe. The program will have to recogn-
ize the strobe and fetch the hexadecimal number that identifies the key.
There is a
time constraint since the program cannot miss any data or strobes. The constraint is
not serious, since keyboard entries will be at least several milliseconds apart.

The transmission input similarly consists of a series of characters, each identified


by a strobe (perhaps from a UART). The program will have to recognize each
strobe and fetch the character. The data being sent across the transmission lines
is usually organized into messages. A possible message format is:

• introductory characters, or header


• Terminal destination address
• Coded yes or no
• Ending characters, or trailer

The terminal will check the header, read the destination address, and see if the
message is intended for it. If the message is for the terminal the terminal accepts the
data. The address could be (and often is) hard-wired into the terminal so that
the ter-
minal receives only messages intended for it This approach simplifies the software at
the cost of some flexibility.

The output also more complex than in the earlier examples.


is VERIFICATION
If the displays are multiplexed, the processor must not
only TERMINAL
send the data to the display port but must also direct the data OUTPUTS
to a particular display. We
will need either a separate control port
or a counter and decoder to handle this.
Note that hardware blanking controls can
blank leading zeros as long as the a multi-digit number is never zero. Soft-
first digit in
ware can also handle this task. Time constraints include the pulse length and frequency
required to produce a continuous display for the operator.

The communications output will consist of a series of characters with a particular


format. The program will also have to consider the time required between charac-
ters. A possible format for the output message is:

• Header
• Terminal address
• Credit card number
• Trailer

A central communications computer may poll the terminals, checking for data
ready to be sent
The processing in this system involves many new tasks, such as:

• Identifying the control keys by number and performing the proper actions
• Adding the header terminal address, and trailer to the outgoing message
• Recognizing the header and trailer in the returning message
• Checking the incoming terminal address

13-13
Note that none of the tasks involve any connplex arithmetic or any VERIFICATION
serious tinne or memory constraints. TERMINAL
ERROR
The number of possible errors in this system is, of course,
HANDtlNO
much larger than In the earlier examples. Let us first consider
the possible operator errors. These include:
• Entering the credit card number mcorrectly
• Trying to send an incomplete credit card number
• Trying to send another number while the central computer Is processing one

» Clearing non-existent entries

of these errors can be easily handled by correctly structuring the program. For
Some ex-

ample, the program should not accept the Send key until the credit card number has
been completely entered, and it should ignore any additional keyboard entries until the
response comes back from the central computer. Note that the operator will know that
the entry has not been sent since the Busy light will not go on. The operator will also
know when the keyboard has been locked out (the program is ignoring keyboard en-
tnes). since entries will not appear on the display and the Ready light will be off.

Incorrect entries are an obvious problem. If the operator recog- CORRECTING


nizes an error, he can use the Clear key to make corrections. The KEYBOARD
operator would probably find it more convenient to have two Clear ERRORS
keys, one that cleared the most recent key and one that cleared
the entire entry. This would allow both for the situation in which the operator recog-
nizes the error immediately and for the situation in which the operator recognizes the
error late in the procedure.The operator should be able to correct errors Immediately
and have to repeat as few keys as possible. The operator will, however, make a certain
number of errors without recognizing them. Most credit card numbers Include a self-
checking digit; the terminal could check the number before permitting it to be sent to
the central computer. This step would save the central computer from wasting precious
processing time checking the number.

This requires, however, that the terminal have some way of informing the operator of
the error, perhaps by flashing one of the displays or by providing some other special In-
dicator that the operator is sure to notice.

Stillanother problem is how the operator knows that an entn/ has been lost or pro-
cessed incorrectly. Some terminals simply unlock after a maximum time delay. The
operator notes that the Busy light has gone off without an answer being received. The
operator Is then expected to try the entry again. After one or two retries, the operator
should report the failure to supervisory personnel.

Many equipment failures are also possible. Besides the displays, keyboard, and
processor, there now exist the problems of communications errors or failures and
central computer failures.

13-14
The data transmission wlil probably have to include error checking and correcting pro-
cedures. Some possibilities are:

1) Parity provides an error detection facility but no correction CORRECTING


mechanism. The receiver wit! need some way of request- TRANSMISSION
ing retransmission, and the sender wit! have to save a copy ERRORS
of the data until proper reception is acknowledged. Parity
is, however, very simple to implement

2) Short messages may use more elaborate schemes. For example, the yes/no
response to the terminal could be coded so as to provide error detection and cor-
rection capability,

3) An acknowledgement and a limited number of retries could trigger an indicator


thatwould inform the operator of a communications failure (inability to transfer a
message without errors) or central computer failure {no response at all to the
message within a certain period of time). Such a scheme, along with the Lamp
Test would allow simple failure diagnosis.
A communications or central computer failure indicator should also "unlock" the ter-
minal, i.e., allow it to accept another entn/. This is necessary if the terminal will not ac-
cept entries while a verification is in progress. The terminal may also unlock after a cer-
tain maximum time delay. Certain entries could be reserved for diagnostics; i.e., certain
credit card numbers could be used to check the internal operation of the terminal and
test the displays.

REVIEW OF PROBLEM DEFINITION


Problem definition is as important a part of software development as it Is of any
other engineering task. Note that it does not require any programming or
linowledge of the computer; rather, it is based on an understanding of the system
and sound engineering Judgment. Microprocessors can offer flexibility that the
designer can use to provide a range of features which were not previously availa-
ble.

Problem definition is independent of any particular computer, computer language,


or development system. It should, however, provide guidelines as to what type or
speed of computer the application will require and what kind of hard-
ware/software trade-offs the designer can make. The problem definition stage is
in fact independent of whether or not a computer is used at all, although a
knowledge of the capabilities of the computer can help the designer In suggesting
possible implementations of procedures.

13-15
PROGRAM DESIGN
Program design is the stage in which the problem definition is formulated as a pro-
gram. If the program is small and simple, this stage may involve little more than
the writing of a one-page flowchart. If the program is larger or more complex, the
designer should consider more elaborate methods

We Will discuss flowcharting, modular programming, structured programming, and


top-down design. We will try to indicate the reasoning behind these methods, and
their advantages and disadvantages. We will not however, advocate any particular
method since there is no evidence that one method is always superior to alt others. You
should remember that the goal is to produce a good working system, not to follow
religiously the tenets of one methodology or another

Allthe methodologies do, however, have some obvious princi- BASIC


ples in common. Many of these are the same principles that appiy PRINCIPLES
to any kind of design, such as: OF PROGRAM
DESIGN
1) Proceed in small steps. Do not try to do too much at one
time.

2) Divide large jobs into smaH. logically separate tasks. Make the sub-tasks as inde-
pendent of one another as possible, so that they can be tested separately and so
that changes can be made in one without affecting the others.

3) Keep the flow of control as simple as possible so as to make it easier to find errors.

4) Use graphic descriptions as much as possible. They are easier to


pictorial or
visualize than word descriptions. This is the great advantage of flowcharts.

5) Emphasize clarity and simplicity at first You can improve performance (if necess-
ary) once the system is working.

6) Proceed in a thorough and systematic manner. Use checklists and standard pro-
cedures.
7) Do not tempt fate. Either do not use methods that you are not sure of. or use them
very carefully. Watch for situations that might cause confusion, and clarify them
as soon as possible.
8) Keep in mind that the system must be debugged, tested and maintained. Plan for

these later stages.


9) Use simple and consistent terminology and methods. Repetitiveness is no fault in

program design, nor is complexity a virtue.


10) Have your design completely formuiated before you start coding. Resist the
temptation to start writing down instructions: it makes no more sense than mak-
ing parts lists or laying out circuit boards before you know exactly what will be in
the system.
11} Be particularly careful of factors that may change. Make the implementation of
likely changes as simple as possible.

13-16
^7 Input/Output

Processing operation
(Arithmetic, Logtc, Data Movement)

Decision logic

CD Subroutine

o Connector point

Connector arrows

Termmal pomt

c J {Beginning or Ending)

Figure 13-7, Standard Flowchart Symbois

FLOWCHARTING
Flowcharting is certainly the best-known of all program design methods. Programming
textbooks describe how programmers first write complete flowcharts and then start
writing the actual program. In fact few programmers have ever worked this way. and
flowcharting has often been more of a joke or a nuisance to programmers than a design
method. We will try to describe both the advantages and disadvantages of flowcharts,
and show the place of this technique in program design.
The basic advantage of the flowchart is that it is a pictorial ADVANTAGES OF
representation. People find such representations much more FLOWCHARTING
meaningfulthan written descriptions. The designer can visual-
ize the whole system and see the relationships of the various parts. Logical errors and
inconsistencies often stand out instead of being hidden m a printed page. At its best,
the flowchart is a picture of the entire system.

13-17
Some of the more specific advantages of flowcharts are:

1) Standard symbols exist (see Figure 13-7) so that flowcharting forms are widely
recognized.
2) Flowcharts can be understood by someone without a programming background.
3) Flowcharts can be used to divide the entire project mto sub-tasks. The flowchart
can then be examined to measure overall progress.
4) Flowcharts show the sequence of operations and can therefore aid in locating the
source of errors.

5) Flowcharting is widely used in other areas besides programming.


6) There are many tools available to aid m flowcharting, including programmer's
templates and automated drawing packages.

These advantages are all important There is no question that DISADVANTAGES


flowcharting will continue to be widely used. But should we OF
note some of the disadvantages of flowcharting as a pro- FLOWCHARTING
gram design method, e.g.:

1) Flowcharts are difficult to design, draw, or change in all except the simplest situa-
tions.

2) There is no easy way to debug or test a flowchart.

3) Flowcharts tend to become cluttered. Designers find it difficult to balance between


the amount of detail needed to make the flowchart useful and the amount that
makes the flowchart little better than a program listing.
4) Flowcharts show only the program organization. They do not show the organization
of the data or the structure of the input/output modules.

51 Flowcharts do not help with hardware or timing problems or give hints as to where
these problems might occur.
6) Flowcharts allow for highly unstructured design. Lines and arrows backtracking
and looping all over the chart are the antithesis of good structured design princi-

ples.

Thus, flowcharting is a helpful technique that you should not try to extend too far.
Flowcharts are useful as program documentation, since they have standard forms
and are comprehensible to non-programmers. As a design tool, however, flowcharts
cannot provide much more than a starting outline; the programmer cannot debug a
detailed flowchart and the flowchart is often more difficult to design than the program
itself.

13-18
EXAMPLES
Response to a Switch
This simple task, in which a single switch turns on a light FtOWCHARTING
for one second, is easy to flowchart. !n fact such tasks are SWITCH AND
typical examples for flowcharting books, although they form a LIGHT SYSTEM
small part of most systems. The data structure here is so simple
that It can be safely ignored.
Figure 13-8 is the flowchart. There is little difficulty m deciding on the amount of

detail required. The flowchart gives a straightforward picture of the procedure, which
anyone could understand.
Note that the most useful flowcharts may ignore program variables and ask questions
directly.Of course, compromises are often necessary here. Two versions of the
flowchart are sometimes helpful —
one general version in layman's language,
which be useful to non-programmers, and one programmer's version
will in terms
of the program variables, which will be useful to other programmers.

A third type of flowchart, a data flowchart, may also be DATA


helpful. This flowchart serves as a cross-reference for the other FLOWCHARTS
flowcharts, since it shows how the program handles a particular
type of data. Ordinary flowcharts show how the program proceeds, handling different
types of data at different points. Data flowcharts, on the other hand, show how particu-
lar types of data move through the system, passing from one part of the program to
another.Such flowcharts are ven/ useful in debugging and maintenance, since errors
most often show up as a particular type of data being handled incorrectly.

13-19
Turn light on

Turn iight off

C J
Figure 13-8. Flowchart of One-Second Response to a Switch

The Switch-Based Memory Loader


This system (see Figure 13-3} is considerablv more complex FLOWCHARTING
than the previous example, and involves many more decisions. THE
The flowchart (see Figure 13-9) is more difficult to write SWITCH-BASED
and not as straightforward as the previous example. In this MEMORY LOADER
example, we face the problem that there is no way to debug or
test the flowchart

The flowchart in Figure 13-9 includes the improvements we suggested as part of the
problem flowchart is beginning to get cluttered and lose its
definition. Clearly, this
advantages over a written description. Adding other features that define the mean-
ing of the entry with status lights and allow the operator to check entries after comple-
tion would make the flowchart even more complex. Writing the complete flowchart
from scratch could quickly become a formidable task. However, once the program has
been written, the flowchart is useful as documentation.

13-20
High byte of
AddfBss = Data ==SwTtche5
Switches

lights -Switches Lights = Switches lights = Switches

Figure 13-9. Fiowchart of Switch-Based Memory Loader

13-21
t Start
^
t
Gear Entry Array
Key Pointer - Start
of Entry Array
Key Counter =

Ka/ -Keyboard
Input Data
(Key Pointer} = Key

Key Pointer =
Key -Pointer + 1
Key Coufito' ~
Key Counter + 1

C
Figure 13-10. Flowchart of Keyboard Entry Process

The Credit- Verification Terminal


In {see Figures 13-4 through 13-6), the
this application FLOWCHARTING
flowchart will be even nnore complex than in the switch-based THE CREDIT
memory loader case. Here, the best idea is to flowchart sec- VERIFICATION
tions separately so that the flowcharts remain manageable. FLOWCHARTING
However, the presence of data structures {as m the multi-digit SECTIONS
display and the messages) will make the gap between
flowchart and program much wider
Let us look at some of the sections. Figure 13-10 shows the keyboard entry process
for the digit keys. The program must fetch the data after each strobe and place the
digit into the display array if there is room for it if there are already ten digits in the ar-
ray, the program simply ignores the entry.

The actual program will have to handle the displays at the same time. Note that either
software or hardware must de-activate the keyboard strobe after the processor reads a
digit

13-22
r Start
J

Clear Display Arrav


Key Pointer = Start
of Ksplay Airav
Key Counter =

Key = Keyboard
Input Data

key Pointer) - Kev


Key Pointer =
Kev Pointer + 1
Key Counter =
Key Counter -f 1

C D
Figure 13-11. Fiowchart of Keyboard Entry Process with Send Key

Figure 13-11 adds the Send key. This key, of course, is optional The terminal coufd
justsend the data as soon as the operator enters a connplete nunnber. However, that
procedure would not give the operator a chance to check the entire entry. The
flowchart with the Send key is more complex because there are two alternatives.

1) If the operator has not entered ten digits, the program must ignore the Send key
and place any other key into the entry.

2) If the operator has entered ten digits, the program must respond to the Send kev by
transferring control to the Send routine, and ignore al! other keys.
Note that the flowchart has become much more difficult to organize and to follow.
There is also no obvious way to check the flowchart

13-23
c D
^5.
Ctear Display Array
Key Pointer =: Start
of Dteptay Array
Key Counter ==

Kev = Keyboard
mput Data

(Key Potnter) = Key


Key Pointer =
Key Pointer + 1

C Send

Figure 13-12. Flowchart of Keyboard Entry Process with Function Keys

Figure 13-12 shows the flowchart of the keyboard entry process with all the func-
tion keys. In this exampie, the flow of control is not simple. Clearly, some written
descnption is necessary. The organization and layout of complex flowcharts requires
careful planning. We have followed the process of adding features to the flowchart one
at a time, but this still results In a large amount of redrawing. Again we should remem-
ber that throughout the keyboard entry process, the program must also refresh the dis-
plays if they are multiplexed and not controlled by shift registers or other hardware.

13-24
Header flag =
Parity Error flag =
Address Match flag=0
Address Pointer =Start
of termina) address
Address Counter =
Nmess =

Messg (Nmessj =
Parrtv Error
=
Character
f!ag
Nmess = Nmess + t

Address Match
flag = 1

Address Counter =
Address Counter +1 Turn off Busy
Address Pointer = Sight
Address Pointer + 1

EI
Display answer
C ;
c 3
Figure 13-13. Flowchart of Receive Routine

13-25
Figure 13-13 is the flowchart of a receive routine. We assume that the sertal/paraMel
conversion and error checking are done in hardware (e.g.. by a UART). The processor
must:

1) Look for the header (we assume that it is a single character).

2) Read the destination address (we assume that three characters long} and see if
it is

the message is meant for this terminal: i.e., if the three characters agree with the
termmal address.
3) Wait for the trailer character.

4) tf the message is meant for the terminal, turn off the Busy light and go to Display

Answer routine,

5) In the event of any errors, request retransmission by going to RTRAN routine.

This routine involves a large number of decisions, and the flowchart is neither simple
nor obvious.

Clearly, we have come a long way from the simple flowchart (Figure 13-8) of the
firstexample. A complete set of flowcharts for the transaction terminal would be
a major task. It would consist of several interrelated charts with complex logic, and
would require a large amount of effort. Such an effort would be just as difficult as writ-
ing a preliminary program, and not as useful, since you could not check it on the com-
puter.

MODULAR PROGRAMMING
Once programs become targe and complex, flowcharting is no longer a satisfactory
design However, the problem definition and the flowchart can give you some idea
toot.

as to how to divide the program Into reasonable sub-tasks. The division of the entire
program into sub-tasks or modules is called "modular programming." Clearly, most
of the programs we presented in earlier chapters would typically be modules in a large
system program. The problems that the designer faces in modular programming are
how to divide the program into modules and how to put the modules together.
The advantages of modular programming are obvious: ADVANTAGES
and than an
OF MODULAR
1) A single module is easier to write, debug, test
PROGRAMMING
entire program.

2) A module is likely to be useful in many places and in other

programs, particularly if it is reasonably general and performs a common task. You


can build up a library of standard modules.
3) Modular programming allows the programmer to divide tasks and use previously
written programs.

4) Changes can be incorporated into one module rather than into the entire system.
5) Errors can often be isolated and then attributed to a single module.

6) Modular programming gives an idea of how much progress has been made and
how much of the work is left.

13-26
The idea of modular programming is such an obvious one DISADVANTAGES
that its disadvantages are often ignored. These include: OF MODULAR
11 Fitting the modules together can be a major problem, par-
PROGRAMMING
ticularlv if different people write the modules.

2) Modules require very careful documentation, since they may affect other parts of
the program, such as data structures used by all the modules.
3) Testing and debugging modules separately ts difficult since other modules may
produce the data used by the module being debugged and still other modules may
use the results. You may have to write special programs (called "drivers") just to
produce sample data and test the programs. These drivers require extra program-
ming effort that adds nothing to the system.
4) Programs may be very difficult to modularize. !f you modularize the program poorly,
integration wil! be very difficult since almost ail errors and changes will involve
several modules.

5) Modular programs often require extra time and memory, since the separate
modules may repeat functions.
Therefore, while modular programming is certainly an improvement over trying to write

the entire program from scratch, It does have some disadvantages as well

Important considerations include restricting the amount of information shared by


modules, limiting design decisions that are subject to change to a single module
and restricting the access of one module to another.^
An obvious problem is that there are no proven, PRINCIPLES OF
systematic methods for modularizing programs. We MODULARIZATION
should mention the following principles:^
1) Modules that reference common data should be parts of the same overall module.
2) Two modules in which the first uses or depends on the second, but not the reverse,
should be separate.
3) A module that is used by more than one other module should be part of a different
overall module than the others.

4) Two modules inwhich the first is used by many other modules and the second is

used by only a few other modules should be separate.


5) Two modules whose frequencies of usage are significantly different should be part
of different modules.

6) The structure or organization of related data should be hidden within a single


module.

If you find it very difficult to modularize your program, it is a strong indication that

the problem is poorly defined, and redefinition is called for. Too many special cases,
each requiring special handling, or the use of a large number of variables, each requir-
ing special processing, are problems that can be most efficiently handled, by redefining
the tasks at hand.

13-27
EXAMPLES
Response to a Switch
This simple program can be divided into two modules: MODULARIZING
THE SWITCH
Module 1 watts for the switch to be turned on and turns AND LIGHT
the light on In response. SYSTEM
Module 2 provides the one-second delay.

Module 1 be specific to the system, since it will depend on how the switch
is likeiy to

and light are attached. Module 2 will be generally useful, since many tasks require
delays. Clearly, it would be advantageous to have a standard delay module that could
provide delays of varying lengths. The module will require careful documentation so
that you will know how to specify the length of the delay, how to call the module, and
what registers and memory locations the module affects.

A general version of Module 1 would be far less useful, since it would have to deal with
different types and connections of switches and tights.

You would probably find it Simpler to write a module for a particular configuration of
switches and lights rather than try to use a standard routine. Note the difference be-
tween thts situation and Module 2.

The Switch-Based Memory Loader


The switch-based memory loader is difficult to modularize, MODULARIZING
since all the programming tasks depend on the hardware THE
configuration and the tasks are so simple that modules SWITCH- BASED
hardly seem worthwhile. The flowchart m Figure 13-9 sug- MEMORY LOADER
gests that one module might be the one that waits for the
operator to press one of the three pushbuttons.

Some other modules might be:

• A delay module that provides the delay required to debounce the switches
' A switch and display module that reads the data from the switches and sends it to
the displays
• A Lamp Test module

Highly system-dependent modules such as the last two are unlikely to be generally

useful. This example is not one m which modular programming offers great advantages.

The Verification Terminal


The verification terminal, on the other hand, lends itself very MODULARIZING
well to modular programming.The entire system can easily be THE
divided into three main modules: VERIFICATION
TERMINAL
• Keyboard and display module
• Data transmission module
• Data reception module
A general keyboard and display module could handle many keyboard- and display-
based systems. The sub-modules would perform such tasks as:

• Recognizing a new keyboard entry and fetching the data


• Clearing the arrav in response to a Clear key
• Entering digits into storage
• Looking for the terminator or Send key
• Displaying the digits

13-28
Although the key interpretations and the number of digits will vary, the basic entry,
data storage, and data display processes will be the same for many programs. Such
function keys as Clear would also be standard. Clearly, the designer must consider
which modules will be useful in other applications, and pay careful attention to
those modules.

The data transmission module could also be divided into such sub-modules as:

1) Adding the header character.


2) Transmitting characters as the output line can handle them.
3) Generating delay times between bits or characters.

4) Adding the trailer character.

5) Checking for transmission failures; i.e.. no acknowledgement or inability to


transmit without errors.

The data reception module could include sub-modules which:


1) Look for the header character.
2) Check the message destination address against the terminal address.
3} Store and interpret the message.
4) Look for the trailer character.

5) Generate bit or character delays.

Note here how important it is that each design decision (such as INFORMATION
the bit rate,message format, or error-checking procedure) be im- HIDING
plemented m only one module. A change in any of these decisions PRINCIPLE
will then require changes only to that single module. The other
modules should be written so that they are totally unaware of the values chosen or the
methods used in the implementing module. An important concept here Is the "infor-
mation-hiding principle/'^ whereby modules share only information that is ab-
solutely essential to getting the task done. Other information is hidden within a
single module.

An important use of this principle is m error handling. Whenever a module detects a


lethal error,it should not undertake recovery procedures. Instead, it should pass the er-

ror statusback up to the calling module and allow it to make the decision of how to
recover from the error. The reason for this is that the lower level procedure often does
not have enough information to adequately decide what recovery procedures are
necessary. For example, suppose we have a module that accepts numeric input from a
user. Thismodule terminates normally when the user enters a stnng of numeric digits
terminated by a carnage return. Entry of any non-numeric characters causes the
module to immediately terminate abnormally. Since the module does not know m what
context it is being used (i.e.. is it part of an assembler, an interactive editor, or a file
management system?) it cannot make a valid decision of what action to take when en-
countering an invalid character. If a single error recovery method was designed into the
module, it would lose its generality and become specific to those situations that employ
this error recovery technique.

13-29
REVIEW OF MODULAR PROGRAMMING
Modular programming can be very helpful if you abide by RULES FOR
the following rules: MODULAR
1) Use modules of 20
to 50 lines. Shorter modules are
PROGRAMMING
usually a waste of ttme, while longer modules are seldom
genera! and may be difficult to integrate.
2) Try to make modules reasonably general. Differentiate between common
features like ASCII code or asynchronous transmission formats, which will be the
same for many applications and key identifications, and number of displays or
number of characters m a message, which are likely to be unique to a particular ap-
plication. Make the changing of the latter parameters simple. Major changes like
different character codes should be handled by separate modules.

3) Take extra time on modules like delays, display handlers, keyboard handlers, etc.
that will be useful in other projects or in many different places in the present
program.
4) Try to keep modules as distinct and logically separate as possible. Restrict the
flow of information between modules and implement each design decision in a
single module.
5) Do not try to modularize simple tasks where rewriting the entire task may be
easier than assembling or modifying the module.

STRUCTURED PROGRAMMING
How do you keep modules distinct and stop them from interacting? How do you
write a program that has a clear sequence of operations so that you can isolate
and correct errors? One answer is to use the methods known as "structured pro-
gramming", whereby each part of the program consists of elements from a limited
set of structures and each structure has a single entry and a single exit.

Figure 13-14 shows a flowchart of an unstructured program. If an error occurs in

Module B,we have five possible sources for that error. Not only must we check each se-
quence, but we also have to make sure that any changes made to correct the error do
not affect any of the other sequences. The usual result is that debugging becomes like
wrestling an octopus. Every time you think the situation is under control, there is
another loose tentacle somewhere.

13-30
O00 o

o Xves

C
i\
.'

1
B
]

^^ D ^V^Ves
^^»w ^ .^^
^hJ^
G)

Figure 13-14. Flowchart of an Unstructured Program

The solution [S sequence of operations so


to establish a clear BASIC
that you can isolate errors. Such a sequence uses single-entry, STRUCTURES
single-exit nnodujes. The basic modules that are needed are: OF
1) An ordinary sequence; i.e.. a linear structure in which
STRUCTURED
statements or structures are executed consecutively. In
PROGRAMMING
the sequence:

S1
S2
S3
the computer executes SI first S2 second, and S3 third. S1. S2, and S3 may be
single instructions or entire programs.

2) A conditional structure.
The common one is "if C then S1 else S2." where C is a condition and S1 and S2
are statements or sequences of statements. The computer executes SI if C Is true,
and S2 if C is false. Figure 13-15 shows the logic of this structure. Note that the

structure has a single entry and a single exit; there is no way to enter or leaye S1 or
S2 other than through the structure.
3) A loop structure.
The common loop structure is "while C do S." where C is a condition and S is a
statement or sequence of statements. The computer checks C and executes S if C
IS true. This structure (see Figure 13-16) also has a single entry and a single exit.

Note that the computer will not execute S at all if C is onginatly false, since the
value of C is checked before S is executed.

13-31
c Start
D
C true

If V

SI S2

't'
c End
D
Figure 13-15. Flowchart of the lf-Then-E!se Structure

C ^•''^
)

^^^^jr
1
Q - ; s

Figure 13-16. Flowchart of the Do-While Structure

tn most structured programming languages, an alternative looping construct is pro-


vided. This construct is known as the do-until clause, Its basic structure is "do S until
C".. where C is and S is a statement or sequence of statements. It is similar
a condition
to the do-while construct except that the test of the looping condition C is performed at
the end of the loop. This has the effect of guaranteeing that the loop is always executed
at least once. This is Illustrated by the flowchart in Figure 13-17. The common index-
controlled or DO loop can be implemented as a special case of either of these two basic
looping constructs.

13-32
Figure 13-17, Flowchart of the Do-Untii Structure

4) A case structure.
Although not a primitive structure like sequential, if-then-eise.
and do-whlie. the
case structure so connmonlY used that we include it here as an adjunct to the
is

basic structure descriptions. The case structure is "case of SO, S1. .Sn", where
I .
I

iS an index and SO, S1. ,Sn are statements or sequences of statements. If


.
is I

equal to zero then statement SO is executed; if is equal to 1 then statement SI is


I

executed, etc. Only one of the n statements is executed. After its execution, control
passes to the next sequential statement following the case statement group. If is I

greater than n (i,e,. the number of statements In the case statement), then none of

the statements in the case statement is executed, and control is passed directly to
the next sequential statement following the case statement This is illustrated by
the flowchart In Figure 13-18,

Note the following features of structured programming:


1) Only the three basic structures, and possibly a small number of auxiliary
structures, are permitted.
2) Structures may be nested to any level of complexity so that any program can,
in turn, contain any of the structures.

3) Each structure has a single entry and a single exit.

Some examples of the conditional structure illustrated in EXAMPLES


Figure 13-15 are: OF
1) S2 included: STRUCTURES
if X ^ then NPOS = NPOS + 1

else NNEG - NNEG + 1

Both S1 and S2 are single statements.

2) S2 omitted:
if X^O then Y = 1/X
Here no action is taken if C {X ^0) is false. S2 and "else" can be omitted in this case.

13-33
Figure 13-18. Flowchart of the Case Structure

Some examples of the loop structure Illustrated in Figure 13-16 are:

1) Form the sum of Integers from 1 to N.

SUM-0
do while <N
(

t-t+ 1

SUM = SUM + 1

end
The computer executes the loop as long as ( < N. If N = 0, the program within the "do-
while" is not executed at alt.

2) Count characters in an array SENTENCE until you find an ASCII period.

NCHAR-0
do while SENTENCE (NCHAR) 9^ PERIOD
NCHAR = NCHAR+ 1

end
The computer executes the loop as long as the character in SENTENCE is- not an ASCI!
period. The count is zero if the first character is a period.

13-34
The advaiita9e8 of structured programming are: ADVANTAGES OF
1) The sequence of operations is simple to trace. This allows
STRUCTURED
you to test and debug easily. PROQRAMMINQ
2) The number of structures is limited and the terminology is

standardized.
3) The structures can easily be made into modules.
4) Theoreticians have proved that the given set of structures is complete; that is, all
programs can be written in terms of the three structures.
5) The structured version of a program is partly self-documenting and fairly easy to
read.

6) Structured programs are easy to describe with program outlines.


7) Structured programming has been shown in practice to increase programmer pro-
ductivity.

Structured programming basically forces much more discipline on the programmer


than does modular programming. The result is more systematic and better-
organized programs.
The disadvantages of structured programming are: DISADVANTAGES
1) Only a few high-level languages (e.g.. PL/M. PASCAL) will OF
directly accept the structures. The programmer therefore STRUCTURED
has to go through an extra translation stage to convert the PROQRAMMINQ
structures to assembly language code. The structured ver-
sion of the program, however, is often useful as documentation.

Structured programs often execute more slowly and use more memory than
unstructured programs.
Limiting the structures to the four basic forms makes some tasks very awkward to
perform. The completeness of the structures only means that all programs can be
implemented with them; it does not mean that a given program can be imple-
mented efficiently or conveniently.
The standard structures are often quite confusing, e.g., nested "if-then-else" struc-
tures may bevery difficult to read, since there may be no clear indication of where
the inner structures end. A series of nested "do-while" loops can also be difficult to
read.

Structured programs consider only the sequence of program operations, not the
flow of data. Therefore, the structures may handle data awkwardly.
Few programmers are accustomed to structured programming. Many find the stan-
dard structures awkward and restrictive.

We are neither advocating nor discouraging the use of structured programming. It


is one way of systematizing program design. In general, structured programming
is most useful in the following situations:
'
Larger programs, perhaps exceeding 1000 instructions WHEN TO USE
'
Applications in which memory usage is not critical. STRUCTURED
'
Low-volume applications where software development costs, PROGRAMMING
particularly testing and debugging, are important factors.

Applications involving string manipulation, process control.
or other algorithms rather than simple bit manipulations.

13-35
in the future, we expect the cost of memory to decrease, the average size of
microprocessor programs to increase, and the cost of software development to
increase. Therefore, methods like structured programming, which decrease soft-
ware development costs for larger programs but use more memory, will become
more valuable.
Just because structured programming concepts are usually expressed in high-!evei
languages does not mean that structured programming is not appticabie to assembiy
language programming. On the contrary, the assembly language programmer with the
totalfreedom of expression that assembly level programming allows, needs the struc-
turing concepts provided by structured programming. Creating modules with single
entry and exit points, using simple control structures and keeping the complexity of
each module minimal makes assembly language coding more efficient.

EXAMPLES
Response to a Switch
The structured version of this example is: STRUCTURED
PROGRAMMING
SWITCH = OFF
IN THE
do while SWITCH = OFF
SWITCH AND
READ SWITCH
LIGHT SYSTEM
end
LIGHT = ON
DELAY 1

LIGHT = OFF
ON and OFF must have the proper definitions for the switch and light We assume that
DELAY is a module that provides a delay given by its parameter in seconds.

A statement in a structured program may actually be a subroutine. However, in order to


conform to the rules of structured programming, the subroutine cannot have any exits
other than the one that returns control to the main program.

Since "do-while" checks the condition before executing the loop, we set the variable
SWITCH to OFF before starting. The structured program Is straightforward, readable,
and easy to check by hand. However, It would probably require somewhat more memo-
n/ than an unstructured program, which would not have to initialize SWITCH and could
combine the reading and checking procedures.

The Switch-Based Memory Loader


The switch-based memory loader is a more complex struc- STRUCTURED
tured programming problem. We may implement the PROGRAMMING
flowchart of Figure 13-9 as follows {an • Indicates a com- FOR THE
ment) :
SWITCH-BASED
MEMORY LOADER
. INITIALIZE VARIABLES

HIADDRESS =
LOADDRESS=0

THIS PROGRAM USES A DO-WHILE CONSTRUCT WITH NO CONDITION


(CALLED SIMPLY DO-FOREVER). THEREFORE, THE SYSTEM CONTINUALLY
EXECUTES THE PROGRAM CONTAINED IN THIS DO-WHtLE LOOP,

do forever

13-36
• TEST FOR HIADDRESS BUTTON: PERFORM THE REQUIRED PROCESSING
. IF IT IS ON.

if HIADDRBUTTON = 1 then
begin
HIADDRESS = SWITCHES
LIGHTS = SWITCHES
do
DELAY (DEBOUNCE TIME)
untilHIADDRBUTTON 9^ 1
end

• TEST FOR LOADDRESS BUTTON: PERFORM LOW ADDRESS PROCESSING


• IF IT IS ON.

if LOADDRBUTTON - 1 then
begin
LOADDRESS = SWITCHES
LIGHTS= SWITCHES
do
DELAY (DEBOUNCE TIME)
until LOADDRBUTTON 9^1
end

• TEST FOR DATABUTTON, AND STORE DATA INTO MEMORY


• IF IT IS ON,

if DATABUTTON = 1 then
begin
DATA = SWITCHES
LIGHTS - SWITCHES
(HIADDRESS. LOADDRESS) = DATA
do
DELAY (DEBOUNCE TIME)
until DATABUTTON 9^1
end
end

• THE LAST END ABOVE TERMINATES THE


do forever LOOP

Structured programs are not easy to write, but they can give a great deal of insight into
the overall progranrt logic. You can check the logic of the structured program by hand
before writing any actual code.

13-37
1

The bredlt-Verif ication Terminal


Let us look at the keyboard entry for the transaction terminal.
STRUCTURED
We will assume that the display array is ENTRY, the
keyboard PROGRAM FOR
strobeis KEYSTROBE. and the keyboard data
is KEYIN. The struc- THE CREDIT-
VERIi=ICATION
tured program without the function keys is:
TERMINAL
NKEYS = 10
STRUCTURED
KEYBOARD
. CLEAR ENTRY TO START ROUTINE

do while NKEYS >


NKEYS = NKEYS -

ENTRYiNKEYS) =0 *

end

. FETCH A COMPLETE ENTRY FROM KEYBOARD

do while NKEYS < 10


if KEYSTROBE = ACTIVE then
begin
KEYSTROBE - INACTIVE
ENTRY(NKEYS) - KEYIN
NKEYS - NKEYS + 1
end
end
has
Adding the SEND key means that the program must ignore extra digits after it
entry. The
a complete entry, and must ignore the SEND key until it has a complete
structured program is:

NKEYS = 10

. CLEAR ENTRY TO START

do while NKEYS >


NKEYS - NKEYS - 1

ENTRY{NKEYS)-0
end

. WAIT FOR COMPLETE ENTRY FOLLOWED BY SEND KEY

do while KEY ^SEND or NKEYS 5^10


if KEYSTROBE = ACTIVE then
begin
KEYSTROBE = INACTIVE
KEY = KEYIN
if NKEYS ^ 10 and KEY ?^SEND then
begin
ENTRY(NKEYS)=KEY
NKEYS = NKEYS + 1
end
end
end

13-38
)

Note the foitowing features of this structured program.

1 The second if-then is nested within the first one. since keys are only entered after a
strobe is recognized. !f the second if-then were on the sanne level as the first a
single key coutd fill the entry, since its value would be entered into the array during
each iteration of the do-whl!e loop.

2) KEY need not be defined initially, since NKEYS is set to zero as part of the clear-
ing of the entry.

Adding the CLEAR key allows the program to clear the entry originally by simulat-
ing the pressing of CLEAR; i.e., by setting NKEYS
10 and KEY to CLEAR before to
starting. The structured program must also clear only digits that have previously been
filled. The new structured program is:

• SIMULATE COMPLETE CLEARING

NKEYS = 10
KEY = CLEAR

. WAIT FOR COMPLETE ENTRY AND SEND KEY

do while KEY ^SEND or NKEYS ^10

. CLEAR WHOLE ENTRY IF CLEAR KEY STRUCK

if KEY = CLEAR then


begin
KEY=0
do while NKEYS >0
NKEYS = NKEYS - 1

ENTRY(NKEYS) =0
end
end

• GET DIGIT IF ENTRY INCOMPLETE

if KEYSTROBE = ACTIVE then


begin
KEYSTROBE = INACTIVE
KEY - KEYIN
if KEY < 10 and NKEYS ?^ 10 then
begin
ENTRY(NKEYS) = KEY
NKEYS = NKEYS + 1

end
end
end

Note that the program resets KEY to zero after clearing the array, so that the operation is
not repeated.

13-39
We can similarly build a structured program for the receive STRUCTURED
routine. An initial program could look just for the header and RECEIVE
trailer characters. We will assume that RSTB is the indicator that a | ROUTINE
character is ready The structured program is:

CLEAR HEADER FLAG TO START

HFLAG =

WAIT FOR HEADER AND TRAILER

do while HFLAG ^ or CHAR ^TRAILER

GET CHARACTER IF READY, LOOK FOR HEADER

if RSTB - ACTIVE then


begin
RSTB = INACTIVE
CHAR = INPUT
ifCHAR = HEADER then HFLAG = 1

end

13-40
Now we can add the section that checks the message address against the three
digits in TgRMINAL ADDRESS (TERIVIADDR). If any of the corresponding digits
are not equal the ADDRESS MATCH flag (ADDRIVIATCH) Is set to 1.

- CLEAR HEADER FLAG. ADDRESS MATCH FLAG, ADDRESS COUNTER TO START

HFLAG =
ADDRMATCH =
ADDRCTR =

. WAIT FOR HEADER. DESTINATION ADDRESS AND TRAILER

do while HFLAG = or CHAR =?^ TRAILER OR ADDRCTR ^^3

. GET CHARACTER IF READY

if RSTB = ACTIVE then


begin
RSTB -INACTIVE
CHAR INPUT
===

end

• CHECK FOR TERMINAL ADDRESS AND HEADER

if HFLAG = 1 and ADDRCTR ^3 then


begin
ADDRMATCH = 1

ADDRCTR = ADDRCTR -f 1

end
if CHAR = HEADER then HFLAG = 1

end
The program must now wait for a header, a three-digit identification code, and a trailer
You must be careful of what happens during the iteration when the program finds the
header, and of what happens if an erroneous identification code character is the same
as the trailer

13-41
A further addition can store the message in MESSG. NMESS is the number of
characters in the message; if it is not zero at the end, the program knows that the
terminal has received a valid message. We have not tried to minimize the iogic ex-
pressions in this program.

. CLEAR FLAGS, COUNTERS TO START

HFLAG =
ADDRMATCH -
ADDRCTR =
NMESS =

. WAIT FOR HEADER, DESTINATION ADDRESS AND TRAILER

do while HFLAG - or CHAR ?t TRAILER or ADDRCTR ^^3

- GET CHARACTER !F READY

if RSTB = ACTIVE then


begin
RSTB - INACTIVE
CHAR = INPUT
end

. READ MESSAGE IF DESTINATION ADDRESS = TERMINAL ADDRESS

if HFLAG = 1 and ADDRCTR = 3 then


if ADDRMATCH = and CHAR ^TRAILER then
begin
MESSG(NMESS)=CHAR
NMESS = NMESS + 1

end

. CHECK FOR TERMINAL ADDRESS

if HFLAG - 1and ADDRCTR ^^3 then


if CHAR ^TERMADDR(ADDRCTR) then
begin
ADDRMATCH = 1

ADDRCTR - ADDRCTR + 1

end

• LOOK FOR HEADER

if CHAR = HEADER then HFLAG = 1

end

13-42
The program checks for the identification code only
if it found a header during a pre-

vious iteration. It accepts the message only has previously found a header and a
if it

complete, matching destination address. The program must work properly during the
iterations when it finds the header, the trailer and the last digit of the destination ad-
dress, it must not tn/ to match the header with the terminal address or place the trailer
or the final digit of the destination address in the message. You might try adding the
rest of the logic from the flowchart (Figure 1 3- 1 31 to the structured program. Note
that the order of operations is often critical. You must be sure that the program
does not complete one phase and start the next one during the same iteration.

REVIEW OF STRUCTURED PROGRAMMING


Structured programming brings discipline to program design. It forces you to limit
the types of structures you use and the sequence of operations. It provides single-
entry, single-exit structures,
which you can check for logical accuracy. Structured
programming often makes the designer aware of inconsistencies or possible com-
binations of inputs. Structured programming Is not a cure-ail, but it does bring
some order into a process that can be chaotic. The structured program should also
aid in debugging, testing, and documentation.

Structured programming is not simple. The programmer must not only define the
problem adequately, but must also work through the logic carefully. This is
tedious and difficult, but it results in a clearly written, working program.

The particular structures we have presented are not ideal and TERMINATORS
are often awkward. In addition, it can be difficult to dis- FOR
tinguish where one structure ends and another begins, partic- STRUCTURES
ularly if they are nested. Theorists may provide better struc-
tures in the future, or designers may wish to add some of their own. Some kind of
terminator for each structure seems necessary, since indenting does not always clarify
the situation. "End" is a logical terminator for the "do-whiie" loop. There Is no obvious
terminator, however, for the "if-then-eise" statement; some theorists have suggested
"endif" or "fi" ("if" backwards), but these are both awkward and detract from the
readability of the program.

We suggest the following rules for applying structured pro- RULES FOR
gramming: STRUCTURED
1) Begin by writing a basic flowchart to help define the
PROGRAMMING
logic of the program.

2) Start with the "sequential/' "if-then-else," and "do-while" constructs.


They
are known to be a complete set, i.e.. any program can be written in
terms of these
structures,

3) Indent each level a few spaces from the previous level, so that vou will know
which statements belong where.
4) Use terminators for each structure; e.g.. "end" for the "do-while" and "endif" or
the "if-then-e(se".
"fi" for The terminators plus the indentation should make the
program reasonably clear.
5) Emphasize simplicity and readability. Leave lots of spaces, use meaningful
names, and make expressions as clear as possible. Do not try to minimize the logic
at the cost of clarity.

6) Comment the program in an organized manner


7) Check the logic. Try the extreme cases or special conditions and a few sample
all

cases. Any logical errors you find at this level will not plague you later.

13-43
TOP-DOWN DESIGN
The remaining problem is how to check and integrate modules BOTTOM-UP
or structures. Certainlywe want to divide a large task into I DESIGN
sub- tasks. But how do we check the sub-tasks In isolation and
put them together? The standard procedure, called "bottom-up design/' requires
extra work in testing and debugging and leaves the entire integration task to the
end. What we need is a method that allows testing and debugging in the actual
program environment and modularizes system integration.
This method is "top-down design." Here we start by writing TOP-DOWN
the overall supervisor program. We
replace the undefined sub- DESIGN
programs by program "stubs/' temporary programs that may METHODS
either record the entry, provide the answer to a selected test STUBS
problem, or do nothing. We then test the supervisor program ^

correct.
to see that Its logic is
,^^_____^
We proceed by expanding the stubs. Each stub will often con- EXPANDING
tain sub-tasks, which we will temporarily represent as stubs. STUBS
This process of expansion, debugging, and testing continues ADVANTAGES
until all the stubs are replaced by working programs. Note that Qp xOP-DOWN
testing and integration occur at each level rather than al! at the p^siGN
end. No special driver or data generation programs are necessary, "

We get a clear idea of exactly where we are in the design. Top-


down design assumes modular programming, and Is compatible with structured
programming as well.
The disadvantages of top-down design are:

1) The overall design nnay not mesh well with system hard DISADVANTAGES
ware, OF TOP-DOWN
2} It may not take good advantage of existing software.
DESIGN
3) Stubs may be difficult to write, particularly if they must
work correctly In several different places.

4} Top-down design may not result In generally useful modules.


5) Errors at the top level can have catastrophic effects, whereas errors m bottom-up
design are usually limited to a particular module.

In large programming projects, top-down design has been shown to greatly im-
prove programmer productivity. However, almost all of these projects have used
some bottom-up design in cases where the top-down method would have
resulted in a large amount of extra work.

Top-down design Is a useful tool that should not be followed to extremes. It pro-
vides the same discipline for system testing and Integration that structured pro-
gramming provides for module design. The method, however, has more general
applicability, since it does not assume the use of programmed logic. However,
top-down design may not result in the most efficient implementation.

13-44
1

EXAMPLES
Response to a Switch
The firststructured programming example actually demon- TOP-DOWN
strates top-down design as well. The program was: DESIGN
SWITCH - OFF OF SWITCH
do while SWITCH = OFF AND LIGHT
READ SWITCH SYSTEM
end
LIGHT = ON
DELAY 1

LIGHT - OFF
These statements are really stubs, since none of them is fully defined. For exam-
ple, what does READ SWITCH mean? If the switch were one bit
of input port SPORT, it
realtv means:
SWITCH =- SPORT AND SMASK
where SMASK has a '1'
the appropriate position. The masking may. of course, be
bit in
implemented with a Bit Test instruction.

Similarly, DELAY 1 actually means (if the processor itself provides the delay):
REG = COUNT
do while REG ^^0
REG - REG - 1
end
COUNT is the appropriate number to proyide a one-second
delay. The expanded ver-
sion of the program is:

SWITCH -
do while SWITCH =0
SWITCH -= SPORT AND MASK
end
LIGHT = ON
REG = COUNT
do while REG t^O
REG = REG -
end
LIGHT - NOT (LIGHT)

Certainly this program Is more explicit, and could more easily be translated Into
actual Instructions or statements.

13-45
The Switch-Based Memory Loader
This example is more complex than the first example, so we
TOP-DOWN
must proceed systematically. Here again, the structured pro- DESIGN OF
gram contains stubs. SWITCH-BASED
MEMORY
For example, if ADDRESS
the HIGH button is one bit of input
LOADER
port CPORT, "if HIADDR8UTT0N = 1" really means:

1) Input from CPORT


2) Complement
3) Logical AND with HAMASK
where HAMASK has a 'V in the appropnate bit position and 'Os elsewhere. Similarly
the condition "if DATABUTTON = 1" really means:

1) Input from CPORT


2) Complement
3) Logical AND with DAMASK
So. the>initial stubs could just assign values to the buttons, e.g..

HIADDRBUTTON-0
LOADDRBUTTON =
DATABUTTON -
A run of the supervisor program should show that it takes the implied "else" path
through the "if-then-e!se" structures, and never reads the switches. Similarly. If the
stub were:

HIADDRBUTTON = 1

the supervisor program should stay in the "do while HIADDRBUTTON


= 1" loop wait-
ing for the button to be released. These simple runs check the overall logic.

Now we can expand each stub and see if the expansion produces a reasonable
overall result. Note how debugging and testing proceed in a straightforward and
modular manner. We expand the HIADDRBUTTON == 1 stub to:

READ CPORT
HIADDRBUTTON -NOT (CPORT) AND HAMASK
The program should wait for the HIGH ADDRESS button to be closed. The program
should then display the values of the switches on the lights. This run checks for the
proper response to the HIGH ADDRESS button.

We then expand the LOW ADDRESS button module to:

READ CPOBT
LOADDhBUTTON = NOT (CPORT) AND LAMASK
With the LOW ADDRESS button in the closed position, the program should display the
values of the switches on the lights. This run checks for the proper response to the LOW
ADDRESS button.

Similarly, we can expand the DATA button module and check for the proper response
to that button. The entire program willthen have been tested.

When all the stubs have been expanded, the coding, debugging, and testing

stages will all be complete. Of course, we must know exactly what results each
stub should produce. However, many logical errors will become obvious at each
level without any further expansion.

13-46
f Start
D
Keyboard

t
ACK =0

^^
> ^Jo

>-
AC. K n

"
Transmit
Disptav
Receive

1
C End
D
Figure 13-19 Initial Flowchart for Transaction Termina

The Transaction Terminal


This example, of course, will have more levels of detail. We TOP-DOWN
could start with the following program (see Figure 13-19 for DESIGN OF
a flowchart): VERIFICATION
KEYBOARD TERMINAL
ACK =
do while ACK -=

TRANSMIT
RECEIVE
end
DISPLAY
Here KEYBOARD. TRANSMIT. RECEIVE, and DISPLAY are program stubs that will
be expanded later. KEYBOARD, for example, could simply place a ten-digit verified
number into the appropriate buffer.

13-47
Complete = C J

KEN
I

Figure 13-20. Flowchart for Expanded KEYBOARD Routine

The next stage of expansion could produce the following pro- EXPANDING
gram for KEYBOARD (see Figure 13-20): THE
-0 KEYBOARD
VER ROUTINE
do while VER =0
COMPLETE -
do while COMPLETE =
KEYIN
KEYDS
end
VERIFY
end
Here VER =0 means that an entry has not been verified: COMPLETE =0 means that
the entry incomplete. KEYIN and KEYDS are the keyboard mput and display routines
is

respectively VERIFY checks the entry. A stub for KEYIN would simply place a random
entry (from a random number table or generator) into the buffer and set COMPLETE to
1.

We would continue by similarly expanding, debugging, and testing TRANSMIT,


RECEIVE, and DISPLAY. Note that you should expand each program by one level
so that you do not perform the integration of an entire program at any one time.
You must use your Judgment in defining levels. Too small a step wastes time,
while too targe a step gets you back to the problems of system integration that
top-down design is supposed to solve.

13-48
)

REVIEW OF TOP-DOWN DESIGN


Top-down design brings discipline to the testing and integration stages of pro-
gram design. It provides a systematic method for expanding a flowchart or prob-
lem definition to the level required to actually write a program. Together with
structured programming. It forms a complete set of design techniques.

Like structured programming, top-down design is not simple. The designer must
have defined the problem carefully and must work systematically through each
level. Here again the methodology may seem tedious, but the payoff can be sub-
stantial if you follow the rules.

We recommend the following approach to top-down design: FORMAT


1 Start with a basic flowchart. FOR
2) Make the stubs as complete and as separate as possible.
TOP-DOWN
DESIGN
3) Define precisely all the possible outcomes from each stub
and select a test set
4) Check each level carefully and systematically
5) Use the structures from structured programming.
6) Expand each stub by one level. Do not tn/ to do too much in one step.
7) Watch carefully for common tasks and data structures.
8) Test and debug after each stub expansion. Do not try to do an entire level at a
time.

9) Be aware of what the hardware can do. Do not hesitate to stop and do a little
bottom-up design where that seems necessary.

REVIEW OF PROBLEM DEFINITiON AND PROGRAM DESIGN


You should note that we
have spent an entire chapter without mentioning any
specific microprocessor or assembly language, and without writing a single line of
actual code. Hopefully, though, you now know a lot more about the examples than
you would have if we had Just asked you to write the programs at the start.
Although we often think of the writing of computer instructions as a key part of
software development. It is actually one of the easiest stages.
Once you have written a few programs, coding
will become simple. You will soon
learn the instruction set, recognize which Instructions are really useful, and
remember the common sequences that make up the largest part of most pro-
grams. You will then find that many of the other stages of software development
remain difficult and have few clear rules.

We have suggested here some ways to systematize the important early stages. In
the problem definition stage, you must define all the characteristics of the
system —
its inputs, outputs, processing, time and memory constraints, and error
handling. You must particularly consider how the system will interact with the
larger system
of which it Is a part, and whether that larger system includes
electricalequipment, mechanical equipment, or a human operator. You must start
at this stage to make the system easy to use and maintain.

In the program design stage, several techniques can help you to systematically
specify and document the logic of your program. Modular programming forces you
to divide the total program Into small, distinct modules. Structured programming
provides a systematic way of defining the logic of those modules, while top-down
design is a systematic method for integrating and testing them. Of course, no one
can compel you to follow all of these techniques; they are. In fact, guidelines more
than anything else. But they do provide a unified approach to design, and you
should consider them a basis on which to develop your own approach.

13-49
REFERENCES
1. See, for example, V. P Srini. "Fault Diagnosts of Microprocessor Systems," Com-
puter, January 1977, pp. 60-65. For a description of signature analysis, see G. Gor-
don and H. Nadig. "Hexadecimal Signatures identify Trouble-spots in
Microprocessor Systems," Electronics March 3, 1977. pp. 89-96. There is also an
.

Application Note (#222) entitled "A Designer's Guide to Signature Analysis"


available from Hewlett-Packard,

2. human factors considerations, see G. Morns, "Make Your


For a brief discussion of
Next Instrument Design Emphasize User Needs and Wants," EDN October 20, .

1978, pp. 100-105.

3. D, L Parnas (see the references below) has been a leader in the area of modular pro-
gramming.
4. Collected by B. W. Unger (see reference below).

5. Formulated by D. L Parnas.

The following references provide additional information on problem definition and pro-
gram design:
Chaplin, N., Flowcharts Auerbach, Princeton, N.
,
J.. 1971.

Dahl, 0. J., C, A. R. Hoave. and E. W. Dijkstra, Structured Programming. Academic


Press. New York. N. Y.. 1972.

Datton, W, F., "Design Microcomputer Software like Other Systems — Systematically,"


Electronics January 19, 1978, pp. 97-101.
,

Dijkstra, E. W., A Discipline of Programming, Prentice-Hall,


™ Englewood Cliffs, N. J.,

1976. "

Halstead, M. H.. Elements of Software Science, American Elsevier. New York, 1977.

Hughes. J. K. and J. I. Michtom, A Structured Approach to Programming. Prentice-Hali,


Englewood Cliffs. N. J.. 1977

Morgan, D. E. and D. J. Taylor, "A Survey of Methods for Achieving Reliable Software."
Computer, February 1977. pp. 44-52. •

Myers, W., "The Need for Software Engineering," Computer February 1978. pp. 12-25. .

Parnas, D. L. the Criteria to be Used in Decomposing Systems into Modules,"


"On Com-
munications of the ACM
December 1972, pp. 1053-1058.
.

L.. "A Technique for the Specification of Software Modules with Examples,"
Parnas. D.
Communications of the ACM May 1973, pp. 330-336. .

Schneider, "Prediction of Software Effort and Proiect Duration


V., — Four New For-

^'^'^S'" 31GPLAN Notices. June 1978. pp. 49-59.

Shneiderman. B. et a!.. "Experimental investigations of the Utility of Detailed Flow-


charts in Programming." Communications of the ACM. June 1977. pp. 373-381.

Ulrickson. R. W.. "Software Modules Are the Building Blocks," Electronic Design.
February 1. 1977, pp. 62-66.

Ulrickson, R. W., "Solve Software Problems Step-by-Step," Electronic Design January ,

18, 1977. pp. 54-58.

Unger, B. W., "Programming Languages for Computer System Simulation," Simulation,


April 1978. pp. 101-110.

13-50
Wirth. N.. Algorithms + Data Structures ==
~~
Programs Prentice-Hall, EngJewood
. Cliffs.
N. J.. 1976^~
Wirth. N.. Syste matic Programming: an Introduction. Prentice-Hall. Englewood
" " Cliffs. N.
J., 1973.

Yourdon.
Cliffs. N. J..
E Techniques
U.,
1975~"
of
— —
Program Structure and Desig n. Prentice-Hall, Englewood

13-51
Chapter 14
DEBUGQIhlG AND TESTING
As we noted at the begmning of the previous chapter, debugging and testing are
among the nnost time-consuming stages of software development Even though such
methods as modular programming, structured programming, and top-down design
can simplify programs and reduce the frequency of errors, debugging and testing
still are difficult because they are so poorly defined. The selection of an
adequate set
of test data is seldom a clear or scientific process. Finding errors sometimes seems like
a
game of "pm the tail on the donkey," except that the donkey is movrng and the pro-
grammer must position the tail by remote control. Surely, few tasks are as frustrating as
debugging programs.
This chapter will first describe the tools available to aid in debugging. It will then
discuss basic debugging procedures, describe the common types of errors, and
present some examples of program debugging. The last sections will describe
how to select test data and test programs.
We will not do much more than describe the purposes of most of the debugging tools.
There very little standardization m this area, and not enough space to discuss all the
is

devices and programs that are currently available. The examples should give you some
idea of the uses, advantages, and limitations of particular hardware or software aids.

SIMPLE DEBUGGING TOOLS


The simplest debugging tools available are:
• A single-step facility
• A breakpoint facility
• A Register Dump program (or utility)
• A Memory Dump program
The single-step facility allows you to execute the program one SINGLE-
step at a time. Most Z80-based microcomputers have this facility, STEP
since the circuitry is fairly simple. Of course, the only things that
you will be able to see when the computer executes a single-step are the states
of the output lines that you are monitoring. The most important tines are:

• Data Bus
• Address Bus
• Control lines MREQ (Memorv Request). lORQ (Input/Output Request}, RD {Memory
Read), and WR (Memory Write).

If you monitor these lines (either in hardware or in software), you will be able
to
see the progression of addresses, instructions, and data as the program executes.
You will be able to tell what kind of operations the CPU is performing. This infor-
mation will inform you of such errors as incorrect Jump instructions, omitted or incor-
rect addresses, erroneous operation codes, or incorrect data values. However, you can-
not see the contents of registers and flags without some additional debugging facility
or a special sequence of instructions. Many of the operations of the program cannot be
checked in real time.

14-1
Table 14-1. Z 80 Restart and nterrupt Addresses
1

Instruction or External Input Instruct on Ob[ect Code Destination Address


(Hex) (Hex)
(Mnemontc) (Pin)

RST OOH C7 0000


RST 08H CF 0008
RST 10H D/ 0010
RST 18H DF 0018
RST 20H E7 0020
RST 28H EF 0028
RST 30H F7 0030
RST 38H or INT m Mode 1 FF 0038
NMI 0066

There are many errors that a sing le-step mode cannot help you LIMITATIONS
to find. These include tmnmg errors and errors in the interrupt OF SINGLE-
or DMA SYStems. Furthermore. the single -step mode IS very STEP MODE
slow, typically executing a program at less than one millionth
of the speed of the processor itself. To single-step through one second of real processor
time would take more than ten days. The singie-step mode is useful only to check the
logic of short instruction sequences.

A breakpoint is a place at which the program will automat- |SREAKPOiNT|


ically halt or wait so that the user can examine the current
status of the system. The program will usually not start again until the operator re-
quests a resumption of execution. Breakpoints allow you to check or pass through an
entire section of a program. Thus, to see if an initialization routine is correct, you can
place a breakpoint at the end of it and run the program. You can then check memory
locations and registers to see if the entire section is correct However, note that if the

section IS not correct, you'll have


still to pin down the error, either with earlier break-
points or With a single-step mode.

Breakpoints complement the single-step mode. You can use breakpoints either to
localize the error or to pass through sections that you know are correct. You can
then do the detailed debugging in the single-step mode. In some cases, breakpoints
do not affect program timing; they can then be used to check mput/output interrupts.
Breakpoints often use part or all of the microprocessor interrupt RST AS A
system. Some microprocessors have a special SOFTWARE INTER- BREAKPOINT
RUPT or TRAP can act as a breakpoint. On the Z80, if
facility that

you are not already using all the RST vectors In your program, you can use the RST

{Restart) instruction as a breakpoint. Table 14-1 gives the destination addresses for
the various RST instructions. Chapter 12 describes the RST instruction in more detail
The breakpoint routine can print register and memory contents or just wait (e.g.. ex-
ecute HALT or a conditional jump dependent on a switch input) until_you allow the
computer to proce ed, if you are not using the maskable interrupt (INT) or the non-
maskable interrupt (NMI) m your system, you can use those vect ors as externally con-
trolled breakpoints. But remember that the interrupts (including NMI) and RST use the
Stack and Stack Pointer to store the return address. Figure 14-1 shows a routine where
RST results in an endless loop. You would have to clear this breakpoint with a RESET or
interrupt signal.

14-2
Figure 14-1, A Simple Breakpoint Routine

ORG 18H
RST18 EQU 18H
JR RST18 ;WAIT !N PLACE

The simplest method for msertlng breakpoints is to replace the first byte of the In-
struction with a RST instructionor to replace the instruction with a Jump or CALL
Instruction. Use of a RST instruction is preferred on the Z80, since it involves the
replacement of only a single byte, whereas a JP or CALL involves three
bytes. The JR
instruction is not suitable for breakpointmg because
you cannot guarantee that the
debug software is within -126 to +129 bytes of the instruction being
breakpointed.
Multiple-byte instructions used to implement breakpoints can
cause problems on the
Z80 due to the presence of single-byte instructions. To illustrate
this program, examine
the program segment shown below:

Memory Address Memory Contents Instruction


^Hex) (Hex) (Mnemonic)
100 7B LD A.E
^^^ 87 L1: ADD A.A
^02 87 L2: ADD A,A

If you wish to set a breakpoint at location


1
00i 5 using a 3-byte CALL or JP, the code at
locations 101 and 102^6 will also get overlaid by the CALL or JP instruction. This
-jg
means that the debugger has to be aware that these locations have also been modified.
Any transfers of control to LI or L2 while the breakpoint is set will produce unexpected
results unless the debugger is designed to catch this case. This added complexity
can
be avoided by using a RST instruction.

Many monitors have facilities for inserting and removing INSERTING


breakpoints implemented via some type of Jump instruction. BREAKPOINTS
Such breakpoints do not affect the timing of the program until
the breakpoint is executed. However, note that this procedure will not work if part
or all
of the program is in ROM or PROM. Other monitors implement breakpoints
by actually
checking the address lines or the Program Counter in hardware or m software. This
method allows breakpoints on addresses in ROM or PROM, but it may affect the timing
if the address must be checked m software. A
more powerful facility would allow the
user to enter an address to which the processor would transfer control. Another
possibility would be a return dependent on a switch:

ORG 18H
RST18 EQU 18H
PUSH AF :SAVE ACCUMULATOR, FLAGS
WAITS. IN A.(PIODRA} :GET SWITCH DATA
BIT SW.A :ISSWITCH CLOSED?
JR NZ.WAITS :N0. WAIT UNTIL IT IS
POP AF ;REST0RE ACCUMULATOR. FLAGS
RET
Remember to re-enable the interrupts if the routine uses an external interrupt input.

14-3
CHZ)
Store ail registers
in Stack
COUhTT = Number of
bytes in register = 22
Data Pointer =
Stack Pointer + 20

Store Data Pointer


in Stack

Data Pointer =
Data Pointer - 1

Print (Data Pointer)

as 2 hex digits
COUNT = COUNT -t

Restore all registers

fixim Stack

C J
Figure 14-Z Flowchart of Register Dump Program

A Register Dump utility on a microcomputer is a program that REGISTER


lists the contents of ail the CPU registers. This information is DUMPS
usuaNy not directly obtainable. The following routine will print
the contents of all the registers on the system printer, if we assume that PRTHEX
prints the contents of the Accumulator as two hexadecimal digits. Figure 14-2 is a
flowchart of the program and Figure 14-3 shows a typical result. We assume that the
routine \s entered with a CALL instruction that stores the old Program Counter at the
top of the Stack.

14-4
: PLACE ALL CPU REGISTER CONTENTS !N STACK (PC ALREADY ON STACK)

PUSH AF ;SAVE REGULAR USER REGISTERS


PUSH BC
PUSH DE
PUSH HL
PUSH IX ;SAVE INDEX REGISTERS
PUSH lY
EX AF.AF lACCESS AND SAVE PRIMED CPU REGISTERS
EXX
PUSH AF
PUSH BC
PUSH DE
PUSH HL

; USE STACK POINTER AS STARTING ADDRESS

LD HUO GET STACK POINTER


ADD HL.SP
LD DE.20 COMPUTE ORIGINAL STACK POINTER
ADD HLDE
PUSH HL SAVE ORIGINAL STACK POINTER IN STACK

; PRINT CONTENTS OF REGISTERS


: ORDER IS PC{HIGH),PC(L0W),A,F,B.C.D.E.H,LJX(HiGH)JX(LO\A/)JY(HIGH).
; IY(LOW),A',r,B',C',D',E',H',L.SP(HIGH),SP(LOW)

LD B.22 :NUM8ER OF BYTES - 22


PRNT1: DEC HL
LD A,(HU ;GETA BYTE FROM STACK
CALL PRTHEX ;AND PRINT IT
DJNZ PRNT1

RESTORE REGISTERS FROM STACK

POP HL ;POP AND DISCARD ORIGINAL STACK POINTER


POP HL :RESTORE PRIMED CPU REGISTERS
POP DE
POP BC
POP AF
EX AF.AF
EXX
POP lY ;RESTORE INDEX REGISTERS
POP IX
POP HL ;RESTORE REGULAR CPU REGISTERS
POP DE
POP BC
POP AF

14-5
1D (A)

42 (F)

07 (B)

3E (C)

23 (D)

01 (E)

17 (H)

01 (U
D3 (IX)

58
E2 (lY)

A2
36 (A')

67 (F'j

E8 (B')

11 (C)
EB (D')

09 (E)
D7 (H')

66 (L')

68 (STACK POINTER)
E2

Figure 14-3 Results of a Typical Z80 Register Dump

14-8
A Memory Dump Is a program that lists the contents of memo- MEMORY
ry on an output device (such as a printer). This is a much more DUMP
efficient way to examine data arrays or entire programs than |ust
looking at single iocations. However, very large memory dumps are not useful (except
to supply scrap paper) because
sheer mass of information that they produce.
of the
They may also take a long time to execute on a slow printer. Smali dumps may,
however, provide the programmer with a reasonable amount of information that
can be examined as a unit. Relationships such as regular repetitions of data pat-
terns or offsets of entire arrays may become obvious.

A general dump is often rather difficult to wnte. The programmer should be careful of
the following situations:

1) The size of the memory area exceeds 256 bytes, so that an 8-bit counter will not
suffice,

2) The ending location is an address smaller than the starting location. This can be
treated as an error, or simply cause no output since the user would seldom want to
print the entire memory contents in an unusual order.

Since the speed of the Memory Dump depends on the speed of the output device, the
efficiency of the routine seldom matters. The following program will ignore cases
where the starting address is larger than the ending address, and will handle
blocks of any length. We
assume that the starting address is in Register Pair DE and
the ending address is in Register Pair HL.

STOP IF ENDING ADDRESS BEFORE STARTING ADDRESS

AND A ;CLEAR CARRY


SBC HL.DE IS ENDING ADDRESS BEFORE STARTING?
JR C.DONE YES. DO NOT DUMP ANYTHING
XCHG GET STARTING ADDRESS INTO HL
INC DE COUNT = NUMBER OF LOCATIONS TO BE
DUMPED

; PRINT CONTENTS OF LOCATIONS

DUMP; LD A.(HL) ;GET CONTENTS OF A LOCATION


CALL PRTHEX :AND PRINT IT
INC HL
DEC DE
LD A.E ;ALL LOCATIONS DUMPED?
OR D
JR NZ.DUMP ;N0. CONTINUE DUMPING
DONE: HALT
Note that the only 1 6-bit Subtract instruction is SBC. which subtracts the contents of a
register pair and the Carry from Register Pair HL. SBC. like other Subtract instructions,
sets the Carry if a borrow is required (contrary to what some Z80 manuals say).

Figure 14-4 shows the output from a dump of memory locations 1000 to 101 F.

14-7
23 IF 60 54 37 28 3E 00
6E 42 38 17 59 44 98 37
47 36 23 81 E1 FF FF 5A
34 ED BC AF FE FF 27 02

Figure 14-4. Results of a Typscal Memory Dump

This routine correctly handles the case in which the starting and ending locations are
the same (tryYou^ will have to interpret the results carefully
itl). if the dump area
includes the Stack, since the dump subroutine itself uses the Stack, PRTHEX may also
change memory and Stack locations.

In amemory dump, the data can be displayed in a number of different ways. Common
forms are ASCII characters or pairs of hexadecimal digits tor8-bit values and four hex-
adecimal digits for 16-bit values. The format should be chosen based on the intended
use of the dump, it is almost always easier to interpret an obiect code dump if it is dis-
played in hexadecimal form rather than ASCII form.

A common and useful dump format is illustrated here:

1000 54 68 65 20 64 75 6D 70 The dump

Each line consists of three parts.The line starts with the hexadecimal address of the
first byte displayed on the Following the address are eight or sixteen bytes dis-
line.

played in hexadecimal form. Last is the ASCII representation of the same eight or six-
teen bytes. Try rewriting the memory dump program so that it wilt print the address and
the ASCI! characters as well as the hexadecimal form of the memory contents.

MORE ADVANCED DEBUGGING TOOLS


The more advanced debugging tools that are most widely used are:

• Similar programs to check software


• Logic analyzers to check signals and timing

fvlany variations of both these tools exist, and we shall discuss only the standard
features.

The simulator is the computerized equivalent of the pencil-and- SOFTWARE


paper computer It is a computer program that goes through the SIMULATOR
operating cycle of another computer, keeping track of the con-
tents of all the registers, flags, and memory locations. We could, of course, do this
by hand, but it would require a large amount of effort and close attention to the exact
effects of each instruction. The simulator program never gets tired or confused, forgets
an instruction or register, or runs out of paper.

Most simulators are large FORTRAN programs. They can be purchased or used on the
time-sharing services. The Z80 simulator \s available in several versions from different

sources.

14-8
Typical simulator features are:

1) A breakpoint facility. Usuallv. breakpoints can be set after a particular number of


cycles have been executed, when a memory location or one of a set of memory
locations is referenced, when the contents of a location or one of a set of locations
are altered, or on other conditions.

2) Register and memory dump facilities that can display the values of memory loca-
tions, registers, and I/O ports.

3) A trace facility that will print the contents of particular registers or memory loca-
tions whenever the program changes or uses them.

4) A load facility that allows you to set values mitiatly or change them during the
simulation.

Some simulators can also simulate input/output, interrupts, and even DMA.
The simulator has many advantages:
1) It can provide a complete description of the status of the computer, since the
simulator program is not restricted by pin limitations or other characteristics of the

underlying circuitry,
2) Itcan provide breakpoints, dumps, traces, and other facilities, without using any of
the processor's memory space or control system. These facilities will therefore not
interfere with the user program.

3) Programs, starting points, and other conditions are easy to change.


4) All the facilities of a large computer, including peripherals and software, are availa-
ble to the microprocessor designer.

On the other hand, the simulator is limited by its software base and its separation
from the real microcomputer. The major limitations are:
1) The simulator cannot help with timing problems, since it operates far more slowly
than real time and does not model actual hardware or interfaces.

2) The simulator cannot fully model the input/output section.

3) The simulator is usually quite slow. Reproducing one second of actual processor
time may require hours of computer time. Using the simulator can be quite expen-
sive.

The simulator represents the software side of debugging; it has the typical ad-
vantages and limitations of a wholly software-based approach. The simulator can
provide insight into program logic and other software problems, but cannot help
with timing, \/0, and other hardware problems.
The logic or microprocessor analyzer Is the hardware solution LOGIC
to debugging. Basically, the analyzer is the parallel digital ver- ANALYZER
sion of the standard oscilloscope. The analyzer displays informa-
hexadecimal or mnemonic form on a CRT. and has a variety of triggering
tion in binary,
events, thresholds,and inputs. Most analyzers also have a memory so that they can dis-
play the past contents of the busses.

The standard procedure is to set a triggering event, such as the occurrence of a particu-

laraddress on the Address Bus or instruction on the Data Bus. For example, one might
trigger the analyzer if the microcomputer tries to store data in a particular address or ex-
ecute an input or output instruction. One may then look at the sequence of events that
preceded the breakpoint Common problems you can find in this way include short
noise spikes (or glitches), incorrect signal sequences, overlapping wave-forms,
and other timing or signaling errors. Of course, a software simulator could not be
used to diagnose those errors any more than a logic analyzer could conveniently
be used to find errors In program logic.

14-9
Logic analyzers vary in many respects. Some of these are: IMPORTANT
FEATURES
1) Number of input lines. At least 24 are necessary to nnonitor
OF LOGIC
an 8-bit Data Bus and a 16-bit Address Bus. Still more are
ANALYZERS
necessary for contro! signals, clocks, and other important in-
puts.

2) Amount of memory. Each previous state that !S saved will occupy several bytes.

3) Maximum frequency. It must be several MHz to handle the fastest processors.

4) Minimum signal width (important for catching glitches).

5) Type and number events allowed. Important features are pre- and
of triggering
post-trigger delays; these allow the user to display events occurring before or
after the trigger event.

6) Methods of connecting to the microcomputer. This may require a rather complex


interface.

7) Number of display channels.

8) Binary, hexadecimal or mnemonic displays.

9) Display formats.
10) Signal hold time requirements.
1 1) Probe capacitance.
12) Single or dual thresholds.

All of these factors are important in comparing different logic and microprocessor
analyzers, since these instruments are new and unstandardized. .A tremendous variety
of products is already available and this variety will become even greater in the future.

Logic analyzers, of course, are necessary only for systems with complex timing.
Simple applications with low-speed peripherals have few hardware problems that
a designer cannot handle with a standard oscilloscope.

DEBUGGING WITH CHECKLISTS


The designer cannot possibly check an program by hand: however, there are
entire
You can use systematic hand
certain trouble spots that the designer can easily check.
checking to find a large number of errors without resorting to any debugging tools.
The question is where to place the effort. The answer is on TO WHAT
points that can be handled with either a yes-no answer or with INCLUDE IN
a simple arithmetic calculation. Do not try to do complex CHECKLIST
arithmetic, follow all the flags, or try every conceivable case. Limit
your hand checking to matters that can be settled easily. Leave the complex problems
to be solved with the aid of debugging tools. But proceed systematically; build your
checklist, and make sure that the program performs the basic operations correctly.
The first step is to compare the flowchart or other program documentation with
the actual code. Make sure that everything that appears in one also appears in the
other. A simple checklist will do the iob. It is easy to completely omit a branch or a pro-
cessing section.

Next concentrate on the program loops. Make sure that all registers and memory
locations used inside the loops are initialized correctly. This is a common source of er-

rors; once again, a simple checklist will suffice.

Now look at each conditional branch. Select a sample case that should produce a
branch and one that should not; try both of them. Is the branch correct or reversed? If
the branch involves checking whether a number is above or below a threshold, try the
equality case. Does the correct branch occur^ Make sure that your choice is consistent
with the problem definition.

14-10
Look at the loops as a whole. Try the first and last iterations by hand: these are often
troublesonne special cases. What happens if the number of iterations is zero; i.e., there
IS no data or the table Has no elennents? Does the program fall through correctly? Pro-
grams often will perform one iteration unnecessarily, or. even worse, decrement coun-
ters past zero before checking them.

Check everything down to the last statement. Don't assume (hopefully) that
off
the the only one in the program. Hand checking will allow you to get
first error Is
the maximum benefit from debugging runs, since you will get rid of many simple
errors ahead of time.
A quick review of the hand checking questions: HAND
1) Isevery element of the program design in the program (and
CHECKING
vice versa for documentation purposes)^
QUESTIONS
2) Are all registers and memory locations used inside loops in-

itialized before they are used?


3) Are all conditional branches correct?
4} Do all loops start and end properly?
5) Are equality cases handled correctly*'
6) Are trivial cases handled correctly''

LOOKING FOR ERRORS


Of course, despite all these precautions (or If you skip over COMMON
some of them), programs often still don't work. The designer ERRORS
is left with the problem of how to find the mistakes. The hand

checklist provides a starting place If you didn't use it earlier; some of the errors
that you may not have eliminated are:

1) Failure to initialize variables such as counters, pointers, sums, etc. Do not


assume that registers, memory locations, or flags necessarily contain zero belore
they are used.

2) Inverting the logicof a conditional jump, such as using Jump on Carry when you
mean Jump on Not Carry. Remember the effects of a comparison or subtraction (A
IS the contents of the Accumulator. M the contents of the register or memory loca-
tion):

Zero flag = 1 if A =M
= if A^M
Carry flag == 1 If A < M
= if A > M
Note particularly that Carry = if A = M, (the equality case). So. Jump on Carry
means jump if A < M, and Jump on Not Carry means |ump if A > M. If you want
the equality case on the other side, try either reversing the roles of A and M or
adding 1 to M. For example, if you want a jump if A > 10, use:

CP 10
JR NC.ADDR
If, on the other hand, you want a |ump if A > 10, use:

CP 11
JR NC.ADDR
3) Updating the counters and pointers in the wrong place or not at all. Be sure
that there are no paths through a loop that either skip or repeat the updating in-
structions.

14-11
4) Failure to fall through correctly in trivial cases such as no data in a buffer, no
tests to be run, or no entries in a transaction. Do not assunne that such cases will
never occur uniess the program specificatlv eliminates them.

Other problems to watch for are:


5) Reversing the order of operands. Remember that the LD instruction moves the
second operand into the first operand. For example, LD B,A moves the contents of
A to B, not the other way around,

6) Changing condition flags before you use them.


Remember that INC and DEC. when applied to a single register or memon/ loca-
tion, affect alt the flags except Carry, Remember also that POP AF and EX AF.AF^
affect alt the flags, and that Logical instructions clear the Carry.

7) Failing to change condition flags when you intend to.

The Zero and Sign flags may


not represent the current state of the Accumulator,
since many instructions (particularly LD) do not change the flags. Note that incre-
menting or decrementing register pairs (for example, INC HI or DEC BC) and com-
plementing the Accumulator (CPL) affect no flags at all.

8) Confusing values and addresses.


Remember that LD HL1000H toads HL with the number 1000 (hex) while LD
HL(IOOOH) loads HL with the contents of memory locations 1000 and 1001. A
similar distinction applies to LD A.COUNT and LD A.(COUNT).

9) Accidentally reinitializing a register or memory location.

Make sure that no Jump instructions transfer control back to initialization state-
ments.

1 0) Confusing numbers and characters.


Remember that the ASCII and EBCDIC representations of digits differ from the
digits themselves. For example. ASCII 7 is hex 37, whereas hex 07 is the ASCII

BELL character.
111 Confusing binary and decimal numbers.
Remember that the BCD representation of a number differs from its binary repre-
sentation. For example. BCD 36. when treated as a simple hexadecimal constant.
IS equivalent to 54 decimal (try it).

1 2) Reversing the order in subtraction. Be careful also with other operations (like
division) that do not commute. Remember that SUB and CP produce A-M, not
M-A.
1 3) Ignoring the effects of subroutines and macros.
Don't assume that calls to subroutines or invocations of macros will not change
flags, registers, or memory locations. Be sure of exactly what effects subroutines
or macros have. Note that It is very important to document these effects so that
the user can determine them without going through the entire listing.

14) Using the Shift instructions improperly.


Remember They are
the precise effects of RLC. RL, RRC, RR. SLA, SRA. and SRL.
all 1-bit shifts. SLA and SRL both empty bit. SRA preserves the sign
clear the
(most significant bit) by extending it to the right. RLC and RRC are circular shifts
that do not include the Carn/ in the circular register; RL and RR are circular shifts
that include the Carry. Remember that these instructions affect all the flags, even
if they are applied to the data memory location.
in a Note, however, that the one-
word shifts RLCA. RLA, RRCA. and RRA affect only the Carry.

14-12
1 5) Counting the length of an array incorrectly.
Remember that there are five {not four) memory locations included m addresses
0100 through 0104. inclusive.

1 6) Confusing registers and register pairs.


Remember that the CPU and
register pairs are physically the same. You
registers
can use them singly for 8-bit data or in pairs for addresses or 16-bit data, but not
both at the same time. Note that INC HL actually increments L. affecting H only if
L IS incremented to zero.

17} Confusing 8- and 16-bit registers.


The Accumulator and other CPU registers are eight bits long, while the index
registers. Program Counter, Stack Pointer, and register pairs are 16 bits long. You
cannot transfer the contents of a 16-bit register to an 8-bit register or vice versa.
18) Forgetting that 16-bit numbers or addresses occupy two memory locations.
LD HL,(40H) loads Register Pair HL with the contents of memory locations 0040
and 0041 . Similarly, PUSH DE stores Register Pair DE in two Stack locations. Also
remember Z80 stores all 2-byte quantities in low-order/hlgh-order format
that the
For example, LD (40H),HL will store the contents of Register L in location 0040
and the contents of Register H in location 0041.

1 9) Confusing the Stack and the Stack Pointer.


DEC, INC, and LD affect the Stack Pointer, not the contents of the Stack. PUSH
and POP transfer data to or from the Stack. Remember that CALL, RET. RETL
RETN, and RST also use the Stack to save or restore the Program Counter. The
response to an interrupt always involves saving the old Program Counter in the
Stack even if no explicit instruction is obtained externally {as in responding to NMI
or to INT in interrupt modes 1 or 2). Note that such instructions as EX (SP),HL do
not affect the Stack Pointer; they exchange the top two memory locations in the
Stack with the contents of a register pair or Index register, but leave the Stack
length unchanged.

20) Forgetting to initialize the Stack Pointer.


Remember that you must place the proper memory address into the Stack Pointer
before calling any subroutines or performing any Stack operations.

21) Changing a register or memory location before using it.

Remember that LD changes


the contents of the destination (but not the source).
Be careful of instructions that implicitly use certain registers for example, —
DJNZ decrements LDDR. CPI, CPIR, CPD, and CPDR
Register B; LDI, LDIR. LDD.
all decrement the Byte Counter m Register Pair BC and increment or decrement

Register Pair HL LDI, LDIR, LDD, and LDDR also increment or decrement Register
Pair DE. INI. INIR, IND. INDR. OUTI. OUTIR. OUTD. and OTDR all decrement
Register B and increment or decrement Register Pair HL.

22) Forgetting to transfer control past sections of the program that should not be
executed In particular situations.

Remember that the computer will proceed sequentially through the program
memory unless specifically ordered to do otherwise.

14-13
)

Interrupt-driven programs are particularly difficult to debug, DEBUGGING


since errors may occur randomly. If. for example, the program INTERRUPT-
enables the interrupts a few instructions too early, an error wt!l oc- DRIVEN
cur only if an interrupt is received while the program is executing I PROGRAMS

those few instructions. In fact you can usually assume that ran-
domly occurring errors are caused by the interrupt system.^ Typical errors in Inter-
rupt-drlven programs are:

1 Forgetting to re-enable interrupts after accepting one and servicing it.

The processor disables the system automatically on RESET or on accept-


interrupt
ing an interrupt. Be sure that no possible sequences fail to re-enable the interrupt
system. Remember that, in addition to re-enabling interrupts, the program often
has to perform some action to cause the interrupting signal to be reset. If this is not
done, it will appear as if the interrupting device is constantly requesting service.

2) Using the Accumulator before saving it; i.e., PUSH AF must precede any input
or output operations that jnvolve the Accumulator.

3) Forgetting to save and restore the Accumulator and flags (Register Pair AF).

4) Restoring registers in the wrong order.


If the order m which they were saved was:
PUSH AF
PUSH BC
PUSH DE
PUSH HL
the order of restoration should be:

POP HL
POPDE
POP BC
POP AF
5) Enabling interrupts before establishing all the necessary conditions such as
priority, flags, PiO and SIO configurations, pointers, counters, etc.

A checklist can aid here.

6) Leaving results in registers and destroying them in the restoration process.


As noted earlier, registers should not be used to pass information between the
regular program and the interrupt service routines.

7) Forgetting that RST (and NMI) leaves an address in the Stack whether you
use it or not.
You may have to re-mitialize or update the Stack Pointer.

8) Not disabling the interrupt during multi-word transfers or instruction se-


quences.
Watch particularly for situations where the interrupt service routine may use the
same memory locations that the program is using.

Hopefully* these lists will at least give you some Ideas as to where to look for er-
rors. Unfortunately, even the most systematic debugging can still leave some
truly puzzling problems, particularly when interrupts are Involved.^

14-14
I

C """ 3

Data =(40)

Result -(SSEG
=

——
Resuit
+ Data)

I
(41)= Result

dHU)
Figure 14-5. Flowchart of Decimal to Seven-Segment Conversion

14-15
Debugging Example 1 : Decimal to Seven-Segment Conversion
The program converts a decimal number m memory location 0040 DEBUGGING
to a seven-segment code m memory location 0041. It blanks the A CODE
display if memory location 0040 does not contain a decimal num- CONVERSION
ber. PROGRAM
initial Program Tom flowchart
( in Figure 14-5):

LD A,40H ;GET DATA


C? 9 ;ISDATA A DECIMAL DIGIT?
JR CDONE ;N0, KEEP ERROR CODE
LD HL.fSSEG) ;GET BASE ADDRESS OF T-SEGMENT TABLE
LD D,A
ADD HL.DE FIND ELEMENT BY INDEXING
LD A,(HU GET 7-SEGMENT CODE FROM TABLE
DONE. LD (41 H}. A SAVE 7-SEGMENT CODE OR ERROR CODE
HALT
SSEG. DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7DH
DEFB 6FH
Using the checklist procedure, we were able to find the following errors;

1) The block that cleared Result had been omitted.


2) The conditional branch was incorrect.

For example, if the data is zero, CP 9 sets the Carry, since < 9. However, the |ump on
the opposite condition (i.e.. JR NCDONE) still did not produce the correct result. Now
the program handles the equality case incorrectly since, if the data is 9. CP 9 clears the
Carry and causes a jump. The correct version is:

CP 10 ;1SDATA A DECIMAL DIGIT?


JR NCDONE :N0. KEEP ERROR CODE

14-16
Second Program:
LD B.O GET ERROR CODE TO BLANK DISPLAY
LD A.40H GET DATA
CP 10 !S DATA A DECIMAL DIGIT?
JR NCDONE NO, KEEP ERROR CODE
LD HL,{SSEG) GET BASE ADDRESS OF 7-SEGMENT TABLE
LD D.A
ADD HLDE FIND ELEMENT BY INDEXING
LD A,{HL) GET 7-SEGMENT CODE FROM TABLE
DONE: LD (41H).A SAVE 7-SEGMENT CODE OR ERROR CODE
HALT
SSEG; DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7DH
DEFB 6FH
This version was hand checked successtully.

Since the program was sinnple. the next stage was to single-step through it with read
data. The data selected for the trials was:

(the smallest number)


9 (the largest number)
10 (aborder case)
6B (hex) (random)

The first tnal was with zero in location 0040 (hex). The first error was obvious LD —
A.40H loaded the number 40 into A, not the contents of memory location 0040. The
correct instruction was LD A.(40H). After this correction was made, the program moved
along with no apparent errors until it tried to execute the LD A,(HL) instruction.

The contents of the Address Bus during the data fetch was 0647, an address that did
not even exist in the microcomputer. Clearly, something had gone wrong.

It was now time some more hand-checking Since we knew


for that JR NCDONE was
correct, the error was beyond that instruction but before LD A.(HL). A hand check
showed:
1) LD HL.(SSEG) places 3F (hex) into L and 06 (hex) into H.

This is wrong. We want LD, HL,SSEG. not LD HL,(SSEG). That is. we want
clearly
the address SSEG, not the contents of that address, to be loaded into Register Pair
HL
2) LD D.A places into Register D.

This IS wrong — the data should be placed into E. since we want to add it to the
least significant bits of the table address, in fact, an instruction should clear
Register D. since the erroneous program was not initializing or changing the other
half of Register Pair DE at all.

14-17
A

Third Program:

LD B,0 GET ERROR CODE TO BLANK DISPLAY


LD A,(40H) GET DATA
CP 10 IS DATA A DECIMAL DIGIT?

JR NC.DONE NO, KEEP ERROR CODE


LD HLSSEG GET BASE ADDRESS OF 7-SEGMENT TABLE
ID E.A
LD D.O USE DATA AS 16-BIT INDEX
ADD HLDE FIND ELEMENT BY INDEXING
LD A,(HL) GET 7-SEGMENT CODE FROM TABLE
DONE. LD (41 H). SAVE 7.SEGMENT CODE OR ERROR CODE
HALT
SSEG. DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7DH
DEFB 6FH
This program produced the following results:

Data Result
00 3F
09 6F
OA OA
6B 6B
The program was not clearing the result if the data was invalid, i.e., greater than 9. The
program never used the blank code m Register B. Since the program was simple, it
could be tested for all the decimal digits. The results were:

Data Result
3F
1 06
2 5B
3 4F
4 69
5 6D
6 7D
7 07
8 7D
9 6F

Note that the result for number 8 is wrong — it should be 7F Since everything else is

correct, the error is almost surely in the table. !n fact, entry 8 in the table had been
mtscopied.

14-18
The final program is:

DECIMAL TO 7-3EGMENT CONVERSION

LD B.O GET ERROR CODE TO BLANK DISPLAY


LD A,(40H) GET DATA
CP 10 IS DATA A DECIMAL DIGIT?
JR NCDONE NO. KEEP ERROR CODE
LD HL.SSEG GET BASE ADDRESS OF 7-SEGMENT TABLE
LD E.A
LD D.O USE DATA AS 16-BlT INDEX
ADD HL,DE FIND ELEMENT BY INDEXING
LD B.(HL) GET 7-SEGMENT CODE FROM TABLE
DONE: LD A,B
LD (41 H}. A ;SAVE 7-SEGMENT CODE OR ERROR CODE
HALT
SSEG. DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7FH
DEFB 6FH
The errors encountered in this program are typical of the ones that Z80 assembly
language programmers should anticipate. They include:
1) Failing to initialize registers or mennory locations.
2} Inverting the logic on conditional branches.
3) Branching incorrectiY m the case in which the operands are equal.
4) Confusing imnnediate and direct addressing, i.e.. data and addresses.
5) Failing to distinguish between 8-bit data and 16-bit addresses.
6) Branching to the wrong place so that one path through the program is incorrect.
7) Copying lists of nunnbers (or instructions) incorrectly.

Note that straightforward instructions like ADD. SUB. AND, etc.. seldom produce any
problems. One particularly annoying error that you should watch for is reversing the
operands on LD instructions. Many of these errors can be eliminated through the use of
a low-level system programming language like PLZ/ASM.^

14-19
c Start
D
tnterchsnge flag = 1

Count =UngtH
of Array
Pointer = Start
of Array

interchange {Pointer)
{Pointer + 1)

Interchange fieg ==

Pointer - Pointer + 1

Count = Count - 1

Figure 14-6. Flowchart of Sort Program

14-20
Debugging Example 2: Sort into Decreasing Order
The program sorts an array
unsigned 8-bU binary nunnbers into
of DEBUGGING
decreasing order. The array begins tn nnemory location 0041 and A SORT
Its length is in nnemory location 0040.
PROGRAM
Initial Program (from flowchart in Figure 14-6);

LD CO ;CLEAR INTERCHANGE FLAG


LD A.(40H) ;COUNT = LENGTH OF ARRAY
LD C.A
LD HL.41H ;PO!NT TO START OF ARRAY
PASS1: LD A.{HL) ;GET ELEMENT FROM ARRAY
INC HL
CP (HL) :!S IT LESS THAN NEXT ELEMENT?
JR C.CNT :N0. NO INTERCHANGE NECESSARY
LD (HU.A ;YES. INTERCHANGE ELEMENTS
INC HL
CNT DJNZ PASS1
DEC C ;WAS INTERCHANGE FLAG SET?
JR NZ,PASS1 :YES. DO ANOTHER PASS
HALT
The hand check shows that all the blocks m the flowchart have been implemented m
the program and that all the registers have been initialized. The conditional branches
must be examined carefully. The instruction JR CCNT must force a branch if the new
value IS less than or equal to the old value. Note that the equality case
must not result in
an interchange, since this will create an endless loop with the two equal elements
being switched back and forth.

Try an example;

(0040) = 30
(0041) = 37
CP (HL) results in the calculation of 30—37 The Carry is set to one. This example
should result m an interchange but does not.

JR NC.CNT will provide the proper branch In this case. If the two numbers are equal,
the comparison will clear the Carry and JR NC.CNT is again correct.

How about JR NZ.SORT at the end of the program? If there are any elements out of
order, the interchange flag will
be one. so the branch is wrong. It should be JR Z.SORT.
Now let's hand check the first iteration of the program. The initialization results in the
following values;

A = COUNT
B = COUNT
C =
HL = 0041
The effects of the loop instructions are;

LD A.(HL) ;A= (0041)


INC HL ;HL=0042
CP (HL) ;(0041)-(0042)
JR NC.CNT
LD (HU.A = (0041)
;(0042)
INC HL ;HL-0043
CNT: DJNZ PASS1 ;B-C0UNT-1

14-21
1

Note that we have already checked the Conditional Jump instructions. Clearly the logic
is incorrect. If the first two nunnbers are out of order, the results after the first iteration
should be:

(0041) = OLD (0042)


(0042) - OLD (0041)
HL = 0042
8 = COUNT-
Instead, they are:

(0041) = UNCHANGED
(0042) = OLD (0041)
HL = 0043
B = COUNT-1
The error inHL is easy to correct. The second INC HL is unnecessary and should be
omitted. The interchange requires a bit more care and a temporary register, i.e..
LD D,(HL)
LD {HU,A
DEC HL
LD (HU.D
INC HL
An interchange always requires a temporary storage place in which one number can be
saved while the other one is being transferred.

14-22
All of these changes require a new copy of the program, i.e.,

LD CO :CLEAR INTERCHANGE FLAG


LD A.(40H) ;COUNT - LENGTH OF ARRAY
LD C.A
LD HL.41 H ;PO!NT TO START OF ARRAY
PASS1: LD A,(HU ;GET ELEMENT FROM ARRAY
!NC HL
CP (HU IS IT LESS THAN NEXT ELEMENT?
JR NC.CNT NO. NO INTERCHANGE NECESSARY
LD D,(HL1 YES, INTERCHANGE ELEMENTS
LD (HL),A
DEC HL
LD (HU.D
INC HL
CNT: DJNZ PASS1
DEC C :WAS INTERCHANGE FLAG SET?
JR NZ.PASS1 DO ANOTHER PASS
;YES.
HALT
How about the last iteration? Let's say that there are three elements:

(0040) - 03
(0041) = 02
(0042) = 04
(0043) = 06
Each tinne through, the program increments Register Pair HL by one. So, at the start of
the third iteration,

(HL) = 0041 +2=0043


The effects of the loop instructions are:

LD A,(HL) :A= (0043)


INC HL ;HL=0044
CP (HL) ;(0043)-(0044)

This IS the program has tried to move beyond the end of the data. The pre-
incorrect:
vious iteration should, in fact, have been the last one, since the number of pairs is one
less than the number of elements. The correction is to reduce the number of iterations
by one; this can be accomplished by placing DEC B after LD A.(40H).

How about the trivial cases? What happens if the array contains no elements at
all, one element? The answer is that the program does not work correctly
or only
and may change a whole block of data improperly and without any warning (try
iti). The corrections to handle the trivial cases are simple but essential; the cost

is only a few bytes of memory to avoid problems that could be very difficult to

solve later.

14-23
The new program is:

LD CO CLEAR INTERCHANGE FLAG


LD A,(40H) COUNT = LENGTH OF ARRAY
CP 2 ; DOES ARRAY HAVE 2 OR MORE ELEMENTS?
JR C.DONE ; NO. NO ACTION NECESSARY
LD B,A
DEC B NUMBER OF PAIRS -COUNT-1
LD HL41H POINT TO START OF ARRAY
PASS1: LD A,(HL) GET ELEMENT FROM ARRAY
INC HL
CP (HL) IS IT LESS THAN NEXT ELEMENT?
JR NC.CNT :N0. NO INTERCHANGE NECESSARY
LD D.(HL) :YES. INTERCHANGE ELEMENTS
LD {HL),A
DEC HL
LD (HU.D
INC HL
CNT: DJNZ PASS1
DEC C WAS INTERCHANGE FLAG SET?
JR NZ.PASS1 YES. DO ANOTHER PASS
HALT
Now It's time to check the program on the computer or on the simulator A simple set of
data is:

(0040) = 02
(0041) = 00
(0042) = 01

This set consists of two elements in the wrong order The program should take two
passes. The first pass should rearrange the elements, producing;

(0041) - 01
(0042) = 00
C - 01

The second pass should complete the operation and produce:


C = 00
This program is rather long for single stepping, so we'll use breakpoints instead. Each
breakpoint will halt the computer and print the contents of all the registers. The break-
points will come:

1) After LD HL,41H to check the mittalization.

2) After CP (HL) to check the comparison.


3) After the second INC HL (i.e.. |ust before the label CNT) to check the interchange.
4) After DEC C to check the completion pass through the array. The contents
of a of

the registers after the first breakpoint were:

Register Contents
A 02
B 01
C 00
H 00
L 41

These are all correct, so the program is performing the initialization correctly sn this

case.

14-24
The results at the second breakpoint were:

Register Contents
A 00
B 01
C 00
H 00
L 42
CARRY 1

These results are also correct. The results at the third 1:

Register Contents
A 00
8 01
C 00
D 01
H 00
L 42
Checking nnennory showed:

(0041) = 01
(0042) - 00
The results at the fourth breakpoint were:

Register Contents
A 00
B 01
C 00
D 01
H 00
L 42
Here, Register C does not contain the correct value —
it should have been set to one to

indicate that an interchange had occurred. In fact a look at the program shows that no
instruction ever changes C to mark the interchange. The correction is to place the in-
struction LD C.I after JR NCCNT
Now the procedure is to load Register C with the correct value and continue. The sec-
ond Iteration of the second breakpoint gives;

Register Contents
A 00
B 00
C 00
H 00
L 43
CARRY 1

Clearly the progrann has proceeded incorrectly without reinitializing the registers (par-
ticularly HL). The conditional jump that depends on the interchange flag should transfer
control all the way back to the start of the program, not to the label PASS1.

14-25
The final version of the program Is:

SORT; LD CO :CLEAR INTERCHANGE FLAG


LD A.(40H) ;COUNT = LENGTH OF ARRAY
CP 2 ;DOES ARRAY HAVE 2 OR MORE ELEMENTS?
JR C.DONE ;N0. NO ACTION NECESSARY
LD B.A
DEC B NUMBER OF PAIRS =C0UNT-1
LD HL41H POINT TO START OF ARRAY
PASS1 LD A,(HL) GET ELEMENT FROM ARRAY
tNC HL
CP (HL) ;IS IT LESS THAN NEXT ELEMENT?
JR NC.CNT ;N0. NO INTERCHANGE NECESSARY
LD c::i SET INTERCHANGE FLAG
;YES.
LD D,(HU JNTERCHANGE ELEMENTS
LD (HU.A
DEC HL
LD (HL),D
INC HL
CNT: DJNZ PASS1
DEC C ;WAS INTERCHANGE FLAG SET?
JR NZ.SORT :YES. DO ANOTHER PASS
HALT
Clearly we cannot check all the possible input values for this program. Two other simple
sets of data for debugging purposes are:

1) Two equal elements

(0040) - 02
(0041) = 00
(0042) - 00
2) Two elements already m decreasing order

(0040) = 02
(0041) 01
(0042) 00

14-26
INTRODUCTION TO TESTING
Program testing is closely related to program debugging. USING TEST
Surely some of the test cases will be the same as the test CASES FROM
data used for debugging, such as: DEBUGGING
• Trivial cases such as no data or a single element
> Special cases that the program singles out forsome reason
• Simple examples that exercise particular parts of the program
In the case of the decimal to seven-segment conversion program, these cases
cover all the possible situations. The test data consists of:
• The numbers through 9
• The boundary case 10
• The randonrs case 6B
The program does not distinguish any other cases. Here debugging and testing are
virtually the same.

Inthe sorting program, the problem is more difficult. The number of elements could
range from to 255, and each of the elements coutd lie anywhere in that range. The
number of possible cases is therefore enormous. Furthermore, the program \s
moderately complex. How do we select test data that will give us a degree of confi-
dence in that program? Here testing requires some design decisions. The testing
problem is particularly difficult if the program depends on sequences of real-time data.
How do we select the data, generate tt and present it to the microcomputer in a
realistic manner?

Most of the tools mentioned earlier for debugging are helpful TESTING
in testing also. Logic or microprocessor analyzers can help AIDS
check the hardware; simulators can help check the software.
Other tools can also be of assistance, e.g.,
1) I/O simulations that can simulate a variety of devices from a single input and a
single output device.
2) In-clrcuit emulators that allow you to attach the prototype to a development
system or control panel and test it.
3) ROM simulators that have the flexibility of a RAM but the timing of the particular
ROM or PROM that will be used in the final system.
4) Beal-time operating systems that can provide inputs or interrupts at specific
times (or perhaps randomly) and mark the occurrence of outputs. Real-time break-
points and traces may also be included.
5) Emulations (often on micro programmable computers) that may provide real-time
execution speed and programmable 1/0.^
6} Interfaces that allow another computer to control the I/O system and test the
microcomputer program.
7) Testing programs that check each branch m a program for logical errors.
8) Test generation programs that can generate random data or other distributions.

Formal testing theorems exist but they are usually applicable only to very short pro-
grams.

You must be careful that the test equipment does not invalidate the test by
modifying the environment. Often, test equipment may buffer, latch, or condition
input and output signals. The actual system may not do this, and may therefore
behave quite differently.

14-27
°

Furthermore, extra software in the test environment may use some of the memo-
ry space or part of the interrupt system. It may also provide error recovery and
other features that will not exist in the final system. A software test bed must be
lust as realistic as a hardware test bed, since software failure can be [ust
as cnttcal as
hardware failure.
Emulations and simulations are, of course, never precise. They are usually ade-
quate for checking logic, but can seldom help test the interface or the timing. On
the other hand, real-time test equipment does not provide much of an overview of
the program logic and may affect the interfacing and timing.

SELECTING TEST DATA


Very few real programs can be checked for all cases. The designer must choose a
sample set that in some sense describes the entire range of possibilities.
Testing should, of course, be part of the total developnnent pro- STRUCTURED
cedure. Top-down design and structured programming provide for TESTING
testing as part of the design. This is called structured testing.
Each module withm a structured program should be checked separately. Testing, as
well as design, should be 4tiodular, structured, and top-down.

But that leaves the question of selecting test data for a TESTING
module. The designer must first list all special cases that a SPECIAL
program recognizes. These may include: CASES
• Trivial cases
• Equality cases
• Special situations

The test data should include all of these.

You must next identify each class of data that statements FORMING
within the program may distinguish. These may include: CLASSES
OF DATA
- Positive or negative numbers
• Numbers above or below a particular threshold
« Data that does or does not include a particular sequence or character
• Data that is or is not present at a particular time

If the modules are short, the total number of classes should still be small even though

each division is multiplicative: i.e.. two two-way divisions result in four data classes.
You must now separate the classes according to whether the SELECTING
program produces a different result for each entry in the class DATA FROM
(as in a table) or produces the same result for each entry (such CLASSES
as a warning that a parameter is above a threshold). In the dis-
crete case, one may include each element if the total number is small or sample if the
number is large. The sample should include all boundary cases and at least one case
selected randomly. Random number tables are available in books, and random number
generators are part of most computer facilities.

You must be careful of distinctions that may not be obvious. For example, an 8-bit
microprocessor will regard an 8-bit unsigned number greater than 127 as nega-
tive; the programmer must consider this when using conditional branches that
depend on the Sign flag. You must also watch for instructions that do not affect
flags, overflow in signed arithmetic, and the distinctions between address-length
{16-bit) quantities and data-length f8-blt) quantities.

14-28
Testing Example 1 : Sort Program
The special cases here are obvious; TESTING
• No elements in the array A SORT
One element, magnitude may be
PROGRAM

selected randomly

The other special case to be considered is one in which elements are equal.
There may be some problem
here with signs and data length. Note that the array itself
must contain fewer than 256 elements. The use of the instruction LD C,1 or SET 1,C
rather than DEC C to clear the interchange flag means that there will be no difficulty if
the number of elements or interchanges exceeds 128.

We could check the effects of sign by picking half the regular test cases with numbers
ofelements between 128 and 255 and half between 2 and 127. All magnitudes should
be chosen randomly so as to avoid unconscious bias as much as possible.

Testing Example 2: Self-Checking Numbers (see Chapter 8)


Here we will presume that a pnor validity check has ensured that TESTING AN
the number has the right length and consists of valid digits. Since ARITHMETIC
the program makes no other distinctions, test data should be PROGRAM
selected randomly. Here a random number table or random num-
ber generator will prove ideal; the range of the random numbers is to 9.

TESTING PRECAUTIONS
The designer can simplify the testing stage by designing pro- RULES FOR
grams sensibly. You should use the following rules: TESTING
1) Try to eliminate trivial cases as early as possible without in-
troducing unnecessary distinctions.
2) Minimize the number of special cases. Each special case means additional testing
and debugging time.
3) Consider performing validity or error checks on the data prior to processing.
4) Be careful of inadvertent and unnecessary distinctions, particularly in handling
signed numbers or using operations that refer to signed numbers.
5) Check boundary cases by hand. These are often a source of errors. Be sure that the
problem definition specifies what is to happen in these cases.
6) Make the program as general as reasonably possible. Each distinction and separate
routine increases the required testing,
7} Divide the program and design the modules so that the testing can proceed in
steps m conjunction with the other stages of software development.*^

14-29
CONCLUSIONS
Debugging and testing are the stepchildren of the software development process.
Most projects leave far too little time for them and most textbooks neglect them.
But designers and managers often find that these stages are the most expensive
and time-consuming. Progress may be very difficult to measure or produce.
Debugging and testing microprocessor software is particularly difficult because
the powerful hardware and software tools that can be used on larger computers
are seldom available for microcomputers.

The designer should plan debugging and testing carefully. We recommend the
following procedure:

1) Try to write programs that can easily be debugged and tested. Modular pro-
gramming, structured programming, and top-down design are useful techni-
ques.
2) Prepare a debugging and testing plan as part of the program design. Decide
early what data you must generate and what equipment you will need.
3) Debug and test each module as part of the top-down design process.
4) Debug each module's logic systematically. Use checklists, breakpoints, and
the single-step mode. If the program logic is complex, consider using the soft-
ware simulator.
5) Check each module's timing systematically if this is a problem. An
oscilloscope can solve many problems if you plan the test properly. If the tim-
ing is complex, consider using a logic or microprocessor analyzer.
61 Be sure that the test data is a representative sample. Watch for any classes of
data that the program may distinguish. Include all special and trivial cases.
If the program handles each element differently or the number of cases
is
7)
large, select the test data randomly.^

8) Record alltest results as part of the documentation. If problems occur, you


will not have to repeat test cases that have already been checked.

14-30
REFERENCES
1. For more information about logic analyzers, see:

R. L Down, "Understanding Logic Analyzers," Computer Design, June 1977. pp.


188-191.

W. A. Farnbach, "Bring up Your ^P." Electronic Design, July 10. 1976, pp. 80-85.

B. Fatly, "Logic Analyzers Aren't Ail Alike," Electronic Design, Feb. 1, 1978. op.
70-76.

K. Pines, "What Do Logic Analyzers Do?." Digital Design. September 1977. pp.
55-77.

N. A. Robin. "The Logic Analyzer: A Computer Troubleshooting Tool." Computer


Design March 1976, pp. 89-96.
.

S. Runyon, "Focus on Logic and fxP Analyzers," Electronic Design, February 1.


1977.. pp. 40-50.

A. Santoni, "The Latest Logic Analyzers Offer More Functions and Less Cost"
Electronic Design Feb. 1. 1978, pp. 26-32.
,

See W.
2. J. Weller, Assembly Level Programming for Small Computers Lexington

Books. Lexington. Mass.. 1975.


^— ,

3. Some guidelines for debugging interrupt problems are given m R. L. Baldrige, "In-
terrupts Add Power, Comptexitv to Microcomputer System Design." EDN. August
5, 1977. pp. 67-73.

4. See C. Bass, "PLZ: A Family of System Programming Languages for


Microprocessors," Computer March 1978. pp. 34-39.
.

5. See, for example. H. R. Burns. "Time-Scaled Emulations of the 8080


Microprocessor," Proceedings of t he 1977 National Computer Conference, pp.
""""
937-946.

6. See D. A. Walsh, "Structured Testing." Datamation. July 1977. pp. 111-118.


7. Testing (and debugging) are also discussed in R. A. DeMillo et al., "Hints on Test
Data Selection: Help for the Practicing Programmer." Computer April 1978, pp. .

34-41 and in W. F, Dalton. "Design Microcomputer Software," Electronics January ,

19. 1978. pp. 97-101.

8. Random numbers and their generation are discussed in T. G. Lewis. Distribution


Sampling for Computer Simulation Lexington Books. Lexington. Mass., 1975 and
,

in R. A. Mueller, etal.. "A Random Number Generator for Microprocessors," Simula-


tion. April 1977. pp. 123-127.

14-31
Chapter 15
DOCUMENTATION AND REDESIGN
The working program is not the only requirement of software development. Ade-
quate documentation is also an important part of a software product. Not only
does documentation help the designer in the testing and debugging stages, it is
also essential for later use and extension of the program. A poorly documented
program will be difficult to maintain, use, or extend.
Occasionally, a program uses too much memory or executes too slowly. The
designer must then improve it. This stage is called redesign, and requires that you
concentrate on the parts of the program that can yield the most improvement.

SELF-DOCUMENTING PROGRAMS
Although no program is ever completely self-document- RULES FOR
ing, some of the rules that we mentioned earlier can heip. SELF-DOCUMENTING
These include: PROGRAMS
• Clear, sinnpie structure with as few transfers of control
(junnps) as possible

• Use of meaningful names and labels


• Use of names for I/O devices, parameters, numerical factors, etc.
• Emphasis on simplicttv rather than on minor savings m memory usage, execution
time, or typing

For example, the following program sends a string of characters to a tetetypewnter:

LD A,(2000H)
LD B.A
LD HL1000H
W: LD A,{HL)
OUT (6),A
CALL XXX
INC HL
DJNZ W
HALT
Even without comments we car

MESSG ECU 1000H


COUNT ECU 2000H
TTYSIO EQU 6
LD A. (COUNT)
LD B.A
LD HLMESSG
OUTCH: LD A,(HL)
OUT (TTYS!0),A
CALL BITDLY
INC HL
DJNZ OUTCH
HALT

15-1
Surety this program is easier to understand than the earlier version. Even without

further documentation, you could probably guess at the function of the program and
the meanings of most of the variables. Other documentation techniques cannot
substitute for self-documentation.

Some further notes on choosing names: CHOOSING


USEFUL
1) Use the obvious name when it is available, like TTY or CRT NAMES
for output devices. START or RESET for addresses, DELAY or
SORT for subroutines, COUNT or LENGTH for data.

2) Avoid acronyms like S16BA for SORT 16-BIT ARRAY. These seldom mean any-
thing to anybody.
3} Use full words or close to full words when possible, like DONE. PRINT. SEND. etc.

4) Keep the names as distinct as possible

COMMENTS
The most obvious form of additional documentation is the comment. However,
few programs (even those used as examples in books), have effective comments.
You should consider the following guidelines for good comments,
1) Don't repeat the meaning of the instruction code. Rather, COMMENTING
explain the purpose of the instruction m the program. Com- GUIDELINES
ments like

DECS ;B = B-1

add nothing to documentation. Rather, use


DEC 8 ;LINE NUMBER -
LINE NUMBER-1
Remember that you know what the operation codes mean and anyone else can
look them up in the manual The important point is to explain what task the
program is performing.
2) Make the comments as clear as possible. Do not use abbreviations or acronyms
unless they are well-known (like ASCII, PIO. or UART) or standard (like no for num-

ber, ms for millisecond, etc.). Avoid comments like

DEC B ;LN = LN-1


or
DEC B :DEC LN BY 1

The extra typing simply is not all that expensive.

3) Comment every important or obscure point. Be particularly careful to mark


operations that may not have obvious functions, such as
AND 1101111 1B ;TURN TAPE READER BIT OFF
or
ADD HL.DE ;1NDEX GRAY CODE TABLE
Clearly, I/O operations often require extensivecomments. If you're not exactly
what an instruction does, or if you have to think about it add a clarifying
sure of
comment. The comment will save you time later and will be helpful in documenta-
tion.

15-2
4) Don't comment the obvious. A comment on each line simply makes it difficult to
find the important points. Standard sequences like
INC HL
DJNZ SEARCH
need not be marked unless you're domg something special. One comment will
often suffice for several lines, as m

RRCA :SWAP DIGITS


RRCA
RRCA
RRCA
LD A.C ;EXCHANGE MOST SIGNIFICANT. LEAST
LD C.B . SIGNIFICANT BYTES
LD B,A

5) Place comments on the lines to which they refer or at the start of a se-
quence.
6) Keep your comments up-to-date. If you change the program, change the com-
ments.

7) Use standard forms and terms m commenting. Don^t worry about repetitiveness.
Variednames for the same things are confusing, even if the variations are just
COUNT and COUNTER. START and BEGIN. DISPLAY and LEDS. or PANEL and
SWITCHES.
There's no real gam m not being consistent. The variations may seem obvious to
you now, but may not be clear later; others will get confused from the very begin-
ning.

8) Make comments mingled with instructions brief. Leave a complete explanation


to header comments and other documentation. Otherwise, the program gets lost
in the comments and you may have a hard time even finding it

9) Keep Improving your comments. If you come to one that you cant read or un-
derstand, take the time to change it. If you find that the listing is getting crowded,
add some blank lines. The comments wonT improve themselves: in fact, they will
just become worse as you leave the task behind and forget exactly what you did.

10) Before every major section, subsection, or subroutine. Insert a number of


comments describing the functions of the code that follows. Care should be
taken to describe all mputs, outputs, and side effects, as well as the algorithm
employed.
11) It is good practice when modifying working programs to use comments to In-
dicate the date, author, and type of modification made.

Remember, comments are important. Good ones will save you time and effort. Rut
some work Into comments and try to make them as effective as possible.

16-3
Multiple-Precision
COMMENTING
Commenting Example 1 :
EXAMPLES
Addition
The basic program Is:

LD A.OOH)
LD B.A
LD HL41H
LD DE51H
AND A
ADDWD: LD A.(DE)
ADC A.(HU
LD (HU.A
INC DE
INC HL
DJNZ ADDWD
HALT
First comment the important points. These are typicailv initializations, data fetches,
and processing operations. Don't bother with standard sequences like updating poin-
ters and counters. Remember that names are clearer than numbers, so use
them freely.

The new version of the program is:

;MULTIPRECISION ADDITION

;TH1S PROGRAM PERFORMS MULTI-BYTE ADDITION

INPUTS LOCATION 30H - LENGTH OF NUMBERS (IN BYTES)


LOCATIONS 41H-50H == FIRST ADDEND IN LSB-^MSB ORDER
':

LOCATIONS 51 H-60H = SECOND ADDEND


:OUTPUTS: LOCATIONS 41H-51H = SUM

LENGTH EQU 30H


NUMB1 EQU 41H
NUMB2 EQU 51H
LDA LENGTH ;COUNT = LENGTH OF NUMBERS (IN BYTES)
LD B,A
LD HLNUMB1 ;START AT LSB'S OF 1ST NUMBER
LD DE,NUMB2 :START AT LSB'S OF 2ND NUMBER
AND A
ADDWD: LD A,(DE} 2ND NUMBER
:GET 8 BITS OF
ADC A,(HL) :ADD8BITS0F 1ST NUMBER
LD (HU,A :ST0RE RESULT IN 1ST NUMBER
INC DE
INC HL
DJNZ ADDWD
HALT
Second, look for any instructions that might not have obvious QUESTIONS
functions and mark them. Here, the purpose of AND A Is to clear FOR
the Carn/ the first time through. j COMMENTING
Third, ask yourself whether the comments tell you what you would
need to know if you wanted to use the program, e.g.;

1) Where is the program entered? Are there alternative entry points?

2) What parameters are necessary? How and in what form must thev be supplied?

15-4
3) What operations does the program perform?

4) From where does it get the data?

5) Where does it store the results?

6) What special cases does it consider?


7} What does the program do about errors?

8) How does it exit?

Some of the may not be relevant to a particular program and some of the
questions
answers may be obvious. Make sure that you won^t have to sit down and dissect the
program to figure out what the answers are. Remember that too much explanation is
just dead wood that vou will have to clear out of the way. is there
anything that you
would add to or subtract from this listing? If sa go ahead —
you are the one who has to
fee! that the commenting is adequate and reasonable.
MULTiPRECiStON ADDITION

THIS PROGRAM PERFORMS MULTI-BYTE ADDITION

INPUTS; LOCATION 30H = LENGTH OF NUMBERS (IN BYTES)


LOCATIONS 41H-50H - FIRST ADDEND IN LSB— MSB ORDER
LOCATIONS 51 H-60H = SECOND ADDEND
OUTPUTS: LOCATIONS 41H-51H =SUM

LENGTH ECU 30H ;LENGTH OF NUMBERS


NUMB1 EQU 41H LSB'S OF 1ST NUMBER AND RESULT
NUMB2 EQU 51H LSB'S OF2ND NUMBER
LDA LENGTH COUNT = LENGTH OF NUMBERS (IN BYTES)
LD B.A
LD HLNUMB1 ;START AT LSB'S OF 1ST NUMBER
LD DE.NUMB2 START AT LSB'S OF 2ND NUMBER
AND A CLEAR CARRY TO START
ADDWD: LD A,(DE) ;GET 8 BITS OF 2ND NUMBER
ADC A,(HL) ADD 8 BITS OF 1ST NUMBER
LD (HU.A STORE RESULT IN 1ST NUMBER
INC DE
INC HL
DJNZ ADDWD
HALT
Commenting Example 2: Teletypewriter Output
The basic program is:

LD A,(60H)
ADD A,A
LD B.11
TBtT: OUT (PIODRB),A
RRA

CALL BITDLY
DJNZ TBIT
HALT

15-5
Commenting the important points and adding names gives:

:TELETYPEWR1TER OUTPUT PROGRAM

:TH1S PROGRAM PRINTS THE CONTENTS OF MEMORY LOCATION 60H TO THE


; TELETYPEWRITER

; INPUTS: LOCATION 60H = CHARACTER CODE


; OUTPUTS: NONE

TTYPIO EQU PIODRB


NBITS EQU 11 NUMBER OF BITS PER CHARACTER
TDATA EQU 60H ADDRESS OF CHARACTER TO BE
TRANSMITTED
LD A, (TDATA) GET DATA
ADD A,A AND FORM START BIT
SHIFT LEFT
LD B.NBITS COUNT = NUMBER OF BITS PER CHARACTER
TBIT: OUT (TTYPIO),A SEND BIT TO TTY
RRA UPDATE FOR NEXT BIT
SCF FORM STOP BIT (LOGIC ONE)
CALL BITDLY DELAY 1 BIT TIME
DJNZ TBIT
HALT
Note how easily we could change this program so that it would transfer a whole string
of data, starting at the address in locations DPTR and DPTR + 1 and ending with an
"03" character (ASCII ETX). Furthermore, let us make the terminal a 30 character per

second device with one stop bit (we will have to change subroutine BITDLY). Try mak-
ing the changes before looking at the listing.

;STRtNG OUTPUT PROGRAM

:THIS PROGRAM OUTPUTS A STRING TO THE TERMINAL TRANSMISSION CEASES


: WHEN AN ASCII ETX (30H) IS ENCOUNTERED

: INPUTS: LOCATIONS 60H-61 H CONTAIN ADDRESS OF


; STRING TO OUTPUT
: OUTPUTS: NONE

DPTR EOU 60H LOCATION OF OUTPUT BUFFER START


: ADDRESS
ENOCH EQU 03 :ENDING CHARACTER -ASCII ETX
NBITS EQU 11 :NUMBER OF BITS PER CHARACTER
TTYPIO EQU PIODRB
LD HL,(DPTR) GET STARTING ADDRESS OF STRING
TCHAR: LD A,(HL) GET A CHARACTER
CP ENOCH IS IT ENDING CHARACTER?
JR Z,DONE YES,DONE
ADD A,A SHIFTDATA LEFT AND FORM START BIT
LD B,NBITS COUNT = NUMBER OF BITS PER CHARACTER
TBIT: OUT (TTYPIO).A SEND BIT TO TTY
RRA UPDATE FOR NEXT BIT
SCF FORM STOP BIT (LOGIC ONE)
CALL BITDLY DELAY 1 BIT TIME
DJNZ TBIT
INC HL
JR TCHAR
DONE: HALT
15-6
Good comments can make it easy for you to change a program to meet new require-
ments. For example, try changing the last program so that it:
• Starts each message with ASCI! SIX (02 hex) foNowed by a three-digit identification
code stored in memory locations 0030 through 0032

• Adds no start or stop bits

• Waits 1 ms between bits

• Transmits 40 characters, starting with the one located at the address in DPTR and
DPTR+1
• Ends each message with two consecutive ASCII ETXs (03 hex)

FLOWCHARTS AS DOCUMENTATION
We have already described the use of flowcharts as a design too! HINTS FOR
in Chapter 13. Flowcharts are also useful in documentation, partic- USING
ularly if:
FLOWCHARTS
• They are not so detailed as to be unreadable
• Their decision points are clearly explained and marked
• They Include all branches
• They correspond to the actual program listings

Flowcharts are helpful if they give you an overall picture of the program. They are not
helpful if they are just as difficult to read as an ordinary listing.

STRUCTURED PROGRAMS AS DOCUMENTATION


A structured program can serve as documentation for an assembly language program
if:

• You describe the purpose of each section in the comments


• You make which statements are included
it clear in each conditional or loop structure
by using indentation and ending markers
• You make the total structure as simple as possible
• You use a consistent well-defined language
The structured program can help you to check the logic or improve It Furthermore,
since the structured program machine-independent, it can also aid you in implement-
is

ing the same task on another computer.

MEMORY MAPS
A memory map is simply a list of all the memory assignments in a program. The map

allows you to determine the amount of memory needed, the locations of data or
subroutines, and the parts of memory not allocated. The map is a handy reference for
finding storage locations and entry points and for dividing memory between different
routines or programmers. The map will also give you easy access to data and
subroutines if you need them in later extensions or in maintenance. Sometimes a
graphical map is more helpful than a listing.

15-7
A typical map would be: TYPICAL
MEMORY
MAP

Program Memory j

Address Routine Purpose

0000-0002 RESET TRANSFE-RS CONTROL TO MAIN PROGRAM IN LOCATION


40 HEX
0038-003A INTRPT TRANSFERS CONTROL TO INTERRUPT SERVICE
IN LOCATION 300 HEX
0040-0265 MAIN MAIN PROGRAM
0270-027F DELAY DELAY PROGRAM
0280-0290 DSPLY DISPLAY CONTROL PROGRAM
0300-0340 KEVIN INTERRUPT CONTROL PROGRAM FOR KEYBOARD

Data Memory |

1000 NKEYS NUMBER OF KEYS


1001-1002 KPTR KEYBOARD BUFFER POINTER
1003-1041 KBFR KEYBOARD BUFFER
1042-1051 DBFR DISPLAY BUFFER
1052-105F TEMP TEMPORARY STORAGE
10E0-10FF STACK RAM STACK

The map may also list additional entry points and include a specific description of the

unused parts of memory.

PARAMETER AND DEFIMITION LISTS


Parameter and definition lists at the start of the program and each subroutine
make understanding and changing the program far simpler. The following rules can
help:

Separate RAM locations, I/O units, parameterSr defini- RULES FOR


tions, and memory system constants. DEFINITION
LISTS
2) Arrange lists alphabetically when possible, with a descrip-
each entry.
tion of

Give each parameter that might change a name and include it in the lists. Such

parameters may include timing constants, inputs or codes corresponding to partic-


ular keys or functions, control or masking patterns, starting or ending characters,
thresholds, etc.

4) Make the memory system constants into a separate list. These constants will
include Reset and interrupt service addresses, the starting address of the program,
RAM areas. Stack areas, etc.

Give each port used by an I/O device a name, even though devices may share
ports in the current system. The separation wilt make expansion or reconfiguration
much simpler.

15-8
A typical list of definitions will be: TYPICAL
DEFINITION
LIST
;MEMORY SYSTEM CONSTANTS

RESET EQU RESET ADDRESS


INTRP EQU 38H INTERRUPT ENTRY
START ECU 40H START OF MAIN PROGRAM
KEVIN EQU 300H KEYBOARD INTERRUPT PROGRAM
RAMST ECU 1000H START OF DATA STORAGE
STKPTR ECU 1100H START OF STACK

. I/O UNITS

DSPLY EQU OEOH OUTPUT PIO FOR DISPLAYS


KBDIN EQU 0E1H INPUT PIO FOR KEYBOARD
KBDOUT EQU OEOH OUTPUT PIO FOR KEYBOARD
TTYPIO EQU OFOH TTY DATA PORT

;RAM LOCATIONS

ORG RAMST
NKEYS DEFS 1 ; NUMBER OF KEYS
KBDPTR DEFS 2 ; KEYBOARD BUFFER POINTER
KBDBFR DEFS 40H : KEYBOARD INPUT BUFFER
DSPBFR DEFS 10H : DISPLAY DATA BUFFER
TEMP DEFS 14H TEMPORARY STORAGE

;PARAMETERS

BOUNCE EQU 2 : DEBOUNCING TIME IN MS


GOKEY EQU 10 : IDENTIFICATION OF 'GO' KEY
MSCNT EQU 133 ; COUNT FOR 1 MS DELAY

OPEN EQU OFH : PATTERN FOR OPEN KEYS


TPULS EQU 1 ; PULSE LENGTH FOR DISPLAYS IN MS

;DEFtNITIONS

ALL1 EQU OFFH : ALL ONES PATTERN


STCON EQU 80H : START CONVERSION PULSE

Of course, the RAM entries will usually not be in alphabetical order, smce the designer
must order these so as to minimize the number of address changes required m the pro-
gram.

15-9
LIBRARY ROUTINES
Standard documentation of subroutines will allow you to build up a library of
useful programs. The idea Is to make these programs easity accessible. A standard for-
mat will allow YOU or anyone else to see at a glance what the program does. The best
procedure is to make up a standard form and use it consistently. Save these programs
m a well-organized manner (for example, according to processor, language, and type of
program), and you will soon have a useful set. But remember that without organiza-
tion and proper documentation, using the library may be more difficult than rewrit-
ing the program from scratch. Debugging a system requires a precise understanding
of all the effects of each subroutine.

Among the information that you will need in the standard form is; STANDARD
program
PROGRAM
• Purpose of the
LIBRARY
• Processor used FORMS
• Language used
• Parameters required and how they are passed to the subroutine
• Results produced and how they are passed to the mam program
• Number of bytes of memory used
• Number of clock cycles required. This number may be an average or a typical figure,
or It may vary widely. Actual execution time will, of course, depend on the processor
clock rate
• Registers affected
• Flags affected
• A typical example
• Error handling
• Special cases
• Documented program listing

If the program complex, the standard library form should also include a general
is

flowchart or a structured program. As we have mentioned before, a library program is


most likely to be useful if it performs a single distinct function in a reasonably general
manner.

LIBRARY EXAMPLES
Library Example 1 Sum : of Data
Purpose: The program SUMS computes the sum of a set of 8-bit unsigned binary num-
bers.

language: Z80 assembler.


Initial Conditions: Starting address of set of numbers m Register Pair HL, length of set
in Accumulator.

Final Conditions: Sum in Accumulator.

Requirements:
Memory - 7 bytes.
Time - 13 + 26N clock cycles, where N is the
length of the set of numbers.
Registers - A, B. H. L
All flags affected.

15-10
Typical Case: (all data in hexadecimal)
Start:
HL = 0050
A - 03
(0050) - 27
(0051) = 3E
(0052) = 26
End:
A = 8B
Error Handling: Program ignores ai! carries. Carry bit reflects only the last operation.
Initial contents of Accumulator must be 1 or more.

Listing:

:SUM OF 8-BIT DATA

SUMS: LD B.A :COUNT = LENGTH OF DATA BLOCK


SUB A :SUM=ZERO
ADDS: ADD A.(HU :SUM = SUM + DATA ENTRY
INC HL
DJNZ ADDS
RET
Library Example 2: Declmal-to-Seven-Segment Conversion
Purpose: The program SEVEN converts a decimal number to a seven-segment display
code.

Language: Z80 assembler.


Initial Conditions: Data in Accumulator.
Final Conditions: Seven-segment code in Accumulator.
Requirements:
Memory - 26 bytes, including the seven-segment table {10 en-
tries).

Time - 74 clock cycles if the data Is valid. 40 if it is not.


Registers - A, B, D. E. H, L.

Alt flags affected.

Input data in Accumulator is destroyed.

Typical Case: (data in hexadecimal)


Start:
A - 05
End:
A = 66
Error Handling: Program returns zero in the Accumulator if data is not a decimal digit

15-11
Listing:

:DEC!MAL TO SEVEN-SEGMENT CONVERSION

SEVEN: LD B.O GET ERROR CODE TO BLANK DISPLAY


CP 10 IS DATA A DECIMAL DIGIT?

JR NC.DONE NO. KEEP ERROR CODE


LD LA YES. MAKE DATA INTO A 16-BtT INDEX
LD H.O
LD DE.SSEG GET BASE ADDRESS OF 7-SEGMENT TABLE
ADD HLDE FIND ELEMENT BY INDEXING
LD B.(HL) GET 7-SEGMENT CODE FROM TABLE
DONE: LD A,B SAVE 7-SEGMENT CODE OR ERROR CODE
RET
SSEG: DEFB 3FH
DEFB 06H
DEFB 5BH
DEFB 4FH
DEFB 66H
DEFB 6DH
DEFB 7DH
DEFB 07H
DEFB 7FH
DEFB 6FH
Library Example 3: Decimal Sum
Purpose: The program DECSUM adds two multi-word decimal numbers.
Language: Z80 assembler
Initial Conditions: Address of LSBs of one number m Register Pair HL, address of LSBs
of other number in Register Pair DE. length of numbers (in bytes) in
A. Numbers arranged starting with LSBs at lowest address.
Final Conditions: Sum replaces number with starting address In Register Pair HL
Requirements:
Memory - 1 1 bytes.
Time - 13 + 50N clock cycles, where N is the number of
bytes involved.
Registers - A. B, D. E, H, L
All flags affected. Carry shows if sum produced a carry.

ical Case: (data in hex<


Start:
HL - 0060
DE = 0050
A - 2
(0060) - 34
(0061) - 55
(0050) = 88
(0051) = 15
End:
(0060)- 22
(0061)- 71
CARRY =

15-12
Error Handling: Program does not check the validity of decimal inputs. Accumulator
must be 1 or greater.

Listing:
DECSUM: LD 8,A COUNT = LENGTH OF NUMBERS (IN BYTES)
AND A CLEAR CARRY TO START
DECADD: LD A,(DE) GET 2 DECIMAL DIGITS FROM STRING 2
ADC A,(HU ADD PAIR OF DIGITS FROM STRING 1

DAA MAKE ADDITION DECIMAL


LD {HU.A STORE RESULT IN STRING 1

INC DE
INC HL
DJNZ DECADD
RET
TOTAL DOCUMENTATION
Complete documentation of microprocessor software will in- DOCUIVIENTATION
clude all or most of the elements that we have mentioned. So, PACKAGE
the total documentation package may involve:
• General flowcharts
• A written description of the program
• A list of all parameters and definitions
• A memory map
• A documented listing of the program
• A description of the test plan and test results

The documentation may also include:


• Programmers' flowcharts
• Data flowcharts
• Structured programs

The documentation procedures outlined above are the minimal acceptable set of
documents for non-production software. Production software demands even
greater documentation efforts. The following documents should also be produced:
• Program Logic Manual
• User Guide
• Maintenance Manual
The program logic manual expands on the written explanation produced with the
software. It should be written for a technically competent individual who may not
possess the detailed knowledge assumed in the written explanation in the software.
The program logic manual should explain what the design goals of the system were,
what algorithms were chosen to implement these goals, and what tradeoffs had to be
made in achieving them.
Itshould then explain In great detail what data structures were employed and how they
are manipulated, it should provide a step-by-step guide to the inner workings of the

code. Finally, it should contain any special tables or graphs that help explain any of the
concepts embodied in the code. Code conversion charts, state diagrams, translation
matrices, and flowcharts should be included.

The user guide probably the most important and most overlooked piece of docu-
is
mentation. No matter how well a system is designed, it is useless if no one can
use it effectively. The user guide should provide all users, sophisticated and un-
sophisticated, with an introduction to the system. It should then provide detailed ex-

15-13
planations of system features and their use. Use plenty of exannpies because a good ex-
annpte can crystailize the information contained m many pages of text Step-by-step
directions should be given. Test the user guide, i.e.. try out the step-by-step usage pro-
cedures as you have documented them. Programmers with detailed knowledge of a
system s design often take shortcuts that are not at all apparent to the general reader.
An entire book could be written about the writing of user guides, and further discussion
IS beyond the scope of this book. However, remember that you can never spend too

much effort m preparing a user guide, because it will be the most used of all system
documents.

The maintenance manual is designed for the programmer who has to modify the

system. should outline step-by-step procedures for those reconfigurations designed


It

into the system, in addition, it should outline any provisions placed into code for future
expansion.

Documentation should not be taken lightly or postponed until the end of the soft-
ware development. Proper documentation, combined with proper programming
practices, is not only an important part of the final product but can also make
development simpler, faster, and more productive. The designer should make con-
sistent and thorough documentation part of every stage of software development.

REDESlQiy
Sometimes the designer may have to squeeze the last microsecond of speed or
the last byte of extra memory out of a program. As larger single-chip memones have
become available, the memory problem has become less serious. The time problem, of
course, is serious only if the application ts time-critical; in many applications the
microprocessor spends most of its time waiting for external devices, and program speed
IS not a maior factor.

Squeezing the last bit of performance out of a program is |


COST OF
seldom as important as some writers would have you believe. | RiPIESIGN
In the first place, the practice is expensive for the foil owing
reasons:

1) It requires extra programmer time, which is often the single largest cost in software
development.
2) It sacrifices structure and simplicity with a resulting Increase in debugging and
testing time.

3) The programs require extra documentation.


4) The resulting programs will be difficult to extend, maintain, or re-use.

in the second place, the lower per-unit cost and higher performance may not really
be important. Will the lower cost and higher performance really sell more units? Or
would you do better with more user-oriented features? The only sppllcations that
would seem to justify the extra effort and time are very high-volume, low-cost
and low-performance applications where the cost of an extra memory chip will far
outweigh the cost of the extra software development. For other applications, you
will find that you are playing an expensive game for no reason.

However, you must redesign a program, the following


If MAJOR OR
hints will help. First, determine how much more perfor- MINOR
mance or how much less memory usage is necessary. If REORGANIZATION
the required improvement is 25% or less, you may be
able to achieve it by reorganizing the program. If it is more than 25%, you have
made a basic design error; you will need to consider drastic changes in hardware
or software. We will deal first with reorganization and later with drastic changes. You
should also look at Chapter 5 of Z80 Programming for Logic Design for some examples.

15-14
Note particularly that saving memory can be crltlcai if it allows a program to fit into the
limited amount of ROM and RAM available in a simple one-chip or two-chfp microcom-
puter. The hardware cost for smalt systems can thus be substantrally reduced, if their
requirements can be limited to the memory size and I/O limitations of that particular
one-chip or two-chip system.

REORGANIZING TO USE LESS MEMORY


The following procedures will reduce memory usage for Z80 SAVING
assembly language programs: MEMORY
1) Replace repetitious in-line code with subroutines. Be
sura however, that the CALL and RETURN instructions do not offset most of the
gain. Note that this replacement usually results in slower programs because of the
time spent in transferring control back and forth.

2) Use register operations when possible. But remember the cost of the extra in-
itialization.

3} Use the Stack when possible. The Stack Pointer is automatically updated after
each use so that no explicit updating instructions are necessary.
4) Eliminate Jump instructions. Try to reorganize the program or use Indirect jumps
UP (HU or JP (IX or lY)), RST, or RETURN instructions.

5) Take advantage of addresses that you can manipulate as 8-bit quantities.


These include page zero and addresses that are multiples of 100 hexadecimal. For
example, you might try to place all ROM tables in one lOO^g-byte section of
memory, and all RAM vanables into another lOOig-byte section.
6) Organize data and tables so that you can address them without worrying
about address calculation carries or without any actual indexing. This will
again allow you to manipulate 16-bit addresses as 8-bit quantities. See pages 5-1
to 5-6 of Z80 Programming for Logic Design for an example.

7) Use the 16-bit instructions to replace two separate 8-bit operations. This
may be particularly useful in initialization or storing results.
8) Use leftover results from previous sections of the program.

9) Take advantage of such instructions as INC (HU. DCR {HU, LD (HU, RL (HU, and
RR (HU, which operate directly on memory locations without using registers.
10) Use INC or DEC to set or reset flag bits.
11) Use relative jumps rather than Jumps with direct addressing.

1 2) Take advantage of the Block Move, Block Search, and Block I/O instructions
whenever you are handling blocks of data.
13) Watch for special short forms of instructions such as the Accumulator shifts
(RLCA, RLA, RRCA, and RRA) and DJNZ.

14) Use algorithms rather than tables to calculate arithmetic or logical expressions
and to perform code conversions. Note that this replacement may result in slower
programs.

1 5) Reduce the size of mathematical tables by interpolating between entries. Here


we are saving memory at the cost of execution time.
again,

16) Take advantage of the alternate register set to cut down on the use of
storage. This can save time as well.

Although some of the methods that reduce memory usage also SAVING
save time, you can generally save an appreciable amount of EXECUTION
time only by concentrating on frequently executed loops. Even TIME

16-15
compietelv eliminating an instruction that is executed only once can save at most a few
microseconds. But a savings in a loop that is executed frequently will be multiplied
many times over.
So, if you must reduce execution time, proceed as follows:
1) Determine how frequently each program loop is executed. You can do this by
hand or by using the software simulator or another testing method.
2) Examine the loops In the order determined by their frequency of execution,
starting with the most frequent Continue through the list until you achieve the re-
quired reduction.

3) First, see there are any operations that can be moved outside the loop, i.e..
if

repetitive calculations, data thatcan be placed into a register or the Stack, ad-
dresses that can be placed into register pairs or index registers, special cases or
errors that can be handled elsewhere, etc. Note that this will require extra in-
itialization and memory but will save time.

4) Try to eliminate Jump statements. These are very time-consuming. Or, use

jumps with direct addressing that require more memory but less time than jumps
with relative addressing,

5) Replace subroutines with in-line code. This will save at least a CALL and a
RETURN instruction.

6) Use the Stack for temporary data storage.


7) Use any of the hints mentioned in saving memory that also decrease execu-
tion time. These include the use of block handling instructions, 8-b(t addresses,
16-bit instructions, RST. special short forms of instructions, etc.

8) Do not oven look at Instructions that are executed only once. Any changes
that you make in such instructions only invite errors for no appreciable gain.

9) Avoid indexed and relative addressing whenever possible because they take
extra time.

10) Use tables rather than algorithms; make the tables handle as much of the tasks

as possible even if many entries must be repeated.

MAJOR REORGANIZATIONS
Ifyou need more than a 25% increase in speed or decrease in memory usage, do
not try reorganizing the code. Your chances of getting that much of an improve-
ment are small unless you call In an outside expert. You are generally better off
making a major change.
The most obvious change is a better algorithm. Particularly if BETTiB
you are doing sorts, searches, or mathematical calculations, you ALGORITHMS
may be able to find a faster or shorter method in the literature.
Libraries of algorithms are available in some journals and from professional groups. See,
for example. References 1 through 10 at the end of this chapter.

More hardware can replace some of the software. Counters, shift registers,
arithmetic units, hardware multipliers, and other fast add-ons can save both time and
memory. Calculators, UARTs, keyboards, encoders, and other slower add-ons may save
memory even though they operate slowly. Compatible parallel and serial interfaces, and
other devices specially designed for use with the Z80 may save time by taking some of
the burden off the CPU.

15-16
Other changes may help as well: OTHER
1) A CPU with a longer word will be faster if the data is long MAJOR
enough. Such a CPU wilt use less total memory. 16-bit pro- CHANGES
cessors, for example, use memory more efficiently than 8-bit
processors, since more of their instructions are one word long.

2) Versions of the CPU may exist that operate at higher clock rates. But remem-
ber that you will need faster memory and I/O ports, and you will have to adjust any
delay loops.

3) Two CPUs may be able to do the Job In parallel or separately if you can divide the
job and solve the communications problem.

4) A specially microprogrammed processor may be able to execute the same pro-


gram much faster. The cost however, will be much higher even if you use an off-
the-shelf emulation.

51 You can make tradeoffs between time and memory. Lookup tables and function
ROMs will be faster than algorithms, but will occupy more memory.
This kind of problem, in which a large improvement is neces- DECIDING
sary, usually results from lack of adequate planning in the ON A MAJOR
definition and design stages. In the problem definition stage CHANGE
you should determine which processor and methods will be
adequate to handle the problem. If you misjudge, the cost later will be high. A
cheap solution may result in an unwarranted expenditure of expensive develop-
ment time. Do not try to Just get by; the best solution is usually to do the proper
design and chalk a failure up to experience. If you have followed such methods as
flowcharting, modular programming, structured programming, top-down design,
and proper documentation, you will be able to salvage a lot of your effort even if
you have to make a major change.

15-17
REFERENCES
1. Coltected Algorithms from ACM, ACM. Inc., P 0. Box 12105. Church Street Sta-
tion. New York 10249.

2. Chen. T. C. "Automatic Computation of Exponentials. Logarithms. Ratios, and


Square Roots," IBM Journal of Research and Development. Volume 18, pp.
380-388. July, 1972.

3. H. Schmid, Decimal Computation. Wiley-lntersctence. New York, 1974.

4. Knuth. D, E., The Art of Computer Pro q rammm g , Volume 1: Fundamental


Algorithms, Addison-Wesley, Reading. Mass.. 1967.

5. Knuth. D. E., The Art of Computer Pro g rammin g , Volume 2: Semmumerical


Alg orithms Addison-Wesley. Reading, Mass., 1969.
.

6. Knuth, D. E., The Art of Computer Pro g rammin g Volume


. 3: Sortin g and Search-
mg, Addison-Wesley, Reading. Mass.. 1973.
1. Carnahan. B. et al.. Ap plied Numerical Methods. Wiiey, New York. 1969.

8. Despain. A. M. "Fourier Transform Computers Using CORDIC Iterations," IEEE


Transactions on Computers. October 1974. pp. 993-1001,

9. Luke, Y L., Alg orithms for the Computation of Mathematical Functions, Academic
Press, New York. 1977

10. Hwang, K., Computer Anthmetic. Wiley, New York. 1978.

11. Dollhoff. T,. to Optimize Timing and Memory


"Microprocessor Software: How
Usage. Part Four: Techniques for the Zilog Z80." Digital Desi gn. February 1977,
pp. 44-51.

15-18
Chapter 16
SAMPLE PROJECTS
PROJECT #1: A Digital Stopwatch
Purpose: This project Is The operator enters
a digital stopwatch. STOPWATCH
two digits (minutes and tenths of minutes) from a INPUT
catculator-iike keyboard and then presses the GO key. PROCEDURE
The system counts down the remaining time on two
seven-segment LED displays (see Chapter 11 for a description of unencoded
keyboards and LED displays).

Hardware: The project usesone input port and one output port (one Z80 Parallel
Input/Output Device or two seven-segment displays, a 12-key keyboard, a 7404
PIO),
inverter, and either a 7400 NAND gate or a 7408 AND gate, depending on the polarity
of the seven-segment displays. The displays may require drivers, inverters, and resis-
tors, depending on their polarity and configuration.

The hardware is organized as shown in Figure 16-1. Output lines 0, 1, and 2 are used to

scan the keyboard. Input lines 0. 1,2, and 3 are used to determine whether any keys
have been pressed. Output lines 0, 1,2. and 3 are used to send BCD digits to the seven-
segment decoder/drivers. Output line 4 is used to activate the LED displays (if line 4 is
'V, the displays are lit). Output line 5 is used to select the left or right display; output
line 5 is '1' if the left display is being used, '0' if the right display is being used. Thus,
the common line on the left display should be active if line 4 is '1' and line 5 is 'V, while
the common line on the right display should be active if line 4 is '1' and line 5 is '0'
Output line 6 controls the right-hand decimal point on the left display. It may be driven
with an inverter or simply left on.

Keyboard Connections: The keyboard is a simple calculator keyboard available for


50(tfrom a local source. It consists of 12 unencoded key-switches arranged
in four rows
of three columns each. Since the wiring of the keyboard does not coincide with the ob-
served rows and columns, the program uses a table to identify the keys. Tables 16-1
and 1 6-2 contain the input and output connections for the keyboard. The decimal point
key IS present for operator convenience and for future expansion; the current program
does not actually use the key.

In an actual application, the keyboard would require pullup resistors to ensure that the
inputs would actually be read as logic '1's when the keys were not being pressed. It
would also require current-limiting resistors or diodes on the output port to avoid
damaging the drivers in the case where two outputs were driving against each other.
This could occur if two keys in the same row were pressed at the same time, thus con-
necting two different column outputs.

16-1
B7 -{not used)
Be
Output B5
Port B4
(P!0 B3
Port B) B2

H Do D^ D2 D3
DP
U
11
Dp D^ D2 D3

Display Display
Input .

""^ and and


Port '

Keyboard
Driver Driver
(PIO A,
{ieft) (right)
Port A)

Figure 16-1. Digital


y^J
Stopwatch I/O Configuration
^
Table 16-1. input Connections for Stopwatch Keyboard

Input Bit Keys Connected


'3'. '5*, '8'

'2'. '6', '9'


1

2
'4'. '/.
3 'GO'

Table 16-2. Output Connections for Stopwatch Keyboard

Output Bit Keys Connected


'0'. '2'. *3'. '4'

'1'. '8'.. '9\ 'GO'


1

2 5\ '6', 7'. '/

16-2
General Program Flowchart:

CIEiZ)

16-3
Display Connections: The displays are seven-segment displays with their own in-
tegral decoders. A typical example would be the Texas Instruments TIL309 device,
which has an internal TTL MSI chip with latch, decoder, and driver. Clearly, standard
seven-segment displays would be cheaper but would require some additional software
(the seven-segment conversion routine shown In Chapter 7). Data is entered into the
display as a single binary coded decimal digit; the digtts are represented as shown in
Figure 11-15. The decimal point is a single LED that is turned on when the decimal
point input is a logic
'1'
You can find more information about displays in References 10
and 1 1 at the end of this chapter.

Program Description:
The program is modular and has several subroutines. The emphasis is on clarity and

generality rather than efficiency; obviously, the program does not utilize the full
capabilities of the Z80 processor. Each section of the listing will now be described in
detail.

1) Introductory Comments
The introductory comments fully describe the program; these comments are a

reference so that other users can easily apply, extend, and understand the pro-
gram. Standard formats, indentations, and spaclngs increase the readability of the
program.

2) Variable Definitions
are placed at the start of the program so that they can easily
All variable definitions
be checked and changed. Each variable is placed in a list alphabetically with other
variables of the same type; comments describe the meaning of each variable. The
categories are:
a} Memory system constants that may vary from system to system depending on
the memory space allocated to different programs or types of memories
b) Temporary storage (RAM) used for variables

c) 1/0 (PIO) port addresses


d) Definitions

The memory system constants are placed in the definitions so that the user may
relocate the program, temporary storage, and memory stack without making any
other changes. The memory constants can be changed to accommodate other
programs or to coincide with a particular system's allocation of ROM and RAM ad-
dresses.
Temporary storage is allocated by means of DEFS (Define Storage) pseudo-opera-
tions. An ORG pseudo-operation places the temporary storage locations in
(origin)
a particular part of memory. No values are placed in these locations so that the
program could eventually be placed in ROM or PROM and the system could be
operated from power-on reset without reloading.
Each port address occupied by a PIO is named so that the addresses can easily be
changed to handle varied configurations. The naming also serves to clearly dis-
tinguish control registers from data registers.
The definitions clarify the meaning of certain constants and allow parameters to
be changed easily. Each definition is given in the form (binan/. hex, octal. ASCII, or
decimal) m which its meaning is the clearest Parameters (such as debounce time)
are placed here so that they can be varied with system needs.

16-4
3) Initialization

Memory location on the Z80 mtcroprocessor) contams a |ump


{the reset location
to the starting address of the main program. The main program can thus be
placed anywhere in memory and reached via a "RESET" signal.
The mitialization consists of four steps:

a) Place a starting value in the Stack Pointer. The Stack is used only to store
subroutine return addresses.
b) Configure the PIO control registers.
c) Start the number of digit keys pressed at zero.
d) Initializethe location where the next digit key pressed will be saved to the
start of the digit key array. An indirect procedure is used, in which KEYAD
contams the address in which the next digit will be placed. Each time a digit
key recognized, the contents of KEYAD are incremented so that the next
is

digit key will be placed into the next memory location.

4) Look for Key Closure


Flowchart:

C ^- )
^x
Ground all keyboatxi
columns

No
^^ any mws ^^^
^^(^arounded ^^^
^Yes

( .. )

Key closures are identified by grounding alt the keyboard columns and then
checking for grounded rows (i.e.. co!umn-to-row switch closures). Note that the
program does not assume that the unused input bits are all high; instead, the bits
attached to the keyboard are isolated with a logical AND instruction.

5) Debounce Key
The program debounces the key closure in software by waiting for two millise-
conds. This is usually long enough for a clean contact to be made. Subroutine
DELAY Simply counts with Register C for 1 millisecond. The number of millise-
conds is m the Accumulator. DELAY would have to be adjusted if a slower clock or
slower memories were being used. You could make the change simply by redefin-
ing the constant MSCNT.

16-5
6) identify Key Closure
Flowchart:

Start
(^ j

J
S8t kev table pointer
to KTAB - 1
Set pattern pointer
toPATT

Ground a keyboard
coiumn by output of
{pattern pointer)
C

Increment
pointer
W table
by the number
Increment key tabi?
pointer by t
of keys in a column
(KCOL) Increment Shift keyboard input
pattern pointer fay 1 right 1 bit

Key ID =
(key table pointer)
Use key table pointer
toget key !D

J
The particular key closed by grounding single columns and observing
is identified
whether a closure is found. Once
is found {so the key column is known),
a closure
the key row can be determined by shifting the input

The patterns required to ground single keyboard columns are in a table PATT in
memory. The final pattern m the table is a marker (ECODE) which indicates that ail
the columns have been grounded without a closure being found. This pattern also
indicates to the main program that the closure could not be identified (e.g., the
key closure ended or a hardware error occurred before we could find the closure).
The key identifications are in table KTAB in memory. The KEY
keys in the first column (attached to the least significant out- TABLE
put bit) are followed by those in the second column, etc.
Within a column, the key in the row attached to the (east significant mput bit is
first etc. Thus, each time a column is scanned without finding a closure, the num-
ber of keys in a column (NROWS) must be added to the key table pointer in order
to move to the next column. The key table pointer is also incremented by one
before each bit in the row inputs is examined; this process stops when a zero input
IS found. Note that the key table pointer is started one location before the table,

since it is always incremented once in the search for the proper row.
If we cannot identify the key closure, we simply ignore it and look for another
closure.

7) Act on Key Identification


If enough digits (two m this simple case), it looks only for the GO
the program has
key and ignores all other keys. If it finds a digit key, it saves the value in the key
array, increments the number of digit keys pressed, and increments the key array
pointer.

If the entry is not complete, the program must wait for the key closure to end so
that the system will not read the same closure again. The user must watt between
key closures one key before pressing another one). Note that the pro-
(i.e.. release
gram will identify double key closures as one key or the other, depending on
which closure the identification routine finds first. An improved version of this
program would display digits as they were entered and would allow the user to
omit a leading or trailing zero, (i.e., key in ".". "1" "GO" to get a count of seven-
..

tenths of a minute).

8) Set Up Display Output


The digits are placed in registers or memory locations with bit 4 set so that the
output issent to the displays. Bits 5 and 6 are set for the most significant digit to
direct the output to the left display and to turn on the decimal point

9) Pulse the LED Displays


Each display is turned on for two milliseconds. This process is repeated 1500

times order to get a total delay of 0.1 minutes, or 6 seconds. The pulses are fre-
in
quent enough so that the LED displays appear to be lit continuously.

16-7
1 0) Decrement Display Count
Flowchart:

End of timer
«9ht Displays= 9
program

^
C End
J
The value of the less significant digit is reduced by one. If this affects bit 4
{LEDON — used to turn the displays on}, the digit has become negative. A borrow
must then be obtained from the more significant digit. If the borrow from the more
significant digit affects bit 4, the count has gone past zero and the countdown is
finished. Otherwise, the program sets the value of the less significant digit to 9
and continues.

Note that comments describe both sections of the program and individual statements.
The comments explain what the program is doing, not what specific instruction codes
do. Spacing and Indentation have been used to improve readability.

16-8
PROGRAM NAME: TIMER
DATE OF PROGRAM: 10/24/78
PROGRAMMER; LANCE A. LEVENTHAL
PROGRAM REQUIREMENTS; D1 (209) BYTES
RAM REQUIREMENTS: 5 BYTES
1/0 REQUIREMENTS; 1 INPUT PORT, 1 OUTPUT PORT (1 Z80 PIO)

THIS PROGRAM IS A SOFTWARE TIMER WHICH ACCEPTS INPUTS FROM A


CALCULATOR-LIKE KEYBOARD AND THEN PROVIDES A STOPWATCH
COUNTDOWN ON TWO 7-SEGMENT LED DISPLAYS IN MINUTES AND TENTHS
OF MINUTES

KEYBOARD

A 12-KEY KEYBOARD IS ASSUMED


THREE COLUMN CONNECTIONS ARE OUTPUTS FROM THE PROCESSOR
SO THAT A COLUMN OF KEYS CAN BE GROUNDED
FOUR ROW CONNECTIONS ARE INPUTS TO THE PROCESSOR SO THAT
COMPLETED CIRCUITS CAN BE IDENTIFIED
THE KEYBOARD IS DEBOUNCED BY WAITING FOR TWO MILLISECONDS
AFTER A KEY CLOSURE IS RECOGNIZED
A NEW KEY CLOSURE IS IDENTIFIED BY WAITING FOR THE OLD ONE
TO END SINCE NO STROBE IS USED
THE KEYBOARD COLUMNS ARE CONNECTED TO BITS
TO 2 OF THE PIO B PORT
THE KEYBOARD ROWS ARE CONNECTED TO BITS
TO 3 OF THE PIO A PORT

DISPLAYS

TWO 7-SEGMENT LED DISPLAYS ARE USED WITH SEPARATE DECODERS


OR 7448 DEPENDING ON THE TYPE OF DISPLAY)
(7447
THE DECODER DATA INPUTS ARE CONNECTED TO BITS TO 3
OF THE PIO B PORT
BIT 4 OF THE PIO B PORT IS USED TO ACTIVATE THE LED
DISPLAYS (BIT 4 IS TO SEND DATA TO LEDS)
1

BIT 5 OF THE PIO B PORT IS USED TO SELECT WHICH


LED IS BEING USED (BIT 5 IS 1 IF THE LEADING DISPLAY
IS BEING USED. IF THE TRAILING DISPLAY IS BEING USED)

BIT 6 OF THE PIO B PORT IS USED TO LIGHT THE DECIMAL


POINT LED ON THE LEADING DISPLAY (BIT 6 IS 1 IF
THE DISPLAY IS TO BE LIT)

METHOD

STEP 1 - INITIALIZATION
THE MEMORY STACK POINTER (USED FOR SUBROUTINE RETURN
ADDRESSES) IS INITIALIZED. THE NUMBER OF DIGIT KEYS PRESSED IS SET
TO ZERO, AND THE ADDRESS INTO WHICH THE NEXT DIGIT KEY
IDENTIFICATION WILL BE PLACED IS INITIALIZED TO THE FIRST ADDRESS
IN THE DIGIT KEY ARRAY
STEP 2 - LOOK FOR KEY CLOSURE
ALL KEYBOARD COLUMNS ARE GROUNDED AND THE KEYBOARD ROWS
ARE EXAMINED UNTIL A CLOSED CIRCUIT IS FOUND

16-9
1

STEP 3 DEBOUNCE KEY CLOSURE


-

A WAIT OF 2 MS IS INTRODUCED TO ELIMINATE KEY BOUNCE


STEP 4 - IDENTIFY KEY CLOSURE
THE KEY CLOSURE IS IDENTIFIED BY GROUNDING SINGLE KEYBOARD
COLUMNS AND DETERMINING THE ROW AND COLUMN OF THE KEY
CLOSURE. A TABLE IS USED TO ENCODE THE KEYS ACCORDING TO THEIR
ROW AND COLUMN NUMBER
IN THE KEY TABLE, THE DIGITS ARE IDENTIFIED BY THEIR VALUES.
THE DECIMAL POINT KEY IS NO. 10. AND THE "GO" KEY IS NO. 1
STEP 5 - SAVE KEY CLOSURE
DIGIT KEY CLOSURES ARE SAVED IN THE DIGIT KEY ARRAY UNTIL
TWO DIGITS HAVE BEEN IDENTIFIED. DECIMAL POINTS. FURTHER DIGITS.
AND CLOSURES OF THE "GO" KEY BEFORE TWO DIGITS HAVE BEEN
IDENTIFIED ARE IGNORED
AFTER TWO DIGITS HAVE BEEN FOUND. THE "GO" KEY IS USED TO
START THE COUNTDOWN PROCESS
STEP 6 - COUNT DOWN TIMER INTERVAL ON LEDS
A COUNTDOWN IS PERFORMED ON THE LEDS WITH THE LEADING DIGIT
REPRESENTING THE REMAINING NUMBER OF MINUTES AND THE TRAILING
DIGIT REPRESENTING THE REMAINING NUMBER OF TENTHS OF MINUTES

TIMER VARIABLE DEFINITIONS


MEMORY SYSTEM CONSTANTS

BEGIN EQU 50H BEGIN IS STARTING MEMORY LOCATION

FOR PROG
LASTM EQU 1000H LASTM IS STARTING STACK ADDRESS
TEMP EQU 800H TEMP IS START OF RAM STORAGE
:RAM TEMPORARY STORAGE
ORG TEMP
KEYAD: DEFS 2 KEYAD HOLDS THE ADDRESS IN THE
DIGIT KEY ARRAY IN WHICH THE
IDENTIFICATION OF THE NEXT DIGIT
KEY WILL BE PLACED
KEYNO: DEFS KEYNO IS THE DIGIT KEY ARRAY - IT
HOLDS THE IDENTIFICATIONS OF THE
DIGIT KEYS THAT HAVE BEEN PRESSED
NKEYS: DEFS NKEYS HOLDS NUMBER OF DIGIT KEYS
PRESSED

:l/0 UNITS AND PIO ADDRESSES

PIODRA EQU OEOH .INPUT PIO FOR KEYBOARD


PIOCRA EQU 0E2H
PIODRB EQU DE1H :OUTPUT PIO FOR KEYBOARD AND
; DISPLAY
PIOCRB EQU 0E3H

;DEFiNmONS

DECPT EQU 6 ;BIT POSITION TO TURN ON DECIMAL


; POINT LED

16-10
ECODE EQU OFFH ERROR CODE IF ID ROUTINE DOES NOT F!ND
KEY
GOKEY EQU 11 IDENTIFICATION NUMBER FOR "GO" KEY
LEDON EQU 4 BIT POSITION TO SEND OUTPUT TO LEDS
LEDSL EQU 5 BIT POSITION TO SELECT LEADING
DISPLAY
MSCNT EQU 0F9H COUNT NEEDED TO GIVE MS DELAY TIME
1

MXKEY EQU 2 MAXIMUM NUMBER OF DIGIT KEY


CLOSURES USED
NROWS EQU 4 NUMBER OF ROWS IN KEYBOARD OR KEYS
IN COLUMN
OPEN EQU 00001111 INPUT FROM KEYBOARD IF NO KEY
CLOSED
TPULS EQU 2 NUMBER OF MS BETWEEN DIGIT DISPLAYS
TWAIT EQU 2 NUMBER OF MS TO DEBOUNCE KEYS

ORG

; RESET ROUTINE TO REACH TIMER PROGRAM

JP BEGIN ;FIND TIMER PROGRAM

:INITIALIZATION OF TIMER PROGRAM

ORG BEGIN
LD A.01001111B ;MAKE PIO PORT A INPUT
OUT (PIOCRA),A
LD A.OOOOmiB ;MAKE PIO PORT B OUTPUT
OUT {PIOCRB),A
LD SP.LASTM :PUT STACK AT END OF MEMORY
SUB A
LD (NKEYS).A ;NUMBER OF DIGIT KEYS PRESSED = ZERO
LD HLKEYNO iSTARTING LOCATION FOR DIGIT KEYS
LD (KEYADl.HL

;SCAN KEYBOARD LOOKING FOR KEY CLOSURE

START: CALL SCANC ;WAIT FOR KEY CLOSURE

WAIT FOR KEY TO BE DEBOUNCED

LD A.TWAIT ;GETDEBOUNCE TIME IN MS


CALL DELAY :WAIT FOR KEY TO STOP BOUNCING

IDENTIFY WHICH KEY WAS PRESSED

CALL IDKEY IDENTIFY KEY CLOSURE


CP ECODE WAS KEY CLOSURE IDENTIFIED?
JR Z.START NO, WAIT FOR ANOTHER CLOSURE

;ACT ON KEY IDENTIFICATION

16-11
LD B,A SAVE KEY NUMBER
LD HLNKEYS ;CHECK FOR MAXIMUM NUMBER OF DIGiT
KEYS
LD A,(HL)
CP MXKEY HAS MAXIMUM BEEN REACHED?
JR ZXEYF YES. LOOK FOR GO KEY
LD A.B NO. LOOK FOR DIGIT KEYS ONLY
CP 10 IS THIS KEY A DIGIT?

JR NC.WAITK NO. IGNORE IT

INC (HU YES, INCREMENT DIGIT KEY COUNTER


LD HL(KEYAD) SAVE KEY NUMBER IN ARRAY
LD (HU,A
INC HL
LQ (KEYAD),HL

-.WAIT FOR CURRENT KEY CLOSURE TO END

WAITK; CALL SCANO ;WA!T FOR KEY TO BE RELEASED


JR START ;G0 LOOK FOR NEXT KEY

:LOOK FOR GO KEY IF ENOUGH DIGITS FOUND

KEYF LD A.B GET NUMBER OF KEY PRESSED


CP GOKEY IS IT "GO" KEY?

JR NZ.WAITK NO. IGNORE IT

;PUT DIGITS INTO REGISTERS FOR DISPLAY

LD HLKEYNO
LD D.(HL) GET LEADING DIGIT
SET DECPT.D TURN ON DECIMAL POINT
SET LEDON.D SET OUTPUT TO LEDS
SET LEDSL.D SELECT LEADING DISPLAY
INC HL
LD E.(HL) :GET TRAILING DIGIT
SET LEDON.E ;SET OUTPUT TO LEDS

;PULSE THE LED DISPLAYS

LD C.PIODRB :GET OUTPUT PORT ADDRESS


LEDLP: LD H.6 ;SET COUNTERS FOR 6 SECONDS
TLOOP: LD B.250
LDPUL: OUT (C).D ;OUTPUT LEADING DIGIT TO LED 1

LD A.TPULS ;DELAY BETWEEN DIGITS


CALL DELAY
OUT (C).E OUTPUT TRAILING DIGIT TO LED 2
LD A.TPULS :DELAY BETWEEN DIGITS
CALL DELAY
DJNZ LDPUL
DEC H
JR NZ.TLOOP

;DECREMENT COUNT ON LED DISPLAYS

16-12
DEC E COUNT DOWN TRAILING DIGIT
BIT LEDON.E iSTRAILING DIGIT PAST ZERO?
JR NZ.LEDLP NO, CONTINUE
DEC D COUNT DOWN LEADING DIGIT
BIT LEDON.D IS LEADING DIGIT PAST ZERO?
JP Z,BEGIN YES, WAIT FOR NEXT TIMING TASK
LD E,9 NO, SET TRAILING DIGIT TO 9
SET LEDON.E SET OUTPUT TO LEDS
JR LEDLP RETURN TO DISPLAY SECTION

:SUBROUTiNE SCANC SCANS THE KEYBOARD WAITING FOR A KEY CLOSURE


;ALLKEYBOARD INPUTS ARE GROUNDED

; SUB A ;GROUND ALL KEYBOARD COLUMNS


OUT (PiODRBI.A
IN A.iPIODRA)
AND OPEN IGNORE UNUSED INPUTS
CP OPEN ARE ANY KEYS CLOSED?
JR Z.SCANC NO. CONTINUE SCANNING
RET

SUBROUTINE DELAY WAITS FOR THE NUMBER OF MILLISECONDS SPECIFIED


IN REGISTER A

DELAY ^
EXX ;SAVE USER REGISTERS
DLYl; LD C.MSCNT :LOAD REGISTER C FOR 1 MS
WTLP: DEC C ;WAIT 1 MS
JR NZ.WTLP
DEC A ;COUNT DOWN NUMBER OF MS
JR NZ.DLYI
EXX ;RESTORE USER REGISTERS
RET

iSUBROUTINE IDKEY DETERMINES THE ROW AND COLUMN NUMBER OF THE


, KEY CLOSURE AND IDENTIFIES THE KEY BY USING A TABLE

IDKEY: LD BCPATT POINT TO SCAN PATTERNS


LD HLKTAB-1 START KEY TABLE POINTER
LD DE.NROWS GET NUMBER OF KEYS IN A COLUMN

YBOAR D COLUMNS S

FCOL; LD A.iBC) GET PATTERN TO GROUND COLUMN


CP ECODE ALL COLUMNS SCANNED?
RET Z YES, RETURN WITH ERROR CODE
OUT (PIODRBI.A SCAN COLUMN
IN A.iPIODRA)
AND OPEN IGNORE UNUSED INPUTS
CP OPEN ANY KEYS IN THIS COLUMN CLOSED?
JR NZ.FROW YES. GO DETERMINE CLOSURE ROW
ADD HL.DE NO, MOVE KEY TABLE POINTER TO
NEXT COLUMN
INC BC POINT TO NEXT SCAN PATTERN
JR FCOL

16-13
B 1

;DETERMtNE ROW NUMBER OF CLOSURE

FROW: INC HL MOVE KEY TABLE POINTER TO NEXT ROW


RRCA NEXT ROW GROUNDED?
JR CFROW NO, KEEP LOOKING

;IDENTIFY KEY FROM TABLE

LD A,(HL) ;GET KEY NUMBER


RET

;SCAN PATTERNS USED TO GROUND ONE COLUMN AT A TIME



ERROR PATTERN USED TO INDICATE THAT ALL COLUMNS HAVE BEEN SCANNED
;THE COLUMN ATTACHED TO OUTPUT BIT IS SCANNED FIRST, THEN
. THE ONE ATTACHED TO OUTPUT BIT 1, ETC.

PATT: DEFB 0000011 OB


DEFB 00000101
DEFB 00000011
DEFB ECODE

KEYBOARD TABLE

COLUMNS ARE PRIMARY INDEX, ROWS SECONDARY INDEX


THE KEYS IN THE COLUMN ATTACHED TO OUTPUT BIT ARE FOLLOWED
BY THOSE IN THE COLUMN ATTACHED TO OUTPUT BIT 1. ETC. WITHIN
A COLUMN, THE KEY ATTACHED TO INPUT BIT IS FIRST FOLLOWED
BY THE ONE ATTACHED TO INPUT BIT 1. ETC.
THE DIGIT KEYS ARE TO 9. DECIMAL POINT tS 10. GO IS 1

KTAB: DEFB 3 CO.RO


DEFB 2 C0,R1
DEFB C0,R2
DEFB 4 caR3
DEFB 8 C1,R0
DEFB 9 CI.RI
DEFB 1 C1.R2
DEFB 11 C1.R3
DEFB 5 C2.R0
DEFB 6 C2,R1
DEFB 7 C2,R2
DEFB 10 C2,R3

:SUBROUTINE SCANO SCANS THE KEYBOARD WAITING FOR KEY CLOSURE TC


, END SO NEXT CLOSURE CAN BE FOUND

SCANO: SUB A ;GROUND ALL KEYBOARD COLUMNS


OUT (P!ODRB),A
IN A,(PIODRA)
AND OPEN IGNORE UNUSED INPUTS
CP OPEN ARE ANY KEYS STILL CLOSED?
JR NZ.SCANO YES, CONTINUE SCANNING
RET
END

16-14
PROJECT #2: A Digital Thermometer
Purpose: This project is a digital thermometer which shows the temperature in
degrees Celsius on two seven-segment dispiays.

Hardware: The project uses one input port and one output port, two seven.-segment
displays, a 74LS04 Inverter, a 74LS00 NAND gate or a 74LS08 AND gate depending on
the polarity of the displays, an Analog Devices AD7570J 8-bit monolithic A/D con-
verter, an LM311 comparator, and various peripheral drivers, resistors, and capacitors
as required by the displays and the converter. (See Chapter 1 1 and Reference 1 at the
end of this chapter for discussions of A/D converters.)
Figure 16-2 shows the organization of the hardware. Output line 7 from PIO Port B is
used send a Start Conversion signal to the A/D converter Input lines through 7 are
to
attached directly to the eight digital data lines from the converter. Output tines
through 3 are used to send BCD digits to the seven-segment decoder/drivers. Output
line 4 activates the dispiays and output line 5 selects the left or right display '1'
(tine 5 is
for the left display).

The analog part of the hardware is shown in Figure 16-3. The THERMOMETER
thermistor simply provides a resistance that depends on tem- ANALOG
perature. Figure 1 6-4 is a plot of the resistance and Figure 1 6-5 HARDWARE
shows the range of current values over which the resistance is
linear. The conversion to degrees Celsius in the program is performed with
a calibration
table. The two potentiometers can be adjusted to scale the data properly. A
clock for
the A/D converter is generated from an RC network. The values are R7=33 kil and
C1==1000 pF, so that the clock frequency is about 75 kHz. At this frequency, the max-
imum conversion time for eight bits is about 50 microseconds. A much longer delay is
allowed for conversion so that no check for the end of conversion is necessary. The 8-
bit version of the converter requires the following special connections.
The eight data
lines are DB2 through DB9 (DB1 is always high during conversion and DBO
tow). The
Short Cycle 8-bit input (pin 26-SC8) is tied low so that only an 8-bit conversion is per-
formed. In the present case. High Byte Enable (pin 20-HBEN) and Low Byte Enable (pin
21-LBEN) were both tied high so that the data outputs were always enabled.

The A/D converter uses the successive approximation method to perform a conversion.
The ADC's data register is connected to the inputs of an internal D/A converter whose
output (available at 0UT1 and 0UT2) is compared to the analog input. When a conver-
sion is initiated, the ADC logic sets the data register to
all zeros with the exception of

the most significant bit (MSB), which is the analog input is less than the
set to one. If

resulting internally generated analog value, then the MSB is reset to zero: otherwise it
remains a one. The next most significant bit is then set to one and the process repeated
until all eight bits have been "tested" In this way. After the eighth cycle, the value in the
register is the value which most closely corresponds to the analog input.

This methodis fast, but it requires that the input be stable during the conversion pro-

cess. Rapidlychanging or noisy inputs would require additional signal conditioning. The
references at the end of this chapter describe more accurate methods for handling
analog I/O.

16-15
Output ^5
Port ^4
(PIO ^3
Port B) ^2
Bl
Bo

Iff IU'2'^I
Start Do D^ D2 D3
A? Conversion
As
Input A5 Display Dispiav

Port A4 A/D and and

(PIO A3 Converter Dnver Dnver

Port A) A2 (left) (right)

At
Ao Common

Analog Input- to
-T"

Figure 16-Z I/O Configuration for a Digita!


^
Thermometer

16-16
V

R6
50 kn
OFFSET ADJ
-15V O '^^i + 15V

+15V +5
9 9

Note: if positive V^^gp is used, the ANALOG INPUT range !S to -Vpjgp, and the
COMPARATOR'S [-) tnput should be connected to 0UT1 (pin 4) of the AD7570.
Rj IS the thermistor. The analog input from the voltage divider ts:

^ X 15 Volt

Since Rp = 68 kH. the input is: 1.02 MO.

Rf + 68 kn

Rj has a minimum value of 34 kH (T=50X. see Figure 16-4} so full scale is 10 Volt.

Figure 16-3. Digital Thermometer Analog Hardware

16-17
1000 OOOi

T(*C) R {OhmJ

365 000
25 100 000
50 34 000
100 6000

"O-^.

^>

25

Temperature C^)

Figure 16-4. Thermistor Characteristics


(FenwalGA51J1 Bead)

The curve Is linear (i.e., the resistance is

independent of current) for currents less


than 0.1 milttampere.

Figure 16-5. Typical E-! Curve for Thermistor (25*'C)

16-18
General Program Flowchart-

C ^- )
i

tnlti^ization

»—
t
Send Start
Conversion signal
to A/D converter

Wat 1ms

Read data from


A/D converter

Convert data to
degrees Celsius

Dtsptav
temperature on
LHDs for six seconds

16-19
Program Description:
1) Initialization

Location (the Z80 microprocessor RESET location) contains a jump to the starting
address of the main program.The initialization configures the PIO control registers
and starts the Stack Pointer at the highest address in RAM. The Stack is used only
to store subroutine return addresses.

2) Send START CONVERSION Signal to A/D Converter


The CPU pulses the START CONVERSION line bv first placing a 'V on line 7 of PIO
'0'
Port B and then placing a on that line. Each input from the converter requires a
starting pulse.

3) Walt 1 ms for Conversion


A delay of 1 ms after the START CONVERSION putse guarantees a completed con-
version. Actually, the converter takes only a maximum of 10 micro seconds for an
8-bit conversion. We could reduce the delay by checking the BUSY signal from the
'0' (conversion
converter. This signal is either a 'V {conversion complete) or in

progress) if the BUSY ENABLE the present case there is no


line is addressed. In

reason to speed the conversion process. Clearly, interrupts could be used with
BUSY tied to the P!0 STROBE tine.

4) Read Data from A/D Converter


Reading the data involves a smgle input operation. We should note that the Analog
Devices AD7570J has an Enable input and tristate outputs so that it could be tied
directly to the microprocessor Data Bus.

The 7570 converter is, of course, underutilized m this particular application, partic-

ularly since we are interfacing it to theZ80 processor through a PIO. A simpler 8-bit
A/D converter such as the National 5357 device would do the job at lower cost;
thisdevice is available m an 1 8-pin package, has a START CONVERSION input, and
provides tristate outputs. It also has output latches and an END OF CONVERSION
output signal.

16-20
5) Convert Data to Degrees Celsius
Flowchart:

c Start
J
Value = Data recaived
from A/D converter
Index =
Pointer. = Start of table

{Pointer} >*S^Yes
Value

fndex = Index + 1
Temperature = index
Pointer = Pointer + 1

C D
The conversion uses a table that contains the largest in- USING A
put value corresponding to a given temperature. The pro- CALIBRATION
gram searches the table, looking for a value greater than TABLE
or equal to the value received from the converter The first
fc——--——
such value it finds corresponds to the required temperature; that is, if the tenth
entry is the first value larger than or equal to the data, the temperature is 10
degrees. This search method is inefficient but adequate for the present applica-
tion.

Note that we must keep the entry number m decimal rather than binary. The in-
struction sequence "ADD A.1: DAA" keeps the index as two decimal digits in-
stead of a binary number. For example, the entry number after 9 (00001001 bin-
ary) will be decimal 10 {00010000 BCD) rather than binary ten (00001010). The
reason for this is that we plan to display the temperature as two decimal digits and
would have to convert it from binary to decimal otherwise.
The table could be obtained by calibration or by a mathematical approximation.
The method is simple, since the thermometer must be calibrated any-
calibration
way. The table occupies one memory location for each temperature value to be
displayed.^
To calibrate the thermometer, you must first adjust the potentiometers to produce
the proper overall range and then determine the converter output values corres-
ponding to specific temperatures.

16-21
6) Prepare Data for Display
Flowchart:

c D
Get least significant

digit and set


output to LEDs

Set output to lEDs

CIEI3
The least significant digit is nnasked off. We set the bit that BLANKING
turns on the dispiays. The result Is saved in Register E. A LEADING
ZERO
The only difference for the most significant digit is that a lead-
ing zero is blanked (i.e., the displays show "blank 7" rather
than "07" for 7''C). This sinnply involves not setting the bit that turns on the dis-

plays if the digit is zero. The result is saved in Register D.

16-22
7) Display Temperature for Six Seconds
Flowchart:

f Start
J

Count = TSAMP

Send most
significant digit

to left display

Wait 2 ms

Send least

significant digit

to right display

I
J.
Count = Count - 1

Each display is pulsed often enougn so that U appears to be lit contmuouslv. If


TPULS were made longer (say 50 nns), the displays would appear to flash on and
off.

The program uses a 16-blt counter to count the time between temperature sam-
ples. The Z80 has instructions to increment or decrement 1 6-bit register pairs or in-
dex registers. However these instructions do not affect the flags, so there is no way
to directly determine when the counter reaches zero. So we make this determina-
tion by logically ORing the eight most significant and the eight least significant bits
of the counter. If that result is zero, the 16-bit counter is zero.

16-23
:PROGRAM NAME: THERMOMETER
;DATE OF PROGRAM: 10/20/78
;PROGRAMMER: LANCE A. LEVENTHAL
:PROGRAM MEMORY REQUIREMENTS: 154 BYTES
:RAM REQUIREMENTS; NONE
:l/0 REQUIREMENTS: 1 INPUT PORT, 1 OUTPUT PORT (1 Z80 PIO)

; PROGRAM IS A DIGITAL THERMOMETER THAT ACCEPTS INPUTS FROM


jHis
; AN A/D CONVERTER ATTACHED TO A THERMISTOR, CONVERTS THE INPUT
, TO DEGREES CELSIUS. AND DISPLAYS THE RESULTS ON TWO
; SEVEN-SEGMENT LED DISPLAYS

;A/D CONVERTER

:THE A/DCONVERTER IS AN ANALOG DEVICES 7570J MONOLITHIC CONVERTER


: WHICH PRODUCES AN 8-BIT OUTPUT
;THE CONVERSION PROCESS IS STARTED BY A PULSE ON THE START
; CONVERSION LINE (BIT 7 OF PIO PORT B)
:THE CONVERSION IS COMPLETED IN 50 MICROSECONDS AND THE
DIGITAL DATA IS LATCHED
;

;DISPLAYS

TWO SEVEN-SEGMENT LED DISPLAYS ARE USED WITH SEPARATE DECODERS


; (7447 OR 7448 DEPENDING ON THE TYPE OF DISPLAY)
;THE DECODER DATA INPUTS ARE CONNECTED TO BITS TO 3 OF
: PIO PORT B
:BIT 4 OF PIO PORT B IS USED TO ACTIVATE THE LED DISPLAYS
; (BIT 4 IS 1 TO SEND DATA TO LEDS)
;BIT 5 OF PIO PORT B iS USED TO SELECT WHICH LED IS BEING
; USED (BIT 5 tS 1 IF THE LEADING DISPLAY IS BEING USED.
, IF THE TRAILING DISPLAY IS BEING USED)

: METHOD

;STEP 1 - INITIALIZATION
, THE MEMORY STACK (USED FOR SUBROUTINE RETURN ADDRESSES) IS

, INITIALIZED
:STEP 2 ' PULSE START CONVERSION LINE
; THE A/D CONVERTER'S START CONVERSION LINE (BIT 7 OF PiO
; PORT B) IS PULSED
;STEP 3 - WAIT FOR A/D OUTPUT TO SETTLE
: A WAIT OF 1 MS ALLOWS FOR COMPLETION OF THE CONVERSION
;STEP 4 - READ A/D VALUE, CONVERT TO DEGREES CELSIUS.
; A TABLE IS USED FOR CONVERSION IT /CONTAINS THE MAXIMUM
. INPUT VALUE FOR EACH TEMPERATURE READING
:STEP 5 - DISPLAY TEMPERATURE ON LEDS
; THE TEMPERATURE IS DISPLAYED ON THE LEDS FOR SIX SECONDS
; BEFORE ANOTHER CONVERSION IS PERFORMED

:THERMOMETER VARIABLE DEFINITIONS

IMEMORY SYSTEM CONSTANTS

16-24
BEGIN EQU BOH ;STARTING ADDRESS OF MAIN PROGRAM
LASTM EQU 1000H :STARTING ADDRESS FOR RAM STACK

:l/0 UNITS AND P!0 ADDRESSES

PIODRA EQU OEOH :INPUT PIO FOR CONVERTER


PIOCRA EQU 0E2H
PtODRB EQU 0E1H ;OUTPUT PIO FOR DISPLAYS
PIOCRB EQU 0E3H

;DEF!NmONS

LEDON EQU 4 BIT POSITIONTO SEND DATA TO LEDS


LEDSL EQU 5 BIT POSITIONTO SELECT LEADING DISPLAY
MSCNT EQU 0F9H COUNT NEEDED TO GIVE 1 MS DELAY
STCON EQU 100000008 OUTPUT TO BRING START CONVERSION HIGH
TPULS EQU 2 DISPLAY PULSE LENGTH IN MS
TSAMP EQU 1500 TSAMP IS THE NUMBER, OF TIMES THE
DISPLAYS ARE PULSED IN A
TEMPERATURE SAMPLING PERIOD. THE
LENGTH OF A SAMPLING PERIOD IS THUS
2*TPULS*TSAMP MILLISECONDS.THE FACTOR
OF 2*TPULS IS INTRODUCED BY THE FACT
THAT EACH OF 2 DISPLAYS IS PULSED FOR
TPULS MS

ORG

:RESET ROUTINE TO REACH THERMOMETER PROGRAM

JP BEGIN :FIND THERMOMETER PROGRAM

INITIALIZATION OF THERMOMETER PROGRAM

ORG BEGIN
LD A.01001111B :MAKE PIO PORT A INPUT
OUT (PIOCRAl.A
LD A.000011118 :MAKE PIO PORTS OUTPUT
OUT (PIOCRB).A
LD SP.LASTM :PUT STACK AT END OF RAM

;PULSE START CONVERSION LINE

START: LD A.STCON
OUT (P10DR8),A :SEND START CONVERSION HIGH
SUB A
OUT (PIODRB).A ;SEND START CONVERSION LOW

16-25
;DELAY 1 MS FOR CONVERSION

LD A.I ;CONVERSION DELAY TIME IN MS


CALL DELAY :WAIT FOR CONVERSION

:READ DIGITAL DATA FROM CONVERTER

IN A,{P!ODRA) :GET DATA FROM A/D CONVERTER

;CONVERT A/D DATA TO 2 BCD DIGITS

CALL CONVR :CONVERT DATA TO BCD

;GET LEAST SIGNIFICANT DIGIT

LD B.A SAVE BCD DIGITS


AND OFH MASK OFF LSD
SET LEDON.A SET OUTPUT TO LEDS
LD E,A SAVE LSD IN REGISTER E

;GET MOST SIGNIFICANT DIGIT, BLANK LEADING ZERO

LD A.B ;RESTORE BCD DIGITS


RRCA ;SHIFT MSD
RRCA
RRCA
RRCA
AND OFH MASK OFF MSD
JR Z.SVMSD DON'T TURN DISPLAY ON IF VALUE ZERO
SET LEDON.A SET OUTPUT TO LEDS
SET LEDSL,A SELECT LEADING DISPLAY
SVMSD: LD D.A SAVE MSD IN REGISTER D

:PULSE THE LED DISPLAYS

LD C.PIODRB GET OUTPUT PORT ADDRESS


LD HL.TSAMP GET t6-BIT PULSE COUNTER
DSPLY; OUT (C},D OUTPUT LEADING DIGIT TO DISPLAY
LD A.TPULS DELAY DISPLAY PULSE LENGTH
CALL DELAY
OUT (O.E ;OUTPUT TRAILING DIGIT TO DISPLAY
LD A.TPULS ;DELAY DISPLAY PULSE LENGTH
CALL DELAY
DEC HL :COUNT DOWN 16-BIT COUNTER
LD A.H : REMEMBER DEC HL DOES NOT SET Z FLAG
OR L
JR NZ.DSPLY ;C0NT1NUE PULSING DISPLAYS
JP START ;G0 SAMPLE TEMPERATURE AGAIN

:SUBR0UTtNE DELAY WAITS FOR THE NUMBER OF MILLISECONDS SPECIFIED


; IN REGISTER A

16-26
DELAY: EXX SAVE USER REGISTERS
DLY1: LD C.MSCNT LOAD REGISTER C FOR 1 MS DELAY
WTLP; DEC C WAIT 1 MS
JR NZ.WTLP
DEC A :COUNT DOWN NUMBER OF MS
JR NZ.DLY1
EXX iRESTORE USER REGISTERS
RET

:SUBROUTINE CONVR CONVERTS INPUT FROM A/D CONVERTER TO DEGREES


; CELSIUS BY USING A TABLE. INPUT DATA IS IN THE ACCUMULATOR.
; RESULT IS 2 BCD DIGITS IN THE ACCUMULATOR

:REGtSTERS USED: A.B.CH.L

CONVR: LD HL.DEGTB GET BASE ADDRESS OF CONVERSION


TABLE
LD 8.A SAVE A/D INPUT
LD CO START DEGREES AT ZERO
CHVAL: LD A,(HU GET ENTRY FROM TABLE
CP B IS A/D INPUT BELOW ENTRY?
LD A,C GET VALUE IN DEGREES CELSIUS
RET NC YES. VALUE FOUND
ADD A.1 NO. ADD 1 TO DEGREES
DAA KEEP DEGREES IN BCD
LD C,A
INC HL
JR CHVAL

TABLE DEGTB WAS OBTAINED BY CALIBRATION WITH A KNOWN REFERENCE


DEGTB CONTAINS THE LARGEST INPUT VALUE THAT CORRESPONDS TO A
PARTICULAR TEMPERATURE READING (I.E. THE FIRST ENTRY IS DECIMAL
58 SO AN INPUT VALUE OF 58 IS THE LARGEST VALUE GIVING A ZERO
TEMPERATURE READING - VALUES BELOW ZERO ARE DISPLAYED AS ZERO

16-27
DEGTB: DEFB 58
DEFB 61
DEFB 63
DEFB 66
DEFB 69
DEFB 71
DEFB 74
DEFB 77
DEFB 80
DEFB 84
DEFB 87
DEFB 90
DEFB 93
DEFB 97
DEFB 101
DEFB 104
DEFB 108
DEFB 112
DEFB 116
DEFB 120
DEFB 124
DEFB 128
DEFB 132
DEFB 136
DEFB 141
DEFB 145
DEFB 149
DEFB 154
DEFB 158
DEFB 163
DEFB 167
DEFB 172
DEFB 177
DEFB 181
DEFB 186
DEFB 191
DEFB 195
DEFB 200
DEFB 204
DEFB 209
DEFB 214
DEFB 218
DEFB 223
DEFB 227
DEFB 232
DEFB 236
DEFB 241
DEFB 245
DEFB 249
DEFB 253
DEFB 255
END

16-28
.

References
1 A method that uses far less memory is described in T. A, Seim. "Numericat Interpola-
tion for Microprocessor-based Systems." Computer Design. February 1978. pp. ni-
ne.
See also:

2. Auslander. D. M. eta!., "Direct Digital Process Control: Practice and Algorithms for
Microprocessor Applications," Proceedings of the IEEE, February 1978, pp. 199-208

3. Bernstein. N., "What to Look for m Analog Input/Output Boards," Electronics, Janu-
ary 19, 1978. pp. 13-119

4. Bibbero, R. J.. Microprocessors in Instruments and C ontrol Wiley, New York, 1977
5. Burton. D. P, and A. L. Systems Handbook. Analog Devices,
Dexter. Microprocessor
Inc.. P.O. Box 796, Norwood. MA. 02062. 1977
6. Finket, J. , Computer-Aided Experimentation Wiley, . New York, 1975
7. Garrett. P. H.. Analog Systems for Microprocessors and Minicomputers. Reston Pub-
lishing Co.. Reston. VA.. 1978
8. Hnatek. E. R. . A User's Handbook of D/A an d A/D Conv erters, Wiley, New York,
1976
9. Mrozowski, A.. "Analog Output Chips Shrink A-D Conversion Software." Electronics,
June 23. 1977.. pp. 130-133
10. The Optoelectronics Data Book, Texas Instruments, inc., P.O. Box 5012, Dallas, TX,.
1978
11. The Optoelectronic Designer's Catalog, Hewlett-Packard Inc.. 1820 Embarcadero
Road. Palo Alto. CA. 94303.1978

12. Peatman, J. B.. Microcomputer-based Design McGraw-Hill, , New York. 1977


1 3. Rony, P.. "Microcomputer Interfacing; Sample and Hold Devices." Computer
R. et al..

Design, December 1977.. pp. 106-108

14. Sheingold, D. H, ed.. Analog-Digital Conversion Notes, Analog Devices, Inc., P 0.


Box 796. Norwood, MA, 02062, 1977

16-29
Index of Instruction Descriptions

ADC A.data 3-43 IM 3-80


ADC A,reg 3-44 IM 1 3-80
ADC A.(HL) 3-45 iM 2 3-80
ADC A,(IX + disp) 3-45 IN A,(port) 3-81
ADC A.dY + disp) 3-45 !NC reg 3-82
ADC HLrp 3-46 INC rp 3-83
ADDA.data 3-47 INC IX 3-83
ADD A.reg 3-48 INC lY 3-83
ADD A.(HL) 3-49 INC (HL) 3-84
ADD A.dX + disp) 3-49 INC (IX + disp) 3-84
ADD A,(iY + disp) 3-49 INC (lY -f-disp) 3-84
ADD HLrp 3-50 IND 3-85
ADDxv.rp 3-51 INDR 3-85
AND data 3-52 IN! 3-86
AND reg 3-53 INIR 3-86
AND (HL) 3-54 IN reg.(C) 3-87
AND (IX + disp) 3-54
AND (lY disp) -1- 3-54 JP label 3-88
„_ ^ ^ ^^ JP conditionjabel 3-89
BIT b.reg 3-55 jp ^^^ g.gQ
BIT b,(HL) 3-56 jp nj^j 3-90
BIT b.dX -I- disp) 3-56 jp (jy) 399
BIT b,(tY + disp) 3-56 JRC.disp 3-91
CALL label 3-57 JR disp 3-92
CALL condition.label 3-58 JR NCdisp 3-93
CCF 3-59 JR NZ.disp 3-93
CP data 3-60 JR Z.disp 3-94
CP reg 3-61
CP(HU 3-62 ^^^'l 3-94
CP(IX + disp) 3-62 ^^ ^'^ 3-94
CP(iY-fdisp) 3-62 LDA.(addri 3-95
CPD 3-63 ^^ ^'^^P^ 3-96
CPDR 3-64 LDdst.src 3-97
Cpt 3,65 LD HL,(addr) 3-98
CPIR 3-66 ^^ rpjaddr) 3-98
CPL 3-67 '-^ IXJaddr) 3-98
LD lYJaddrl 3-98
DAA 3-68 LDLA 3-99
DEC reg 3-69 LD R.A 3-99
DEC rp 3-70 LD reg.data 3-100
DEC IX 3-70 LDrp.data 3-101
DECIY LDIX.data 3-101
DEC (ML) 3-71 LDIY.data 3-101
DEC (IX 4- disp) 3-71 LDreg.lHU 3-102
DEC (lY + disp) 3-71 LD reg.dX disp) 3-102
-f-

Dl 3-72 LD reg.dY 4- disp) 3-102


DJNZ disp 3-73 LD SP,HL 3-103
£1 3 73
LDSP.IX 3-103
EXAF.AF 3-75 ^° ^P.IY 3-103
EXDE.HL 3-76
LD (addr).A 3-104
EX(SP)HL 3-77 LD(addr).HL 3-105
LD(addr).rp 3-105
EX(SP),IX 3-77
EX (SP) lY 3-77
LD (addr).xY 3-105
EXX 3-78 ^^ (HL).data 3-107
LD dX + disp).data 3-107
HALT 3-79 LD dY + dispi.data 3-107
Index of Instruction Descriptions (Continued)

LD (HU.reg 3-108 ^^D 3-136


LD (IX + displ.reg 3-108 ^^^^9 3-137
LD {lY + displ.reg 3-108 ^^ ^HL) 3-138
LD(rpU 3-109 RR (IX -f disp} 3-138
LQQ 3, 110 RR(IY + dtspl 3-138
LDDR 3-111 ^^^ 3-139
LQI 3.112 RRCreg 3-140
LDtR 3-113 ^^C(HL) 3-141
RRC OX -Fdisp) 3-141
NEG 3-113 RRC (lY -f- dlspj 3-141
NOP 3-114 BRCA 3-142
OR data 3-115 R^D 3-143
ORreg 3-116 f^ST n 3-144
OR (HL) 3-117 SBC A,data 3-145
OR (IX + disp) 3-117 SBC A.reg 3-146
OR (lY + disp) 3-117 jBC A.(HL) 3-147
OUT(C).reg 3-118 SBC A,{IX -f disp) 3-147
OUTD 3-119 SBC A.(IY 4- disp) 3-147
OTDR 3-119 SBCHLrp 3-148
OUT! 3-120 SCF 3-149
OTIR 3-120 SETb.reg 3-150
OUT(port),A 3-121 SET b,(HL) 3-151
POPrp 3-122 SET b.dX -H disp) 3-151
POP IX 3-122 SETb.dY -h disp) 3-151
POP lY 3-122 SLAreg 3-152
PUSHrp 3-123 SLA (HL) 3-153
PUSH IX 3-123 SLA (IX -F disp) 3-153
PUSH lY 3-123 SLA (IY + disp) 3-153
SRA reg 3-154
RESb.reg 3-124 SRA (HL) 3-155
RES8.(HL) 3-125 SRA (IX -f disp) 3-155
RES b.dX + disp) 3-125 sr^ (ly + ^isp) 3-155
RES b.ilY -h disp) 3-125 SRL reg 3-156
BET 3-126 SRL (HL) 3-157
RETcond 3-127 SRL {IX -f disp)- 3-157
RETI 3-128 SRL (IY + disp) 3-157
BETN 3-129 SUB data 3-158
RLreg 3-130 sUB reg 3-159
RL(HU 3-131 SUB(HU 3-160
RL (IX + disp) 3-131 gyg (i^ + ^jsp) 3,160
RL {!Y -f disp) 3-131 gUB (lY -f- disp) 3-160
RLA 3-132
RLC reg 3-133 XOR data 3-161
RLC (HL) 3-133 XOR reg 3-162
RLC (IX -F disp) 3-134 XOR (HL) 3-163
RLC (lY ¥ dispi 3-134 XOR (IX + disp) 3-163
RLCA 3-135 XOR (lY -f disp) 3-163
Index

Accumulator, using the. 4-2 questions for. 15-4


Add/Subtract flag, 8-7 Common-anode or common-cathode displays.
Address field, numbers and characters in, 3-172 11-43
Algebraic notation. 1-8 Compiler. 1-7
Algorithm cost of, 1-8
multiplication. 8-8 Computer program, 1-1
simple sorting. 9-10 COND and ENDC pseudo-operations, 3-174
Allocating RAM, 2-7 Control and status information. 11-57
Arithmetic and Logical Expressions, 2-10 Control information, combining, 11-58
ASCII Credit verification terminal, structural program
characters, 2-10 for. 13-38

handling data in, 6-1 Cross-assembler, 2-14


Assembler. 1-5
Daisy chain
arithmetic and logical operations, 3-172
device operation in, 12-10
choosing an. 1-6
interrupts, advantages and disadvantages,
meta-. 2-14
12-9
micro-. 2-14
PtO interrupts. 12-9
one-pass, 2-14
Data, forming classes of. 14-28
resident, 2-14
moving within a block, 7-8
two-pass. 2-14
Data flowcharts. 13-19
Assembler directive, 2-4
Debouncing
Assembly language
in software. 11-26
applications. 1-10
with cross-coupled NAND gates. 11-28
fields, 2-1
Debugging, 13-3
program, 1-5
code conversion program, 14-6
Basic software delay, 11-8 interrupt-dnven programs, 14-14
BCD and binary, accuracy in, 8-8 sort program, 14-6
Blanking a leading zero. 16-22 use of test cases from, 14-27
Block I/O instruction. 6-6 Decimal
use of, 11-21 accuracy in binary, 8-4
Block, moving data within, 7-8 adjust, 8-7
Block search instructions, 6-6 data or addresses. 2-9
Block transfer instructions, 8-4 rounding. 8-24
Binary and BCD, accuracy m. 8-8 shift instructions. 8-21
Binary instructions, 1-1 DEFB. DEFL. DEFM, DEFS. DEFW pseudo-
rounding. 8-24 operajtions, 3-170, 3-171
Binary numbers, doubling and halving. 8-23 Definition list

Bootstrap loader. 2-15 rules .for. 15-8


Bottom-up design. 13-44 typical. 15-9
Breakpoint, 14-2 Definitions, placement of. 2-7
insertion of, 14-3 Delay loop constant, 11-10
RST as, 14-2 Delimiters, 2-2
Buffer Direct memory access (DMA), 1 1-5
double buffering, 12-7 Disabling interrupts, 12-25
emptying with interrupts. 12-19 Displays, common-anode or common-cathode,
filling via interrupts, 12-16 11-43
Buffer, emptying with interrupts, 12-19 Division algorithm, 8-12
Documentation, 13-3
Calibration table, use of, 16-21
of status and control transfer. 1 1-59
Character format, 1 1-81
of subroutines, 10-2
Checklist, what to include In, 14-10
package. 15-13
Coding, 13-3
Double buffering, 12-7
relative importance of, 13-1
Commenting 8-bit summation, 5-3
examples. 15-4 8080A unused operation codes, 3-164
guidelines. 15-2 8080A/Z80
techniques, 2-13 assembly level conversion. 3-164
1

Index (Continued)

8080A/Z80 (continued) disabling, 12-2. 12-25

compatibiiitY features. 3-164 disadvantages of, 12-2


incompatibilities, 3-164 enabling, 12-2
8085/Z80 incompatibitities. 3-165 emptying a line buffer with, 12-19
ENDC and COND pseudo-operations. 3-174 handling by monitors, 12-13
Error considerations, 13-5 inputs, 12-2. 12-3

Errors, common, 14-11 instruction, 12-3

Example format, 4-1 keyboard, 12-14


Examples, guidelines for, 4-1 modes. 12-4
Execution time, saving, 15-15 non-maskable. 12-2. 12-3
External references, 2-8 on particular microconnputers. 12-13
PIO. 12-6. 12-7
Ftowchartmg reasoning behind, 12-1
advantages 13-17
of, SIO. 12-26, 12-10
credit verification, 13-22 start bit interrupt, 12-28
disadvantages of, 13-18 systems, charactenstics of, 12-1
sections, 13-22 I/O
switch and light system, 13-19 and memory. 11-1
switch-based memory loader, 13-20 categories. 11-1
Flowcharts driver. 11-18
data. 13-19 instruction examples, 11-19
hints for use, 15-7 instructions with absolute addressing. 11-18
Format, 2-2
Jumps, indirect. 9-15
FORTRAN. 1-7
Full-duplex, 11-89 Key closure, waiting for. 1 1-62
Key table, 16-7
General service routines, tasks for. 12-30
Keyboard errors, correcting, 13-14
Hand assembly, 1-5 Keyboard interrupt 12-14
Hand checking questions. 14-11 Keyboard routine, expanding the. 13-48
Handshake. 11-2 Keyboard scan, 11-60
Hashing, 9-4 Label field. 2-2
Hexadecimal loader. 1-3 Labeling, rules of. 2-3
Hexadecimal or octal. 1-3 Labels
High-level language choice of. 2-3
advantages of. 1-9 m iump instructions, 2-2
applications for. 1-10 Language levels
disadvantages of. 1-9 application areas for. 1-10
inefficiency of. 1-8 future trends in. 1-11
machine independence. 1-7 LED control. 11-39
overhead for, 1-9 Ltnk editor, 2-15
portability of. 1-8 Linking loaders, 2-15
syntax of. 1-10 Loader
unsuitability of, 1-10 bootstrap, 2-15
hexadecimal. 1-3
Index registers, use of, 7-7
linking. 2-15
Information hiding pricipie, 13-29
memory, 13-10. 13-28
Initializing RAM. 2-8
relocating. 2-15
Input, factors m. 13-4
Local or global variables. 2-13
Instructions
Location counter, 2-7
defining a sequence of. 2-1
Logic analyzer. 14-9
fasterand slower executing, 3-164 14-10
important features of,
Interfaces, standard. 11-103
Logical and arithmetic expressions. 2-10
Interfacing
high-speed devices. 11-5 Machine language
medium-speed devices, 11-2 applications for, 1-10
slow devices. 11-2 program. 1-2
Interrupts MACRO and ENDM pseudo-operations. 3-174

xw//
index (Continued)

Macro-assembler, 2-14 Processing, factors in. 13-5


Macros Program design, 13-3
advantages of, 2-12 basic principles of. 13-6
disadvantages of, 2-12 Programming guidelines. 4-2
Maintenance and redesign, 13-3 Pseudo-operations, 2-4
Matrix keyboard, 11-60 COND. 3-174
Memory dump, 14-7 DEFB. 3-170
Memory loader error handling, 13-10 DEFL. 3-171
Memory map, typical, 15-8 DEFM, 3-170
Meta-assembler. 2-14 DEFS, 3-171
Micro-assembler, 2-14 DEFW. 3-170
Mnemonics, problems with, 1-4 END, 3-172
Modular programming ENDC. 3-174
advantages of, 13-26 ENDM. 3-174
disadvantages of, 13-27 EQU. 3-171
rules for, 13-30 MACRO. 3-174
Modularization ORG, 3-171
principles of, 13-27
switch and light system, 13-28 RAM
switch-based memory loader. 13-28 allocating, 2-7
verification terminal, 13-28 Initializing, 2-8
Multiplication algorithm, 8-8 Real-time clock. 12-20
frequency of. 12-20
Names priority of, 12-21
choice of, 2-6. 15-2
synchronization with, 12-20
defining, 2-6
Real time, maintaming, 12-24
use of, 2-6
Receive routine, structured, 13-40
Number systems. 2-9 Redesign and maintenance, 13-3
Numbers, self-checking. 8-17 Redesign, cost of, 15-14
Non-maskable interrupt. 12-2. 12-3 Re-entrant subroutine. 10-2
Object program, 1-2. 1-5 References, external, 2-8
Octal or hexadecimal, 1-3 Register dumps, 14-4
One-pass assembler, 2-14 Register Pair HL, using, 4-2
Operation codes, two-word, 3-164 Relocating loader, 2-15
Operator error connection in memory loader. Relocation, 10-2
13-10 Relocation constant, 2-3
Operator interaction, 13-6 Reorganization, major or minor. 15-14
ORG pseudo-operation. 3-171 Resident assembler, 2-14
Restart instruction, 12-4
Passing parameters. 10-1 Return address, changing the, 12-16
PIO Rollover. 11-69
addresses. 11-11 RST as a breakpoint, 14-2
mode, 11-15
bidirectional
control mode. 11-15 Searching methods. 9-6
daisy chain signals. 12-9 Self-checking numbers, 8-17
directions m control mode, 11-15 Self-documenting programs, rules for. 15-1
mput mode. 11-15 Seven-segment representations. 11-45
interrupts, enabling and disabling. 12-7 Sign propagation. 8-25
modes, 11-15. 11-16 Simple sorting algorithm, 9-10
output mode, 11-15 Single-step, 14-1
registers and control lines, 11-11 Single-step mode, limitations of, 14-2
steps in configuring. 11-17 StO
Polling, 12-2. 12-10 addresses. 1 1-89
Polling interrupt systems with SIOs. 12-10 configuration, example of, 11-100
Portability, 1-6 error status. 11-100
Primed registers, saving values in. 12-16 interrupt routine, 12-26
Priority, 12-16 interrupts, 12-10
Problem definition, 13-3 read and write register, addressmg, 11-89
Index {Contfoyed}

S!0 (continued) rules for. 14-29


reset 11-97 sort program, 14-29
special features 11-97
of. special cases, 14-28
Software devetopement, stages of, 13-1 Testing aids. 14-27
Software simulator, 14-8 Testing, structured. 14-28
Source program. 1-5 Thermometer analog hardware, 16-15
Special instructions. 4-3 Timing incompatibilities, 3-165
Standard interfaces, 11-103 Timing mtervais
Standard program library forms. 15-10 methods for producing, 11-8
Standard TTY. 11-81 uses of, 11-8
Start bit interrupt. 12-28 Timing method, choosmg a, 11-8
Status and control transfers, documenting, Top-down design
11-59 advantages of, 13-44
Status changes with instruction execution. 3-22 disadvantages of, 13-44
Status information, separating, 11-58 format for. 13-49
Stopwatch input procedure, 16-1 methods. 13-44
Strobe. 11-5 of switch and light system. 13-45
Structures, examples of, 13-33 of switch-based memorv loader. 13-46

terminators for. 13-43 of verification terminal. 13-47


Structured l<:evboard routine. 13-38 Transmission errors
Structured program for credit verification correcting, 13,15
terminal, 13-38 reducing, 11-5
Structured programming Transparent delay routine. 11-8
advantages of. 13-35 TTL encoder, using a, 11 -34
basic structures of, 13-31 TTY
disadvantages of. 13-35 interface, 11-81
for switch-based memorv loader, 13-36 receive mode, 11-81
m switch and tight system. 13-36 standard TTY. 11-81
rules for, 13-43 transmit mode, 11-86
when to use. 13-35 Two-pass assembler 2-14
Structured receive routine, 13-40 Two-word operation codes, 3-164
Structed testing, 14-28
UART. 11-88
Stubs. 13-44
Subroutine instructions, 10-1 Variables, local or global, 2-13
Subroutine library, 10-1 Vectoring, 12-2
Subroutines, documenting, 10-2 Verification terminal
Switch and light error handling, 13-7 defining a. 13-11
Switch and tight input. 13-6 error handling, 13-14
Switch and light outputs, 13-7 inputs, 13-13
Switch and light system, defining, 13-6 outputs, 13-13
Switch-based memory loader, defining, 13-8
Z80
Switch bounce, 11-26
delay loop constant, 11-10
Symbol table, 2-6
index registers, use of, 7-7
Synchronizing with I/O devices. 11-57
interrupt inputs. 12-2
interrupt instruction. 12-3
Terminators for structures, 13-43 interrupt response. 12-3
Testing, 13-3 I/O instructions, 11-18
arithmetic program, 14-29 non-maskable interrupt, 12-3
About the Author

Lance A. Leventhal is a partner in Emulative Systems Company, a San

Diego-based consulting firm specializing in microprocessors and


microprogramming. He serves as Technical Editor of the Society for Com-
puter Simulation and as a Contributing Editor for Digital Design. He is a na-
tional lecturer on microprocessors for the IEEE, the author of five books
and over forty articles on microprocessors, and a regular contributor to
such publications as Simulation , Digital Design, and Kilobaud.

Dr. Leventhal's previous experience includes affiliations with Linkabtt Cor-


poration, Intelcom Bad Tech, Naval Electronics Laboratory Center and Har-
ry Diamond Laboratories. He received a 8.A. degree from Washington

University in St. Louis, Missouri, and M.S. and Ph.D. degrees from the
University of California at San Diego. He is a member of SCS, ACM, and
IEEE.
OSBORNE/McGraw-Hill GENERAL BOOKS
An Introduction to Microcomputers series
by Adam Osborne
Volume — The Beginner's Book
Volume 1 — Basic Concepts
Volume 2 — Some Real Microprocessors {1978 ed.)
Volume 3 — Some Real Support Devices (1978 ed.)
Volume 2 1978-1979 Update Series
Volume 3 1978-1979 Update Series
The 8089 I/O Processor Handbook
by Adam Osborne
The 8086 Book
by R. Rector and G. Alexy
8080 Programming for Logic Design
by Adam Osborne
6800 Programming for Logic Design
by Adam Osborne
Z80 Programming for Logic Design
by Adam Osborne
8080A/8085 Assembly Language Programming
by L. Leventhal
6800 Assembly Language Programming
by L Leventhal
6502 Assembly Language Programming
by L. Leventhal
Z8000 Assembly Language Programming
by L. Leventhal et al.
Running Wild: The Next Industrial Revolution
by Adam Osborne
PET-CBM Personal Computer Guide
by Carroll Donahue and Janice Enger
PET and the IEEE 488 Bus (GPIB)
by E. Fisher and C. W. Jensen

OSBORNE/McGraw-Hill SOFTWARE
Practical Basic Programs
by L Poole et al.
Some Common BASIC Programs
by L Poole and M. Borchers
Payroll with Cost Accounting - CBASiC
by Lon Poole et al
Accounts Payable and Accounts Receivable - CBASiC
by Lon Poole et al.
General Ledger - CBASIC
by Lon Poole et al.
Some Common Basic Programs — PET/CBM
edited by Lon Poole et al.
» I

'

^B
ifSaaiv

«« •> !««
80 ASSEMBLY LANGUAGE PROGRAMMIN&
<r
flBBjpa
Wmmi

'

BY LANCE A^LEUENTHAL
Z80 ASSEMBLY LANGUAGE PROGRAMMING
Z80
provides comprehensive coverage of the
microprocessor assembly language
Progrartiming examptes illustrate software
development concepts and actual assembly
language usage Assemblers and assembler
directives. are also explained
Features include
• More than 80 sample programming^roblems
'
411 problem solutions in sourcg co'de and
dteject code
• ^dch 580 instruction fully explained
• Complete Z8'0 instruction set reference table
^* Z80 Assembler conventions
• ^80 Idevices and interfacing methods
V :ComFrarisons of Z80 and 8080A 8085
mstruction set^ and interrupt structure

ISBN 0931 988-21-7

You might also like