Z-80 Assembly Language Programming 1979 Leventhal Text
Z-80 Assembly Language Programming 1979 Leventhal Text
«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
5 6 7 8 9 DODO 8 7 6 5 4 3 2
ISBN 0-931988-21-7
Copyright © 1979 by McGraw-Hill Inc.
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
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
Contents (Continued)
Chapter Page
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
"7-1
7 Code Conversion
Examples 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
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
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
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.
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.
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.
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.
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.
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-
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
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.
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.
As in the case of hexadecimal to binary conversion, hand assemblyis a rote task which
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,
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-
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.
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 |
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.
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).
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.
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.
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.
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
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.
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.
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.
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.
• 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.
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.
Operation Operand
Label Code or or
Field Mnemonic Address
Comment Field
Field Field
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
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
1) Do not use extra spaces, particularly after commas that separate operands.
Include standard delimiters even if your assembler does not require them.
Your pro-
3)
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
{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
These are recommendations, not rules. You do not have to follow them, but don't blame
us If you waste time on silly problems.
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.
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 treats the data as a permanent part of the program.
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.;
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 '
The EQUATE pseudo-operation assigns the numeric value in its operand field to
TTY EQU 5
LAST EQU 5000
Most assemblers will allow you to define one label in terms of another, e.g.;
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
Definitions used only in a specific subroutine should appear at the start of the
subroutine.
Microprocessor programs often contain several ORIGIN statements for the following
purposes:
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.
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.
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.
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 ENTRY, usually abbreviated ENT, signifies that the name is
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.
ADD 100
means "add the contents of memory location 100 decimal to the contents of the Ac-
cumulator"
B or % for binary
2-9
Assembiers generaltv require hexadecimal numbers to start with a decima!
digit (e.g..
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-
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 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
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
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.
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-
instruction Ml
instruction M2
instruction M3
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.
struction set. You use the macro as an extension of your instruction set
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.
7) Comment all definitions, describing their purposes. Also mark ail tables and data
storage areas.
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.
ERRORS
Assemblers normally provide error messages, often consisting of a single coded
letter. Some typical errors are:
2-14
^ .
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.
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.
2-15
REFERENCES
A compiete monograph on macros is M. CanRpbell-Kelly, An Introduction to Macros.
American Elsevier. New York, 1973,
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.
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
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
Alternate Accumulator
Stack Pointer
Program Counter
Index Register
Index 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.
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.
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.
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.
• 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
LDiR
is iliustrated as follows:
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
L 1
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
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
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.
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:
RST OOH
is illustrated as follows:
'^-*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
The instruction
JP (HU
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|
Register Pair BC
3-15
Table 3-t Frequently Used Instructions of the Z80
3-16
Table 3-2. Occasionaltv Used instructions of the Z80
3-17
Table 3-3. Seidom Used Instructions of the Z80
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.
C -Carry (C - 1)
PO - Parity Odd (P = 0)
PE -Panty Even (P = 1)
P - Positive Sign (S = 0)
M - Negative Sign (S - 1)
PC Program Counter
port An 8-blt t/0 port address
3-18
1
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)
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
For example:
[[HU] - [[HL]] + 1
(HU — [HLl + 1
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
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)
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).
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)
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
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
u§
° ? "
'"
^ ^
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
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 §
<" 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
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 -^ -^
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
=
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
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
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 '
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
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
3-35
o
u
CO
O
00
M
06
<
CO
CO
3-36
^
M^^
-^
ffl 50 £• o
S| |<
.9
o
o| s—
o
e£
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
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
oc INC C 56 LD D.(HU
12 LD {DE),A 6E LD L,(HU
14 INC D 76 HALT
15 DEC D 7 Isss LD A.reg
16 yy LD D.data 7E LD A,(HU
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
20 INC L C5 PUSH BC
2D DEC L C6yy ADD A,data
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)
3-41
Tabie 3-5. Instruction Object Codes in Numerical Order (Continued)
3-42
1
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-
ADC A7CH
has executed, the Accumulator will contain BSig:
3A = 1 1 10 10
7C 0111 1 00
1
Carry
01 1 01 1
>- ^ .
The ADC instruction is frequently used in multtbyte addition for the second and subse-
quent bytes.
3-43
1
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
E3 = 1 1 1 11
AO-1010 0000
Carry = ^
1_
000 0100
1 setsS to 1-^-- Non-zero result set Z to
J^
1
^
Vl"^. set P/0
:
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
Add the contents of nmemory iocation (specified by the contents of the HL register pair)
and the Carry status to the Accumulator
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
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
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.
ADC HLBC
the HL register pair wit! contain:
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.
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
3-47
1
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.
ADD A,E
E3 = 1 1 1 11
AO-1010 0000
000 001
J
1 1
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
^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
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.
3-49
1 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.
ADD HLBC
has executed, the HL register pair wi!i contain 2496-tg.
N
Addition instruction, set to
3-60
1 1
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
n''^
'
ADD lY.BC
3-51
' 3 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.
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
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
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.
AND E
E3 = 1 1 1 11
AO 1010 0000
1010 0000
1 sets S to ,^ ii
-Two 1 bits, set P/0 to 1
3-53
AND (HL) — AND MEMORY WITH ACCUMULATOR
AND (IX+disp)
AND (lY+disp)
S Z Ac P/O N C
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)
E3 1110 111
AO 1010 0000
10 10 0000
1 sets S to 1
*J 4
-Two 1 bits, set P/0 to 1
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.
3-54
^ 1
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
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
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
Examine specified bit within memory location indicated by the sum of Index Register IX
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
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.
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
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-
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
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
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
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
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
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
3-61
CP (HL) —COMPARE MEMORY WITH ACCUMULATOR
CP (IX+disp)
CP (lY-hdisp)
S Z AcP^O N C
FHxIXlXiXnlxj
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.
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
No borrow, set A^
to
to-0
No borrow, set C to 0-.
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.
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
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
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
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-
3-66
1
Program
Memory
2F mmmm
mmmm +
mmmm + 2
mmmm + 3
CPL
2F
Complement the contents of the Accumulator. No other registers contents are
affected.
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
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
DEC A
Register A will contain 4Fiq.
3-69
1
A
B,C
D.E
H.L
SP
PC mmmm
tx
!Y
1
R
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.
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:
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
DEC (HL)
35
Subtract 1 fronn the contents of mennory location (specified by the contents of the HL
register pair).
DEC (HL)
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
3-71
1
DEC {IX+displ
DD 35 d
Subtract 1 from the contents of memory location (specified by the sum of the contents
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.
3-72
1
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.
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
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
,
3-74
^ 1
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
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.
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-
EX DE.HL
LD A.(HL)
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)
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
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.
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
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"
EXX
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
IM 1 —INTERRUPT MODE 1
IM 1
ED 56
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
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)
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
!NC E
3-82
1 1 1
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
INC rp
00 XX 0011
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
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
INC (IX+disp)
DD 34 d
Add 1 to the contents of memorY location (specified by the sum of the contents of
of the instruction
INC (IX+OFH)
36 - 00 1 1 110
1
11 111
sets S to J Non-zero
No
result, set
carry, set Aq to
Z 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
,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.
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-
memory location 2400^6 will contain 19i6. The B register will contain
has executed,
04i6 and the HL register pair 240110.
ED B2
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
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)
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
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
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-
3-88
JP condltionjabel— JUMP TO ADDRESS IDENTIFIED IN THE
OPERAND IF CONDITION IS
SATISIFED
JP cond, label
11 cc 010 ppqq
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
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
JP (HL)
E9
an
The contents of the HL register pair are moved to the Progrann Counter; therefore,
implied addressing )ump is performed.
LD H.ADDR
JP (HU
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
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.
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.
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
^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
4000 18
4001 02
4002 -
4003
—
-
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,
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.
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.
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.
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
LD AJ.
ED 57
Move the contents of the Interrupt Vector register to the Accunnulator, and reflect inter-
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
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
LD A.dabel)
The instruction
LD A. (label)
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)
Normally, the LD A,(rp) and LD rp.data will be used together, since the LD rp,data in-
LD BC,084AH
LD A.{BO
3-96
1 1
Oldddsss nnmninri
R
mmmm +
mmmm + 2
mmmm + 3
LD dst src
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
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
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
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).
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
LD R.A
ED4F
Load Refresh register from Accumulator.
LD R,A
has executed, the Refresh register will contain IF-^q.
LDLA
ED 47
Load Interrupt Vector register from Accumulator
3-99
1
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.
LD A,2AH
has executed, 2A'i6 is loaded into the Accumulator.
3-100
1
S Z Ac P/O N C
Data
^' I I I I I I Memorv
BX
D,E
A
\ ^ Select BC, DE.
LD rp, data
00 XX 0001 ppqq
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
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
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.
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-
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),
S Z Ac P/O N C
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
F9
LD SP.HL
has executed, the Stac(< Pointer will contain 083Fi5.
LD SP.IX
DD F9
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 )
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
LD (label).A
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
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
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
ED 01 XX 0011 ppqq
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.
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
LD (!X+dlsp).data
DO 36 d XX
Load immediate into the Memory location designated by base relative addressing.
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
LD (HLl.reg
01110 XXX
Load memory location (specified by the contents of the HL register pair) from specified
register.
LD (HU.C
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
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
LD BC.084AH
LD (BO.A
3-109
1
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.
3-110
LDDR — TRANSFER DATA BETWEEN MEMORY
LOCATIONS UNTIL BYTE COUNTER IS
ZERO. DECREMENT DESTINATION AND
SOURCE ADDRESSES
LDDR
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
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
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.
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.
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.
3-114
I i
OR data
F6 T7
OR the Accumutator with the contents of the second instruction object code byte.
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
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
OR E
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
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)
E3 = 1 11 011
A8 = 1 1 10
^
—
Six 1 bits, set
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
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
OUT (C).H
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.
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-
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
ED B3
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
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
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.
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
11 XX 0001
POP the two top stack bytes into the designated register pair.
POP HL
into the H register Execution of the instruction
ioads 01 16 into the L register and 2Ai 6
POP AF
DD E1
FD El
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
FD mmmm
H
1 E5 mmmm +
mmmm + 2
mmmm + 3
PUSH !Y
FD E5
PUSH the contents of the !Y register onto the top of the stack.
PUSH lY
PUSH IX
DD E5
PUSH the contents of the IX register onto the top of the stack.
PUSH rp
11 XX 0101
PUSH contents of designated register pair onto the top of the stack.
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
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
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
RES b,(IX+dlsp)
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.
RES 0.(IX+7)
has executed, bit in memory location 41 17^6 will be 0.
RES b,{IY+disp)
3-125
of the IX register.
RES b.(HL)
CB lObbb 110
RES 7,(HL)
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
3-126
RET cond — RETURN FROM SUBROUTINE IF CONDITION
IS SATISFIED
RET cond
1 XXX 000
CALL SUBR
AND 7CH-^
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.
3-128
1
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
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
RL D
'
Before After
3-130
1
~^^
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
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
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.
"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
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
3-132
; 1
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
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
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
CB 06
Rotate contents of memory location (specified by the contents of the ML register pair)
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
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
RLC (IX+7)
3-134
has executed, memory location 4007ie will contain 5E\q, and Carry wil! be 0:
Before After
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.
--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
3-135
1
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
7 I F I
7 I 1 I [hf]
3-136
: 1
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
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
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
3-137
1
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
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)
Before After
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.
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
3-139
: 1
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
RRC reg
CB 00001 XXX
status.
RRC D
Before After
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
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.
RRC (HU
memon/ location 450016 will contain lA^g, and Carry will be 0:
Before After
Memory Carry Memory Carry
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
^
try status.
RRC (lY+disp)
FD CB a OE
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,
struction
RRCA
contain 3Di 6 and the Carry status will be reset to
has executed, the Accumulator will
0:
Before After
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
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.
SBC A.7CH
has executed, the Accumulator will contain BD^q.
3A = 1 1 10 10
Twos comp of 7C 1 000 00
1
1 sets S to 1
Non-zero result set Z to
Borrow, set C to 1
Sorrow, set A^ to 1
The Carry flag is set to 1 for a borrow and reset to if there ts no borrow,
3-145
1
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
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^
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.
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
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 —
A
, IT
HL SP
BC 1 BC, DE, or
mmmm + 2
mmmm + 3
SBC HL rp
01 XX 0010
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:
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
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
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 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
SET 5,(HU
has executed, bit 5 m memory position 400016 will be 1.
SET b,(IX+disp)
DD CB d 11 bbb 110
Set indicated bit within memon/ location indicated by the sum of Index Register iX and
displacement.
3-161
1
SET 6.(!X+5H)
SET b,(IY+disp)
FD CB d 11 bbb 110
of the IX register.
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
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.
SLA B
Register B will contain SE-je and Carn/ wilt be zero.
3-152
Before After
Register B Carry Register B Carry
sets S to •
^Non-zero result set Z to
5 ones, set P/0 to ^
1
CR
^ 1 26 mmmm -f 1
mmmm + 2
mmmm + 3
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)
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
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.
R 00101111
mmmm 2
-f
mmmm + 3
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.
3-154
Before After
Register H C Register H C
[0101 1 00 1|
m 10010 1100l HI
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
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)
1 1 1 II
B^ r mmmm + Program
2J Memorv
CB mmmm
00111011 mmmm + 1
mmmm + 2
mmmm 3 -i-
SRL reg
CB 00111 XXX
SRL D
3-156
Before After
Register D Carry Register D Carry
—
4 ones, set P/0 to 1
u Non-zero result set Z to
S Z Aq p/0 n c
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)
Before After
Memory Carry Memory Carry
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.
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.
SUB 7CH
has executed, the Accumulator will contain BEig.
3A = 1 1 10 10
Two"s comp of 7C = 1OOP 01 00
1011 1110
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
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
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
SUB (tX+displ
DD 96 d
Subtract contents of memory location {specified by the sum of the contents of the !X
Suppose ppqq=4000^6, xx^FFig, and memon/ location 40FF'j6 contains BOiq. After
execution of
SUB (IX+OFFH)
FF = 1 1 1 1 1111
Two's comp of 50 = 10 11 0000
10 1111
J
1
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)
3-160
I
XOR data
Exclusive-OR the contents of the second object code byte with the Accumulator.
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
3-161
1
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
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
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
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)
E3 - 1 1 1 11
AG = 1010 0000
1 00 001 1
k
sets S to o*J -Non-zero result set Z 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.
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
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-
3-164
Tabie 3-6. Register and Flag Correspondence between
Z80 and 8080A
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.
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
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
LD XTHL EX (SP),HL
LDA addr A,{addrj
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)
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
RLC !HL)
— SUB {xy + disp)
—
XOR data XR! data
RLC reg
3-168
Table 3-9. Unused 8080A Operation Codes and Their Z80 Meanings
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
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.
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.
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-171
Examples:
RESET EQU
ORG RESET
RESET instruction sequence in mennory beginning at address
This sequence places the
0,
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
,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). ^
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.
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.
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
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.
We now summarize some useful information that you should keep In mind when
writing programs.
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.
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
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
plicit addresses.
8-Bit Addition
Purpose: Add the contents of memory locations 0040 and 0041. and place the result
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 :
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).
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
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
significant four bits of memory location 0041. Clear the most significant four
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:
SUB A
LD (40H),A ;CLEAR LOCATION 40
HALT
Object Program:
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).
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-
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)
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
(if carn/
= 1), the computer continues with the next sequential memory location after
the JR instruction.
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 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
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 :
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:
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
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).
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.
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 :
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
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
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)
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.
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
J^Yes
Conciuding
Section
i
^"^
C ]
1
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 :
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
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
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
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 :
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
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
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
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. 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)
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.
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
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
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
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;
20^ g - space
3F^g - ^ (question mark)
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
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:
The instruction INC B adds 1 to the string length counter in Register B. LD B,0 mitializes
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
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
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.
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?
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
Sample Problems:
a. (0042) - 37 7'
contain blanks.
(0041) = 00
6-8
Flowchart:
f Start "1
Pornter = 42
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" >
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.
f Start
I
Pointer = 41
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.
Sample Problems:
a. (0040) - 02
(0041) - 36 '6'
(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:
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:
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
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,
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
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.
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
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.
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.
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
Sample Problems:
a. (0040) = 04
(0041) = 37 7'
(0042) = 2E
(0043) = 38 '8'
(0044) = 31 'V
(0042)
~ 37 7'
== '1'
(0043) 31
Result: Unchanged, as number is assumed to be 671,
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'
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.
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 =
{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
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.''
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
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
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)
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..
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.
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
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
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
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-
ASCII to decimal conversion is necessary when decimal numbers are being entered
from an ASCII device like a teletypewriter or video terminal.
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
Sample Problems:
(0040) 02
(0041) 09
b. (0040) 07
(0041) 01
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).
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 |
(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.
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
.
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
Sample Problems:
'1'
a. (0042) - 31
(0043) =31 'V
(0044) = 30 '0'
(0045) - 31 'V
(0046) - 30 '0'
(0047) = 30 '0'
(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.
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
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
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
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/
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
8-4
Object Program:
Memorv Address Memorv Contents Instruction 1
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
8-6
Object Program:
+ 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)
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
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.
bits of the result Into memory location 0042 and the eight most
significant
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.
Step 1 - Initialization
Product ==
Counter = 8
8-8
Step 4 - Add Multiplicand to Product if Carry Is 1
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
Product 006F
Multiplier 84
Multiplicand 6F
Counter 06
Carry from Multiplier 1
Product 014D
Multiplier 08
Multiplicand 6F
Counter 05
Carry from Multiplier 1
Product 029A
Multiplier 10
Multiplicand 6F
Counter 04
Carry from Multiplier
Product 0534
Multiplier 20
Multiplicand 6F
Counter 03
Carry from Multiplier
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
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 |
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
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-
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.^
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)
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 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
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
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:
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
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
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 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:
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
':
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!).
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
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
1
'
\
\
F
V,..,.
1
1 2
] H F
(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
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?
This rule works because 1 is halfway between and 10 in binary, much as 5 ts halfway
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.
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
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
Sample Problemsi:
I
a. (0040) 03
(0041) = 00
(0042) 05
(0043)
„ OF
Result:
(0044) 00
(0045) 00
Result: (0043) OF
(0044) 5C
(0045) = 2B
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)
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.
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.
549321
the result will be:
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
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 .
Weissberger, A. J. and T. Toal, "Tough Mathematical Tasks Are Child's Play for
Number Cruncher." Electronics February 17, 1977, pp. 102-107.
,
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?
9-2
Object Program:
Memory Address Memory Contents Instruction 1
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)
wise.
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:
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.
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
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)
9-8
Flowchart:
f Start
J
(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
LD A,H
OR L
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
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
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
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.
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
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
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 ,
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
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
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 .
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.
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.
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 recursive if it calls itself. Such a subroutine clearly must also be re-
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.
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.
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:
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
. 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.
(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 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.
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.
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.
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
: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
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
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.
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.
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).
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
;SAMPLE CASE:
; INITIAL CONDITIONS: (HU^0041
: (A) (00411 = 32, (0042) = 33
= 2.
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
ORG
LD SP.80H START STACK AT LOCATION 0080
LD DE,60H GET STARTING ADDRESS OF STRING 1
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
ISUBROUTINE PMTCH
;FINAL CONDITIONS: IN A IF
: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.
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 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
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
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
Sample Problem:
(HL) = 0041
(0041) = 49
(0042) = 02 STX
(0043) = 47 'G*
(0044) = 4F '0'
(0045) = 03 ETX
Result: (A) = 02
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).
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'
(0051) = 4F '0'
(0052) = 47 'G'
(0060) =r 44 'D'
'0'
(0061) =r 4F
(0062) = 47 'G'
(A) :=03
(DE) = 0060
(HL) = 0050
(0050) = 43 'C
(0051) = 41 'A'
(0052) = 54 T
(0060) = 43 'C
(0061) - 55 'U'
(0062) = 54 T'
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
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.
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.
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.
been accepted. Note that the peripheral may be or contain another p rocessor.
The standard unclocked procedure the handshake. Here the
is | HANDSHAKE |
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
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
11-3
Data Inputs
Data
Outputs
IC=3
Port
Data inputs 1
c
Countra^ Data Inputs 3
Inputs
The CoimM' controb which mput tfw Whrttiptexer gates to ttw Input Ptfft.
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)
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.,
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
^
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
11-6
Output Ready
I/O
c Section
^ Peripheral
Peripheral Ready
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
Peripheral Ready
Output Ready
Data
I/O
CPU > Peripheral
:> Section
Penphera! Ready
d) CPU sends Output Ready signal to Penpheral (this may be a hardware connection).
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
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.
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.
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
Time Budget:
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.
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
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
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
^ )
11-13
Table 11-1. PtO Addresses
The port addresses assume that C/D SEL is tied to Ai and B/A SEL to Aq. |
REGISTER ADDRESSING
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
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).
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
(Binary) (Hex}
Output 00001111 OF
t Input 01001111 4F
2 Bidirectional 10001111 8F
3 Control 11001111 CF
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
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.
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
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.
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:
• 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.
11-19
4) Store the contents of memory location 0040 in Output r^ort 5.
11-20
6) Send the contents of memory locations 0040 through 0047 to Output Port 5.
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
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:
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:
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)
11-22
Flowchart:
c Start
:>
(0040) =
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:
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:
MASK depends on the bit to which the pushbutton Is connected; ft has a one m the
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
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
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:
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-
Circuit Diagram:
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:
2) Set a memory location to one when the state of the switch changes.
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.
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
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)?
HALT
Object Program:
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
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-
11-32
o-
^
o
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
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.
11-33
Table 11-3, Data Input vs. Switch Position
Data Input |
11111110 FE
1 11111101 FD
2 11111011 FB
3 11110111 F7
4 11101111 EF
5 11011111 DF
6 10111111 BF
7 01111111 7F
Purpose: The program waits for the switch to be m a specific position and then places
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.
Oi
741S148
8-to-3
Encoder Ao
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
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
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?
11-38
A
D
C
B
E
Object Program:
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.
A. Send a Logic One to the LED (turn a positive display on or a negative display off).
Source Program:
(form data initially)
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
11-41
Object Program:
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).
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
B2
^b
Bo Common
i 1
"S" + 5V
{Common- (Common-
87 may be used for decimal posnt LED. Cathode) Anode}
Circuit Diagram:
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.
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
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
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
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
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?
11-50
Object Program:
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
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
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:
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?
Sample Problem:
(0040) - 03 causes the program to wait 3 ms between readings.
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.
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
)
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.
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.
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:
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.
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.
11-59
Table 11-6.Companson Between independent Connections
and Matrix Connections for Keyboards
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
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
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
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.
11-61
Column Column 1 Coiumn 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)
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.
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:
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-
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.
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.
Flowchart:
f Start
J
Key Numt?er = - 1
Counter = Number
„ „ of rows
Scan Pattern =
11111110
Ground row by
output of
Scan Pattern
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
11-66
A
D
B
F
E
Object Program:
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.
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
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
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 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
Source Program:
1
11-70
A
Object Program:
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.
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
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
-WVH^
CO
"W^>
^^t^wsm;
^
BO
(H^^HM^^il
11-73
Data 8us Analog
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:
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.
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
85 B2 Valid Conversron
i\
t
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:
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:
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:
11-80
Pantv Stop Stop
Bit Sit Bit
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:
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.
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
11-81
r Start
J
received parity ?)
Count = 8
Wait one bit time
Data =
End
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)
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:
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
( '- )
r*
»"f
Semi data to
Output Port
t
Shift data nght
circularlv with Carry
Carry = 1 (Stop bit)
Count = Count - 1
No
^T Count
^^
C ^"^ 3
Purpose: Transmit data to a teletypewriter through bit of a PIO data register. The
data is in memory location 0060.
The transmission routine must wait one bit time between each operation.
11-
Source Program: (Assume that parity need not be generated)
Object l*rogram:
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
1 1 Ability to handle various bit lengths (usually 5 to 8), parity options, and numbers of
2) indicators for framing errors, parity errors, and "overrun errors" (failure to read a
character before another one is received).
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
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
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
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
Null Cofto
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
• WAfT/REAOY on R/T
• WArr FN/READY FN
WAIT/READY Enable
.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
Write Register 4
1
n SYNC Modes
1
Enable
Stop Bit/Character
Parity Enable
- Parity Even/Odd
1 1 2 Stop Bits/Character
x1 Clock Mode
1 x16 Clock Mode
1 x32 Clock Mode
1 1 x64 Ctock Mode
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
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 14
-SYNC Bit 15 ,
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
Parity Error
Special Rx
- Rx Ovenain Enror
Condition
• CRC/Frammg En-or
Interrupts
" Bid of Frame (SDLC)
11-95
Read Register 2 (Channel B Oniy}
D2 DO
ii ii a ii
I >
(ntemipt
Vector
11-96
Note the foNowing special features of the SIO:
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:
11-99
The program establishes Write Register 4 as follows:
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:
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
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:
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
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^^^
Sample Problem:
Readings are (hex) 86, 89. 81, 84
Result: (0040) = 85
11-104
REFERENCES
1. Barnes, J., and V Gregory. "Use Microcomputers to Enhance Perfornnance with
Noisy Data," EDN, August 20. 1976, pp. 71-72.
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-
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 ,
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
.
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.
—
.
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,
,
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.
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
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
»
a special way to handle tow-priority interrupts that may be ignored for long periods of
time.
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
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
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
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,
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).
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-
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.
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:
as follows:
Mode 2 is designed to work with Z80 PIOs, SIOs, and CTCs. PIO and StO interrupts are
described later in this chapter.
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
high-order
/ Starting
Address
: Table
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.
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
LD AJVECT
OUT (PIOCRI.A
12-6
D7 D6 05 D4 D3 D2 D1 DO
D7 D6 D5 D4 D3 D2 D1 DO
0n}y those port lines whose mask bit iS zero will be monitored for generating an interrupt.
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:
3) Interrupting control port with vector located at address 48i6- An interrupt will^ be
generated if data tines A4 and Ay both go low. ^, ^
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.
Obviously a repeated Block Output instruction could be used to shorten these programs
considerably.
!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;
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.
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
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
V3 V2 VI
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.
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,
Flowchart:
CZEZ)
Initialize Stack Pointer
Enable startup
interrupt on PiO
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:
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.
12-13
You can include the loading of memon/ iocations USRINT and USRINT+1 in your nnatn
progrann; i.e.,
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
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
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-
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-
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.
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.
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.
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
12-17
Flowchart:
c Start
D
I
Stack Pointer
tnitiatize
I
Enable printer
interrupt on PtO
Data =(40)
T
Enable CPU intemipt
,
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
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
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
12-19
)
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?
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.
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
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
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
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
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:
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
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!
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
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.
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
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
WRITE REGISTER 4
Bit 7 = 0, bit 6 = 1 for X1 6 clock mode
Bit 1 =0 to select odd parity
WRITE REGISTER 3
Bit 7 = 0. bit 6 = 1 to select 7-bit characters
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.
Source Program:
Main Program:
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
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
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
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:
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,
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
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.
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
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.
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.
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.
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.
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
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
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.
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.
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:
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?
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.
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.
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,
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.
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
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-
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 designer must also consider the effects of equipment failure. Just as before,
• 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.
13-10
Keyboard Keyboai^ Strobe
Input Port
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
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.
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.
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.
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.
• 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
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.
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:
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,
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
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.
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
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)
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.
1) Flowcharts are difficult to design, draw, or change in all except the simplest situa-
tions.
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.
13-19
Turn light on
C J
Figure 13-8. Flowchart of One-Second Response to a Switch
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
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 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
Key = Keyboard
Input Data
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
C Send
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:
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,
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.
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
4) Two modules inwhich the first is used by many other modules and the second is
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.
• 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.
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:
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.
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.
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)
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
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
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,
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
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.
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.
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.
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.
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.
HIADDRESS =
LOADDRESS=0
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
if LOADDRBUTTON - 1 then
begin
LOADDRESS = SWITCHES
LIGHTS= SWITCHES
do
DELAY (DEBOUNCE TIME)
until LOADDRBUTTON 9^1
end
if DATABUTTON = 1 then
begin
DATA = SWITCHES
LIGHTS - SWITCHES
(HIADDRESS. LOADDRESS) = DATA
do
DELAY (DEBOUNCE TIME)
until DATABUTTON 9^1
end
end
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
ENTRYiNKEYS) =0 *
end
NKEYS = 10
ENTRY{NKEYS)-0
end
13-38
)
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:
NKEYS = 10
KEY = CLEAR
ENTRY(NKEYS) =0
end
end
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:
HFLAG =
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.
HFLAG =
ADDRMATCH =
ADDRCTR =
end
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.
HFLAG =
ADDRMATCH -
ADDRCTR =
NMESS =
end
ADDRCTR - ADDRCTR + 1
end
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.
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.
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.
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, "
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.
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:
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
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.
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
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
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.
13-48
)
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.
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.
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
.
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.
1976. "
Halstead, M. H.. Elements of Software Science, American Elsevier. New York, 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. .
L.. "A Technique for the Specification of Software Modules with Examples,"
Parnas. D.
Communications of the ACM May 1973, pp. 330-336. .
Ulrickson. R. W.. "Software Modules Are the Building Blocks," Electronic Design.
February 1. 1977, pp. 62-66.
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.
• 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
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.
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:
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
Data Pointer =
Data Pointer - 1
as 2 hex digits
COUNT = COUNT -t
fixim Stack
C J
Figure 14-Z Flowchart of Register Dump Program
14-4
: PLACE ALL CPU REGISTER CONTENTS !N STACK (PC ALREADY ON STACK)
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
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.
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
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.
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.
fvlany variations of both these tools exist, and we shall discuss only the standard
features.
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:
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.
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.
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.
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.
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.
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-
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-
checklist provides a starting place If you didn't use it earlier; some of the errors
that you may not have eliminated are:
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.
Make sure that no Jump instructions transfer control back to initialization state-
ments.
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-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.
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
)
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:
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).
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.
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.
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):
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:
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 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.
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:
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:
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
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);
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;
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) = 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.,
(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,
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:
(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
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
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:
(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.
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
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 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.^
14-30
REFERENCES
1. For more information about logic analyzers, see:
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.
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
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.
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
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
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.
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.
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
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
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.
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.
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.
;MULTIPRECISION ADDITION
2) What parameters are necessary? How and in what form must thev be supplied?
15-4
3) What operations does the program perform?
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
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:
second device with one stop bit (we will have to change subroutine BITDLY). Try mak-
ing the changes before looking at the listing.
• 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.
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
Data Memory |
The map may also list additional entry points and include a specific description of the
Give each parameter that might change a name and include it in the lists. Such
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
. I/O UNITS
;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
;DEFtNITIONS
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
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.
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:
15-11
Listing:
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
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 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
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
9. Luke, Y L., Alg orithms for the Computation of Mathematical Functions, Academic
Press, New York. 1977
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.
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 .
Keyboard
Driver Driver
(PIO A,
{ieft) (right)
Port A)
2
'4'. '/.
3 'GO'
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
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
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
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.
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).
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)
KEYBOARD
DISPLAYS
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
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
;DEFiNmONS
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
ORG
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
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?
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
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
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
YBOAR D COLUMNS S
16-13
B 1
KEYBOARD TABLE
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
At
Ao Common
Analog Input- to
-T"
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
Rf + 68 kn
Rj has a minimum value of 34 kH (T=50X. see Figure 16-4} so full scale is 10 Volt.
16-17
1000 OOOi
T(*C) R {OhmJ
365 000
25 100 000
50 34 000
100 6000
"O-^.
^>
25
Temperature C^)
16-18
General Program Flowchart-
C ^- )
i
tnlti^ization
»—
t
Send Start
Conversion signal
to A/D converter
Wat 1ms
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.
reason to speed the conversion process. Clearly, interrupts could be used with
BUSY tied to the P!0 STROBE tine.
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
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-
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
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)
;A/D CONVERTER
;DISPLAYS
: 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
16-24
BEGIN EQU BOH ;STARTING ADDRESS OF MAIN PROGRAM
LASTM EQU 1000H :STARTING ADDRESS FOR RAM STACK
;DEF!NmONS
ORG
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
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
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
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
16-29
Index of Instruction Descriptions
Index (Continued)
xw//
index (Continued)
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