Programming The z80 3rd Edition
Programming The z80 3rd Edition
"Z80" is a registered trademark of ZILOG Inc., with whom SYBEX is not connected in any way. Cover Design by Daniel le Noury Every effort has been made to supply complete and accurate information. However, Sybex assumes no responsibility for its use; nor any infringements of patents or other nghts of third parties which would result. No license is granted by the equipment manufacturers under any patent or patent nghts. Manufacturers reserve the right to change circuitry at any time without notice. In particular, technical characteristics and prices are subject to rapid change. Comparisons and evaluations are presented for their educational value and for guidance principles. The reader is referred to the manufacturer's data for exact specifications. Copyright C)1980, SYBEX Inc. World rights reserved. No part of this publication may be stored in a retrieval system, transmitted, or reproduced in any way, including but not limited to, photocopy, photograph, or magnetic or other record, without the prior written permission of the publisher. Library of Congress Card Number: 80-5468 ISBN: 0-89588-094-6 First Edition published 1979. Third Edition 1981 Printed in the United States of America Pnnting 10 9 8 7 6 5 4 3
ACKNOWLEDGEMENTS
Designing a programming textbook is always difficult. Designing it so that it will teach elementary programming as well as advanced concepts while covering both hardware and software aspects makes it a challenge. The author would like to acknowledge here the many constructive suggestions for improvements or changes made by: O.M. Barlow, Dennis L. Feick. Richard D. Reid, Stanley E. Erwin, Philip Hooper, Dennis B. Kitsz, R. Ratke, and Jim Crocker. A special acknowledgement is also due to Chris Williams for his contribution to the instruction-set and the data structures section. Any additional suggestions for improvements or changes should be sent to the author, and will be reflected in forthcoming editions. Several tables in Chapter Four showing hexadecimal codes for the Z80 instructions have been repnnted by permission of Zilog Inc. Tables 2.26 and 2.27 have been reprinted by permission of Intel Corporation.
TABLE OF CONTENTS
13 15
H.
46
Introduction, System Architecture, Internal Organization of the Z80, Instruction Formats, Execution of Instructions with the Z80, Hardware Summary
94
Introduction, Arithmetic Programs, BCD AnthmeticMultiplication, Binary Division, Instruction Summary, Subroutines, Summary
IV.
154
V.
ADDRESSING TECHNIQUES
438
Introduction, Possible Addressing Modes, Z80 Addressing Modes, Using the Z80 Addressing Modes, Summary
VI.
INPUT/OUTPUT TECHNIQUES
460
Introduction, Input/output, Parallel Word Transfer, Bit Serial Transfer, Peripheral Summary, Input/Output Scheduling, Summary
511
Introduction, The Standard P10, The Internal Control Register, Programming a P10, The Zilog Z80 PIO
520
Introduction, Clearing a Section of Memory, Polling I/O Devices, Getting Characters In, Testing A Character, Bracket Testing, Parity Generation, Code Conversion: ASCII to BCD, Convert Hex to ASCII, Finding the Largest Element of a Table. Sum of N Elements, A Checksum Computation, Count the Zeroes, Block Transfer, BCD Block Transfer, Compare Two Signed 16-bit Numbers, Bubble-Sort, Summary
IX.
DATA STRUCTURES
539
PART ITHEORY Introduction, Pointers. Lists, Searching and Sorting, Section Summary PART 2DESIGN EXAMPLES Introduction, Data Representation for the List. A Simple List. Alphabetic Set. Linked List, Summary
X.
PROGRAM DEVELOPMENT
579
Introduction, Basic Programming Chokes, Software Support, The Program Development Sequence, Hardware Alternatives, The Assembler, Conditional Assembly, Summary
XI. CONCLUSION
Technological Development, The Next Step
602
APPENDIX A
Hexadecimal Conversion Table
APPENDIX B
ASCII Conversion Table
APPENDIX C
Relative Branch Tables
APPENDIX D
Decimal to BCD Conversion
APPENDIX E
Z80 Instruction Codes
APPENDIX F
Z80 to 8080 Equivalence
APPENDIX G
8080 to Z80 Equivalence
INDEX
PREFACE
This book has been designed as a complete self-contained text for learning programming, using the Z80. It can be used by a person who has never programmed before, and should also be of value to anyone using the Z80. For the person who has already programmed, this book will teach specific programming techniques using (or working around) the specific characteristics of the Z80. This text covers the elementary to intermediate techniques required to start programming effectively. This text aims at providing a true level of competence to the person who wishes to program using this microprocessor. Naturally, no book will effectively teach how to program, unless one actually practices. However, it is hoped that this book will take the reader to the point where he feels that he can start programming by himself and can solve simple or even moderately complex problems using a microcomputer. This book is based on the author's experience in teaching more than 1000 persons how to program microcomputers. As a result, it is strongly structured. Chapters normally go from the simple to the complex. For readers who have already learned elementary programming, the introductory chapter may be skipped. For others who have never programmed, the final sections of some chapters may require a second reading. The book has been designed to take the reader systematically through all the basic concepts and techniques required to build increasingly, complex programs. It is, therefore, strongly suggested that the ordering of the chapters be followed. In addition, for effective results, it is important that the reader attempt to solve as many exercises as possible. The difficulty within the exercises has been carefully graduated. They are designed to verify that the material which has been presented is really understood. Without doing the programming exercises, it will not be possible to realize the full value of this book as an educational medium. Several of the exercises may require time, such as the multiplication exercise. However, by doing them, you will actually program and learn by doing. This is indispensable. For those who have acquired a taste for programming when reaching the end of this volume, a companion volume is planned: the Z80 Applications Book.
13
Other books in this series cover programming for other popular microprocessors. For those who wish to develop their hardware knowledge, it is suggested that the reference books From Chips to Systems: an Introduction to Microprocessors (ref. C201A) and Microprocessor Interfacing Techniques (ref. C207) be consulted. The contents of this book have been checked carefully and are believed to be reliable. However, inevitably, some typographical or other errors will be found. The author will be grateful for any comments by alert readers so that future editions may benefit from their experience. Any other suggestions for improvements, such as other programs desired, developed, or found of value by readers, will be appreciated.
14
1 BASIC CONCEPTS
INTRODUCTION This chapter will introduce the basic concepts and definitions relating to computer programming. The reader already familiar with these concepts may want to glance quickly at the contents of this chapter and then move on to Chapter 2. It is suggested, however, that even the experienced reader look at the contents of this introductory chapter. Many significant concepts are presented here including, for example, two's complement, BCD, and other representations. Some of these concepts may be new to the reader; others may improve the knowledge and skills of experienced programmers. WHAT IS PROGRAMMING? Given a problem, one must first devise a solution. This solution, expressed as a step-by-step procedure, is called an algorithm. An algorithm is a step-by-step specification of the solution to a given problem. It must terminate in a finite number of steps. This algorithm may be expressed in any language or symbolism. A simple example of an algorithm is: 1insert key in the keyhole 2turn key one full turn to the left 3seize doorknob 4turn doorknob left and push the door
15
At this point, if the algorithm is correct for the type of lock involved, the door will open. This four-step procedure qualifies as an algorithm for door opening. Once a solution to a problem has been expressed in the form of an algorithm, the algorithm must be executed by the computer. Unfortunately, it is now a well-established fact that computers cannot understand or execute ordinary spoken English (or any other human language). The reason lies in the syntactic ambiguity of all common human languages. Only a well-defined subset of natural language can be "understood" by the computer. This is called a programming language. Converting an algorithm into a sequence of instructions in a programming language is called programming. To be more specific, the actual translation phase of the algorithm into the programming language is called coding. Programming really refers not just to the coding but also to the overall design of the programs and "data structures" which will implement the algorithm. Effective programming requires not only understanding the possible implementation techniques for standard algorithms, but also the skillful use of all the computer hardware resources, such as internal registers, memory, and peripheral devices, plus a creative use of appropriate data structures. These techniques will be covered in the next chapters. Programming also requires a strict documentation discipline, so that the programs are understandable to others, as well as to the author. Documentation must be both internal and external to the program. Internal program documentation refers to the comments placed in the body of a program, which explain its operation. External documentation refers to the design documents which are separate from the program: written explanations, manuals, and flowcharts. FLOWCHARTING One intermediate step is almost always used between the algorithm and the program. It is called a flowchart. A flowchart is simply a symbolic representation of the algorithm expressed as a sequence of rectangles and diamonds containing the steps of the algorithm. Rectangles are used for commands, or "executable statements." Diamonds are used for tests such as: If information
16
BASIC CONCEPTS X is true, then take action A, else B. Instead of presenting a formal definition of flowcharts at this point, we will introduce and discuss flowcharts later on in the book when we present programs. Flowcharting is a highly recommended intermediate step between the algorithm specification and the actual coding of the solution. Remarkably, it has been observed that perhaps 10% of the programming population can write a program successfully without having to flowchart. Unfortunately, it has also been observed that 90% of the population believes it belongs to this 10%! The result: 80% of these programs, on the average, will fail the first time they are run on a computer. (These percentages are naturally not meant to be accurate.) In short, most novice programmers seldom see the necessity of drawing a flowchart. This usually results in "unclean" or erroneous programs. They must then spend a long time testing and correcting their program (this is called the
START
1
READ ACTUAL ROOM TEMPERATURE Hi' FROM THERMOMETER OR OTHER SENSOR
(OPTIONAL DELAY)
(OPTIONAL DELAY)
17
debugging phase). The discipline of flowcharting is therefore highly recommended in all cases. It will require a small amount of additional time prior to the coding, but will usually result in a clear program which executes correctly and quickly. Once flowcharting is well understood, a small percentage of programmers will be able to perform this step mentally without having to do it on paper. Unfortunately, in such cases the programs that they write will usually be hard to understand for anybody else without the documentation provided by flowcharts. As a result, it is universally recommended that flowcharting be used as a strict discipline for any significant program. Many examples will be provided throughout the book. INFORMATION REPRESENTATION All computers manipulate information in the form of numbers or in the form of characters. Let us examine here the external and internal representations of information in a computer. INTERNAL REPRESENTATION OF INFORMATION All information in a computer is stored as groups of bits. A bit stands for a binary digit("0" or "I"). Because of the limitations of conventional electronics, the only practical representation of information uses two-state logic (the representation of the state "0" and "I"). The two states of the circuits used in digital electronics are generally "on" or "off", and these are represented logically by the symbols "0" or "I". Because these circuits are used to implement "logical" functions, they are called "binary logic." As a result, virtually all information-processing today is performed in binary format. In the case of microprocessors in general, and of the Z80 in particular, these bits are structured in groups of eight. A group of eight bits is called a byte. A group of four bits is called a nibble. Let us now examine how information is represented internally in this binary format. Two entities must be represented inside the computer. The first one is the program, which is a sequence of instructions. The second one is the data on which the program will operate, which may include numbers or alphanumeric text. We will discuss below three representations: program, numbers, and alphanumerics.
18
BASIC CONCEPTS Program Representation All instructions are represented internally as single or multiple bytes. A so-called "short instruction" is represented by a single byte. A longer instruction will be represented by two or more bytes. Because the Z80 is an eight-bit microprocessor, it fetches bytes successively from its memory. Therefore, a single-byte instruction always has a potential for executing faster than a twoor three-byte instruction. It will be seen later that this is an important feature of the instruction set of any microprocessor and in particular the Z80, where a special effort has been made to provide as many single-byte instructions as possible in order to improve the efficiency of the program execution. However, the limitation to 8 bits in length has resulted in important restrictions which will be outlined. This is a classic example of the compromise between speed and flexibility in programming. The binary code used to represent instructions is dictated by the manufacturer. The Z80, like any other microprocessor, comes equipped with a fixed instruction set. These instructions are defined by the manufacturer and are listed at the end of this book, with their code. Any program will be expressed as a sequence of these binary instructions. The Z80 instructions are presented in Chapter 4. Representing Numeric Data Representing numbers is not quite straightforward, and several cases must be distinguished. We must first represent integers, then signed numbers, i.e., positive and negative numbers, and finally we must be able to represent decimal numbers. Let us now address these requirements and possible solutions. Representing integers may be performed by using a direct binary representation. The direct binary representation is simply the representation of the decimal value of a number in the binary system. In the binary system, the right-most bit represents 2 to the power 0. The next one to the left represents 2 to the power 1, the next represents 2 to the power 2, and the left-most bit represents 2 to the power 7 = 128. b,b6b,b,bab2b,b represents b,2' + 1).26 + 13525 + b,2' + 6,21 + 6222 + b,2' + ba
19
PROGRAMMING THE Z80 The powers of 2 are: 2 = 128, 26 = 64, 25 = 32, T = 16, T = 8, 2 = 4, 2' = 2, 2 = 1 The binary representation is analogous to the decimal representation of numbers, where "123" represents: 1 X 100 = 100 + 2 X 10= 20 +3X1=3 = 123 Note that 100 = 102, 10 = 10', 1 = 10. In this "positional notation," each digit represents a power of 10. In the binary system, each binary digit or "bit" represents a power of 2, instead of a power of 10 in the decimal system. Example: "00001001" in binary represents: 1X 1 0X 2 0X 4 1X 8 0 X 16 0 X 32 0 X 64 0 X 128 in decimal: "10000001" represents: 1X 1= 1 0 X 2= 0 0X 4= 0 0X 8= 0 0 X 16= 0 0 X 32= 0 0 X 64= 0 1 X 128 = 128 in decimal: = 129 "10000001" represents, therefore, the decimal number 129. 20 =1 =0 =0 =8 =0 =0 =0 =0 =9 (2) (2') (29 (29 (21 (29 (2) (21
BASIC CONCEPTS By examining the binary representation of numbers, you will understand why bits are numbered from 0 to 7, going from right to left. Bit 0 is "b." and corresponds to 2. Bit 1 is "b," and corresponds to 2', and so on.
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 31
Binary 00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000 00001001 00001010 00001011 00001100 00001101 00001110 00001111 00010000 00010001
Decimal 32 33 63 64 65
00011111
The binary equivalents of the numbers from 0 to 255 are shown in Fig. 1-2. Exercise 1.1: What is the decimal value of "11111100"?
21
PROGRAMMING THE Z80 Decimal to Binary Conversely, let us compute the binary equivalent of "11" decimal: 11 .+.2 =5 remains 1 el (LSB) 5-2=2 remains 1 --dol 2+2=1 remains 0 .0 1+2=0 remains 1 0.1 (MSB) The binary equivalent is 1011 (read right-most column from bottom to top). The binary equivalent of a decimal number may be obtained by dividing successively by 2 until a quotient of 0 is obtained. Exercise 1.2: What is the binary for 257? Exercise 1.3: Convert 19 to binary, then back to decimal. Operating on Binary Data The arithmetic rules for binary numbers are straightforward. The rules for addition are: 0+0= 0 0+1= 1 1 1+0= 1+1=(I) 0 where (1) denotes a "carry" of 1 (note that "10" is the binary equivalent of "2" decimal). Binary subtraction will be performed by "adding the complement" and will be explained once we learn how to represent negative numbers. Example: (2) +(1) =(3) 10 +01 11
Addition is performed just like in decimal, by adding columns, from right to left: Adding the right-most column: 10 +01 (0 + 1 = 1. No carry.) 22
(1 + 0 =1. No carry.)
Exercise 1.4: Compute 5 + 10 in binary. Verify that the result is 15. Some additional examples of binary addition: 0010 +0001 =0011 (2) (1) (3) 0011 +0001 =0100 (3) (1) (4)
This last example illustrates the role of the carry. Looking at the right-most bits: 1 + 1 = (1) 0 A carry of 1 is generated, which must be added to the next bits: 001 column 0 has just been added +000 + 1 (carry) = (1)0 where (1) indicates a new carry into column 2. The final result is: 0100 Another example: 0111 +0011 1010 (7) + (3) =(10)
In this example, a carry is again generated, up to the left-most column. Exercise 1.5: Compute the result of 1111 +0001 =9 23
With eight bits, it is therefore possible to represent directly the numbers "00000000" to "11111111," i.e., "0" to "255". Two obstacles should be visible immediately. First, we are only representing positive numbers. Second, the magnitude of these numbers is limited to 255 if we use only eight bits. Let us address each of these problems in turn.
Signed Binary
In a signed binary representation, the left-most bit is used to indicate the sign of the number. Traditionally, "0" is used to denote a positive number while "1" is used to denote a negative number. Now "11111111" will represent 127, while "01111111" will represent +127. We can now represent positive and negative numbers, but we have reduced the maximum magnitude of these numbers to 127. Example: "0000 0001" represents +1 (the leading "0" is "+", followed by "000 0001" = 1). "1000 0001" is 1 (the leading "1" is ""I.
Exercise 1.6: What is the representation of "-5" in signed binary?
Let us now address the magnitude problem: in order to represent larger numbers, it will be necessary to use a larger number of bits. For example, if we use sixteen bits (two bytes) to represent numbers, we will be able to represent numbers from 32K to +32K in signed binary (1K in computer jargon represents 1,024). Bit 15 is used for the sign, and the remaining 15 bits (bit 14 to bit 0) are used for the magnitude: 2'5 = 32K. If this magnitude is still too small, we will use 3 bytes or more. If we wish to represent large integers, it will be necessary to use a larger number of bytes internally to represent them. This is why most simple BASICs, and other languages, provide only a limited precision for integers. This way, they can use a shorter internal format for the numbers which they manipulate. Better versions of BASIC, or of these other languages, provide a larger number of significant decimal digits at the expense of a large number of bytes for each number. Now let us solve another problem, the one of speed efficiency. We are going to attempt performing an addition in the signed 24
BASIC CONCEPTS
binary representation which we have introduced. Let us add " 5" and "+7". +7 is represented by 00000111 5 is represented by 10000101 The binary sum is: 10001100, or 12
This is not the correct result. The correct result should be +2. In order to use this representation, special actions must be taken, depending on the sign. This results in increased complexity and reduced performance. In other words, the binary addition of signed numbers does not "work correctly." This is annoying. Clearly, the computer must not only represent information, but also perform arithmetic on it. The solution to this problem is called the two's complement representation, which will be used instead of the signed binary representation. In order to introduce two's complement let us first introduce an intermediate step: one's complement. One's Complement In the one's complement representation, all positive integers are represented in their correct binary format. For example " +3" is represented as usual by 00000011. However, its complement " 3" is obtained by complementing every bit in the original representation. Each 0 is transformed into a 1 and each 1 is transformed into a 0. In our example, the one's complement representation of " 3" will be 11111100. Another example: +2 is 00000010 2 is 11111101 Note that, in this representation, positive numbers start with a "0" on the left, and negative ones with a "1" on the left. Exercise 1.7: The representation of "+6" is "00000110". What is the representation of "-6" in one's complement? As a test, let us add minus 4 and plus 6:
25
PROGRAMMING THE Z80 4 is 11111011 +6 is 00000110 (1) 00000001 where (1) indicates a carry
The "correct result" should be "2", or "00000010". Let us try again: 3 is 11111100 2 is 11111101 (1) 11111.001
or " 6." plus a carry. The correct result should be " ." The representation of " 5" is 11111010. It did not work. This representation does represent positive and negative numbers. However the result of an ordinary addition does not always come out "correctly." We will use still another representation. It is evolved from the one's complement and is called the two's complement representation. Two's Complement Representation In the two's complement representation, positive numbers are still represented, as usual, in signed binary, just like in one's complement. The difference lies in the representation of negative numbers. A negative number represented in two's complement is obtained by first computing the one's complement, and then adding one. Let us examine this in an example: +3 is represented in signed binary by 00000011. Its one's complement representation is 11111100. The two's complement is obtained by adding one. It is 11111101. Let us try an addition: (3) +(5) =(8) The result is correct 00000011 +00000101 =00001000
26
=11111110 Let us identify the result by computing the two's complement: 00000001 the one's complement of 11111110 is Adding 1 + 1 therefore the two's complement is 00000010 or +2 Our result above, "11111110" represents "-2". It is correct. We have now tried addition and subtraction, and the results were correct (ignoring the carry). It seems that two's complement works! Exercise 1.8: What is the two's complement representation of "+127"? Exercise 1.9: What is the two's complement representation of '128"? Let us now add +4 and 3 (the subtraction is performed by adding the two's complement): +4 is 00000100 3 is 11111101 The result is: (1) 00000001 If we ignore the carry, the result is 00000001, i.e., "1" in decimal. This is the correct result. Without giving the complete mathematical proof, let us simply state that this representation does work. In two's complement, it is possible to add or subtract signed numbers regardless of the sign. Using the usual rules of binary addition, the result comes out correctly, including the sign. The carry is ignored. This is a very significant advantage. If it were not the case, one would have to correct the result for sign every time, causing a much slower addition or subtraction time. For the sake of completeness, let us state that two's complement is simply the most convenient representation to use for simpler processors such as microprocessors. On complex processors, other representations may be used. For example, one's complement may be used, but it requires special circuitry to "correct the result." 27
PROGRAMMING THE Z80 From this point on, all signed integers will implicitly be represented internally in two's complement notation. See Fig. 1.3 for a table of two's complement numbers. Exercise 1.10: What are the smallest and the largest numbers which one may represent in two's complement notation, using only one byte? Exercise 1.11: Compute the two's complement of 20. Then compute the two's complement of your result. Do you find 20 again? The following examples will serve to demonstrate the rules of two's complement. In particular, C denotes a possible carry (or borrow) condition. (It is bit 8 of the result.) V denotes a two's complement overflow, i.e., when the sign of the result is changed "accidentally" because the numbers are too large. It is an essentially internal carry from bit 6 into bit 7 (the sign bit). This will be clarified below. Let us now demonstrate the role of the carry "C" and the overflow The Carry C Here is an example of a carry: (128) +(129) where (1) indicates a carry. The result requires a ninth bit (bit "8", since the right-most bit is "0"). It is the carry bit. If we assume that the carry is the ninth bit of the result, we recognize the result as being 100000001 = 257. However, the carry must be recognized and handled with care. Inside the microprocessor, the registers used to hold information are generally only eight-bit wide.When storing the result, only bits 0 to 7 will be preserved. A carry, therefore, always requires special action: it must be detected by special instructions, then processed. Processing the carry means either storing it somewhere (with a special instruction), or ignoring it, or deciding that it is an error (if the largest authorized result is "11111111"). 28 10000000 +10000001
BASIC CONCEPTS
2's complement +_ code +127 +126 +125 01111111 01111110 01111101 128 127 126 125 65 64 63 33 32 31 17 16 15 14 13 12 11 10 9 8 7 6 3 4 3 2 1
2's complement code 10000000 10000001 10000010 10000011 10111111 11000000 11000001 11011111 11100000 11100001 11101111 11110000 11110001 11110010 11110011 11110100 11110101 11110110 11110111 11111000 11111001 11111010 11111011 11111100 11111101 11111110 11111111
01000001 01000000 00111111 00100001 00100000 00011111 00010001 00010000 00001111 00001110 00001101 00001100 00001011 00001010 00001001 00001000 00000111 00000110 00000101 00000100 00000011 00000010 00000001 00000000
. ..
+33 +32 +31 +17 +16 +15 +14 +13 +12 +11 +10 +9 +8 +7 +6 +5 +4 +3 +2 +1 +0
29
Here is an example of overflow: bit 6 bit 7H (64) +(65) =10000001 =( 127) An internal carry has been generated from bit 6 into bit 7. This is called an overflow. The result is now negative, "by accident." This situation must be detected, so that it can be corrected. Let us examine another situation: 11111111. (-1) +1111111.1 +(-1) =(1) 11111110 =( 2) carry In this case, an internal carry has been generated from bit 6 into bit 7, and also from bit 7 into bit 8 (the formal "Carry" C we have examined in the preceding section). The rules of two's complement arithmetic specify that this carry should be ignored. The result is then correct. This is because the carry from bit 6 into bit 7 did not change the sign bit. This is not an overflow condition. When operating on negative numbers, the overflow is not simply a carry from bit 6 into bit 7. Let us examine one more example. 11000000 +10111111 =(1) 01111111 carry (-64) (-65) (+127) 01000000 +01000001
This time, there has been no internal carry from bit 6 into bit 7, but there has been an external carry. The result is incorrect, as bit 7 has been changed. An overflow condition should be indicated.
30
BASIC CONCEPTS Overflow will occur in four situations: 1adding large positive numbers 2adding large negative numbers 3subtracting a large positive number from a large negative number 4subtracting a large negative number from a large positive number. Let us now improve our definition of the overflow: Technically, the overflow indicator, a special bit reserved for this purpose, ancrcalled a "flag," will be set when there is a carry from bit 6 into bit 7 and no external carry, or else when there is no carry from bit 6 into bit 7 but there is an external carry. This indicates that bit 7, i.e., the sign of the result, has been accidentally changed. For the technically-minded reader, the overflow flag is set by Exclusive ORing the carry-in and carry-out of bit 7 (the sign bit). Practically every microprocessor is supplied with a special overflow flag to automatically detect this condition, which requires corrective action. Overflow indicates that the result of an addition or a subtraction requires more bits than are available in the standard eight-bit register used to contain the result. The Carry and the Overflow The carry and the overflow bits are called "flags." They are provided in every microprocessor, and in the next chapter we will learn to use them for effective programming. These two indicators are located in a special register called the flags or "status" register. This register also contains additional indicators whose function will be clarified in Chapter 4. Examples Let us now illustrate the operation of the carry and the overflow in actual examples. In each example, the symbol V denotes the overflow, and C the carry. If there has been no overflow, V = 0. If there has been an overflow, V = 1 (same for the carry C). Remember that the rules of two's complement specify that the carry be ignored. (The mathematical proof is not supplied here.)
31
= 00001110 (+14) V:0 (CORRECT) Positive-Positive with Overflow + 01111111 (+127) 00000001 (+1)
C:0
The above is invalid because an overflow has occurred. (ERROR) Positive-Negative (result positive) + 00000100 (+4) 11111110 (-2) V:0 C:1 (disregard)
= 11111110 (-21 V:0 (CORRECT) Negative-Negative + 11111110 (-21 11111100 (-4) V:0
C:1 (disregard)
Negative-Negative with Overflow + 10000001 (-127) 11000010 (-62) (67) V:1 C:1
=(1)01000011 (ERROR) 32
BASIC CONCEPTS This time an "underflow" has occurred, by adding two large negative numbers. The result would be 189, which is too large to reside in eight bits. Exercise 1.12: Complete the following additions. Indicate the result, the carry C, the overflow V, and whether the result is correct or not: 10111111 +11000001 (_.) 11111010 1_1 +11111001 ( = V C K CORRECT K ERROR 01111110 (_) +00101010 (._) = V C _ K CORRECT K ERROR
Exercise 1.13: Can you show an example of overflow when adding a positive and a negative number? Why? Fixed Format Representation Now we know how to represent signed integers. However, we have not yet resolved the problem of magnitude. If we want to represent larger integers, we will need several bytes. In order to perform arithmetic operations efficiently, it is necessary to use a fixed number of bytes rather than a variable one. Therefore, once the number of bytes is chosen, the maximum magnitude of the number which can be represented is fixed. Exercise 1.14: What are the largest and the smallest numbers which may be represented in two bytes using two's complement? The Magnitude Problem When adding numbers we have restricted ourselves to eight bits because the processor we will use operates internally on eight bits at a time. However, this restricts us to the numbers in the range 128 to +127. Clearly, this is not sufficient for many applications. Multiple precision will be used to increase the number of digits which can be represented. A two-, three-, or N-byte format may 33
PROGRAMMING THE Z80 then be used. For example, let us examine a 16-bit, "double-precision" format: 00000000 00000000 00000000 00000001 is "0" is "1"
is "32767" 11111111 01111111 is " 1" 11111111 11111111 is " 2" 11111110 11111111 Exercise 1.15: What is the largest negative integer which can be represented in a two's complement triple-precision format? However, this method will result in disadvantages. When adding two numbers, for example, we will generally have to add them eight bits at a time. This will be explained in Chapter 3 (Basic Programming Techniques). It results in slower processing. Also, this representation uses 16 bits for any number, even if it could be represented with only eight bits. It is, therefore, common to use 16 or perhaps 32 bits, but seldom more. Let us consider the following important point: whatever the number of bits N chosen for the two's complement representation, it is fixed. If any result or intermediate computation should generate a number requiring more than N bits, some bits will be lost. The program normally retains the N left-most bits (the most significant) and drops the low-order ones. This is called truncating the result. Here is an example in the decimal system, using a six digit representation: 123456 X L2 246912 123456 =148147.2 The result requires 7 digits! The "2" after the decimal point will be dropped and the final result will be 148147. It has been truncated. Usually, as long as the position of the decimal point is not lost, this method is used to extend the range of the operations which may be performed, at the expense of precision. The problem is the same in binary. The details of a binary multi-
34
BASIC CONCEPTS plication will be shown in Chapter 4. This fixed-format representation may cause a loss of precision, but it may be sufficient for usual computations or mathematical operations. Unfortunately, in the case of accounting, no loss of precision is tolerable. For example, if a customer rings up a large total on a cash register, it would not be acceptable to have a five figure amount to pay, which would be approximated to the dollar. Another representation must be used wherever precision in the result is essential. The solution normally used is BCD, or binary-coded decimal. BCD Representation The principle used in representing numbers in BCD is to encode each decimal digit separately, and to use as many bits as necessary to represent the complete number exactly. In order to encode each of the digits from 0 through 9, four bits are necessary. Three bits would only supply eight combinations, and can therefore not encode the ten digits. Four bits allow sixteen combinations and are therefore sufficient to encode the digits "0" through "9". It can also be noted that six of the possible codes will not be used in the BCD representation (see Fig. 1-4). This will result later on in a potential problem during additions and subtractions, which we will have to solve.
BCD SYMBOL 0 1 2 3 4 5 6 7
35
PROGRAMMING THE Z80 Since only four bits are needed to encode a BCD digit, two BCD digits may be encoded in every byte. This is called "packed BCD. " As an example, "00000000" will be "00" in BCD. "10011001" will be "99", A BCD code is read as follows: 0010 BCD digit "2" 411-1 BCD digit "1" I BCD number "21" 0001
J
Exercise 1.16: What is the BCD representation for "29"? "91" 2 Exercise 1.17: Is "10100000" a valid BCD representation? Why? As many bytes as necessary will be used to represent all BCD digits. Typically, one or more nibbles will be used at the beginning of the representation to indicate the total number of nibbles, i.e., the total number of BCD digits used. Another nibble or byte will be used to denote the position of the decimal point. However, conventions may vary. Here is an example of a representation for multibyte BCD integers: 3 2 2 number "221" ( 3 bytes)
This represents +221 (The sign may be represented by 0000 for +, and 0001 for , for example.) Exercise 1.18: Using the same convention, represent "-23123". Show it in BCD format, as above, then in binary. Exercise 1.19: Show the BCD for "222" and "111", then for the result of 222 X 111. (Compute the result by hand, then show it in the above representation.) The BCD representation can easily accommodate decimal numbers. 36
BASIC CONCEPTS For example, +2.21 may be represented by: 3 2 digit 3 2 digit 2 2 221 3 digits " " is on the left of digit 2 digit 1
The advantage of BCD is that it yields absolutely correct results. Its disadvantage is that it uses a large amount of memory and results in slow arithmetic operations. This is acceptable only in an accounting environment and is normally not used in other cases. Exercise 1.20: How many bits are required to encode "9999" in BCD? And in two's complement? We have now solved the problems associated with the representation of integers, signed integers and even large integers. We have even already presented one possible method of representing decimal numbers, with BCD representation. Let us now examine the problem of representing decimal numbers in a fixed length format. Floating-Point Representation The basic principle is that decimal numbers must be represented with a fixed format. In order not to waste bits, the representation will normalize all the numbers. For example, "0.000123" wastes three zeros on the left of the number, which have no meaning except to indicate the position of the decimal point. Normalizing this number results in .123 X 104. ".123" is called a normalized mantissa. " 3" is called the exponent. We have normalized this number by eliminating all the meaningless zeros on the left of it and adjusting the exponent. Let us consider another example: 22.1 is normalized as .221 x 102 or M X 10E where M is the mantissa, and E is the exponent.
37
It can be readily seen that a normalized number is characterized by a mantissa less than 1 and greater or equal to .1 in all cases where the number is not zero. In other words, this can be represented mathematically by: .1 < M < 1 or 10-' M < 10 Similarly, in the binary representation: 2-'4M<2 (or .54M<1) Where M is the absolute value of the mantissa (disregarding the For example: 111.01 is normalized as: .11101 X V. The mantissa is 11101. The exponent is 3. Now that we have defined the principle of the representation, let us examine the actual format. A typical floating-point representation appears below.
31 5 EXP 24 23 S 1 16 15 8 7
MANTISSA I
In the representation used in this example, four bytes are used for a total of 32 bits. The first byte on the left of the illustration is used to represent the exponent. Both the exponent and the mantissa will be represented in two's complement. As a result, the maximum exponent will be 128. "S" in Fig. 1-5 denotes the sign bit. Three bytes are used to represent the mantissa. Since the first bit in the two's complement representation indicates the sign, this leaves 23 bits for the representation of the magnitude of the mantissa.
38
BASIC CONCEPTS Exercise 1.21: How many decimal digits can the mantissa represent with the 23 bits? This is only one example of a floating point representation. It is possible to use only three bytes, or it is possible to use more. The four-byte representation proposed above is just a common one which represents a reasonable compromise in terms of accuracy, magnitude of numbers, storage utilization, and efficiency in arithmetic operation. We have now explored the problems associated with the representation of numbers and we know how to represent them in integer form, with a sign, or in decimal form. Let us now examine how to represent alphanumeric data internally. Representing Alphanumeric Data The representation of alphanumeric data, i.e. characters, is completely straightforward: all characters are encoded in an eight-bit code. Only two codes are in general use in the computer world, the ASCII Code, and the EBCDIC Code. ASCII stands for "American Standard Code for Information Interchange," and is universally used in the world of microprocessors. EBCDIC is a variation of ASCII used by IBM, and therefore not used in the microcomputer world unless one interfaces to an IBM terminal. Let us briefly examine the ASCII encoding. We must encode 26 letters of the alphabet for both upper and lower case, plus 10 numeric symbols, plus perhaps 20 additional special symbols. This can be easily accomplished with 7 bits, which allow 128 possible codes. (See Fig.l-6.) All characters are therefore encoded in 7 bits. The eighth bit, when it is used, is the parity bit. Parity is a technique for verifying that the contents of a byte have not been accidentally changed. The number of 1's in the byte is counted and the eighth bit is set to one if the count was odd, thus making the total even. This is called even parity. One can also use odd parity, i.e. writing the eighth bit (the left-most) so that the total number of 1's in the byte is odd. Example: let us compute the parity bit for "0010011" using even parity. The number of l's is 3. The parity bit must therefore be a 1 so that the total number of bits is 4, i.e. even. The result is 10010011, where the leading 1 is the parity bit and 0010011 identifies the character.
39
PROGRAMMING THE Z80 The table of 7-bit ASCII codes is shown in Fig. 1-6. In practice, it is used "as is," i.e. without parity, by adding a 0 in the left-most position, or else with parity, by adding the appropriate extra bit on the left.
Exercise 1.22: Compute the 8-bit representation of the digits "0" through "9", using even parity. (This code will be used in application examples of Chapter 8.) Exercise 1.23: Same for the letters "A" through "F". Exercise 1.24: Using a non-parity ASCII code (where the left-most bit is "0"), indicate the binary contents of the 4 characters below:
HEX LSD 0 1 2 3 4 5 6 7 8 9 A B C D E F
M5D BITS 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
1 001 DLE DC1 DC2 DC3 DC4 NM SYN ETB CAN EM SUB ESC FS GS RS US
7 5 6 3 4 011 100 101 110 111 p 0 @ P 1 A Q a q r BR b 2 c s 3 CS DT d 4 E U e u 5 f v 6F V w 7 G W g 8 H X li x IY1 v 9 J Z 1 z K r k [ < L \ I = M ] m ,, >N A n r o DEL 0 < '
40
BASIC CONCEPTS We have examined the usual representations for both program and data inside the computer. Let us now examine the possible external representations.
EXTERNAL REPRESENTATION OF INFORMATION The external representation refers to the way information is presented to the user, i.e. generally to the programmer. Information may be presented externally in essentially three formats: binary, octal or hexadecimal and symbolic. I. Binary It has been seen that information is stored internally in bytes, which are sequences of eight bits (0's or 1's). It is sometimes desirable to display this internal information directly in its binary format and this is called binary representation. One simple example is provided by Light Emitting Diodes (LEDs) which are essentially miniature lights, on the front panel of the microcomputer. In the case of an eight-bit microprocessor, a front panel will typically be equipped with eight LEDs to display the contents of any internal register. (A register is used to hold eight bits of information and will be described in Chapter 2). A lighted LED indicates a one. A zero is indicated by an LED which is not lighted. Such a binary representation may be used for the fine debugging of a complex program, especially if it involves input/output, but is naturally impractical at the human level. This is because in most cases, one likes to look at information in symbolic form. Thus "9" is much easier to understand or remember than "1001". More convenient representations have been devised, which improve the personmachine interface. 2. Octal and Hexadecimal "Octal" and "hexadecimal" encode respectively three and four binary bits into a unique symbol. In the octal system, any combination of three binary bits is represented by a number between 0 and 7. "Octal" is a format using three bits, where each combination of three bits is represented by a symbol between 0 and 7:
41
PROGRAMMING THE Z80 binary octal 000 001 010 011 100 101 110 111 0 1 2 3 4 5 6 7
Fig. 1.7: Octal Symbols For example, "00 100 100" binary is represented by: 0 4 4 or "044" in octal. Another example: 11 111 111 is:
I' if
3 7 7 or "377" in octal. Conversely, the octal "211" represents: 010 001 001 or "10001001" binary. Octal has traditionally been used on older computers which were employing various numbers of bits ranging from 8 to perhaps 64. More recently, with the dominance of eight-bit microprocessors, the eight-bit format has become the standard, and another more practical representation is used. This is hexadecimal. In the hexdecimal representation, a group of four bits is encoded as one hexadecimal digit. Hexadecimal digits are represented by the symbols from 0 to 9, and by the letters A, B, C, D, E, F. For example, "0000" is represented by "0", "0001" is represented by "1" and "1111" is represented by the letter "F" (see Fig. 1-8).
42
BASIC CONCEPTS
DECIMAL 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
BINARY 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
HEX 0 1 2 3 4 5 6 7 8 9 A B C 0 E F
OCTAL 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17
43
Exercise 1.25: What is the hexadecimal representation of "10101010?' Exercise 1.26: Conversely, what is the binary equivalent of "FA" hexadecimal? Exercise 1.27: What is the octal of "01000001"P Hexadecimal offers the advantage of encoding eight bits into only two digits. This is easier to visualize or memorize and faster to type into a computer than its binary equivalent. Therefore, on most new microcomputers, hexadecimal is the preferred method of representation for groups of bits. Naturally, whenever the information present in the memory has a meaning, such as representing text or numbers, hexadecimal is not convenient for representing the meaning of this information when it is brought out for use by humans. Symbolic Representation Symbolic representation refers to the external representation of information in actual symbolic form. For example, decimal numbers are represented as decimal numbers, and not as sequences of hexadecimal symbols or bits. Similarly, text is represented as such. Naturally, symbolic representation is most practical to the user. It is used whenever an appropriate display device is available, such as a CRT display or a printer. (A CRT display is a television-type screen used to display text or graphics.) Unfortunately, in smaller systems such as one-board microcomputers, it is uneconomical to provide such displays, and the user is restricted to hexadecimal communication with the computer. Summary of External Representations Symbolic representation of information is the most desirable since it is the most natural for a human user. However, it requires an expensive interface in the form of an alphanumeric keyboard, plus a printer or a CRT display. For this reason, it may not be
44
BASIC CONCEPTS
available on the less expensive systems. An alternative type of representation is then used, and in this case hexadecimal is the dominant representation. Only in rare cases relating to fine de-bugging at the hardware or the software level is the binary representation used. Binary directly displays the contents of registers of memory in binary format. (The utility of a direct binary display on a front panel has always been the subject of a heated emotional controversy, which will not be debated here.) We have seen how to represent information internally and externally. We will now examine the actual microprocessor which will manipulate this information.
Additional Exercises
Exercise 1.28: What is the advantage of two's complement over other representations used to represent signed numbers? Exercise 1.29: How would you represent "1024" in direct binary? Signed binary? Two's complement? Exercise 1.30: What is the V-bit? Should the programmer test it after an addition or subtraction? Exercise 1.31: Compute the two's complement of "+16", "+17", Exercise 1.32: Show the hexadecimal representation of the following text, which has been stored internally in ASCII format, with no parity: = "MESSAGE".
45
SYSTEM ARCHITECTURE
The architecture of the microcomputer system appears in Figure 2.1. The microprocessor unit (MPU), which will be a Z80 here, appears on the left of the illustration. It implements the functions of a centralprocessing unit (CPU) within one chip: it includes an arithmetic-logical unit (ALU), plus its internal registers, and a control unit (CU), in
46
Z80 HARDWARE ORGANIZATION charge of sequencing the system. Its operation will be explained in this chapter.
PORT A
POW II
The MPU creates three buses: an 8-bit bidirectional data bus, which appears at the top of the illustration, a 16-bit unidirectional address bus, and a control bus, which appears at the bottom of the illustration. Let us describe the function of each of the buses. The data bus carries the data being exchanged by the various elements of the system. Typically, it will carry data from the memory to the MPU or from the MPU to the memory or from the MPU to an input/output chip. (An input/output chip is a component in charge of communicating with an external device.) The address bus carries an address generated by the MPU, which will select one internal register within one of the chips attached to the system. This address specifies the source, or the destination, of the data which will transit along the data bus. The control bus carries the various synchronization signals required by the system. Having described the purpose of buses, let us now connect the additional components required for a complete system. Every MPU requires a precise timing reference, which is supplied by a clock and a crystal. In most "older" microprocessors, the clock-oscillator is external to the MPU and requires an extra chip. In most recent microprocessors, the clock-oscillator is usually incorporated within the MPU. The quartz crystal, however, because of its bulk, is always exter47
PROGRAMMING THE Z80 nal to the system. The crystal and the clock appear on the left of the MPU box in Figure 2.1. Let us now turn our attention to the other elements of the system. Going from left to right on the illustration, we distinguish: The ROM is the read-only memory and contains the program for the system. The advantage of the ROM memory is that its contents are permanent and do not disappear whenever the system is turned off. The ROM, therefore, always contains a bootstrap or a monitor program (their function will be explained later) to permit initial system operation. In a process-control environment, nearly all the programs will reside in ROM. as they will probably never be changed. In such a case, the industrial user has to protect the system against power failures: programs must not be volatile. They must be in ROM. However, in a hobbyist environment, or in a program-development environment (when the programmer tests his program), most of the programs will reside in RAM so that they can be easily changed. Later, they may remain in RAM, or be transferred into ROM, if desired. RAM, however, is volatile. Its contents are lost when power is turned off. The RAM (random-access memory) is the read/write memory for the system. In the case of a control system, the amount of RAM will typically be small (for data only). On the other hand, in a programdevelopment environment, the amount of RAM will be large, as it will contain programs plus development software. All RAM contents must be loaded prior to use from an external device. Finally the system will contain one or more interface chips so that it may communicate with the external world. The most frequently used interface chip is the PIO or parallel input/output chip. It is the one shown on the illustration. This PIO, like all other chips in the system, connects to all three buses and provides at least two 8-bit ports for communication with the outside world. For more details on how an actual PIO works, refer to book C201 or, for specifics of the Z80 system, refer to Chapter 7 (Input/Output Devices). All the chips are connected to all three buses, including the control bus. The functional modules which have been described need not necessarily reside on a single LSI chip. In fact, we could use combination chips, which may include both PIO and a limited amount of ROM or RAM. Still more components will be required to build a real system. In par-
48
Z80 HARDWARE ORGANIZATION ticular, the buses usually need to be buffered. Also, decoding logic may be used for the memory RAM chips, and, finally, some signals may need to be amplified by drivers. These auxiliary circuits will not be described here as they are not relevant to programming. The reader interested in specific assembly and interfacing techniques is referred to book C207 "Microprocessor Interfacing Techniques." INSIDE A MICROPROCESSOR The large majority of all microprocessor chips on the market today Implement the same architecture. This "standard" architecture will be described here. It is shown in Figure 2.2. The modules of this standard microprocessor will now be detailed, from right to left.
SP
PC
HL
-J
BIT DATA REGISTERS
SHIFTER
The control box on the right represents the control unit which synchronizes the entire system. Its role will be clarified within the remainder of this chapter.
49
PROGRAMMING THE Z80 The ALU performs arithmetic and logic operations. A special register equips one of the inputs of the ALU, the left input here. It is called the accumulator. (Several accumulators may be provided.) The accumulator may be referenced both as input and output (source and destination) within the same instruction. The ALU must also provide shift and rotate facilities. A shift operation consists of moving the contents of a byte by one or more positions to the left or to the right. This is illustrated in Figure 2.3. Each bit has been moved to the left by one position. The details of shifts and rotations will be presented in the next chapter.
SHIFT LEFT
CARRY
El
ROTATE LEFT
r-\ re>
CARRY
Note: Some Shift and Rotate instructions do not include the Carry.
The shifter may be on the ALU output, as illustrated in Figure 2.2, or may be on the accumulator input. To the left of the ALU, the flags or status register appear. Their role is to store exceptional conditions within the microprocessor. The contents of the flags register may be tested by specialized instructions, or may be read on the internal data bus. A conditional instruction will cause the execution of a new program, depending on the value of one of these bits. The role of the status bits in the Z80 will be examined later in this chapter.
50
Z80 HARDWARE ORGANIZATION Setting Flags Most of the instructions executed by the processor will modify some or all of the flags. It is important to always refer to the chart provided by the manufacturer listing which bits will be modified by the instructions. This is essential in understanding the way a program is being executed. Such a chart for the Z80 is shown in Figure 4-17. The Registers Let us look now at Figure 2.2. On the left of the illustration, the registers of the microprocessor appear. Conceptually, one can distinguish the general purpose registers and the address registers. The General-Purpose Registers General-purpose registers must be provided in order for the ALU to manipulate data at high speed. Because of restrictions on the number of bits which it is reasonable to provide within an instruction, the number of (directly addressable) registers is usually limited to fewer than eight. Each of these registers is a set of eight flip-flops, connected to the bidirectional internal data bus. These eight bits can be transferred simultaneously to or from the data bus. The implementation of these registers in MOS flip-flops provides the fastest level of memory available, and their contents can be accessed within tens of nanoseconds. Internal registers are usually labelled from 0 to n. The role of these registers is not defined in advance: they are said to be "general purpose." They may contain any data used by the program. These general-purpose registers will normally be used to store eightbit data. On some microprocessors, facilities exist to manipulate two of these registers at a time. They are then called "register pairs." This arrangement facilitates the storage of 16-bit quantities, whether data or addresses. The Address Registers Address registers are 16-bit registers intended for the storage of addresses..They are also often called data counters or pointers. They are double registers, i.e., two eight-bit registers. Their essential characteristic is to be connected to the address bus. The address registers create the address bus. The address bus appears on the left and the bottom part of the illustration in Figure 2.4.
51
PROGRAMMING THE Z80 The only way to load the contents of these 16-bit registers is via the data bus. Two transfers will be necessary along the data bus in order to transfer 16 bits. In order to differentiate between the lower half and the higher half of each register, they are usually labelled as L (low) or H (high), denoting bits 0 through 7, and 8 through 15 respectively. This label is used whenever it is necessary to differentiate the halves of these registers. At least two address registers are present within most microprocessors. "MUX" in Fig. 2.4 stands for multiplexer.
Fig. 2.4: The 16-bit Address Registers Create the Address Bus
Program Counter (PC) The program counter must be present in any processor. It contains the address of the next instruction to be executed. The presence of the program counter is indispensable and fundamental to program execution. The mechanism of program execution and the automatic sequencing implemented with the program counter will be described in the next section. Briefly, execution of a program is normally sequential. In order to access the next instruction, it is necessary to bring it from the memory into the microprocessor. The contents of the PC will be deposited on the address bus, and transmitted towards the memory. The memory will then read the contents specified by this address and send back the corresponding word to the MPU. This is the instruction.
52
In a few exceptional microprocessors, such as the two-chip F8, there is no PC on the microprocessor. This does not mean that the system does not have a program counter. The PC happens to be implemented directly on the memory chip, for reasons of efficiency. Stack Pointer (SP) The stack has not been introduced yet and will be described in the next section. In most powerful, general-purpose microprocessors, the stack is implemented in "software," i.e., within the memory. In order to keep track of the top of this stack within the memory, a 16-bit register is dedicated to the stack pointer or .5/2. The SP contains the address of the top of the stack within the memory. It will be shown that the stack is indispensable for interrupts and for subroutines. Index Register (IX) Indexing is a memory-addressing facility which is not always provided in microprocessors. The various memory-addressing techniques will be described in Chapter 5. Indexing is a facility for accessing blocks of data in the memory with a single instruction. An index register will typically contain a displacement which will be automatically added to a base (or it might contain a base which would be added to a displacement). In short, indexing is used to access any word within a block of data. The Stack
A stack is formally called an LIFO structure (last-in, first-out). A stack is a set of registers, or memory locations, allocated to this data structure. The essential characteristic of this structure is that it is a chronological structure. The first element introduced into the stack is always at the bottom of the stack. The element most recently deposited in the stack is on the top of the stack. The analogy can be drawn with a stack of plates on a restaurant counter. There is a hole in the counter with a spring in the bottom. Plates are piled up in the hole. With this organization, it is guaranteed that the plate which has been put first in the stack (the oldest) is always at the bottom. The one that has been placed most recently on the stack is the one which is on top of it. This example also illustrates another characteristic of the stack. In normal use, a stack is only accessible via two instructions: "push" and "pop" (or "pull"). The push operation results in depositing one element on
53
PROGRAMMING THE Z80 top of the stack (two in the case of the Z80). The pull operation consists of removing one element from the stack. In the case of a microprocessor, it is the accumulator that will be deposited on top of the stack. The pop will result in a transfer of the top element of the stack into the accumulator. Other specialized instructions may exist to transfer the top of the stack between other specialized registers, such as the status register. The Z80 is more versatile than most in this respect. The availability of a stack is required to implement three programming facilities within the computer system: subroutines, interrupts, and temporary data storage. The role of the stack during subroutines will be explained in Chapter 3 (Basic Programming Techniques). The role of the stack during interrupts will be explained in Chapter 6 (Input/Output Techniques). Finally, the role of the stack in saving data at high speed will be explained during specific application programs. We will simply assume at this point that the stack is a required facility in every computer system. A stack may be implemented in two ways: I. A fixed number of registers may be provided within the microprocessor itself. This is a "hardware stack." It has the advantage of high speed. However, it has the disadvantage of a limited number of registers. 2. Most general-purpose microprocessors choose another approach, the software stack, in order not to restrict the stack to a very small number of registers. This is the approach chosen in the Z80. In the software approach, a dedicated register within the microprocessor, here register SP, stores the stack pointer, i.e., the address of the top element of the stack (or, sometimes, the address of the top element of the stack plus one). The stack is then implemented as an area of memory. The stack pointer will therefore require 16 bits to point anywhere in the memory.
MICROPROCESSOR REGISTER 7 DATA 0 I 7 MEMORY
PUSH
15
L.
54
Z80 HARDWARE ORGANIZATION The Instruction Execution Cycle Let us refer now to Figure 2.6. The microprocessor unit appears on the left, and the memory appears on the right. The memory chip may be a ROM or a RAM, or any other chip which happens to contain memory. The memory is used to store instructions and data. Here, we will fetch one instruction from the memory to illustrate the role of the program counter. We assume that the program counter has valid contents. It now holds a 16-bit address which is the address of the next instruction to fetch in the memory. Every processor proceeds in three cycles: 1fetch the next instruction 2decode the instruction 3execute the instruction
Fetch Let us now follow the sequence. In the first cycle, the contents of the program counter are deposited on the address bus and gated to the memory (on the address bus). Simultaneously, a read signal may be issued on the control bus of the system, if required. The memory will receive the address. This address is used to specify one location within the memory. Upon receiving the read signal, the memory will decode the address it has received, through internal decoders, and will select the location specified by the address. A few hundred nanoseconds later, the memory will deposit the eight-bit data corresponding to the specified address on its data bus. This eight-bit word is the instruction that we want to fetch. In our illustration, this instruction will be deposited the data bus on top of the MPU box. Let us briefly summarize the sequencing: the contents of the program counter are output on the address bus. A read signal is generated. The memory cycles, and perhaps 300 nanoseconds later, the instruction at the specified address is deposited on the data bus (assuming a single byte instruction). The microprocessor then reads the data bus and deposits its contents into a specialized internal register, the IR register. The IR is the instruction register: it is eight-bits wide and is used to contain the instruction just fetched from the memory. The fetch cycle is now completed. The 8 bits of the instruction are now physically in the special internal register of the MPU, the IR register. The IR appears on the left of Figure 2.7. It is not accessible to the programmer.
55
INSTRUCTION
ADDRESS BUS
Fig. 2.6: Fetching an Instruction from the Memory Decoding and Execution
Once the instruction is contained in IR, the control unit of the microprocessor will decode the contents and will be able to generate the correct sequence of internal and external signals for the execution of the specified instruction. There is, therefore, a short decoding delay followed by an execution phase, the length of which depends on the nature of the instruction specified. Some instructions will execute entirely within the MPU. Other instructions will fetch or deposit data from or into the memory. This is why the various instructions of the MPU require various lengths of time to execute. This duration is expressed as a number of (clock) cycles. Refer to Chapter 4 for the number of
Z80 HARDWARE ORGANIZATION cycles required by each instruction. Since various clock rates may be used, speed of execution is normally expressed in number of cycles rather than in number of nanoseconds.
EXTERNAL <
BUS
sna
1F e ACCUMULATOR I
ALU RO
RI REGISTERS
RN
RESULT (DESTINATION) BUS
Fetching the Next Instruction We have described how, using the program counter, an instruction can be fetched from the memory. During the execution of a program, instructions are fetched in sequence from the memory. An automatic mechanism must therefore be provided to fetch instructions in sequence. This task is performed by a simple incrementer attached to the program counter. This is illustrated in Figure 2.7. Every time that the contents of the program counter (at the bottom of the illustration) are placed on the address bus, its contents will be incremented and written back into the program counter. As an example, if the program counter contained the value "0", the value "0" would be output on the address bus. Then the contents of the program counter would be incremented and the value "1" would be written back into the program counter. In this way, the next time that the program counter is used, it is the instruction at address l that will be fetched. We have just implemented an
automatic mechanism for sequencing instructions. It must be stressed that the above descriptions are simplified. In reality, some instructions may be two- or even three-bytes long, so that successive bytes will be fetched in this manner from the memory. However, the mechanism is identical. The program counter is used to fetch
57
PROGRAMMING THE Z80 successive bytes of an instruction as well as to fetch successive instructions themselves. The program counter, together with its incrementer, provides an automatic mechanism for pointing to successive memory locations.
INTERNAL DATA BUS
41MINIS\ amateliatte.
EXTERNAL BUS
R0
RI REGISTERS
EXTERNAL BUS
IRO)
V
R1 REGISTERS
58
Z80 HARDWARE ORGANIZATION We will now execute an instruction within the MPU (see Figure 2.8). A typical instruction will be, for example: RO = RO + RI. This means: "ADD the contents of RO and RI, and store the results in RO." To perform this operation, the contents of RO will be read from register RO, carried via the single bus to the left input of the ALU, and stored in the buffer register there. RI will then be selected and its contents will be read onto the bus, then transferred to the right input of the ALU. This sequence is illustrated in Figures 2.9 and 2.10. At this point, the right input of the ALU is conditioned by RI, and the left input of the ALU is conditioned by the buffer register, containing the previous value of RO. The operation can be performed. The addition is performed by the ALU, and the results appear on the ALU output, in the lower right-hand corner of Fig. 2.11. The results will be deposited on the single bus, and will be propagated back to RO. This means, in practice, that the input latch of RO will be enabled, so that data can be written into it. Execution of the instruction is now complete. The results of the addition are in RO. It should be noted that the contents of RI have not been modified by this operation. This is a general principle: the contents of a register, or of any read/write memory, are not modified by a read operation. The buffer register on the left input of the ALU was necessary in order to memorize the contents of RO, so that the single bus could be used again for another transfer. However, a problem remains.
ACCUMULATOR
Re
RI ACC R1 Re
RBRl
59
The Critical Race Problem The simple organization shown in Figure 2.8 will not function correctly. Question: What is the timing problem? Answer: The problem is that the result which will be propagated out of the ALU will be deposited back on the single bus. It will not propagate just in the direction of RO, but along all of the bus. In particular, it will recondition the right input of the ALU, changing the result coming out of it a few nanoseconds later. This is a critical race. The output of the ALU must be isolated from its input (see Figure 2.12). Several solutions are possible which will isolate the input of the ALU from the output. A buffer register must be used. The buffer register could be placed on the output of the ALU, or on its input. It is usually placed on the input of the ALU. Here it would be placed on its right input. The buffering of the system is now sufficient for a correct operation. It will be shown later in this chapter that if the left register which appears in this illustration is to be used as an accumulator (permitting the use of one-byte long instructions), then the accumulator will require a buffer too, as shown in Figure 2.13.
INTERNAL DATA BU
I I 1
a\ I
N
ACCUMULATOR
k
RO RI REGISTERS
RO
RI REGISTERS
INTERNAL ORGANIZATION OF THE 7,80 The terms necessary in order to understand the internal elements of the microprocessor have been defined. We will now examine in more detail the Z80 itself, and describe its capabilities. The internal organization of the Z80 is shown in Figure 2.14. This diagram presents a logical description of the device. Additional interconnections may exist but are not shown. Let us examine the diagram from right to left. On the right part of the illustration, the arithmetic-logical unit (the ALU) may be recognized by its characteristic "V" shape. The accumulator register, which has been described in the previous section, is identified as A on the right input path of the ALU. It has been shown in the previous section that the accumulator should be equipped with a buffer register. This is the register labeled ACT (temporary accumulator). Here, the left input of the ALU is also equipped with a temporary register, called TMP. The operation of the ALU will become clear in the next section, where we will describe the execution of actual instructions. The flags register is.called"F" in the Z80,and is shown on the right of the accumulator register. The contents of the flags register are essentially conditioned by the ALU, but it will be shown that some of its bits may also be conditioned by other modules or events. The accumulator and the flags registers are shown as double registers labelled respectively A, A' and F, F'. This is because the Z80 is
61
PROGRAMMING THE Z80 equipped internally with two sets of registers: A + F, and A' + F'. However, only one set of these registers may be used at any one time. A special instruction is provided to exchange the contents of A and F with A' and F'. In order to simplify the explanations, only A and F will be shown on most of the diagrams which follow. The reader should remember that he has the option of switching to the alternate register set A' and F' if desired. The role of each flag in the flags register will be described in Chapter 3 (Basic Programming Techniques). A large block of registers is shown at the center of the illustration. On top of the block of registers, two identical groups can be recognized. Each one includes six registers labeled B, C, D, E, H, L. These are the general-purpose eight-bit registers of the Z80. There are two peculiarities of the Z80 with respect to the standard microprocessor which has been described at the beginning of this chapter. First, the Z80 is equipped with two banks of registers, i.e., two identical groups of 6 registers. Only six registers may be used at any one time. However, special instructions are provided to switch between the two banks of registers. One bank, therefore, behaves as an internal memory, while the other one behaves as a working set of internal registers. The possible uses of this special facility will be described in the next chapter. Conceptually, it will be assumed, for the time being, that there are only six working registers, B, C, D, E, H, and L, and the second register bank will temporarily be ignored, in order to avoid confusion. The MUX symbol which appears above the memory bank is an abbreviation for multiplexer. The data coming from the internal data bus will be gated through the multiplexer to the selected register. However, only one of these registers can be connected to the internal data bus at any one time. A second characteristic of these six registers, in addition to being general-purpose eight-bit registers, is that they are equipped with a connection to the address bus. This is why they have been grouped in pairs. For example, the contents of B and C can be gated simultaneously onto the 16-bit address bus which appears at the bottom of the illustration. As a result, this group of 6 registers may be used to store either eight-bit data or else 16-bit pointers for memory addressing. The third group of registers, which appears below the two previous ones in the middle of Figure 2.14, contains four "pure" address registers. As in any microprocessor, we find the program counter (PC) and the stack pointer (SP). Recall that the program counter contains
62
Z80 HARDWARE ORGANIZATION the address of the next instruction to be executed. The stack pointer points to the top of the stack in the memory. In the case of the Z80, the stack pointer points to the last actual entry in the stack. (In other microprocessors, the stack pointer points just above the last entry.) Also, the stack grows "downwards. "i.e. towards the lower addresses. This means that the stack pointer must be decremented any time a new word is pushed on the stack. Conversely, whenever a word is removed (popped) from the stack, the stack pointer must be incremented by one. In the case of the Z80, the "push" and "pop" always involve two words at the same time, so that the contents of the stack pointer will be decremented or incremented by two. Looking at the remaining two registers of this group of four registers, we find a new type of register which has not been described yet: two index-registers, labeled IX (Index Register X) and IY (Index Register Y). These two registers are equipped with a special adder shown as a miniature V-shaped ALU on the right of these registers in Figure 2.14. A byte brought along the internal data bus may be added to the contents of IX or IY. This byte is called the displacement, when using an indexed instruction. Special instructions are provided which will automatically add this displacement to the contents of IX or IY and generate an address. This is called indexing. It allows convenient access to any sequential block of data. This important facility will be described in Chapter 5 on addressing techniques. Finally, a special box labeled" t 1" appears below and to the left of the block of registers. This is an increment/decrement. The contents of any of the register pairs SP, PC, BC, DE, HL (the "pure address" registers) may be automatically incremented or decremented every time they deposit an address on the internal address bus. This is an essential facility for implementing automated program loops which will be described in the next section. Using this feature it will be possible to access successive memory locations conveniently. Let us move now to the left of the illustration. One register pair is shown, isolated on the left: I and R. The I register is called the interruptpage address register. Its role will be described in the section on interrupts of Chapter 6 (Input/Output Techniques). It is used only in a special mode where an indirect call to a memory location is generated in response to an interrupt. The I register is used to store the high-order part of the indirect address. The lower part of the address is supplied by the device which generated the interrupt.
63
PROGRAMMING THE Z80 The R register is the memory-refresh register. It is provided to refresh dynamic memories automatically. Such a register has traditionally been located outside the microprocessor, since it is associated with the dynamic memory. It is a convenient feature which minimizes the amount of external hardware for some types of dynamic memories. It will not be used here for any programming purposes, as it is essentially a hardware feature (see reference 0207 "Microprocessor Interfacing Techniques" for a detailed description of memory refresh techniques). However, it is possible to use it as a software clock, for example. Let us move now to the far left of the illustration. There the control section of the microprocessor is located. From top to bottom, we find first the Instruction register IR, which will contain the instruction to be executed. The IR register is totally distinct from the "I, R" register pair described above. The instruction is received from the memory via the data bus, is transmitted along the internal data bus and is finally deposited into the instruction register. Below the instruction register appears the decoder which will send signals to the controller-sequencer and cause the execution of the instruction within the microprocessor and outside it. The control section generates and manages the control bus which appears at the bottom part of the illustration. The three buses managed or generated by the system, i.e., the data bus, the address bus, and the control bus, propagate outside the microprocessor through its pins. The external connections are shown on the right-most part of the illustration. The buses are isolated from the outside through buffers shown in Figure 2.14. All the logical elements of the Z80 have now been described. It is not essential to understand the detailed operation of the Z80 in order to start writing programs. However, for the programmer who wishes to write efficient codes, the speed of a program and its size will depend upon the correct choice of registers as well as the correct choice of techniques. To make a correct choice, it is necessary to understand how instructions are executed within the microprocessor. We will therefore examine here the execution of typical instructions inside the Z80 to demonstrate the role and use of the internal registers and buses.
64
B
IN RNA!. DATA BUS (a BITS)
II
A C IMP A
U F F R DATA BUS
r
UX MU% B D ACT H L IX 1Y AID SP PC L H C
CONTROL SECTION
v \A
21
21 ADDRESS BUS T ADDRESS BUS (16 BITS) V CONTROL BUS B U CONTROL BUS R
INSTRUCTION FORMATS The Z80 instructions are listed in Chapter 4. Z80 instructions may be formated in one, two, three or four bytes. An instruction specifies the operation to be performed by the microprocessor. From a simplified standpoint, every instruction may be represented as an opcode followed by an optional literal or address field, comprising one or two words. The opcode field specifies the operation to be carried out. In strict computer terminology, the opcode represents only those bits which specify the operation to be performed, exclusive of the register pointers that might be necessary. In the microprocessor world, it is convenient to call opcode the operation code itself, as well as any register pointers which it might incorporate. This "generalized opcode" must reside in an eight-bit word for efficiency (this is the limiting factor on the number of instructions available in a microprocessor). The 8080 uses instructions which may be one, two, three, bytes long (see Figure 2.15). However, the Z80 is equipped with additional indexed instructions, which require one more byte. In the case of the Z80, opcodes are, in general, one byte long, except for special instructions which require a two-byte opcode. Some instructions require that one byte of data follow the opcode. In such a case, the instruction will be a two-byte instruction, the second byte of which is data (except for indexing, which adds an extra byte). In other cases, the instruction might require the specification of an address. An address requires 16 bits and, therefore, two bytes. In that case, the instruction will be a three-byte or a four-byte instruction. For each byte of the instruction, the control unit will have to perform a memory fetch, which will require four clock cycles. The shorter the instruction, the faster the execution. A One-Word Instruction One-word instructions are, in principle, fastest and are favored by the programmer. A typical such instruction for the Z80 is: LD r, r' This instruction means: "Transfer the contents of register r' into r." This is a typical "register-to-register" operation. Every microprocessor must be equipped with such instructions, which allow the programmer to transfer information from any of the machine's registers into another one. Instructions referencing special registers of the machine,
66
such as the accumulator or other special-purpose registers, may have a special opcode. After execution of the above instruction, the contents of r will be equal to the contents of r', The contents of r' will not have been modified by the read operation. Every instruction must be represented internally in a binary format. The above representation "LD r,r' " is symbolic or mnemonic. It is called the assembly-language representation of an instruction. It is simply meant as a convenient symbolic representation of the actual binary encoding for that instruction. The binary code which will represent this instruction inside the memory is: OIDDOSSS (bits 0 to 7). This representation is still partially symbolic. Each of the letters S and D stands for a binary bit. The three D's, "D D D", represent the three bits pointing to the destination register. Three bits allow selection of one out of eight possible registers. The codes for these registers appear in Figure 2.16. For example, the code for register B is "0 0 0", the code for register C is "0 0 I", and so on. Similarly, "S S S" represents the three bits pointing to the source register. The convention here is that register r' is the source, and that register r is the destination. The placement of the bits in the binary representation of an instruction is not meant for the convenience of the programmer, but for the convenience of the control section of the microprocessor, which must decode and execute the instruction. The assembly-language representation, however, is meant for the convenience of the programmer. It could be argued that LD r,r' should really mean: "Transfer contents of r into r ." However, the convention has
67
PROGRAMMING THE Z80 been chosen in order to maintain compatibility with the binary representation in this case. It is naturally arbitrary. Exercise 23: Write below the binary code which will transfer the contents of register C into register B. Consult Fig. 2.16 for the codes corresponding to C and B. Another simple example of a one-word instruction is: ADD A, r This instruction will result in adding the contents of a specified register (r) to the accumulator (A). Symbolically, this operation may be represented by: A = A + r. It can be verified in Chapter 4 that the binary representation of this instruction is: 1 0 0 0 OSSS where S S S specifies the register to be added to the accumulator. Again, the register codes appear in Figure 2.16. Exercise 2.2: What is the binary code of the Instruction which will add the contents of register D to the accumulator?
CODE 000 00 I 010 011 100 101 110 111 REGISTER 8 C 0 E H l - (MEMORY) A
This simple two-word instruction will add the contents of the second byte of the instruction to the accumulator. The contents of the second
68
Z80 HARDWARE ORGANIZATION word of the instruction are said to be a "literal." They are data and are treated as eight bits without any particular significance. They could happen to be a character or numerical data. This is irrelevant to the operation. The code for this instruction is: 1 1 0 0 0 1 1 0 followed by the 8-bit byte "n" This is an immediate operation. "Immediate," in most programming languages, means that the next word, or words, within the instruction contains a piece of data which should not be interpreted (the way an opcode is). It means that the next one or two words are to be treated as a literal. The control unit is programmed to "know" how many words each instruction has. It will, therefore, always fetch and execute the right number of words for each instruction. However, the longer the possible number of words for the instruction, the more complex it is for the control unit to decode.
A Three-Word Instruction
LD A, (nn The instruction requires three words. It means: "Load the accumulator from the memory address specified in the next two bytes of the instruction." Since addresses are 16-bits long, they require two words. In binary, this instruction is represented by: 0 0 1 1 I 0 1 0: Low address: High address: 8 bits for the opcode 8 bits for the lower part of the address 8 bits for the upper part of the address
69
The FETCH phase of an instruction is implemented during the first three states of machine cycle MI; they are called T1, T2, and T3. These three states are common to all instructions of the microprocessor, as all instructions must be fetched prior to execution. The FETCH mechanism is the following: T1 : PC OUT The first step is to present the address of the next instruction to the memory. This address is contained in the program counter (PC). As the first step of any instruction fetch, the contents of the PC are placed on the address bus (see Figure 2.17). At this point, an address is presented to the memory, and the memory address decoders will decode this address in order to select the appropriate location within the memory. Several hundred ns (a nanosecond is 10' second) will elapse before the contents of the selected memory location become available on the out-
DATA US 1 ST.
u5
DEUXER
4
CORTESE SEQUENCER
TO MEMORY
DRESS BUS CONTROL SIGNALS
70
put pins of the memory, which are connected to the data bus. It is standard computer design to use the memory read time to perform an operation within the microprocessor. This operation is the incrementation of the program counter: T2: PC = PC + While the memory is reading, the contents of the PC are incremented
by 1 (see Figure 2.18). At the end of state T2, the contents of the
memory are available and can be transferred within the microprocessor: T3 INST into
IR
DATA BUS
SAS.
MULE
/AIL
a
A II
IT Pi
ACT
CVIIREILLER SEQUENCER LA S P LU
0.00RESS
Bus
COSMIC SIGNALS
The DECODE and EXECUTE Phases During state T3, the instruction which has been read out of the memory is deposited on the data bus and transferred into the instruction register of the Z80, from which point it is decoded. 71
I\
A
DEEIDDEL
!trot
/
FROM MEMORY
rITMP I
ACT
r r
ADDRESS BUS -AECIILROL SIGNALS
It shoUld be noted that state T4 of MI will always be required. Once the instruction has been deposited into IR during T3, it is necessary to decode and execute it. This will require at least one machine state, T4. A few instructions require an extra state of MI (state T5). It will be skipped by the processor for most instructions. Whenever the execution of an instruction requires more than Ml, i.e., M1, M2 or more cycles, the transition will be directly from state T4 of MI into state T1 of M2. Let us examine an example. The detailed internal sequencing for each example is shown in the tables of Figure 2.27. As these tables have not been released for the Z80, the 8080 tables are used instead. They provide an indepth understanding of instruction execution.
LD D, C
This corresponds to MOV rl, r2 for the 8080. Refer to line 1 of Fig. 2.27. By coincidence, the destination register in this example happens to be named "D", The transfer is illustrated in Figure 2.20. This instruction has been described in the previous section. It transfers the contents of register C, denoted by "C", into register D. The first three states of cycle Ml are used to fetch the instruction from the memory. At the end of T3, the instruction is in IR, the Instruction Register, from which point it can be decoded (see Figure 2.19). During T4: (S S S) ~~ TMP. The contents of C are deposited into TMP (See Figure 2.21).
72
During T5: (TMP) ~~ DDD. The contents of TMP are deposited into D. This is shown in Figure 2.22.
oo
I
AFTER
10001000
DECO FR
e.00er.ss eus
71
/4 I COMO. SIGHALS
73
B=.7.Re nS ._;
11151 PEG.
A
ii
ACT
PIA S
111
16
f)ADDRESS
eus
(WM S Wins
Execution of the instruction is now complete. The contents of register C have been transferred into the specified destination register D. This terminates execution of the instruction. The other machine cycles M2, M3, M4, and M5 will not be necessary and execution stops with Ml. It is possible to compute the duration of this instruction easily. The duration of every state for the standard Z80 is the duration of the clock: 500 ns. The duration of this instruction is the duration of five states, or 5 x 500 = 2500 ns = 2.5 us. With a 400 ns clock, 5 x 400 = 2000 ns = 2.0 us. Question: Why does this instruction require two states, T4 and T5, in order to transfer the contents C into D. rather than just one? It transfers the contents of C into TMP, and then the contents of ThIP into D. Wouldn't it be simpler to transfer the contents of C into D directly within a single state? Answer: This is not possible because of the implementation chosen for the internal registers. All the internal registers are, in fact, part of a
74
single RAM, a read/write memory internal to the microprocessor chip. Only one word may be addressed or selected at a time within an RAM (single-port). For this reason, it is not possible to both read and write into, or from, an RAM at two different locations. Two RAM cycles are required. It becomes necessary first to read the data out of the register RAM, and store it in a temporary register, TMP, then, to write it back into the final destination register, here D. This is a design inadequacy. However, this limitation is common to virtually all monolithic microprocessors. A dual-port RAM would be required to solve the problem. This limitation is not intrinsic to microprocessors and it normally does not exist in the case of bit-slice devices. It is a result of the constant search for logic density on the chip and may be eliminated in the future. Important Exercise: At this point, it is highly recommended that the user review by himself the sequencing of this simple instruction before we proceed to more complex ones. For this purpose, go back to Figure 2.14. Assemble a few small-sized "symbols" such as matches, paperclips, etc. Then move the symbols on Figure 2.14 to simulate the flow of data from the registers into the buses. For example, deposit a symbol into PC. TI will move the symbol contained in PC out on the address bus towards the memory. Continue simulated execution in this fashion until you feel comfortable with the transfers along the buses and between the registers. At this point, you should be ready to proceed. Progressively more complex instructions will now be studied: ADD A, r This instruction means: "Add the contents of register r (specified by a binary code S S S) to the accumulator (A), and deposit the result in the accumulator." This is an implicit instruction. It is called implicit as it does not explicitly reference a second register. The instruction explicitly refers only to register r. It implies that the other register involved in the operation is the accumulator. The accumulator, when used in such an implicit instruction, is referenced both as source and destination. Data will be deposited in the accumulator as a result of this addition. The advantage of such an implicit instruction is that its complete opcode is only eight bits in length. It requires only a three-bit register field for the specification of r. This is a fast way to perform an addition operation. Other implicit instructions exist in the system which will reference
75
PROGRAMMING THE Z80 other specialized registers. More complex examples of such implicit instructions are, for example, the PUSH and POP operations, which will transfer information between the top of the stack and the accumulator, and will at the same time update the stack pointer (SP), decrementing it or incrementing it. They implicitly manipulate the SP register. The execution of the ADD A, r instruction will now be examined in detail. This instruction will require two machine cycles, MI and M2. As usual, during the first three states of MI, the instruction is fetched from the memory and deposited in the IR register. At the beginning of T4, it is decoded and can be executed. It will be assumed here that register B is added to the accumulator. The code for the instruction will then be: 1 0 0 0 0 0 0 0 (the code for register B is 0 0 0). The 8080 equivalent is ADD r. ~~ ACT T4: (S S S) ~~ TMP,
INST. itG
r, 'S
k
4
E0.1R011 Oa CEA
MIEN \ .-IMI 0 Mi an
SP
Ma
CI V
ABB Eil BUS CONTROL SIGBILS
Two transfers will be executed simultaneously. First, the contents of the specified source register (here B) are transferred into TMP, i.e., to the right input of the ALU (see Fig. 2.23). At the same time, the contents of the accumulator are transferred to the temporary accumulator (ACT). By inspecting Fig. 2.23, you will ascertain that those transfers can occur in parallel. They use different paths within the system. The
76
Z80 HARDWARE ORGANIZATION transfer from B to TMP uses the internal data bus. The transfer from ACT uses a short internal path independent of this data bus. In order to gain time, both transfers are done simultaneously. At this point, both the left and the right input of the ALU are correctly conditioned. The left input of the ALU is now conditioned by the accumulator contents, and the right input of the ALU is conditioned by the contents of register B. We are ready to perform the addition. We would normally expect to see the addition take place during state T5 of MI. However, this state is simply not used. The addition is not performed! We will enter machine cycle M2. During state T I, nothing happens! It is only in state T2 of M2 that the addition takes place (refer to ADD r in Figure 2.27): T2 of M2: (ACT) + (TMP) ~~ A The contents of ACT are added to the contents of TMP, and the result is finally deposited in the accumulator. See Figure 2.24. The operation is now complete.
\ \
DATA BUS
k
IIIST. PIG.
I/ \\
DECOGEN B 4.; CONTROLLER SEQUENCER O C
, E"`X
brs.n
\n k
SP
PC
LSD
I's
Fig. 2.24: End of ADD r Question: Why was the completion of the addition deferred until state T2 of machine cycle M2, rather than taking place during state TS of MI? (This is a difficult question, which requires an understanding of CPU design. However, the technique involved is fundamental to clocksynchronous CPU design. Try to see what happens.)
77
INSTRUCTION N:
Ti
T2
FETCH
T3
REAL
I
EXECUTE-0'i INSTRUCTION N + ;I r4-FETCH I
T1 I T2 I T3
I T4 EXECUTE
L, (WHIP J
Fig. 2.25: FETCH-EXECUTE Overlap during TI-T2 M I. The duration of the ADD instruction would have been 5 x 500 = 2500 ns. With the overlap approach which has been implemented, once state T4 has been executed, the next instruction is initiated. In a manner 78
Z80 HARDWARE ORGANIZATION that is invisible to this next instruction, the "clever" control unit will use state T2 to carry out the end of the addition. On the chart T2 is shown as part of M2. Conceptually, M2 will be the second machine cycle of the addition. In fact, this M2 will be overlapped, i.e., be identical to machine cycle Ml of the next instruction. For the programmer, the delay introduced by ADD will be only four states, i.e., 4 x 500 = 2000 ns, instead of 2500 ns using the "straightforward" approach. The speed improvement is 500 ns, or 20%! The overlap technique is illustrated on Figure 2.25. It is used whenever possible to increase the apparent execution speed of the microprocessor. Naturally, it it not possible to overlap in all cases. Required buses or facilities must be available without conflict. The control unit "knows" whether an overlap is possible.
NOTES: i. The first memory cycle (4111 is always an instruction INN: the first far onlyl byte. containing the op code. is leldttd during this cycle. 2. U the READY input loon memory it net high dining T2 of each memory cycle. the processor will triter a wait state Nil until READY is templed as high. 3. Sates T4 and T5 are anent. as required, for operation, which are completely internal to the CPU. TM coo tents of the internal but during T4 and T5 are available at the data but: hit in designed for Holing curates only. An "X" denotes Mat the reagent. but ts only used far such internal operations as intlruclan decoding. 4. Only register emirs lip B (registers', ird CI ar re. 0 Regain 0 and El may to specified. 5. These states are skipotd.
121 II the condition was met. the maims el the raptier parr WZ are output on the 'dans lines fAa611 instead of the contents of the Paton own," 1PCI13. If the condition was not met. tutecycles M4 and MS are skipped: the mealier inlaid proceeds immediately to iM inittualcon fetch IM1 I al the eeeee Mittelman [yd.. 14. If the condition was not met, sub-cycles M2 and M3 BM skipped: the peticellen piirlead potted, Immediately to she rnstrutuon letS. IMIll of that neat instruction cycle. IS. Stack pad sub-cycle. 18. Stack swim ash-cycle. II. CONDITION NZ not Iwo IZ . 01 Z zero 12 11 NCc arry ICY 01 C carry ICY 1/ PO parity odd IP 01 PE panty even IP 11 P plus IS 01 PA mina, IS 11 CCC 000 001 010 011 TOO 101 110
G. Memory read sub-cycles; en inttrucion or data word will be reed. 7. Macaw wile sub-cycle. IL The READY signal is not recurred during the second and third sub-cyan IM2 and M3I. The HOLD signal is mama during 1s12 and MI. The SYNC sigml is nal generated duo, MI and M1 During the emeaman of DAD, M2 and M3 ere required fa an internal reginer.pair add: orenom is nal eeeeee need. 9. The results of dose arithmetic. Waal or alai instruction; ere not moved into the accumulator (AI until one T2 of the next insounion cycle. That n. A it loaded while the neat instruction it being fetched; this overapping of operations allows far fatter pocesorq. 10. II the value o1 1M lean tigniliant 4-bite of the action. lator is greater then 907 if the soak's,* carry bit is net. 6 is added to the accumulator. If the value al the most urn ant 4-bits al the accumuletoi is now greater than 9. or if IM carry at is set. 6 it added to the mop sentient 4-bits al the sccumulatar. II. Thin remetentt the first sub-cycle (the Interaction fetch, of the neat instruction cycle.
TB. I/Osuboycle, the I/O pares Elbil select code is dual. oted on adth33311m3D71A0,I and Li IS lAga 51. S. Output sub.cyele. 20. The promo& will remain idle in the halt stem until an imerrupt. ram or a told iumpted. When a hold aunt pa atattpied, iha CPU enters the hold node: after the hold node is terminated, the rantattier returns to the halt nate. After a awl n aCeepled, the morns begins eRecuIran at memory location ono. Alter an crilerrupt II accepted. he pactsser teatet the instruction lamed onto the date as koala a restart inMuctienl. SOS of Value lip a ODD r III A60 j
010 ' SP , II
E
H
J. -11 100 01 _1
011
_L
79
..........
......
or ...Dix. oak... ft n
.4. .4
. . . . . .. .
,,,,, ....
ra
. .
.. non. .
.........
....
in
...4 ...p. .
"4-.T..... affa.
imam . 1. . n
......1. .0..
n.
...,
.......
...... 4 ....
no . cone u.. u. ,..N. .r. .... ....
. ... . . . . . .4 . . , .. , , .. .. , " .. . , . ,
.a 1 . . e. .. 1 . .., .. . . . . 1 . . s. a . .. , .,
T , i 1 .. . a j . . , . . a rc .r. sumo. * p . iggn .. . 0 Z2Kpon . oinnts . ... t.p- ' . . .... I 4,,,, :1. i ...-.. , g.rvs%,
." ....
.4.c, ..,... 4w. ..c.......c44. ,. .....a ...4." ..,._...,.. ,.,4 .c. r i : T : --- .---....,,,_. ,...a u.-u.re 6.1ave* -7 2-- ..n.. n-...m
n iif sat 0. g au- ....no .... ..... 'Aram. .... ....
Mt OUT MM..
a n t. o $ p
Taut
CATS
DO -au
30
.w.
rrAvirgli
V., c111.
ri.ran 1 "
at& iirtel
isav-
rs
Let11117/14C,4
laen.inan.c-
-...041r
0.101111111
1.10-.16C1
OCTIillhe.C7-41.11
81
...moose
incase
..... leo
mom
non nom o o
o . m o 11 oo o o o
I I I I I I I I I
op o
via It no n, nn-.1
to
tm-c
to
n ogh. s
so to ,no ,,...
to oo_.....
1 "1 o o
iiatth ' TA- ".. mmo 'coo, ' o_oo.ow Ann. ,.,.0.._. rttuom c.f.i.." ."" " ".. ..y1.106,1 I 6..
I I I "-." :c: "" IS WIPP "I-4" ft MP 19A, ' MI 1 "0111 1' rc . IC . AL.. CV
I I I I I I I I
...-." Jib, II
ka"." tc SAC 0 0 0 0 I I 1
.._w
... . , . , , . . . . ., , , .. . . .
I I I I I I 1 I I 9 I I I I 0 0
,..,...... ,, ....... ..
ii.-CT $ -CI 1
AL..... ....-. c.
......mtin
1 . ec
c. o
c.......
C mwe wore
NU 11 &Ft.
. ...
stet
I 1111 I I 11 PI
,
else
1101 C 0 l 1 Mil-1.a
Nonce.. ICA
.....kr !MIA W I
vat c.i.f.,
I
igr), nPC, ..., :12:..4. "'"'' " 7.?.11..., ' ' *1-1
-
r2int
::41/W ;:rygild
It .C.
'
-f-L
"" "...!...
...,
PW. is
, , .. , ...
I I II / I A
:...-........ ,,,,, .
I. I 11%1 I. V
r,=. - ----"."
r,se.... ,,,,,. ..,... eir... sstl... ::::" - - - --"-..... ... ...... . -"I---- "-r-" ---" '-" . ...., .,_......
. .. . .
R:.
....
0
... .. , .
Mau%
f !
...........
...,....-
...... ..........
ILO.
82
CI 1.. C. .
. . is po..........
..ai.m...... pc.. .in."... ...,..P.-
-. ..
...
. ..
;Urpem a 'n" "--:Lex_ --.. - r 74,1Tou 'v.' " " .2 .... .j2470. .c..c i wo pi pp, ...... MMUS.
ra er. ... It .1, i cm TA -LI
:Ursa. p
N:it ta r n.a'ar.77:1....
taa-L-
...._1... ,.,__,.....
_I ..'.: ._ . 6;ral
83
PROGRAMMING THE Z80 Question: Would it be possible to go further using this scheme, and to also use state T3 of M2 if we have to execute a longer instruction? In order to clarify the internal sequencing mechanism, it is suggested that you examine Figure 2.27, which shows the detailed instruction execution for the 8080. The Z80 includes all 8080 instructions, and more. The information presented in Figure 2.27 is not available for the Z80. It is shown here for its educational value in understanding the internal operation of this microprocessor. The equivalence between Z80 and 8080 instructions is shown in Appendices F and G. A more complex instruction will now be examined: ADD A, (HL) The opcode for this instruction is 10000110. This instruction means "add to the accumulator the contents of memory location (HL)." The memory location is specified through a rather strange system. It is the memory location whose address is contained in registers H and L. This instruction assumes that these two special registers (HL) have been loaded with contents prior to executing the instruction. The 16-bit contents of these registers will now specify the address in the memory where data resides. This data will be added to the accumulator, and the result will be left in the accumulator. This instruction has a history. It has been supplied in order to provide compatibility between the early 8008, and its successor, the 8080. The early 8008 was not equipped with a direct-memory addressing capability! The procedure used to access the contents of the memory was to load the two registers H and L, and then execute an instruction referencing H and L. ADD A, (HL) is just such an instruction. It must be stressed that the 8080 and the Z80 are not limited in the same way as the 8008 in memory-addressing capability. They do have direct-memory addressing. The facility for using the H and L registers becomes an added advantage, not a drawback, as was the case with the 8008. Let us now follow the execution of this instruction (it is called ADD M for the 8080 and is the 16th instruction on Figure 2.27). States T1, T2, and T3 of MI will be used, as usual, to fetch the instruction. During state T4, the contents of the accumulator are transferred to its buffer register, ACT, and the left input of the ALU is conditioned. Memory must be accessed in order to provide the second byte of data which will be added to the accumulator. The address of this byte of
84
Z80 HARDWARE ORGANIZATION data is contained in H and L. The contents of H and L will therefore have to be transferred onto the address bus, where they will be gated to the memory. Let us do it.
4
DECODER CONIRIXEER 5 OU NC R
sr
TO MEMORY
DRESS BUS ECEITROS SIGRASS
5
Fig. 2.28: Transfer Contents of HI to Address Bus
During machine cycle M2,we read: HL OUT. H and L are deposited on the address bus, in the same way PC used to be deposited there in previous instructions. As a remark, it has already been indicated that during state Ti status is output on the data bus, but no use of this will be made here. From a simplified standpoint, it will require two states: one for the memory to read its data, and one for the data to become available and transferred onto the right input of the ALU, TMP, Both inputs of the ALU are now conditioned. The situation is analogous to the one we were in with the previous instruction ADDA, r: both inputs of the ALU are conditioned. We simply have to ADD as before. A fetch/execute overlap technique will be used, and, instead of executing the addition within state T4 of M2, final execution is postponed until state T2 of M3. It can be seen in Figure 2.27 that during T2 we indeed have: ACT + TMPA. The addition is finally performed, the contents of ACT are added to TMP, and the result deposited into the accumulator A. 85
Question: What is the apparent execution time (to the programmer) for this instruction? Using a 2.5 Mhz clock, is it 3.6 us? 2.8 us?
Another more complex instruction will now be examined which is a direct-memory addressing instruction using two invisible W and Z registers:
LD A,(nn)
The opcode is 00111010. The 8080 equivalent is LDA addr. As usual, states T1, T2, T3 of MI will be used to fetch the instruction from the memory. T4 is used, but no visible result can be described. During state T4, the instruction is in fact decoded. The control unit then finds out that it has to fetch the next two bytes of this instruction in order to obtain the address from which the accumulator will be loaded. The effect of this instruction is to load the accumulator from the memory contents whose address is specified in bytes 2 and 3 of the instruction. Note that state T4 is necessary to decode the instruction. It could be considered a waste of time since only part of the state is necessary to do the decoding. It is. However, this is the philosophy of clock-synchonous logic. Because micromstructsons are used internally to perform the decoding and execution, this is the penalty that has to be paid in return for the advantages of microprogramming. The structure of this instruction appears in Figure 2.29.
m: ! w01: L
LD A ADDRESS
'02: I
The next two bytes of instruction will now be fetched. They will specify an address (see Figure 2.30).
86
11110104
0
0000001100000000]
PC
REGISTERS
MEMORY
Lo
REGISTERS
MEMORY
The effect of the instruction is shown in Figures 2.30 and 2.31 above. Two special registers are available to the control unit within the Z80 (but not to the programmer). They are "W" and "Z", and are shown in Figure 2.28.
87
PROGRAMMING THE Z80 Second Machine Cycle M2: As usual, the first 2 states, T1 and T2, are used to fetch the contents of memory location PC. During T2, the program counter, PC, is incremented. Sometime by the end of T2, data becomes available from the memory, and appears on the data bus. By the end of T3, the word which has been fetched from memory address PC (B2, second byte of the instruction) is available on the data bus. It must now be stored in a temporary register. It is deposited into Z: B2 low Z (see Figure 2.32).
82
DA A U
ADDRESS DECODER
Z80 10-Z80
MEMORY
Machine Cycle M3: Again, PC is deposited on the address bus, incremented, and finally the third byte, B3, is read from the memory and deposited into register W of the microprocessor. At this point, i.e., by the end of state T3 of M3, registers W and Z inside the microprocessor contain B2 and B3, i.e., the complete 16-bit address which was originally contained in the two words following the instruction in the memory. Execution can now be completed. W and Z contain an address. This address will have to be sent to the memory, in order to extract the data. This is done in the next memory cycle: Machine Cycle M4: This time, W and Z are output on the address bus. The 16-bit address is sent to the memory, and by the end of state T2, data corresponding to the contents of the specified memory location becomes available. It is finally deposited in A at the end of state T3. This terminates execution of this instruction.
88
Z80 HARDWARE ORGANIZATION This illustrates the use of an immediate instruction. This instruction required three bytes in order to store a two-byte explicit address. This instruction also required four memory cycles, as it needed to go to the memory three times in order to extract the three bytes of this threeword instruction, plus one more memory access in order to fetch the data specified by the address. It is a long instruction. However, it is also a basic one for loading the accumulator with specified contents residing at a known memory location. It can be noted that this instruction requires the use of W and Z registers. Question: Could this instruction have used other registers than within the system?
Fit,
Answer: No. If this instruction had used other registers, for example the H and L registers, it would have modified their contents. After execution of this instruction, the contents of H and L would have been lost. It is always assumed in a program that an instruction will not modify any registers other than those it is explicitly using. An instruction loading the accumulator should not destroy the contents of any other register. For this reason, it becomes necessary to supply the extra two registers, W and Z, for the internal use of the control unit. Question: Would it be possible to use PC instead of W and Z? Answer: Positively not. This would be suicidal. The reader should analyze this. One more type of instruction will be studied now: a branch or jump instruction, which modifies the sequence in which instructions are executed within the program. So far, we have assumed that instructions were executed sequentially. Instructions exist which allow the programmer to jump out of sequence to another instruction within the program, or in practical terms, to jump to another area of the memory containing the program, or to another address. One such instruction is: JP nn This instruction appears on Line 18 of Figure 2.27' as "JMP addr." Its execution will be described by following the horizontal line of the Table. This is again a three-word instruction. The first word is the opcode, and contains 11000011. The next two words contain the
89
PROGRAMMING THE Z80 16-bit address, to which the jump will be made. Conceptually, the effect of this instruction is to replace the contents of the program counter with the 16 bits following the "JUMP" opcode. In practice, a somewhat different approach will be implemented, for reasons of efficiency. As before, the first three states of MI correspond to the instructionfetch. During state T4 the instruction is decoded and no other event is recorded (X). The next two machine cycles are used to fetch bytes B2 and B3 of the instruction. During M2, B2 is fetched and deposited into internal register Z. The next two steps will be implemented by the processor during the next instruction-fetch, as was the case already with the addition. They will be executed instead of the usual steps for Ti and T2 of the next instruction. Let us look at them. PC. In other The next two steps will be: WZ OUT and (WZ) + I ~~ words, the contents of WZ will be used instead of the contents of PC during the next instruction-fetch. The control unit will have recorded the fact that a jump was being executed and will execute the beginning of the next instruction differently. The effect of these two extra states is the following: The address placed on the address bus of the system will be the address contained in W and Z. In other words, the next instruction will be fetched from the address that was contained in W and Z. This is effectively a jump. In addition, the contents of WZ will be incremented by 1 and deposited in the program counter, so that the next instruction will be fetched correctly by using PC as usual. The effect is therefore correct. Question: Why have we not loaded the contents of PC directly? Why use the intermediate W and Z registers? Answer: It is not possible to use PC. If we had loaded the lower part of PC (PCL) with B2, instead of using Z, we would have destroyed PC! It would then have become impossible to fetch B3. Question: Would it be possible to use just Z, instead of W and Z? Answer: Yes, but it would be slower. We could have loaded Z with B2, then fetched B3, and deposited it into the high order half of PC (PCH). However, it would then have become necessary to transfer Z into PCL, before using the contents of PC. This would slow down the process. For this reason, both W and Z should be used. Further, and in order to save time, W and Z are not transferred into PC. They are directly gated to the address bus in order to fetch the next instruction.
90
Z80 HARDWARE ORGANIZATION Understanding this point is crucial to the understanding of efficient execution of instructions within the microprocessor. Question: (For the alert and informed reader only). What happens in the case of an interrupt at the end of M3? (If instruction execution is suspended at this point, the program counter points to the instruction following the jump, and the jump address, contained in W and Z, will be lost.) The answer is left as an interesting exercise for the alert reader. The detailed descriptions we have presented for the execution of typical instructions should clarify the role of the registers and of the internal buses. A second reading of the preceding section may help in gaining a detailed understanding of the internal operation of the Z80.
CLOCK BUS CONTROL PI P. 6 30 It, 40 25 BUSAK4--, 23 NMI .... 17 IRT I ft- 16 ,WCIT 0- 24 HALT .4-- 18 Rti b. 20 19 MI -4-Cd4 20 TO -.41-- 21 WA 4, 22
and
I To 5
MPU CONTROL
7 to 15 (except 1 I I
DO D7
DATA BUS
28
29
II
GND POWER
+5V
Fig. 2.33: Z80 MPU Pinout The Z80 Chip For completeness, the signals of the Z80 microprocessor chip will be examined here. It is not indispensable to understand the functions of
91
PROGRAMMING THE Z80 the Z80 signals in order to be able to program it. The reader who is not interested in the details of hardware may therefore skip this section. The pinout of the Z80 appears on Fig. 2.33. On the right side of the illustration, the address bus and the data bus perform their usual role, as described at the beginning of this chapter. We will describe here the function of the signals on the control bus. They are shown on the left of Figure 2.33. The control signals have been partitioned in four groups. They will be described, going from the top of Figure 2.33 towards the bottom. The clock input is 4). The Z80 incorporates the clock oscillator within the microprocessor chip. Only a 330-ohm pull-up resistor is necessary externally. It is connected to the 0 input and to 5 volts. However, at 4 MHz, an external clock driver is required. The two bus-control signals, BUSRQ and BUSAK, are used to disconnect the Z80 from its busses. They are mainly used by the DMA, but could also be used by another processor in the system. BUSRQ is the bus-request signal. It is issued to the Z80. In response, the Z80 will place its address bus, data bus, and tristate output control signals in the highimpedance state, at the end of the current machine cycle. BUSAK is the acknowledge signal issued by the Z80 once the busses have been placed in the high-impedance state. Six Z80 control signals are related to its internal status or to its sequencing: INT and NMI are the two interrupt signals. INT is the usual interrupt request. Interrupts will be described in Chapter 6. A number of input/output devices may be connected to the INT interrupt line. Whenever an interrupt request is present on this line, and when the internal interrupt enable flip-flop (IFF) is enabled, the Z80 will accept the interrupt (provided the BUSRQ is not active). It will then generate an acknowledge signal: IORQ (issued during the M I state). The rest of the sequence of events is described in Chapter 6. NMI is the non-maskable interrupt. It is always accepted by the Z80, and it forces the Z80 to jump to location 0066 hexadecimal. It too is described in Chapter 6. (It also assumes that BUSRQ is not active.) WAIT is a signal used to synchronize the Z80 with slow memory or input/output devices. When active, this signal indicates that the memory or the device is not yet ready for the data transfer. The Z80 CPU will then enter a special wait state until the WAIT signal becomes inactive. It will then resume normal sequencing. HALT is the acknowledge signal supplied by the Z80 after it has ex-
92
Z80 HARDWARE ORGANIZATION ecuted the HALT instruction. In this state, the Z80 waits for an external interrupt and keeps executing NOPs to continually refresh memory. RESET is the signal which usually initializes the MPU. It sets the program counter, register I and R to "0". It disables the interrupt enable flip-flop and sets the interrupt mode to "0", It is normally used after power is applied to the board. Memory and I/O Control Six memory and I/O control signals are generated by the Z80. They are: MREQ is the memory request signal. It indicates that the address present on the address bus is valid. A read or write operation can then be performed on the memory. MI is machine cycle 1. This cycle corresponds to the fetch cycle of an instruction. IORQ is the input/output request. It indicates that the I/O address present on bits 0-7 of the address bus is valid. An I/O read or write operation can then be carried out. IORQ is also generated together with Ml when the Z80 acknowledges an interrupt. This information may be used by external chips to place the interrupt response vector on the data bus. (Normal I/O operations never occur during the MI state. The combination IORQ plus Ml indicates an interrupt-acknowledge situation.) RD is the read signal.* It indicates the Z80 is ready to read the contents of the data bus into an internal register. It can be used by any external chip, whether memory or I/O, to deposit data onto the data bus. Wit. is the write signal.* It indicates that the data bus holds valid data, ready to be written into the specified device. RFSH is the refresh signal. When RFSH is active, the lower seven bits of the address bus contain a refresh address for dynamic memories. The MREQ signal is then used to perform the refresh by reading the memory. HARDWARE SUMMARY This completes our description of the internal organization of the Z80. The exact hardware details of the Z80 are not important here. However, the role of each of the registers is important and should be fully understood before proceeding to the next chapters. The actual instructions available on the Z80 will now be introduced, and basic programming techniques for the Z80 will be presented. *used in conjunction with MREQ or IOREQ, 93
94
B
(010) (100) 0 H
C
E I.
B'
c
GENERAL-PURPOSE REGISTERS
H.
I:
I R (interrupt vector) (mem refresh) IX IV SP (stack pointer) PC (program counter) INDEX REGISTERS
ARITHMETIC PROGRAMS
Arithmetic programs include addition, subtraction, multiplication, and division. The programs presented here will operate on integers. These integers may be positive binary integers or may be expressed in two's complement notation, in which case the left-most bit is the sign bit (see Chapter 1 for a description of the two's complement notation).
8-Bit Addition
We will add two 8-bit operands called OP1 and OP2, respectively stored at memory address ADRI, and ADR2. The sum will be called RES and will be stored at memory address ADR3. This is illustrated in Figure 3.1. The program which will perform this addition is the following: Instructions LD A, (ADR1) LD HL, (ADR 2) ADD A, (HL) LD (ADR 3), A Comments LOAD OP1 INTO A LOAD ADDRESS OF OP2 INTO HL ADD OP2 TO OPI SAVE RESULT RES AT ADR3
95
MEMORY
ADR I
(FIRST OPERAND )
ADR2
(SECOND OPERAND)
ADR3
(RESULT)
ADDRESSES
Fig. 3.1: Eight-Bit Addition RES = OP! + OP2 This is our first program. The instructions are listed on the left and comments appear on the right. Let us now examine the program. It is a four-instruction program. Each line is called an instruction and is expressed here in symbolic form. Each such instruction will be translated by the assembler program into one, two, three or four binary bytes. We will not concern ourselves here with the translation and will only look at the symbolic representation. The first line specifies loading the contents of ADRI into the accumulator A. Referring to Figure 3.1, the contents of ADR1 are the first operand. "OP1". This first instruction therefore results in transferring OP1 from the memory into the accumulator. This is shown in Figure 3.2. "ADRI" is a symbolic representation for the actual 16-bit address in the memory. Somewhere else in the program, the ADR1 symbol will be defined. It could, for example, be defined as being equal to the address "100", This load instruction will result in a read operation from address 100 (see Figure 3.2), the contents of which will be transferred along the data
96
Fig. 3.2: LD A, (ADRI): OPI is I oaded from Memory bus and deposited inside the accumulator. You will recall from the previous chapter that arithmetic and logical operations operate on the accumulator as one of the source operands. (Refer to the previous chapter for more details.) Since we wish to add the two values OPI and OP2 together, we must first load OPI into the accumulator. Then, we will be able to add the contents of the accumulator, i.e., add OPI to OP2. The right-most field of this instruction is called a comment field. It is ignored by the assembler program at translation time, but is provided for program readability. In order to understand what the program does, it is of paramount importance to use good comments. This is called documenung a program. Here the comment is self-explanatory: the value of OP1, which is located at address ADRI, is loaded into the accumulator A. The result of this first instruction is illustrated by Figure 3.2. The second instruction of our program is: LD HL, (ADR2) It specifies: "Load from (ADR2) into registers H and L." In order to read the second operand, OP2, from the memory, we must first place its address into a register pair of the Z80, such as H and L. Then, we can add the contents of the memory location whose address is in H and L to the accumulator. ADD A, (HL) Referring to Figure 3.1, the contents of memory location ADR2 are OP2, our second operand. The contents of the accumulator are now OPI, our first operand. As a result of the execution of this instruction, OP2 will be fetched from the memory and added to OPI. This is illustrated in Figure 3.3
97
OAIA PUS
x-02
^WI?
ADDRESS SUS
The sum will be deposited in the accumulator. The reader will remember that, in the case of the Z80, the results of the arithmetic operation are deposited back into the accumulator. In other processors, it may be possible to deposit these results in other registers, or back into the memory. The sum of OP1 and OP2 is now contained in the accumulator. To complete our program, we simply have to transfer the contents of the accumulator into memory location ADR3, in order to store the results at the specified location. This is performed by the fourth instruction of our program: LD (ADR3), A This instruction loads the contents of A into the specified address ADR3. The effect of this final instruction is illustrated by Figure 3.4.
zoo
DATA BUS
APR
NS
ADDOISS BUS
98
Before execution of the ADD operation, the accumulator contained OP I (see Figure 3.3). After the addition, a new result has been written into the accumulator. It is "OP I + OPr . Recall that the contents of any register within the microprocessor, as well as any memory location, remain the same after a read operation has been performed on this register. In other words, reading the contents of a register or memory location does not change its contents. It is only, and exclusively, a write operation into this register location that will change its contents. In this example, the contents of memory locations ADRI and ADR2 remain unchanged throughout the program. However, after the ADD instruction, the contents of the accumulator will have been modified, because the output of the ALU has been written into the accumulator. The previous contents of A are then lost. Actual numerical addresses may be used instead of ADRI, ADR2, and ADR3. In order to keep symbolic addresses, it will be necessary to use so-called "pseudo-instructions" which specify the value of these symbolic addresses, so that the assembly program may, during translation, substitute the actual physical addresses. Such pseudo-instructions could be, for example: ADRI = 100H ADR2 = 120H ADR3 = 200H Exercise 3.1: Now close this book. Refer only to the list of instructions at the end of the book. Write a program which will add two numbers stored at memory locations LOCI and LOC2. Deposit the results at memory location LOC3. Then, compare your program to the one above. 16-Bit Addition An 8-bit addition will only allow the addition of 8-bit numbers, i.e., numbers between 0 and 255, if absolute binary is used. For most practical applications it is necessary to add numbers having 16 bits or more, i.e., to use multiple precision. We will here present examples of arithmetic on I6-bit numbers. They can be readily extended to 24, 32 bits or more (always multiples of 8 bits). We will assume that the first operand is stored at memory locations ADRI and ADRI-1. Since OP I is a 16-bit number this time, it will require two 8-bit memory locations. Similarly,
99
PROGRAMMING THE Z80 OP2 will be stored at ADR2 and ADR2-1. The result is to he deposited at memory addresses ADR3 and ADR3-I. This is illustrated in Figure 3.5. H indicates the high hall (bits 8 through 15), while I. indicates the low half (bits 0 through 7).
(OPI pi MAI
DPI It
D"-'
ADO
(0,11H (021t
Pali- I
insw
ins.
LD HL, ADR2 ADD A, (HL), LD (ADR3), A LD A, (ADR I-I) DEC HL ADC A, (H L) LD (ADR3-I), A
LOAD LOW HALF OF OPI ADDRESS OF LOW HALF OF OP2 ADD OPI AND OP2 LOW STORE RESULT, LOW LOAD HIGH HALF OF OPI ADDRESS OF HIGH HALF OF OP2
(OPI + OP2) HIGH + CARRY STORE RESULT, HIGH
100
BASIC PROGRAMMING TECHNIQUES The first four instructions of this program are identical to the ones used for the 8-bit addition in the previous section. They result in adding the least significant halves (bits 0-7) of OP1 and OP2. The sum, called "RES" is stored at memory location ADR3 (see Figure 3.5). Automatically, whenever an addition is performed, any resulting carry (whether "0" or "I") is saved in the carry bit C of the flags register (register F). If the two numbers do generate a carry, then the C bit will be equal to "I" (it will be set). If the two 8-bit numbers do not generate any carry, the value of the carry bit will be "0". The next four instructions of the program are essentially like those used in the previous 8-bit addition program. This time they add together the most significant half (or high half, i.e., bits 8-15) of OF! and OP2, plus any carry, and store the result at address ADR3-I. After execution of this 8-instruction program, the 16-bit result is stored at memory locations ADR3 and ADR3-1, as specified. Note, however, that there is one difference between the second half of this program and the first half. The "ADD" instruction which has been used is not the same as in the first half. In the first half of this program (the 3rd instruction), we had used the "ADD" instruction. This instruction adds the two operands, regardless of the carry. In the second half, we use the "ADC" instruction, which adds the two operands together, plus any carry that may have been generated. This is necessary in order to obtain the correct result. The addition initially performed on the low operands may result in a carry. Such a possible carry must be taken into account in the second half of the addition. The question which comes naturally then is: what if the addition of the high half of the operands also results in a carry? There are two possibilities: the first one is to assume that this is an error. This program is then designed to work for results of only up to 16 bits, but not 17: The other one is to include additional instructions to test explicitly for the possibility of a carry at the end of this program. This is a choice which the programmer must make, the first of many choices. Note: we have assumed here that the high part of the operand is stored "on top of" the lower part, i.e., at the lower memory address. This need not necessarily be the case. In fact, addresses are stored by the Z80 in the reverse manner: the low part is first saved in the memory, and the high part is saved in the next memory location. In order to use a common convention for both addresses and data, it is recommended that data also be kept with the low part on top of the high part. This is illustrated in Figure 3.6.
101
MN I ADO' .
(OPT It HOPI IN
ADO] AD42. I
(0P211 (On pi
Aw]
ADO .I
InsR
Fig. 3.6: Storing Operands in Reverse Order When operating on multibyte operand, it is important to keep in mind two essential conventions: the order in which data is stored in the memory. where data pointers are pointing: low byte or high byte. Exercises 3.2 and 3.3 are designed to clarify this point.
Exercise 3.2: Rewrite the 16-bit addition program above with the memory layout indicated in Figure 3.6. Exercise 3.3: Assume now that ADR I does not point to the lower half
of OPI (as in Figures 3.5 or 3.6), but points to the higher part of OPI. This is illustrated in Figure 3.7. Again, write the corresponding program.
102
(OPI
(0P2)1. (CIP2)/1
iwsn
It is the programmer, i.e., you, who must decide how to store I6-bit numbers (i.e., low part or high part first) and also whether your address references point to the lower or to the higher half of such numbers. This is another choice which you will learn to make when designing algorithms or data structures. The programs presented above are traditional programs, using the accumulator. We will now present an alternative program for the 16-bit addition that does not use the accumulator, but instead uses some of the special 16-bit instructions available on the Z80. Operands will be assumed to be stored as indicated in Figure 3.5. The program is: LD HL, (ADRI) LD BC, (ADR2) ADD HL, BC LD (ADR3), HL LOAD HL WITH OPI LOAD BC WITH OP2 ADD 16 BITS STORE RES INTO ADR3
Note how much shorter this program is, compared to our previous version. It is more "elegant." In et limited manner, the Z80 allows registers H and L to be used as a 16-bit accumulator.
103
PROGRAMMING THE Z80 Exercise 3.4: Using the 16-bit instructions which have just been introduced, write an addition program for 32-bit operands, assuming that operands are stored as shown in Figure 3.8. (The answer appears below.) Answer : LD HL, (ADR1) LD BC, (ADR2) ADD HL, BC LD (ADR3) LD HL, (ADR1 + 2) LD BC, (ADR2+ 2) ADC HL, BC LD (ADR3 +2)
MEMORY ADRI +3 HIGH OPRI ADRI LOW
104
BASIC PROGRAMMING TECHNIQUES Now that we have learned to perform a binary addition, let us turn to subtraction. Subtracting 16-Bit Numbers Doing an 8-bit subtract would be too simple. Let us keep it as an exercise and directly perform a 16-bit subtract. As usual, our two numbers, OP1 and OP2, are stored at addresses ADRI and ADR2. The memory layout will be assumed to be that of Figure 3.6. In order to subtract, we will use a subtract operation (SBC) instead of an add operation (ADD). Exercise 3.5: Now write a subtraction program. The program appears below. The data paths are shown in Figure 3.9. LD HL, (ADR1) LD DE, (ADR2) AND A SBC HL, DE LD (ADR3), HL OP1 INTO HL OP2 INTO DE CLEAR CARRY OPI OP2 RES INTO ADR3
The program is essentially like the one developed for 16-bit addition. However, the Z80 instruction-set has two types of additions on double registers: ADD and ADC, but only one type of subtraction: SBC. As a result, two changes can be noted.
105
MEMORY
(ORIN
IOPID
ION A
ADRI
IODIDE
ADRI f I
A first change is the use of SBC instead of ADD. The other change is the "AND A" instruction, used to clear the carry flag prior to the subtraction. This instruction does not modify the value of A. This precaution is necessary because the Z80 is equipped with two modes of addition, with and without carry on the H and L register, but with only one mode of subtraction, the SBC instruction of "subtract with carry" when operating on the HL register pair. Because SBC automatically takes into account the value of the carry hit, it must beset too prior to starting the subtraction. This is the role of the "AND A" instruction. Exercise 3.6: Rewrite tire subtraction mograin without using the specialized I6-bit ucsuuctwit. Exercise 3.7: II }tie the subtract pmgrani for 8-bit operands. It must be remembered that in the case of two's complement arithmetic, the final value of the carry flag has no meaning. If an overflow condition has occurred as a result of the subtraction, then the overflow bit (bit V) of the flags register will have been set. It can then be tested.
106
BASIC PROGRAMMING TECHNIQUES The examples just presented are simple binary additions or subtractions. However, another type of arithmetic may be necessary; it is BCD arithmetic. BCD ARITHMETIC 8-Bit BCD Addition The concept of BCD arithmetic has been presented in Chapter I. Let us recall its features. It is essentially used for business applications where it is imperative to retain every significant digit in a result. In the BCD notation, a 4-bit nibble is used to store one decimal digit (0 through 9). As a result, every 8-bit byte may store two BCD digits. (This is called packed BCD). Let us now add two bytes each containing two BCD digits. In order to identify the problems, let us try some numeric examples first. Let us add "01" and "02"; "1" "2" is represented by: 0000 0001 is represented by: 0000 0010 0000 0011
This is the BCD representation for "03" (If you feel unsure of the BCD equivalent, refer to the conversion table at the end of the book.) Everything worked very simply in this case. Let us now try another example. "08" is represented by 0000 1000 "3" is represented by 0000 0011 Exercise 3.8: Compute the sum of the two numbers above in the BCD representation. What do you obtain? (answer follows) If you obtain "0000 1011", you have computed the binary sum of 8 and 3. You have indeed obtained 1I in binary. Unfortunately, "1011" is an illegal code in BCD. You should obtain the BCD representation of "I I", i.e., 0001 0001! The problem stems from the fact that the BCD representation uses only the first ten combinations of 4 digits in order to encode the decimal symbols 0 through 9. The remaining six possible combinations of 4 digits are unused, and the illegal "1011" is one such combination. In other words, whenever the sum of two BCD digits is greater than 9,
107
PROGRAMMING THE Z80 then one must add 6 to the result in order to skip over the 6 unused codes. Add the binary representation of "6" to 1011: 1011 + 0110 The result is: 0001 0001 (illegal binary result) (+6)
This is, indeed, "11" in the BCD notation! We now have the correct result. This example illustrates one of the basic difficulties of the BCD mode. One must compensate for the six missing codes. A special instruction, "DAA", called "decimal adjust," must be used to adjust the result of the binary addition. (Add 6 if the result is greater than 9.) The next problem is illustrated by the same example. In our example, the carry will be generated from the lower BCD digit (the right-most ones into the left-most one. This internal carry must be taken into account and added to the second BCD digit. The addition instruction takes care of this automatically. However, it is often convenient to detect this internal carry from bit 3 to bit 4 (the "half-carry"). The H flag is provided for this purpose. As an example, here is a program to add the BCD numbers "11" and "22": LD A, 1 IH ADD A, 22H DAA LD (ADR), A LOAD LITERAL BCD '1 1 ' ADD LITERAL BCD '22' DECIMAL ADJUST RESULT STORE RESULT
In this program, we are using a new symbol "H". The "H" sign within the operand field of the instruction specifies that the data it follows is expressed in hexadecimal notation. The hexadecimal and the BCD representations for digits "0" through "9" are identical. Here we wish to add the literals (or constants) "11" and "22". The result is stored at the address ADR. When the operand is specified as part of the instruction, as it is in the above example, this is called immediate addressing. (The various addressing modes will be discussed in detail in Chapter 5.) Storing the result at a specified address, such as LD (ADR), A is called absolute addressing when ADR represents a 16-bit address.
108
MEMORY
(Minn
Fig. 3.10: Storing BCD Digits This program is analogous to the 8-bit binary addition, but uses a new instruction: "DAA". Let us illustrate its role in. an example. We will first add "II" and "22" in BCD: 00010001 (11) + 00100010 (22) = 00110011 (33)
VV
The result is correct, using the rules of binary addition. Let us now add "22" and "39", by using the rules of binary addition: 00100010 (22) + 00111001 (39) = 01011011
VV
"1011" is an illegal BCD code. This is because BCD uses only the first 10 binary codes, and "skips over" the next 6. We must do the same, i.e. add 6 to the result: 01011011 (binary result) 0110 (6) = 0110 0001 (61)
109
PROGRAMMING THE Z80 Exercise 3.9: Could we move the DAA instruction to the program after the instruction LD (ADR), A?
BCD Subtraction BCD subtraction is, in appearance, complex. In order to perform a BCD subtraction, one must add the ten's complement of the number, just as one adds the two's complement of a number to perform a binary subtract. The ten's complement is obtained by computing the complement to 9, then adding "I" This requires typically three to four operations on a standard microprocessor. However, the Z80 is equipped with a powerful DAA instruction which simplifies the program. The DAA instruction automatically adjusts the value of the result in the accumulator, depending on the value of the C, H and N flags before DAA, to the correct value. (See the next chapter for more details on DAAJ
16-Bit BCD Addition 16-bit addition is performed just as simply as in the binary case. The program for such an addition appears below: LD A, (ADR1) LD HL, (ADR2) ADD A, (HL) DAA LD (ADR3), A LD A, (ADRI + I) INC HL ADC A, (HL) DAA LD (ADR3 + I), A Packed BCD Subtract Elementary BCD addition and subtraction have been described. However, in actual practice, BCD numbers include any number of bytes. As a simplified example of a packed BCD subtract, we will assume that the two numbers NI and N2 include the same number of BCD bytes. The number of bytes is called COUNT The register and LOAD (OP I) L INTO A LOAD ADR2 INTO HL (OPI + OP2) LOW DECIMAL ADJUST STORE (RESULT) LOW LD (OPI) H INTO A POINT TO ADR2 + I (OPI + OP2) HIGH + CARRY DECIMAL ADJUST STORE (RESULT) HIGH
110
BASIC PROGRAMMING TECHNIQUES memory allocation is shown in Figure 3.11. The program appears below: BCDPAK LD B, COUNT DE, N2 LD LD HL, N1 AND A MINUS LD A, (DE) SBC A, (HL) DAA LD (HL), A INC DE INC HL DJNZ MINUS
COUNT N2 N2 COUNT NI
NI
N 2 - N1
NI and N2 represent the addresses where the BCD numbers are stored. These addresses will be loaded in register pairs DE and HL: BCDPAK LD B, COUNT DE, N2 LD HL, NI LD
111
PROGRAMMING THE Z80 Then, in anticipation of the first subtraction, the carry bit must be cleared. It has been pointed out that the carry bit can be cleared in a number of equivalent ways. Here, for example, we use: AND A The first byte of N2 is loaded into the accumulator, then the first byte of NI is subtracted from it. The DAA instruction is then used, to obtain the correct BCD value: MINUS LD SBC DAA A, (DE) A, (HL)
Finally, the pointers io the current byte are incremented: INC DE INC HL The counter is decremented and the subtraction loop is executed until it reaches the value "0": DJNZ MINUS The DJNZ instruction is a special Z80 instruction which decrements register B and jumps if it is not zero, in a single instruction. Exercise 3. /0: Compare the program above to the one for the 16-bit Nita, addition. What is the difference? Exercise 3.11: Can you exchange the roles of DE and HL? (Hint: Be careful with SBC.1 Exercise 3.12: Write the subtraction program for a 16-bit BCD.
BCD Flags In BCD mode, the carry flag set as the result of an addition indicates the fact that the result is larger than 99. This is not like the two's complement situation, since BCD digits are represented in true binary. Conversely, the presence of the carry flag after a subtraction indicates a borrow. Instruction Types
We have now used two types of microprocessor instructions. We
112
have used LD, which loads the accumulator from the memory address, or stores its contents at the specified address. This is a data transfer instruction. Next, we have used anthmetac instructions, such as ADD, SUB, ADC and SBC. They perform addition and subtraction operations. More ALU instructions will be introduced soon in this chapter. Still other types of instructions are available within the microprocessor which we have not used yet. They arc in particular "jump" instructions, which will modify the order in which the program is being executed. This new type of instruction will be introduced in our next example. Note that jump instructions are often called "branch" for conditional situations, i.e. instances where there is a logical choice in the program. The "branch" derives its name from the analogy to a tree, and implies a fork in the representation of the program.
MULTIPLICATION
Let us now examine a more complex arithmetic problem: the multiplication of binary numbers. In order to introduce the algorithm for a binary multiplication, let us start by examining a usual decimal multiplication: We will multiply 12 by 23.
The multiplication is performed by multiplying the right-most digit of the multiplier by the multiplicand, i.e., "3" x "12", The partial product is "36". Then one multiplies the next digit of the multiplier, i.e., "2", by "12". "24" is then added to the partial product. But there is one more operation: 24 is offset to the left by one position. We will say that 24 is shifted left by one position. Equivalently, we could have said that the partial product (36) had been shifted one postnon to the right before adding. The two numbers, correctly shifted, are then added and the sum is 276. This is simple. The binary multiplication is performed in exactly the same way.
113
Let us look at an example. We will multiply 5 x 3: 101 (MPD) (5) (3) x 011 (MPR) 101 (PP) 10l 000 (15) 01111 (RES)
In order to perform the multiplication, we operate exactly as we did above. The formal representation of this algorithm appears in Figure 3-12. It In flowchart for the algorithm, our first flowchart. Let us examine it more closely.
NO
NO
DONE
This flowchart is a symbolic representation of the algorithm we have Just presented. Every rectangle represents an order to be carried out. It will be translated into one or more program instructions. Every
114
BASIC PROGRAMMING TECHNIQUES diamond-shaped symbol represents a test being performed. This will be a branching point in the program. If the test succeeds, we will branch to a specified location. If the test does not succeed, we will branch to another location. The concept of branching will be explained later, in the program itself. The reader should now examine this flowchart and ascertain that it does indeed exactly represent the algorithm which has been presented. Note that there is an arrow coming out of the last diamond at the bottom of the flowchart, back to the first diamond on top. This is because the same portion of the flowchart will be executed eight times, once for every bit of the multiplier. Such a situation, where execution will restart at the same point, is called a program loop for obvious reasons. Exercise 3.13: Multiply "4" by "7" in binary, using the flowchart, and verify that you obtain "28" If you do not, try again. It is only if you obtain the correct result that you are ready to translate this flowchart Into a program. 8-By-8 Multiplication Let us now translate this flowchart into a program for the Z80. The complete program appears in Figure 3.13. We are going to study it in detail. As you will recall from Chapter I, programming consists here of translating the flowchart of Figure 3.12 into the program of Figure 3.13. Each of the boxes in the flowchart will be translated by one or more instructions. It is assumed that MPR and MPD already have a value. MPY88 LD LD LD LD LD MULT SRL LOAD MULTIPLIER INTO C B IS BIT COUNTER LOAD MULTIPLICAND INTO E CLEAR D SET RESULT TO 0 SHIFT MULTIPLIER BIT INTO CARRY NC, NOADD TEST CARRY JR ADD MPD TO RESULT ADD HL, DE SHIFT MPD LEFT NOADD SLA E SAVE BIT IN D D RL DECREMENT SHIFT COUNTER DEC B DO IT AGAIN IF COUNTER # 0 NZ, MULT JP (RESAD), HL STORE RESULT LD BC, (MPRAD) B, 8 DE, (MPDAD) D, 0 HL, 0 C Fig. 3.13: 8 x S Multiplication Program
115
PROGRAMMING THE Z80 The first box of the flowchart is an brilialization box. It is necessary to set a number of registers or memory locations to "0", as this program will require their use. The registers which will be used by the multiplication program appear in Figure 3.14.
PRAD)
PD
(MPDADI
(RESULT)
RES
(RESAD)
Fig 3.14: 8 x 8 MultiplicationThe Registers Three register pairs of the Z80 are used for the multiplication program. The 8-bit multiplier is assumed to reside at memory address MPRAD. The multiplicand MPD is assumed to reside at memory address MPDAD. The multiplier and the multiplicand respectively will be loaded into registers C and E (see Figure 3.14). Register B will be used as a counter. Registers D and E will hold the multiplicand as it is shifted left one bit at a time. Note that, even though only C and E need to be loaded initially, a 16bit load must be used, so that B and D will also be loaded from memory, and will have to be reset respectively to "8" and to "0".
116
BASIC PROGRAMMING TECHNIQUES Finally, the results of an 8-bit by 8-bit multiplication may require up to 16 bits. This is because 2' x 2' = 2". Two registers must therefore be reserved for the result. They are registers H and L, as indicated on Figure 3.14. The first step is to load registers B, C, and E with the appropriate contents, and to initialize the result (the partial product) to the value "0" as specified by the flowchart of Figure 3.12. This is accomplished by the following instructions: MPY88 LD BC, (MPRAD) LD B, 8 LD DE, (MPDAD) D, 0 LD LD HL, 0 The first three instructions respectively load MPR into the register pair BC, the value "8" into register B, and MPD into the register pair DE. Since MPR and MPD are 8-bit words, they are, in fact, loaded into registers C and E respectively, while the next words in the memory after MPR and MPD get loaded into B and D. This is shown in Figure 3.15 and 3.16. The next instruction will zero the contents of D. In this multiplication program, the multiplicand will be shifted left before being added to the result (remember that, optionally, it is possible to shift the result right instead, as indicated in the fourth box of the flowchart of Figure 3.12). The multiplicand MPD will be shifted into register D at each step. This register D must therefore be initialized to the value "0". This is accomplished by the fourth instruction. Finally, the fifth instruction sets the contents of registers H and L to 0 in a single instruction.
ORY
MPOAD
Ii
Referring back to the flowchart of Figure 3.12, the next step is to test the least significant bit (the right-most bit)ol the multiplier MPR. If this bit is a "I", then the value of MPD must be added to the partial result, otherwise it will not be added. This is accomplished by the next three instructions: MULT SRL C JR NC, NOADD ADD HL, DE The first problem we must solve is how to test the least significant bit of the multiplier, contained in register C. We could here use the BIT instruction of the Z80, which allows testing any bit in any register. However, in this case, we would like to construct a program as simple as possible, using a loop. If we were using the BIT instruction here, we would first test bit 0, then later test bit I, and so on until we reached bit 7. This would require a different instruction every time, and a simple loop could not be used. In order to shorten the length of the program. we must use a different instruction. Here we are using a shift instruction. Note: There is a way to use the BIT instruction and a loop, but this would require the program to modify itself, a practice we will avoid.
118
BASIC PROGRAMMING TECHNIQUES SRL is a new type of operation within the arithemetic and logical unit. It stands for "shift right logical." A logical shift to the right is characterized by the fact tnat a"0" comes into bit position 7. This can be contrasted to an arithemtic shift to the right, where the bit coming into position 7 is identical to the previous value of bit 7. The different types of shift operations will be described in the next chapter. The effect of the SRL C instruction is illustrated in Figure 3.14 by an arrow coming out of register C and into the square used to designate the carry bit (also called "C"). At this point, the right-most bit of the MPR will be in the carry bit C, where it can be tested. The next instruction, "JR NC, NOADD", is a jump operation. It means "jump on no carry" (NC) to the address (the label) NOADD. I f the contents of the carry bit are "0" (no carry), then the program will jump to the address NOADD. If the contents of C are "I" (the carry bit is set), then no branch will occur, and the next sequential instruction will be executed, i.e., the instruction "ADD HL, DE" will be executed. This instruction specifies that the contents of D and E be added to H and L, with the result in H and L. Since E contains the multiplicand MPD (see Figure 3.14), this adds the multiplicand to the partial result. At this point, regardless of whether MPD has been added to the result or not, the multiplicand must be shifted left (this is the fourth box in the flowchart of Figure 3.12). This is accomplished by: NOADD SLA E SLA stands for "shift left arithmetic." It has just been explained above that there are two types of shift operations, a logical shift and an arithmetic shift. This is the arithmetic one. In the case of a left shift, an SLA specifies that the bit coming into the right part of the register (the least significant bit) be a "0" (just as in the case of an SRL before). As an example, let us assume that the initial contents of register E were 00001001. After the SLA instruction, the contents of E will be 00010010. And the contents of the carry bit will be 0. However, looking back at Figure 3.14, we really want to shift the most significant bit (called the MSB) of E directly into D (this is illustrated by the arrow on the illustration coming from E into D). However, there is no instruction which will shift a double register such as D and E in one operation. Once the contents of E have been shifted, the left-most bit has "fallen into" the carry bit. We must collect this bit from the carry bit and shift it into register D. This is accomplished by the next instruction: RL D 119
RL is still another type of shift operation. It stands for rotate left. In a rotation operation, as opposed to a shift operation, this bit coming into the register is the contents of the carry bit C (see Figure 3.17). This is exactly what we want. The contents of the carry bit C are loaded into the right-most part of D, and we have effectively transferred the leftmost bit of E. This sequence of two instructions is illustrated in Figure 3.18. It can be seen that the bit marked by an X in the most significant position of E will first be transferred into the carry bit, then into the least significant position of D. Effectively, it will have been shifted from E into D. At this point, referring back to the flowchart of Figure 3.12, we must point to the next bit of MPR and check for the eighth bit. This is accomplished by decrementing the byte counter, contained in register B (see Figure 3.14). The register is decremented by: DEC B This is a decrement instruction, which has the obvious effect. Finally, we must check whether the counter has decremented to the value zero. This is accomplished by checking the value of the Z bit. The reader will recall that the Z (zero) flag indicates whether the previous arithmetic operation (such as a DEC operation) has produced a zero result. However, note that DEC HL, DEC BC, DEC DE, DEC IX, DEC SP do not affect the Z flag. If the counter is not "0", the operation is not finished, and we must execute this program loop again. This is accomplished by the next instruction: JP NZ MULT SHIFT LEFT
r>
CARRY
LJ
ROTATE LEFT CARRY
t
Fig. 3.18: Shifting from E into D
This is a jump instruction which specifies that whenever the Z bit is not set (NZ stands for non-zero), a Jump occurs to location MULT. This is the program loop, which will be executed repeatedly until B decrements to the value 0. Whenever B decrements to the value 0, the Z bit will be set, and the JP NZ instruction will fail. This will result in the next sequential instruction being executed, namely: LD (RESAD), HL This instruction merely saves the contents of H and L, i.e., the result of the multiplication, at address RESAD, the address specified for the result. Note that this instruction will transfer the contents of both registers H and L into two consecutive memory locations, corresponding to addresses RESAD and RESAD + 1. It saves 16 bits at a time. Exercise 3.14: Could you write the same multiplication program using the BIT instruction (described in the next chapter) instead of the SRL C instruction? What would be the disadvantage? Let us now improve the program, if possible: Exercise 3.15: Can JR be substituted for JP at the end of the program? If so, what is the advantage? Exercise 3.16: Can you use DJNZ to shorten the end of the program?
121
PROGRAMMING THE Z80 Exercise 3.17: Examine the two instructions: LD D. 0 and LD HL, 0 at the beginning of the program. Can you substitute: XOR A LD D. A LD H, A LD L, A If so, what is the impact on size (number of bytes) and speed? Note that, in most cases, the program that we have just developed will be a subroutine and the final instruction in the subroutine will be RET (return). The subroutine mechanism will be explained later in this chapter. Important Self-Tell This is the first significant program we have encountered so far. It includes many different types of instructions, including transfer instructions (LD), arithmetic operations (ADD), logical operations (SRL, SLA, R1), and jump operations (JR, JP). It also implements a program loop, in which the lower seven instructions, starting at address MULT, are executed repeatedly. In order to understand programming, it is essential to understand the operation of such a program in complete detail. The program is much longer than the previous simple arithmetic programs we have developed so far, and it should be studied in detail. An important exercise will now be proposed. The reader is strongly urged to do this exercise completely and correctly before proceeding. This will be the only real proof that the concepts presented so far have been understood. If a correct result is obtained, it will mean that you have really understood the mechanism by which instructions manipulate information in the microprocessor, transfer it between the memory and the registers, and process it. If you do not obtain the correct result, or if you do not do this exercse, it is likely that you will experience difficulties later in writing programs yourself. Learning to program requires personal practice. Please pause now, take a piece of paper, or use the illustration of Figure 3.19, and do the following exercise: Exercise 3.18: Every lime that a program is written, it should be verified by hand, in order to ascertain that its results will be correct. We are going to do just that: the goal of this exercise is to fill in the table of Figure 3.19 completely and accurately.
122
LABEL
INSTRUCTION
BC
C
(CARRY)
HL
Fig. 3.19: Form for Multiplication Exercise You may want to write directly on Figure 3.19 or make a copy of it. You must determine the contents of every relevant register in the Z80 after the execution of each instruction in the program, from beginning to end. All the registers used by the program of Figure 3.13 arc shown in Figure 3.19. From left to right, they are registers B and C, the carry C, registers D and E, and, finally, registers H and L. On the left part of this illustration, fill in the label, if applicable, and then the instructions
123
PROGRAMMING THE Z80 being executed. On the right of the instruction, fill in the contents of each register after execution of the instruction. Whenever the contents of a register are not known (indefinite), you may use dashes to represent its contents. Let us start filling in this table together. You will then have to fill it out by yourself until the end. The first line appears below:
LABEL
INSTRUCTION
BC
HL
MPY88
LD BC,(0200)
00
03
--
--
--
--
We will assume here that we are multiplying "3" (MPR) by "5" (MPD). The first instruction to be executed is "LD BC, (MPRAD)", The contents of memory location MPRAD is loaded into registers B and C. It has been assumed that MPR is equal to 3, i.e., "00000011". After execution of this instruction, the contents of register C have been set to "3". Note that this instruction will also result in loading register B with whatever followed MPR in the memory. However, the next instruction in the program will take care of this by loading register B with "8", as shown in Figure 3.21. Note that, at this point, the contents of D and E and H and L are still undefined, and this is indicated by dashes. The LD instruction does not condition the carry bit, so that the contents of the carry bit C are undefined. This is also indicated by a dash.
LABEL
INSTRUCTION
BC --03
CD .--
E ---
HI ----
MPY88
00
Fig. 3.21: Multiplication: After Two Instructions The situation after the execution of the first five instructions of the program (just before the MULT) is shown in Figure 3.22.
124
LABEL
INSTRUCTION
BC .. .. 03 03 03 03
C -
D .. -00 00 00
E .. -05 05 05
H .. ---00
I. .. ---00
MPY88
00 08 08 08
Fig. 3.22: Mu tiplication: After Five Instructions The SRL instruction will perform a logical shift right, and the rightmost bit of MPR will fall into the carry bit. You can see in Figure 3.23 that the contents of MPR after the shift is "0000 0001". The carry bit C is now set to "1". The other registers are unchanged by this operation. Please continue to fill out the chart by yourself. A second iteration is shown at the end of this chapter in Fig. 3.41.
LABEL
INSTRUCTION
BC
CD
: 1 : 8 8 8 8 8 8 8 88 8
MPY88
00 08 08 08 08 08 08 08 08 08 07 07
03 03 03 03 03 01 01 01 01 01 01 01
---
---
---
05 05 05 05 OA OA OA OA
00 00 00 00 00 00 00 00
00 00 00 05 05 05 05 05
MULT
NOADD
r 0 0000 _._
125
PROGRAMMING THE Z80 A complete listing showing the contents of all the Z80 registers and the flags is shown in Fig. 3.39 at the end of this chapter for the complete multiplication. A hex or decimal listing is shown in Fig. 3.40. Programming Alternatives The program that we have just developed could have been written.in many other ways. As a general rule, every programmer can usually find ways to modify, and often improve, a program. For example, we have shifted the multiplicand left before adding. It would have been mathematically equivalent to shift the result one position to the right before adding it to the multiplicand. As a matter of fact, this is an interesting exercise!
Exercise 3.19: Write an 8 x 8 multiplication program using the same algorithm, but shifting the result one position to the right instead of shifting the multiplicand by one position to the left. Compare it .to the previous program, and determine whether this different approach would be faster or slower than the preceding one. The speeds of the Z80 instructions are given in the next chapter.
Improved Multiplication Program The program that we have just developed is a straightforward translation of the algorithm to code. However, effective programming requires close attention to detail, and the length of the program can often be reduced or its execution speed can be improved. We are now going to study alternatives designed to improve this basic program.
Step I
A first possible improvement lies in the better utilization of the Z80 instruction set. The second-to-last instruction as well as the preceding one can be replaced by a single instruction: DJNZ LOOP This is a special Z80 "automated jump" which decrements the B register and branches to a specified location if it is not "0" To be absolutely correct, the instruction is not completely identical to the previous pair DEC B JP NZ, MULT
126
only a few bytes away, and this improvement is legitimate. The resulting program is shown in Figure 3.24 below: MPY88B LD LD
LD
DE, (MPDAD)
BC, (MPRAD) B, 8
BIT COUNTER
LD HL, 0 MULT SRL C JR NC, NOADD HL, DE ADD NOADD SLA E RL DJNZ MULT LD (RESAD), HL RET Fig. 3.24: Improved Multiply, Step 1
Step 2 In order to improve this multiplication program further, we will observe that three different shift operations are used in the initial program of Figure 3.13. The multiplier is shifted right, then the multiplicand MPD is shifted left, in two operations, by first shifting register E left, then rotating register D to the left. This is time-consuming. A standard programming "trick" used in the case of multiplication is based on the following observation: every time that the multiplier is shifted by one bit position, another bit position becomes available in the multiplier register. For example, assuming that the multiplier shifts right (in the previous example), a bit position becomes available on the left. Simultaneously, it can be observed that the first partial product (or "result") will use, at most, 9 bits. If a single register had been allocated to the result in the beginning of the program, we could then use the bit
position that has been vacated by the multiplier to store the ninth bit of the result.
After the next shift of the MPR, the size of the partial product will be increased by just one bit again. In other words, a single register can be reserved intially for the partial product, and the bit positions which are being freed by the multiplier can then be used as the MPR is being shifted. In order to improve the program, we are therefore going to
127
PROGRAMMING THE Z80 assign MPR and RES to a register pair. Ideally, they should be shifted together in a single operation. Unfortunately, the Z80 shifts only 8-bit registers at a time. Like most other 8-bit microprocessors, it has no instruction that allows shifting 16 bits at a time. However, another trick can be used. The Z80 (like the 8080) is equipped with special 16-bit add instructions that we have already used. Provided that the multiplier and the result are stored in the register pair H and L, we can use the instruction: ADD HL, HL which adds the contents of H and L to itself. Adding a number to itself is doubling it. Doubling a number in the binary system is equivalent to a left shift. We have just obtained a 16-bit shift in a single instruction. Unfortunately, the shift occurs to the left when we would like it to occur to the right. This is not a problem. Conceptually, the MPR can be shifted either left or right. We have used a right shift algorithm because this is the one which is used in ordinary addition. However, it does not necessarily need to be so. The addition operation is commutative, and the order can be reversed: shifting the MPR to the left is just as valid. In order to take advantage of this simulated 16-bit shift, we will have to shift the MPR to the left. Therefore, the MPR will reside in register H and the result in register L. The resulting register configuration is shown in Figure 3.25.
B COUNTER
128
The rest of the program is essentially identical to the previous one. The resulting program appears below: MUL88C LD HL, (MPRAD-I) LD L, 0 LD DE, (MPDAD) LD D.0 LD B,8 MULT ADD HL, HL JR NC, NOADD ADD HL, DE NOADD DJNZ MULT LD (RESAD), HL RET
Fig. 3.26: Improved Multiply, Step 2 When comparing this program to the previous one, it can be seen that the length of the multiplication loop (the number of instructions between MULT and the Jump) has been reduced. This program has been written in fewer instructions and this will usually result in faster execution. This shows the advantage of selecting the correct registers to contain the information. A straightforward design will generally result in a program that works. It will not result in a program that is optimizer/. It is therefore important to understand and use the available registers and instructions in the best possible way. These examples illustrate a rational approach to register selection and instruction selection for maximum efficiency. Exercise 3.20: Compute the speed of a multiplication operation using this last program. Assume that a branch will occur in 50% of the cases. Look up the number of cycles required by every instruction in the index section. Assume a clock rate of 2 MHz (one cycle = 2 us). Exercise 3.21: Note that here we have used the register pair D and E to contain the multiplicand. How would the above program be changed tl we had used the register pair B and C instead? (Hint: this would require a modification at the end.) Exercise 3.22: Why did we have to bother zeroing register D when loading MPD into E? Finally, let us address a detail which may look immung to the programmer who is not yet familiar with the Z80. The reader will have
129
PROGRAMMING THE Z80 noticed that, in order to load MPD into E from the memory, we had to load both registers D and E at the same time from a memory address. This is because, unless the address is contained in registers H and L, there is no way to fetch a single byte directly and load it into register E. This is a feature carried over from the early 8008, which had no direct addressing mode. The feature was carried forward into the 8080, with some improvements, and improved still further in the Z80, where it is possible to fetch 16 bits directly from a given memory address (but not 8 bits - except toward register A). Now, having solved this possible mystery, let us execute a more complex multiplication. A 16 X 16 Multiplication In order to put our newly acquired skills to a test, we Will multiply two 16-bit numbers. However, we will assume that the result requires only 16 bits, so that it can be contained in one of the register pairs. The result, as in our first multiplication example, is contained in registers H and L (see Figure 3.27). The multiplicand MPD is contained in registers D and E.
COUNTER
MPR, HIGH
A MPR. LOW
130
BASIC PROGRAMMING TECHNIQUES It would be tempting to deposit a multiplier into register B and C. However, if we want to take advantage of the DJNZ instruction, register B must be allocated to the counter. As a result, half of the multiplier will be in register C, and the other half in register A (see Figure 3.27). The multiplication program appears below: MULI6 LD LD LD LD LD LD MULT SRL RRA JR ADD NOADD EX ADD NC, NOADD HL, DE DE, HL HL, HL A, (MPRAD + 1) C, A A, (MPRAD) B, 16 DE. (MPDAD) HL, 0 C MPR, HIGH MPR, LOW COUNTER MPD RIGHT SHIFT MPR, HIGH ROTATE RIGHT MPR, LOW TEST CARRY ADD MPD TO RESULT DOUBLE SHIFT MPD LEFT
Finally, the low part of MPR can be read directly into the accumulator: LD A, (MPRAD)
131
PROGRAMMING THE Z80 The rest of the registers, B, D, E, H, and L are initialized as usual: LD LD LD B, 16 DE, (MPDAD) HL, 0
A 16-bit shift must be performed on the multiplier. It requires two separate shift or rotate operations on registers C and A: MULT SRL C RRA After the 16-bit shift, the right-most bit of the MPR, i.e., the LSB, is contained in the carry bit C where it can be tested: R NC, NOADD
As usual, the multiplicand is not added to the result if the carry bit is "0", and is added to the result if the carry bit is "I": ADD HL, DE Next, the multiplicand MPD must be shifted by one position to the left. However, the Z80 does not have an instruction which will shift the contents of register D and E simultaneously to the left by one bit position, and it can also not add the contents of D and E to itself. The contents of D and E will therefore first be transferred into H and L, then doubled, and transferred back to D and E. This is accomplished by the next three instructions: NOADD EX DE, HL ADD HL, HL DE, HL EX Finally, the counter B is decremented and a jump occurs to the beginning of the loop as long as it does not decrement to "0": DJNZ MULT
As usual, it is possible to consider other register allocations which may (or may not) result in shorter codes: Exercise 3.23: Load the multiplier into registers B and C. Place the counter in A. Write the corresponding multiplication program and discuss the advantages or disadvantages of this register allocation.
132
BASIC PROGRAMMING TECHNIQUES Evercise 3.24: Referring to the original 16-bit multiplication program of Figure 3.28, can you propose a way to shift the MPD, contained in registers D and E, without transferring it into registers H and L? Exercise 3.25: Write a 16-by-/6 multiplication program Kloch detects the fact that the result has more than 16 bits. This is a simple improvement of our basic program. Exercise 3.26: Write a 16-by-la multiplication program with a 32-ha result. The suggested register allocation appears in figure 3.29. Remember that the initial result after the first addition in the loop will require only 16 bus, and that the multiplier will free one ba fin' each subsequent aeration.
MPD
MPR
RES
Fig. 3.29: 16 x 16 Multip y with 32-Bit Result Let us now examine the last usual arithmetic operation, the division. BINARY DIVISION The algorithm for binary division is analogous to the one which has been used for the multiplication. The divisor is successively subtracted from the high order bits of the dividend. After each subtraction, the result is used instead of the initial dividend. The value of the quotient is simultaneously increased by I every time. Eventually, the result of the subtraction is negative. This is called an overdraw. One must then restore the partial result by adding the divisor back to it. Naturally, the quotient must be simultaneously decremented by I. Quotient and dividend are then shifted by one bit position to the left and the algorithm is repeated. The flow-chart is shown in Figure 3.30. The method just described is called the restoring method. A variation of this method which yields an improved speed of execution is called the non-restoring method.
133
1
SHIFT LEFT DIVIDEND (WITH 8 LEADING ifs) AND QUOTIENT
YES
QUOTIENT =QUOTIENT
COUNTER = COUNTER I
COUNTER:
DIVIDEND/QUOTIENT
BASIC PROGRAMMING TECHNIQUES 16-by-8 Division As an example, let us here examine a I6-by-8 division, which will yield an 8-bit quotient and an 8-bit remainder dividend. The register allocation is shown in Figure 3.31. The program appears below: DIVI68 LD LD LD LD LD DIV XOR SBC INC JP ADD DEC A, (DVSAD) LOAD DIVISOR D, A INTO D E, 0 HL, (DVDAD) LOAD 16-BIT DIVIDEND B, 8 INITIALIZE COUNTER A CLEAR C BIT HL, DE DIVIDEND DIVISOR HL QUOTIENT = QUOTIENT + P, NOADD HL, DE HL TEST IF REMAINDER POSITIVE RESTORE IF NECESSARY QUOTIENT = QUOTIENT I SHIFT DIVIDEND LEFT LOOP UNTIL B = 0
Fig. 3.32: 16/8 Division Program The first five instructions in the program load the divisor and the dividend respectively into the appropriate registers. They also initialize the counter, in register B, to the value 8. Note again that register B is a preferred location for a counter if the specialized Z80 instruction DJ NZ is to be used: DI V168 LD LD LD LD LD A, (DVSAD) D, A E, 0 HL, (DVDAD) B, 8
Next, the divisor is subtracted from the dividend. Since an SBC instruction must be used (there is no 16-bit subtract without carry), the carry must be set to the value "0" before subtracting. This can be accomplished in a number of ways. The carry can be cleared by perform-
135
ing instructions such as: XOR A AND A OR A Here, an XOR is used: DIV XOR A
It is anticipated that the subtraction will be successful, i.e., that the remainder will be positive. This is called the "trial subtract" step (refer to the flowchart of Figure 3.30). The quotient is therefore incremented by one. If the subtraction has in fact failed (i.e., if the remainder is negative), the quotient will have to be decremented by one later on: INC HL The result of the subtraction is then tested: JP P, NOADD
If the remainder is positive or zero, the subtraction has been successful, and it is not necessary to store it. The program jumps to address NOADD. Otherwise, the current dividend must be restored to its previous value, by adding the divisor back to it, and the quotient must be decremented by one. This is performed by the next instructions: ADD HL, DE DEC HL Finally, the resulting dividend is shifted left, in anticipation of the next trial subtract operation. Finally, the B counter is decremented and tested for the value "0". As long as B is not zero, this loop is executed: NOADD ADD HL, HL DJNZ DIV RET Exercise 3.27: Verify the operation of this division program by hand, by filling out the table of Figure 3.33, as in Exercise 3.18 for the multiplication. Note that the contents of D need not be entered on the form of Figure 3.33, since they are never modified.
136
LABEL
INSTRUCTION
Fig. 3.33: Form for Division Program 8-Bit Division The following program uses a restoring method, and leaves a complemented quotient in A. It divides 8 bits by 8 bits (unsigned). E IS DIVIDEND C IS DIVISOR A IS QUOTIENT B IS REMAINDER DIV88 XOR A LD B, 8 E LOOP88 RL RLA SUB C JR NC, $ + 3 ADD A, C DJNZ LOOP88 LD B, A LD A, E RLA CPL RET CLEAR ACCUMULATOR LOOP COUNTER ROTATE CY INTO ACCDIVIDEND CY WILL BE OFF TRIAL SUBTRACT DIVISOR SUBTRACT OK RESTORE ACCUM, SET CY PUT REMAINDER IN B GET QUOTIENT SHIFT IN LAST RESULT BIT COMPLEMENT BITS
Note: the "S" symbol in the sixth instruction represents the value of the program counter.
137
DIVISOR
IX IY
Fig. 3.34: Non-Restoring DivisionThe Registers Register B is used as a counter, initially set to 16. A and C contain the dividend. D and E contain the divisor. H and L contain the result. The I6-bit dividend is shifted left by: RL C RLA The remainder is shifted left by: ADC HL, HL. The final quotient is left in B, C, with the remainder in HL. The program follows.
138
BASIC PROGRAMMING TECHNIQUES DIVI6 LD LD LD LD LD OR JR LD LD LD TRIALSB RL RLA ADC B, (IX + 1) C, (IX) D,(IY + 1) E, (IY) A, D E
(DIVISOR) HIGH OR (DIVISOR) LOW Z, ERROR CHECK FOR DIVISOR = ZERO A, B GET (DVD) HI CLEAR RESULT HL, 0 B, 16 COUNTER ROTATE RESULT + ACC C LEFT HL, HL
LEFT SHIFT. NEVER SETS CARRY. MINUS DIVISOR SBC HL, DE NULL CCF RESULT BIT NC, NGV ACCUMULATOR JR NEGATIVE? PTV DJNZ TRIALSB COUNTER ZERO? DONE JP ROTATE RESULT + ACC RESTOR RL C LEFT RLA ADC HL, HL AS ABOVE AND A ADC HL, DE RESTORE BY ADDING DVSR JR C, PTV RESULT POSITIVE JR Z, NULL RESULT ZERO NGV DJNZ RESTOR COUNTER ZERO? DONE RL C SHIFT IN RESULT BIT RLA HL, DE ADD CORRECT REMAINDER LD B, A QUOTIENT IS IN B, C RET
139
PROGRAMMING THE Z80 Exercise 3.28: Compare the previous program to the following one, using a restoring technique: DIVIDEND IN AC DIVISOR IN DE QUOTIENT IN AC REMAINDER IN HL DIV'S LD HL, 0 LD B, 16 C LOOPI6 RL RLA ADC HL, HL HL, DE SBC NC, $ + 3 JR ADD HL, DE CCF DJNZ LOOPI6 C RL RLA RET CLEAR ACCUMULATOR SET COUNTER ROT ACC-RESULT LEFT LEFT SHIFT TRIAL SUBTRACT DIVISOR SUB WAS OK RESTORE ACCUM CALC RESULT BIT COUNTER NOT ZERO SHIFT IN LAST RESULT BIT
LOGICAL OPERATIONS The other class of instructions which can be executed by the ALU inside the microprocessor is the set of logical instructions. They include: AND, OR and exclusive OR (XOR). In addition, one can also include here the shift and rotate operations which have already been utilized, and the comparison instruction, called CP for the Z80. The individual use of AND, OR, XOR, will be described in Chapter 4 on the instruction set. Let us now develop a brief program which will check whether a given memory location called LOC contains the value "0", the value "1", or something else. The program will introduce the comparison instruction, and perform a series of logical tests. Depending on the result of the comparison, one program segment or another will be executed.
140
The first instruction: "LD A, (LOC)" reads the contents of memory location LOC, and loads it into the accumulator. This is the character we want to test. It is compared to the value 0 by the following instruction: CP OOH This instruction compares the contents of the accumulator to the hexadecimal value "00", i.e., the bit pattern "0000 0000" This comparison instruction will set the Z bit in the flags register to the value "I", if it succeeds. This bit can then be tested by the next instruction: JP Z, ZERO
The jump instruction tests the value of the Z bit. If the comparison succeeds, the Z bit has been set to one, and the Jump will succeed. The program will then jump to the address ZERO. If the test fails, then the next sequential instruction will be executed: CP 01H Similarly, the following jump instruction will branch to location ONE if the comparison succeeds. If none of the comparisons succeed, then the instruction at location NONEFOUND will be executed. JP NONEFOUND Z, ONE
141
PROGRAMMING THE Z80 This program was introduced to demonstrate the value of the comparison instruction followed by a jump. This combination will be used in many or the following programs. Exercise 3.29: Refer to the definition of the LD A, (LOCI instruction in the next chapter. Evannne the effect of this instruction on the flags, if any. Is the second instruction of this program necessary (CP 0010? Exercise 3.30: Write the program which will read the contents of menuny location "24" and branch to an address called' STAR"if there was a "*" on memory location 24. The bit pattern for a "*" in binary notation will be assumed to be represented by "00101010".
INSTRUCTION SUMMARY We have now studied most of the important instructions of the Z80 by using them. We have transferred values between the memory and the registers. We have performed arithmetic and logical operations on such data. We have tested it, and depending on the results of these tests, have executed various portions or the program. In particular, special "automated" Z80 instructions such as DJNZ have been used to shorten programs. Other automated instructions: LDDR, CPIR, INIR will be introduced throughout the remainder of this book. Full use has been made of special Z80 features, such as 16-bit register instructions to simplify the programs, and the reader should be careful not to use these programs on an 8080: they have been optimized for the Z80. We have also introduced a structure called a loop. Another important programming structure will be introduced now: the subroutine.
SUBROUTINES In concept, a subroutine is simply a block of instructions which has been given a name by the programmer. From a practical standpoint, a subroutine must start with a special instruction called a subroutine declaration, which identifies it as such for the assembler. It is also terminated by another special instruction called a return. Let us first illustrate the use of a subroutine in a program in order to demonstrate its value. Then, we will examine how it is actually implemented.
142
MAIN PlitGliA.
SU5a0U1041
Can we
Can eve
Fig. 3.35: Subroutine Calls The use of a subroutine is illustrated in Figure 3.35. The main program appears on the left of the illustration. The subroutine is shown symbolically on the right. Let us examine the subroutine mechanism. The lines of the main program are executed successively until a new instruction "CALL SUB" is met. This special instruction is the subroutine call and results in a transfer to the subroutine. This means that the next Instruction to be executed after the CALL SUB is the first instruction within the subroutine. This is illustrated by arrow I on the illustration. Then, the subprogram within the subroutine executes just like any other program. We will assume that the subroutine does not contain any other calls. The last instruction of this subroutine is a RETURN. This is a special instruction which will cause a return to the main program. The next instruction to be executed after the RETURN is the one followina the CALL SUB in the main program. This is illustrated by arrow 3 on the illustration. Program execution continues then, as illustrated by arrow 4. In the body of the main program a second CALL SUB appears. A new transfer occurs, shown by arrow 5. This means that the body of the subroutine is again executed following the CALL SUB instruction. Whenever the RETURN within the subroutine is encountered, a return occurs to the instruction following the CALL SUB in question. This is illustrated by arrow 7. Following the return to the main program, program execution proceeds normally, as illustrated by arrow 8. The effect of the two special instructions CALL SUB and RETURN should now he clear. What is the value of the subroutine mechanism? The essential value of the subroutine is that it can be called from any number of points in the main program, and used repeatedly without
143
PROGRAMMING THE Z80 rewrsting u. A first advantage is that this approach saves memory space, since there is no need to rewrite the subroutine every time. A second advantage is that the programmer can design a specific subroutine only once and then use it repeatedly. This is a significant simplification in program design. Exercise 3.31: What is the main disadvantage of a subroutine? (Answer follows.) The disadvantage of the subroutine should be clear just by examining the now of execution between the main program and the subroutine. A subroutine results in a slower execution, since extra instructions must be executed: the CALL SUB and the RETURN. Implementation of the Subroutine Mechanism We will examine here how the two special instructions, CALL SUB and RETURN, are implemented internally within the processor. The effect of the CALL SUB instruction is to cause the next instruction to be letched at a new address. You will remember (or else read Chapter I again) that the address of the next instruction to be executed in a computer is contained in the program counter (PC). This means that the effect of the CALL SUB is to substitute new contents in register PC. Its effect is to load the start address of the subroutine in the program counter. Is that really sufficient? To answer this question, let us consider the other instruction which has to be Implemented: the RETURN. The RETURN must cause, as its name indicates, a return to the instruction that follows the CALL SUB. This is possible only if the address of this instruction has been preserved somewhere. This address happens to be the value of the program counter at the time that the CALL SUB was encountered. This is because the program counter is automatically incremented every time it is used (read Chapter I again). This is precisely the address that we want to preserve, so that we can later perform the RETURN. The next problem is: where can we save this return address? This address must be saved in a location where it is guaranteed that it will not be erased. However, let us now consider the following situation, illustrated by Figure 3.36. In this example, subroutine I contains a call to SUB2. Our mechanism should work in this case as well. Naturally, there might even be more than two subroutines, say N "nested" calls. Whenever a new
144
BASIC PROGRAMMING TECHNIQUES CALL is encountered, the mechanism must therefore again store the program counter. This implies that we need at least 2N memory locations for this mechanism. Additionally, we will need to return from SUB2 first and SUBI next. In other words, we need a structure which can preserve the chronological ordering in which addresses have been saved. The structure has a name and has already been introduced. It is the stack. Figure 3.38 shows the actual contents of the stack during successive subroutine calls. Let us look at the main program first. At address 100, the first call is encountered: CALL SUBI. We will assume that, in this microprocessor, the subroutine call uses 3 bytes (RST is an exception). The next sequential address is therefore not "101", but "103". The CALL instruction uses addresses "100", "101", "102"Because the control unit of the Z80 "knows" that it is a 3-byte instruction, the value of the program counter, when the call has been completely decoded, will be "103". The effect of the call will be to load the value "280" in the program counter. "280" is the starting address of SUBI.
Fig. 3.36: Nested Calls We are now ready to demonstrate the effect of the RETURN instruction and the correct operation of our stack mechanism. Execution proceeds within SUB2 until the RETURN instruction is encountered at time 3. The effect of the RETURN instruction is simply to pop the top of the stack into the program counter. In other words, the program counter is restored to its value prior to the entry into the subroutine. The top of the stack in our example is "303". Figure 3.38 shows that, at time 3, value "303" has been removed from the stack and has been put back into the program counter. As a result, instruction execution proceeds from address "303". At time 4, the RETURN of SUBI is encountered. The value on top of the stack is "103". It is popped and is installed in the program counter. As a result, program execution will proceed from location "103" on within the main program. This is, indeed,
145
PROGRAMMING THE Z80 the effect that we wanted. Figure 3.38 shows that at time 4 the stack is again empty. The mechanism works. The subroutine call mechanism works up to the maximum dimension of the stack. This is why early microprocessors which had a 4- or 8-register stack were essentially limited to 4 or 8 levels of subroutine calls. Note that, on Figures 3.36 and 3.37, the subroutines have been shown to the right of the main program. This is only for the clarity of the diagram. In reality, the subroutines are typed by the user as regular instructions of the program. On a sheet of paper, when producing the listing of the complete program, the subroutines may be at the beginning of the text, in its middle, or at the end. This is why they are preceded by a subroutine declaration: they must be identified. The special instructions tell the assembler that what follows should be treated as a subroutine. Such assembler directives will be discussed in Chapter 10.
ADDRESS VANN)
103 M3
0
RETURN
STACK:
TIME 0 103
TIME C 103
TIMEC)
Z80 Subroutines
The basic concepts relating to subroutines have now been presented. It has been shown that the stack is required in order to implement this mechanism. The Z80 is equipped with a 16-bit stack-pointer register. The stack can therefore reside anywhere within the memory and may have up to 64K (1K = 1024) bytes, assuming they are available for that purpose. In practice, the start address for the stack, as well as its maximum dimension, will be defined by the programmer before writing his program. A memory area will then be reserved for the stack. The subroutine-call instruction, in the case of the Z80, is called CALL, and comes in two versions; the direct or unconditional call, such as CALL ADDRESS, is the one we have already described. In addition, the Z80 is equipped with a conditional call instruction which will call a subroutine if a condition is met. For example: CALL NZ, SUBI will result in a call to subroutine 1 if the Z flag is zero at the time of the test. This is a powerful facility, since many subroutine calls are conditional, i.e., occur only if some specific condition is met. CALL CC, NN is executed only if the condition specified by "CC" is true. CC is a set of three bits (bits 3, 4, and 5 of the opcode) which may specify up to eight conditions. They correspond respectively to the four flags "Z", "C", "Ply", "S" being either zero or non-zero. Similarly, two types of return Instructions are provided: RET and RET CC. RET is the basic return instruction. It occupies one byte, and causes the top two bytes of the stack to be re-installed in the program counter. It is unconditional. RET CC has the same effect except that it is executed only if the conditions specified by CC are true. The condition bits are the same as for the CALL instruction just described. Additionally, two specialized types of return are available which are used to terminate interrupt routines: RETI, RETN. They are described in the section on the Z80 instructions as well as in the section on interrupts. Finally, one more specialized instruction is provided which is analogous to a subroutine call, but allows the program to branch to only one of eight starting locations located in page zero. This is the RST P instruction. This is a one-byte instruction which automatically preserves the program counter in the stack, and causes a branch to the address specified by the three-bit P field. The P field corresponds to bits 3, 4 and 5 of the insrtuction, multiplied by eight.
147
PROGRAMMING THE Z80 In other words, if bits 3, 4, 5 are "000", the jump will occur to location 00H. If these bits are "001", the branch will occur to 08H, ctc. up to I I I, which will cause a branch to location 38H. The RST instruction is very efficient in terms of speed since it is a single-byte instruction. However, it can jump to only eight locations, in page 0. Additionally, these addresses in page 0 are only eight bytes apart. This instruction is a carry-over from the 8080 and was extensively used for interrupts. This will be described in the interrupt section. However, this instruction may be used for any other purpose by the programmer, and should be considered as a possible specialized subroutine call. Subroutine Examples Most of the programs that we have developed and are going to develop would usually be written as subroutines. For example, the multiplication program is likely to be used by many areas of the program. In order to facilitate and clarify program development, it is therefore convenient to define a subroutine whose name would be, for example, MULT. At the end of this subroutine we would simply add the instruction RET. Exercise 3.32: If MULT is used as a subroutine, would it "damage" any internal flags or registers? Recursion Recursion is a word used to indicate that a subroutine is calling itself. If you have understood the implementation mechanism, you should now be able to answer the following question: Exercise 3.33: Is it legal to let a subroutine call itself? (In other words, will everything work even if a subroutine calls itself?) If you are not sure. drays; the slack and fill it with the successive addresses. Then, look at the registers and memory (see Exercise 3.18) and determine if a problem exists. Interrupts will be discussed in the input/output chapter (Chapter 6). All returns except returns from interrupts are one-byte instructions; all calls are 3-byte instructions (except RST). Exercise 3.34: Look at the execution tunes of the CALL and the RET instructions in the next chapter. Why is the return from a subroutine so much faster than the CALL? (Hint: if the answer is not obvious, look again at the stack implementation of the subroutine mechanism, and analyze the internal operations that must be performed.)
148
BASIC PROGRAMMING TECHNIQUES Subroutine Parameters When calling a subroutine, one normally expects the subroutine to work on some data. For example, in the case of multiplication, one wants to transmit two numbers to the subroutine which will perform the multiplication. We saw in the case of the multiplication routine that this subroutine expected to find the multiplier and the multiplicand in given memory locations. This illustrates one method of passing parameters: through memory. Two other techniques are used, so that we have three ways of passing parameters. Ithrough registers 2through memory 3through the stack Registers can be used to pass parameters. This is an advantageous solution, provided that registers are available, since one does not need to use a fixed memory location: the subroutine remains memory-independent. If a fixed memory location is used, any other user of the subroutine must be very careful that he uses the same convention and that the memory location is indeed available (look at Exercise 3.19 above). This is why, in many cases, a block of memory locations is reserved simply to pass parameters among various subroutines. Using memory has the advantage of greater flexibility (more data), but results in poorer performance and also in tying the subroutine to a given memory area. Depositing parameters in the stack has the same advantage as using registers: it is memory-independent. The subroutine simply knows that it is supposed to receive, say, two parameters which are stored on top of the stack. Naturally, it has disadvantages: it clutters the stack with data and, therefore, reduces the number of possible levels of subroutine calls. It also significantly complicates the use of the stack, and may require multiple stacks. The choice is up to the programmer. In general, one wishes to remain independent from actual memory locations as long as possible. If registers are not available, a possible solution is the stack. However, if a large quantity of information should be passed to a subroutine, this information may have to reside directly in the memory. An elegant way around the problem of passing a block of data is simply to transmit a pointer to the information. A pointer is the address of the beginning of the block. A pointer can be transmitted in a register, or in the stack (two-stack locations can be used to store a 16-bit address), or in a given memory location(s).
149
Finally, if neither of the two solutions is applicable, then an agreement may be made with the subroutine that the data will be at some fixed memory location (the "mail-box").
Exercise 135: Which of the three methods above is best for recursion? Subroutine Library
There is a strong advantage to structuring portions of a program into identifiable subroutines: they can be debugged independently and can have a mnemonic name. Provided that they will be used in other areas of the program, they become shareable, and one can thus build a library of useful subroutines. However, there is no general panacea in computer programming. Using subroutines systematically for any group of instructions that can be grouped by function may also result in poor efficiency. The alert programmer will have to weigh the advantages against the disadvantages.
SUMMARY
This chapter has presented the way information is manipulated inside the Z80 by instructions. Increasingly complex algorithms have been introduced and translated into programs. The main types of instructions have been used and explained. Important structures such as loops, stacks and subroutines, have been defined. You should now have acquired a basic understanding of programming, and of the major techniques used in standard applications. Let us study the instructions available.
150
DC.(0200)
(0200')
0.00
DE.(0202) (0202' 1 Dr00 HLr0000 (0000') C
HL=0000 5=0300 P=0111 0111' JR AP=00 D'=0000 D'=0000 H'=0000 X=0000 1=0000 1=00 C A=00 DC=0801 DE=0005 HL=0000 5=0300 P=0113 0113' ADD
A'=00 A=00 A'=00 A=00 A'=00 A=00 A'=00 A=00 B'=0000 BC=0801 D'=0000 BC=0801 D'=0000 BC=0801 Er'=0000 BC=0701 D'=0000 DE=0005 D'=0000 DE=000A D'=0000 DE=0004 0'=0000 DE=000A H'=0000 HL=0005 H'=0000 HL=0005 H'=0000 HL=0005 H'=0000 HL=0005 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 Y=0000 P=0114 1=0000 P=0116 1=0000 P=0118 1=0000 P=0119 1=00 0114' SLA 1=00 0116' RL 1=00 0118' DEC 1=00 0119' JP
NC.0114 (0114')
HLrDE E 0 B
V Z V N
D'=0000 D'=0000 H'=0000 X=0000 1=0000 1=00 DC=0701 DE=000A HL=0005 5=0300 P=010F 010F' SRL D'=0000 D'=0000 H'=0000 X=0000 1=0000 1=00
NZ.010F (010F . ) C
NCr0/14 (0114'1
BC=0700 DE=0004 HL=0005 5=0300 P=0111 0111' JR A'=00 B'=0000 D'=0000 H'=0000 X=0000 1=0000 1=00 2 V C A=00 BC=0700 DE=000A HL=0005 5=0300 P=0113 0113' ADD
HL.DE C
D
ZV V 2V N
N
ZV 2V V ZV
N
N
Z V
2V V ZV
N N
A'=00 D'=0000 4=00 DC=0700 A'=00 W=0000 A=00 DC=0700 A'=00 B'=0000 4=00 PC=0700 A'=00 11=0000 4=00 17=0600 A'=00 D'=0000 4=00 DC=0600 A'=00 D'=0000 A=00 BC=0600 A'=00 P'=0000 4=00 DC=0600 A'=(10 D'=0000 A=00 DC=0600 A'=00 D'=0000 A=00 DC=0600 A'=00 D'=0000 AN00 DC=0500 A'=00 D'=0000 4=00 BC=0500 A'=00 B'=0000 4=00 DC=0500 A'=00 D'=0000 A=00 DC=0500 A'=00 D'=0000 A=00 DC=0500 A'=00 D'=0000 4=00 DC=0500 A'=00 D'=0000 4=00 DC=0400 A'=00 p'=0000 A=00 DC=0400 A'=00 B'=0000
D'=0000 DE=000A 0'=0000 DE=0014 D'=0000 DE=0014 1r=0000 0E=0014 D'=0000 DE=0014 D'=0000 DE=0014 D'=0000 DE=0014 D 1 =0000 DE=0028 D'=0000 DE=0028 EP=0000 DE=0020 D'=0000 DE=0028 D'=0000 DE=0020 D'=0000 DE=0028 D'=0000 DE=0050 D'=0000 DE=0050 D'=0000 DE=0050 0'-0000 DE=0050 D'=0000
H'=0000 HL=000F EV=0000 HL=000F H'=0000 HL=000F H'=0000 FIL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F W=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F H'=0000 HL=000F 11'=0000 HL=000F 14'-0000 HL=000F H'=0000
X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 S=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000 S=0300 X=0000 5=0300 X=0000 5=0300 X=0000 5=0300 X=0000
1=0000 P=0114 1=0000 P=0116 1=0000 P=0118 1=0000 P=0119 1=0000 P=010F 1=0000 P=0111 1=0000 P=0114 1=0000 P=0116 1=0000 P=0118 1=0000 P=0119 1=0000 P=010F 1=0000 P=0111 1=0000 P-0114 1=0000 F'=0116 1=0000 P=0118 Y=0000 P=0117 1=0000 P=010F 1=0000
1=00 0114' 1=00 0116' 1=00 0118' 1=00 0119' 1=00 010F' 1=00 0111' 1=00 0114' 1=00 0116' 1=00 0110' 1=00 0119' 1=00 010F' 1=00 0111' 1=00 0114' 1=00 0116' 1=00 011B' 1=00 0119' 1=00 010F' 1=00
SLA
RL
D F. NZ.010F .010F')
151
r
D
152
on
020101 220402 100001
Errors
C
(CARRY)
D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E 00 00 00 05 05 05 05 05 05 OA OA OA OA OA OA OA 14 14 14 14
HL 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 05 05 05 05 05 05 OF OF OF OF OF
MP488
00 08 08 08 08 08 08 08 08 08 07 07 07 07 07 07 07 06 06
00 03 03 03 03 03 01 01 01 01 01 01 01 00 00 00 00 00 00 00
MULT
NOADD
MULT
NOADD
CLASSES OF INSTRUCTIONS
Instructions may be classified in many ways, and there is no standard. We will here distinguish five main categories of instructions: Idata transfers 2data processing 3test and branch 4input/output 5control Let us now examine each of these classes of instructions in turn.
Data Transfers
Data transfer instructions will transfer data between registers, or between a register and memory, or between a register and an input/output device. Specialized transfer instructions may exist for registers which play a specific role. For example, push and pop operations are provided for efficient stack operation. They will move a word of
154
THE Z80 INSTRUCTION SET data between the top of the stack and the accumulator in a single instruction, while automatically updating the stack-pointer register. Data Processing Data processing instructions fall into five general categories: 1arithmetic operations (such as plus/minus) 2bit manipulation (set and reset) 3increment and decrement 4logical operations (such as AND, OR, exclusive OR) 5skew and shift operations (such as shift, rotate) It should be noted that, for efficient data processing, it is desirable to have powerful arithmetic instructions, such as multiply and divide. Unfortunately, they are not available on most microprocessors. It is also desirable to have powerful shift and skew instructions, such as shift n bits, or a nibble exchange, where the right half and the left half of the byte are exchanged. These are also usually unavailable on most microprocessors. Before examining the actual Z80 instructions, let us recall the difference between a shift and a rotation. The shift will move the contents of a register or a memory location by one bit location to the left or to the right. The bit falling out of the register will go into the carry bit. The bit coming in on the other side will be a "0" except in the case of an "arithmetic shift right," where the MSB will be duplicated. In the case of a rotation, the bit coming out still goes in the carry. However, the bit coming in is the previous value which was in the carry bit. This corresponds to a 9-bit rotation. It is often desirable to have a true 8-bit rotation where the bit coming in on one side is the one falling from the other side. This is not provided on most microprocessors but is available on the Z80 (see Figure 4.1). Finally, when shifting a word to the right, it is convenient to have one more type of shift, called a sign extension or an "arithmetic shift right." When doing operations on two's complement numbers, particularly when implementing floating-point routines, it is often necessary to shift a negative number to the right. When shifting a two's complement number to the right, the bit which must come in on the left side should be a "I" (the sign should get repeated as many times as needed by the successive shifts). This is the arithmetic shift right.
155
SHIFT LEFT
0
CARRY
ROTATE LEFT
cm
cm
CARRY
Fig. 4.1: Shift and Rotate Test and Jump The test instructions will test bits in the specified register for "0" or "1", or combinations. At a minimum, it must be possible to test the flags register. It is, therefore, desirable to have as many flags as possible in this register. In addition, it is convenient to be able to test for combinations of such bits with a single instruction. Finally, it is desirable to be able to test any bit position in any register, and to test the value of a register compared to the value of any other register (greater than, less than, equal). Microprocessor test instructions are usually limited to testing single bits of the flags register. The Z80, however, offers better facilities than most. The jump instructions that may be available generally fall into three categories: Ithe jump, which specifies a full 16-bit address 2the relative jump, which often is restricted to an 8-bit displacement field 3the call, which is used with subroutines 156
THE Z80 INSTRUCTION SET It is convenient to have two- or even three-way jumps, depending, for example, on whether the result of a comparison is "greater than," "less than," or "equal." It is also convenient to have skip operations, which will jump forward or backwards by a few instructions. However, a "skip" is equivalent to a "jump." Finally, in most loops, there is usually a decrement or increment operation ,at the end, followed by a test-and-branch. The availability of a single-instruction increment/ decrement plus test-and-branch is, therefore, a significant advantage for efficient loop implementation. This is not available in most microprocessors. Only simple branches, combined with simple tests,are available. This, naturally, complicates programming and reduces efficiency. In the case of the Z80, a "decrement and jump" instruction is available. However, it only tests a specific register (B) for zero. Input/Output Input/output instructions are specialized instructions for the handling of input/output devices. In practice, a majority of the 8-bit microprocessors use memory-mapped I/O: input/output devices are connected to the address bus just like memory chips, and addressed as such. They appear to the programmer as memory locations. All memory-type operations normally require 3 bytes and are, therefore, slow. For efficient input/output handling in such an environment, it is desirable to have a short addressing mechanism available so that I/O devices whose handling speed is crucial may reside in page 0. However, if page 0 addressing is available, it is usually used for RAM memory, which prevents its effective use for input/output devices. The Z80, like the 8080, is equipped with specialized I/O instructions. As a result, in the case of the Z80, the designer may use either method: input/output devices may be addressed as memory devices, or else as input/output devices, using the I/O instructions. They will be described later in this chapter. Control Instructions Control instructions supply synchronization signals and may suspend or interrupt a program. They can also function as a break or a simulated interrupt. (Interrupts will be described in Chapter 6 on Input/Output Techniques.)
157
The Z80 microprocessor was designed to be a replacement for the 8080, and to offer additional capabilities. As a result of this design philosophy, the Z80 offers all the instructions of the 8080, plus additional instructions. In view of the limited number of bits available in an 8-bit opcode, one may wonder how the designers of the Z80 succeeded in implementing many additional ones. They did so by using a few unused 8080 opcodes and by adding an additional byte to the opcode for indexed operations. This is why some of the Z80 instructions occupy up to five bytes in the memory. It is important to remember that any program can be written in many different ways. A thorough knowledge and understanding of the instruction set is indispensable for achieving efficient programming. However, when learning how to program, it is not essential to write optimized programs. During a first reading of this chapter, it is therefore unimportant to remember all the various instructions. It is important to remember the categories of instructions and to study typical examples. Then, when writing programs, the reader should consult the Z80 instruction-set description, and select the instructions best suited to his needs. The various instructions of the Z80 will therefore be reviewed in this section with the intent of simplifying them and grouping them in logical categories. The reader interested in exploring the capabilities of the various instructions is referred to the individual descriptions of the instructions. We will now examine the capabilities provided by the Z80 in terms of the five classes of instructions which have been defined at the beginning of this chapter.
Data Transfer Instructions
Data transfer instructions on the Z80 may be classified in four categories: 8-bit transfers, 16-bit transfers, stack operations, and block transfers. Let us examine them.
Eight-Bit Data Transfers
All eight-bit data transfers are accomplished by load instructions. The format is: LD destination, source
158
THE Z80 INSTRUCTION SET For example, the accumulator A may be loaded from register B by using the instructions: LD A,B Direct transfers may be accomplished between any two of the working registers (ABCDEHL). In order to load any of the working registers, except for the accumulator, from a memory location, the address of this memory location must first be loaded into the H-L register pair. For example, in order to load register C from memory location 1234, register H and L will first have to be loaded with the value "1234". (A load instruction operating on 16 bits will be used. This is described in the following section.) Then, the instruction LD C, (HL) will be used and will accomplish the desired result. The accumulator is an exception. It can be loaded directly from any specified memory location. This is called the extended addressing mode. For example, in order to load the accumulator with the contents of memory location 1234, the following instruction will be used: LD A, (1234H) (Note the use of "( )" to denote "contents of.") The instruction will be stored in the memory as follows: address PC :3A (opcodo (low order half of the address) PC + 1:34 PC + 2:12 (high order half of the address) Note that the address is stored in "reverse order" in the instruction itself: 3A low addr high addr
All the working registers may also be loaded with any specified eight-bit value, or "literal," contained in the second byte of the instruction (this is called immediate addressing). An example is: LD E, 12H which loads register E with the value 12 hexadecimal. In the memory, the instruction appears as: PC: 1E PC + 1: 12 (opcode) (literal operand)
159
PROGRAMMING THE Z80 As a result of this instruction, the immediate operand, or literal value will be contained in register E. The indexed addressing mode is also available for loading register contents, and will be fully described in the next chapter on addressing techniques. Other miscellaneous possibilities exist for loading specific registers, and a table listing all the possibilities is shown in Figure 4.2 ( tables supplied by Zilog, Inc.). The grey areas show instructions common with the 8080A.
IOU la ....1 0 c 4111 if NI apace cal tioci AMP mato I MAR Ira 160
vane 0
..:0 .
St
....! a- a a. ..
ge ii -
i.1 a
a,
0 Al Do .4 1 so
. .
a
.4Z-
a a
e is r
a ..
De s . oo a cu III
ILO
oo
u ii . Z
ID (0
-. 00 it,:
It: 'it,
ai
- es: 'it
.i
I.
At. 41:1
' r . .
r'
It
Rao
man. na
IOU 110.1 at fe3 map INT. Ian Imi
r i, ti !..
Co " 6 co 0 , W.: OD ' 0 4 a 0
n. ,.
,.
-s
00 Fo
DO ro
00 0
oo AD
a ni
oo 36 a
len CO ID di
Basically, any of the 16-bit register pairs, BC, DE, HL, SP, IX, IY, may be loaded with a literal 16-bit operand, or from a specified memory address (extended addressing), or from the top of the stack, i.e., from the address contained in SP. Conversely, the contents of these
160
THE Z80 INSTRUCTION SET register pairs may be stored in the same manner at a specified memory address or on top of the stack. Additionally, the SP register may be loaded from HL, IX, and IY. This facilitates creating multiple stacks. The register pair AF may also be pushed on top of the stack. The table listing all the possibilities is shown in Figure 4.3. The stack push and pop operations are included as parts of the 16-bit data transfers. All stack operations transfer the contents of a register pair to or from the stack. Note that there are no single push and pop instructions for saving individual eight-bit registers.
REGISTER AF In DE HI SP IX IV
Innl
ISPI
AF 01 A ED
Fl
BC
2
o I DESTINATION
DE HL
' n . n Gli n
LEI
"
01
u. Ig
DO 2A n FD 2/1 n
Si:_;
E R
SP
rt.
OD F9
FO F9
GI 'IR . OD 21 n ED 21
IX
DC El FO El
IV ED 43 ED 53 a Di
Imo
f(,
a n
. IS
n ED 73 n n 00 22 I I n OD ES FD 22 n FD ES
Iv,
II
CI
POP INSTRUCTIONS
Fig. 4.3: 16-Bit Load Group'LLY, 'PUSH' and 'POP' A double-byte push or pop is always executed on a register pair: AF, BC. DE, HL. IX, IY (see the bottom row and right-most column in Figure: 4.3). When operating on AF, BC, DE, HL, a single-byte is required for the instruction, resulting in good efficiency. For example, assume that the
161
PROGRAMMING THE Z80 stack pointer SP contains the value "0100". The following instruction is executed: PUSH AF When pushing the contents of the register pair on the stack, the stack pointer SP is first decremented, then the contents of register A are deposited on top of the stack. Then the SP is decremented again, and the contents of F are deposited on the stack. At the end of the stack transfer, SP points to the top element of the stack, which in our example is the value of F. It is important to remember that, in the case of the Z80, the SP points to the top of the stack and the SP is decremented whenever a register pair is pushed. Other conventions are often used in other processors, and this may be a source of confusion.
IMPLIED
BC, DE & HL
D9
DE
EB
REG. INDIR.
(SP)
ES
DD E3
FD E3
Exchange Instructions
Additionally, a specialized mnemonic EX has been reserved for exchange operations. EX is not a simple data transfer, but a dual data transfer. It actually changes the contents of two specified locations. EX
162
THE Z80 INSTRUCTION SET may be used to exchange the top of the stack with HL, IX, IY and also to swap the contents of DE and HL and AF and AF' (remember that AF' stands for the other AF register pair available in the Z80). Finally, a special EXX instruction is available to exchange the contents of BC, DE, HL with the contents of the corresponding registers in the second register bank of the Z80. The possible exchanges are summarized in Figure 4.4.
'LDI' Load IDEkrtIHL) Inc HL & DE, Dec BC 'LDIR. Load IDE/-aaIHL) Inc HL & DE. Dec BC. Repeat until BC 0 'LDD' Load (DEI-as(11L) Dec HL & OE. Dec BC 'LDDR' Load IDE)-00IHL) Dec HL & DE, Dec BC, Repeat until BC n0
Block Transfer Instructions Block transfer instructions are instructions which will result in the transfer of a block of data rather than a single or double byte. Block transfer instructions are more complex for the manufacturer to implement than most instructions and are usually not provided on microprocessors. They are convenient for programming, and may improve the
163
PROGRAMMING THE Z80 performance of a program, especially during input/output operation. Their use and advantages will be demonstrated throughout this book. Some automatic block transfer instructions are available in the case of the Z80. They use specific conventions. All block transfer instructions require the use of three pairs of registers: BC, DE, HL: BC is used as a I6-bit counter. This means that up to 216 = 64K bytes may be moved automatically. HL is used as the source pointer. It may point anywhere in the memory. DE is used as the destination pointer and may point anywhere in the memory. Four block transfer instructions are provided: LDD, LDDR, LDI, LDIR All of them decrement the counter register BC with each transfer. Two of them decrement the pointer registers DE and HL, LDD and LDDR, while the two others increment DE and HL, LDI and LDIR. For each of these two groups of instructions, the letter R at the end of the mnemonic indicates an automatic repeat. Let us examine these instructions. LDI stands for "load and increment." It transfers one byte from the memory location pointed to by H and L to the destination in the memory pointed to by D and E. It also decrements BC. It will automatically increment H and L and D and E so that all register pairs are properly conditioned to perform the next byte transfer whenever required. LDIR stands for "load increment and repeat," i.e., execute LDI repeatedly until the counter registers BC reach the value "0", It is used to move a continuous block of data automatically from one memory area to another. LDD and LDDR operate in the same way except that the address pointer is decremented rather than incremented. The transfer therefore starts at the highest address in the block instead of the lowest. The effect of the four instructions is summarized in Figure 4,5. Similar automated instructions are available for CP (compare) and are summarized in Figure 4.6.
Data Processing Instructions Arithmetic
Two main arithmetic operations are provided: addition and subtraction. They have been used extensively in the previous chapter. There are two types of addition, with and without carry, ADC and ADD respec-
164
ED Al ED BI ED A9 ED' B9.
Ci'D' Dec HL II BC
E.
Lively. Similarly, two types of subtraction are provided with and without carry. They are SEC and SUB. Additionally, three special instructions are provided: DAA, CPL, and NEG. The Decimalitdjust Accumulator instruction DAA has been used to implement BCD operations. It is normally used for each BCD add or subtract. Two complementation instructions also are available. CPL will compute the one's complement of the accumulator, and NEG will negate the accumulator into its complement format(two's complement). All the previous instructions operate on eight-bit data. 16-bit operations are more restricted. ADD, ADC, and SBC are available on specific registers, as described in Figure 4.8. Finally, increment and decrement instructions are available which operate on all the registers, both in an eight-bit and a 16-bit format. They are listed in Figure 4.7 (eight-bit operations) and 4.8 (16-bit operations).
165
REGISTER ADDRESSING
IMMED.
IHLI
'ADD'
07
90
II
ft
ID
111
03 n CE 04 . DE rt Ea EE Fl WE it
SA
SO
SC
SO
BE
PI
OP
10
91
N.
93
99
N'
IA'- .
OB
OE
SO
N'
Al
AO
Al
Al .
AU
Al
AB
Al
Al
%OR'
AP
Al
BO
AS
111
All
AC
AD
THY
117
02
03
BE
BE
BA
BC
BO
BE
3C
OS
OC
14
IC
24
EC
34
JD
OD
11
1D
OS
2D
3P1
Note that, in general, all arithmetic operations modify some of the flags. Their effect is fully described in the instruction descriptions later in this chapter. However, it is important to note that the INC and DEC instructions which operate on register pairs do not modify any of the flags. This detail is important to keep in mind. This means that if you increment or decrement one of the register pairs to the value "0", the Z-bit in the flags register F will not be set. The value of the register must be explicitly tested for the value "0" in the program. Also, it is important to remember that the instructions ADC and SBC always affect all the flags. This does not mean that all the flags will necessarily be different after their execution. However, they might.
166
SOURCE
BC
DE
HI.
SP
IX
IV
HI.
09
19
29
39
DESTINATION
'ADD'
IX
DO 09 FD 09 ED 4A ED 42 03
130 19 FD 19 ED 5A ED 52 13 ED 6A ED 62 23
DD 39 FD 39 ED 7A ED 72 33
DD 29 FD 29
IV
ADD WITH CARRY AND SET FLAGS ADC' SUB WITH CARRY AND 'SBC' SET FLAGS INCREMENT 'INC'
HL
HL
DO 23 DD 28
FD 23 FD 26
DECREMENT
DEC'
OB
18
2B
3B
Logical
Three logical operations are provided: AND, OR (inclusive) and XOR (exclusive), plus a comparison instruction CP. They all operate exclusively on eight-bit data. Let us examine them in turn. (A table listing all the possibilities and operation codes for these instructions is part of Figure 4.7.)
AND
Each logical operation is characterized by a truth table, which expresses the logical value of the result in function of the inputs. The truth table for AND appears below:
167
AND 0 0 0 0 0
The AND operation is character zed by the fact that the output is "1" only if both inputs are "1". In other words, if one of the inputs is "0", it is guaranteed that the result is "0". This feature is used to zero a bit position in a word. This is called "masking." One of the important uses of the AND instruction is to clear or "mask out" one or more specified bit positions in a word. Assume for example that we want to zero the right-most four-bit positions in a word. This will be performed by the following program: LD AND A. WORD 11110000B WORD CONTAINS '10101010' '11110000' IS MASK
Let us assume that WORD is equal to '10101010'. The result of this program is to leave the value '10100000' in the accumulator. "B" is used to indicate a binary value.
Exercise 4.1: Write a three-line program which will zero bits 1 and 6 of WORD. Exercise 4.2: What happens with a MASK = '11111111'? OR
This instruction is the inclusive OR operation. It is characterized by the following truth table: 0 OR 0 =0 0 OR 1 = 1 Or 1 OR 0 = I 1 OR 1 = I OR 0 0 0
The logical OR is characterized by the fact that if one of the operands is "I", then the result is always "I". The obvious use of OR is to set any bit in a word to "I". Let us set the right-most four bits of WORD to l's. The program is: LD A, WORD OR A, 00001111B
168
THE Z80 INSTRUCTION SET Let us assume that WORD did contain '10101010'. The final value of the accumulator will be '10101111' Exercise 4.3: What would happen if we were to use the instruction
OR 10101111B? Exercise 4.4: What is the effect of ORing with "FF" hexadecimal? XOR
XOR stands for "exclusive OR." The exclusive OR differs from the inclusive OR that we have just described in one respect: the result is "1" only if one, and only one, of the operands is equal to "1". If both operands are equal to "1", the normal OR would give a "1" result. The exclusive OR gives a "0" result. The truth table is: 0 XOR 0 =0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR I = 0 XOR 0 1
Or
1 0
The exclusive OR is used for comparisons. If any bit is different, the exclusive OR of two words will be non-zero. In addition, in the case of the Z80, the exclusive OR may be used to complement a word, since there is no complement instruction on anything but the accumulator. This is done by performing the XOR of a word with all ones. The program appears below: LD r. WORD XOR, 11111111 B LD r, A where "r" designates the register. Let us assume that WORD contained "10101010". The final value of the register will be "01010101", You can verify that this is the complement of the original value. XOR can be used to advantage as a "bit toggle."
Exercise 4.5: What is the effect of XOR using a register with "00" hexadecimal?
Skew Operations (Shift and Rotate) Let us first differentiate between the shift and the rotate operations, which are illustrated in Figure 4.9. In a shift operation, the contents of
169
PROGRAMMING THE Z80 the register are shifted to the left or to the right by one bit position. The bit which falls out of the register goes into the carry bit C, and the bit which comes in is zero. This was explained in the previous section.
SHIFT LEFT
1 n (CARRY
ROTATE tin
rl (-1 r,
CARRY
Fig. 4.9: Shift and Rotate One exception exists: it is the shift-right-arithmetic. When performing operations on negative numbers in the two's complement format, the left-most bit is the sign bit. In the case of negative numbers it is "I". When dividing a negative number by "2" by shifting it to the right, it should remain negative, i.e., the left-most bit should remain a "1". This is performed automatically by the SRA instruction or Shift Right Arithmetic. In this arithmetic shift right, the bit which comes in on the left is identical to the sign bit. It is "0" if the left-most bit was a "0", and "1" if the left-most bit was a "1". This is illustrated on the right of Figure 4.10, which shows all the possible shift and rotate operations. Rotations A rotation differs from a shift by the fact that the bit coming into the register is the one which will fall from either the other end of the register or the carry bit. Two types of rotations are supplied in the case of the Z80: an eight-bit rotation and a nine-bit rotation. The nine-bit rotation is illustrated in Figure 4.11. For example, in the case of a right rotation, the eight bits of the register are shifted right by one bit position. The bit which falls off the right part of the register goes, as usual, into the carry bit. At this time the bit which comes in on the left end of the register is the previous value of the carry bit (before it is overwritten with the bit falling out.) In mathematics this is called a nine-bit rotation since the eight bits of the register plus the ninth bit (the
170
THE Z80 INSTRUCTION SET carry bit) are rotated to the right by one bit position. Conversely, the left rotation accomplishes the same result in the opposite direction.
...
'PC
grTr
t
dik
Loci Loci
CI .,
=MI I
Fig. 4.10: Rotates and Shifts
REGISTER RIGHT ri 0
7 LEFT
REGISTER
7 RIGHT
LEFT
171
RIGHT:
10END'e"".1
ADDRESS MEMORY
A LEFT:
172
REGiSTER ACIDRESSiNG
REG. INDIA
11401610
A SIT o a 47 a 4F 2 a 7 a SF
11
1141.1
CB
40
a 48 a SO a Si a 60 C.9 66
a 41 CO 49 a s1 a Si CB 61
a 42 a 45 a 32
a 43 03 49 CB 63 03 Si a 63 a 69
a 44 a 4C CB Y
a 45 a 40 a SS a SO C.8 ss CB 60
a 46 C5 46 CB 56 a Sf
3 TEST lit 4
a
SA
a
a
64
a
67
a
42
a
66 a GE
ea
a 69
a
61
a
114
a
SC
a
77
a
70
a
71
a
72
a
73
a
74 CB IC CO 54
a
75
a
T6
a
4 76 913 a 4 IT FO a 64 ea FO
7
o
a
IF a 57
a
78 al 110
a
75 a 111
a
74 a 0
a
75 a 10
a
70 a 15
a
71 a 86
76 DO a 4 71 00 a 4
a
SF 2 CI 97 a 9F
a
88 a TO
a
89 a 91
a
64 CB 92 a 94
ma
51 a 03 SC a 94 a SC a 44
a
1113 a 95 CS 90
a
51 a 95
00
a
98
a
99 a Al
a
98
a
a a Al
a
47
a
AO
a
A.7
a
4.3
a
AS
mama,
AF AB 49 AA
ace
All a 53 a VS AC
alas
AD Al
41 BE DO a 4 Ile 00 a 11 6 1313 a 4 45 00
a
57
a
50 a SB
a
81 a Si
a
82 a BA
a
94 a 8C
a
55 a ea
a
Be a SE
CB BF
4 Al DO a 4 66 00 a SE 00
a a a a Dacia
CZ CF a a a 00 a DB a CO a ES a FO a FE a 01 a 01 a DS a El a E9 a Fi a F9 CB CA a 02 a DA a E2 a IA a 92 a FA
can ccs a
a a C11 03 a DS a 13 a Ea a F3 CO FS a CC a 04 a DC a E4 a EC a F4 a FC a co a DS a C10 a ES a ED a FS a FO
a a
a CE CB 03 a OE a 46 a a a F6 CB FE
a d a 4
a 4 a
913
00 a CE DO a 4 W 00 a 4 OE 00 a t6 00 a I t 00 a
913 a CF FO a 4 06 FO a 4 OF
a 07 a OF a 17 CO EF
F0
a 6 90 a
FE
90 a F6 FO a FE
a F7 CS
0 FS
00 a
FF
gF
27
2F
ED 04
3F
37
4 H
TI
(T)
C is the carry, N is add or subtract, P/V is parity or overflow, H is half carry, Z is zero, S is sign. Bits 3 and 5 of the flags register are not used "). The two flags H and N are used for BCD arithmetic and cannot be tested. The other four flags (C, P/V, Z, S) can be tested in conjunction with conditional jump or call instructions. The role of each flag will now be described. Carry (C) In the case of nearly all microprocessors, and of the Z80 in particular, the carry bit assumes a dual role. First, it is used to indicate whether an addition or subtraction operation has resulted in a carry (or borrow). Secondly, it is used as a ninth bit in the case of shift and rotate operations. Using a single bit to perform both roles facilitates some operations, such as a multiplication operation. This should be clear from the explanation of the multiplication which has been presented in the previous chapter.
174
THE Z80 INSTRUCTION SET When learning to use the carry bit, it is important to remember that all arithmetic operations will either set it or reset it. depending on the result of the instructions. Similarly, all shift and rotation operations use the carry bit and will either set it or reset it, depending on the value of the bit which comes out of the register. In the case of logical instructions (AND, OR, XOR), the carry bit will always be reset. They may be used to zero the carry explicitly. Instructions which affect the carry bit are: ADD A,s; ADC A,s; SUB s; SBC A,s; CP s: NEC: AND s; OR s; XOR s; ADD DD,ss; ADC HL,ss; SBC HL,ss; RLA; RLCA; RRA; RRCA; RL m; RLC m: RR m: RRC m; SLA m; SRA m; SRL m; DDA; SCE; CCF; NEG s: Subtract (N) This flag is normally not used by the programmer, and is used by the Z80 itself during BCD operations. The reader will remember from the previous chapter that, following a BCD add or subtract, a DAA (Decimal Adjust Accumulator) instruction is executed to obtain the valid BCD results. However, the "adjustment" operation is different after an addition and after a subtraction. The DAA therefore executes differently depending on the value of the N flag. The N flag is set to "0" after an addition and is set to a "1" after a subtraction. The symbol used for this flag, "N", may be confusing to programmers who have used other processors, since it may be mistaken for the sign bit. It is an internal operation sign bit. N is set to "0" by: ADD A,s; ADC A,s; AND s;ORs; XOR s; INC s; ADD DD,ss; ADC HL.ss; RLA; RLCA; RRA; RRCA; RL m: RLC m; RR m; RRC m; SLA m; SRA m; SRL m; RLD; RRD; SCF; CCF; IN r, (C); LDI; LDD; LDIR; LDDR; LD A, I; LD A, R; BIT b, s. N is set to "1" by: SUB s; SBC A,s; CP s; NEC; DEC m; SBC HL, ss; CPL; INI; IND; OUTI; OUTD; INIR; INDR; OTIR; OTDR; CPI: CPIR; CPD; CPDR. 3 / V) Parity/Overflow (1 The parity/overflow flag performs two different functions. Specific instructions will set or reset this flag depending on the parity of the result; parity is determined by counting the total number of ones in the result. If this number is odd, the parity bit will be set to "0" (odd parity). If it is even, the parity bit will be set to "1" (even parity). Parity is most frequently used on blocks of characters (usually in the ASCII format). The parity bit is an additional bit which is added to the seven-bit code representing the character, in order to verify the integrity of data which has been stored in a memory device. For example, if one bit in the code representing the character has been changed by accident, due
175
PROGRAMMING THE Z80 to a malfunction in the memory device (such as a disk or RAM memory), or during transmission, then the total number of ones in the seven-bit code will have been changed. By checking the parity bit, the discrepancy will be detected, and an error will be flagged. In particular, the flag is used with logical and rotate instructions. Also, naturally, during an input operation from an I/O device, the parity flag will indicate the parity of the data being read. For the reader familiar with the Intel 8080, note that the parity flag in the 8080 is used exclusively as such. In the case of the Z80, it is used for several additional functions. This flag should therefore be handled with care when going from one of the microprocessors to the other. In the case of the Z80, the second essential use of this flag is as an overflow flag (not available in the 8080). The overflow flag has been described in Chapter 1, when the two's complement notation was introduced. It detects the fact that, during an addition or subtraction, the sign of the result is "accidentally"changed due to the overflow of the result into the sign bit. (Recall that, using an eight-bit representation, the largest positive number is + 127, and the smallest negative number is 128 in two's complement.) Finally, this bit is also used, in the case of the Z80, for two unrelated functions. During the block transfer instructions (LDD, LDDR, LDI, LDIR), and during the search instructions (CPD, CPDR, CPI, CPIR), this flag is used to detect whether the counter register B has attained the value "0". With decrementing instructions, this flag is reset to "0" if the byte counter register pair is "0". When incrementing, it is reset if BC 1 = 0 at the beginning of the instruction, i.e., if BC will be decremented to "0" by the instruction. Finally, when executing the two special instructions LD A, I and LD A.R. the P/V flag reflects the value of the interrupt enable flip-flop (IFF2). This feature can be used to preserve or test this value. The P flag is affected by: AND s; OR s; XOR s; RL m; RLC m; RR m; RRC m; SLA m; SRA m; SRL m; RLD; RRD; DAA; IN r,(C). The V flag is affected by: ADD A,s; ADC A,s; SUB s; SBC A,s; CP s; NEG; INC s; DEC m; ADC HL,ss; SBC HL,ss. It is also used by: LDIR; LDDR (set to "0"); LDI; LDD; CPI: CPIR; CPD; CPDR. The Half-Carry Flag (H) The half-carry flag indicates a possible carry from bit 3 into bit 4 during an arithmetic operation. In other words, it represents the carry from
176
THE Z80 INSTRUCTION SET the low-order nibble (group of 4 bits) into the high order one. Clearly, it is primarily used for BCD operations. In particular, it is used internally within the microprocessor by the Decimal Adjust Accumulator (DAA1 instruction in order to adjust the result to its correct value. This flag will be set during an addition when there is a carry from bit 3 to bit 4 and reset when there is no carry. Conversely, during a subtract operation, it will be set if there is a borrow from bit 4 to bit 3, and reset if there is no borrow. The flag will be conditioned by addition, subtraction, increment, decrement, comparisons, and logical operations. Instructions which affect the H bit are: ADD A,r ; ADD A,s; SUB s; SBC A,s; CP s; NEG; AND s; OR s; XOR s; INC s; DEC m; RLA; RLCA; RRA; RRCA; RL in; RLC m; RR m; RRC in; SLA m; SR m; SRL m; RLD; RRD; DAA; CPL, SCF; IN r,(C) LDI; LLD; LDIR; LDDR; LD A: LD Air; BIT b,r. Note that the H bit is randomly affected by the 16-bit add and subtract instructions, and by block input and output instructions. Zero (Z) The Z flag is used to indicate whether the value of a byte which has been computed, or is being transferred, is zero. It is also used with comparison instructions to indicate a match, and for other miscellaneous functions. In the case of an operation resulting in a zero result, or of a data transfer, the Z bit is set to "1" whenever the byte is zero. Z is reset to "0" otherwise. In the case of comparison instructions, the Z bit is set to "I" whenever the comparison succeeds and to "0" otherwise. Additionally, in the case of the Z80, it is used for three more functions: it is used with the BIT instruction to indicate the value of a bit being tested. It is set to "1" if the specified bit is "0" and reset otherwise. With the special "block input-output instructions" (INI, IND, OUTI, OUTD), the Z flag is set if D I = 0, and reset otherwise; it is set if the byte counter will decrement to "0" (INIR, INDR, OTIR, OTDR). Finally, with the special instructions IN r,(C), the Z flag is set to "I" to indicate that the input byte has the value "0". In summary, the following instructions condition the value of the Z bit: ADD A,s; ADC A,s; SUB s; SBC A,s; CP s; NEG; AND s; OR s; XOR s; INC s; DEC in; ADC HL, ss; SBC HL,ss; RL in; RLC m;
177
PROGRAMMING THE Z80 RR m; RRC m; SLA m; SRA m; SRL m; RLD; RRD; DAA; IN r,(C); INI; IND; OUT!: OUTD; INIR; INDR; OTIR; OTDR; CPI; CPIR; CPD; CPDR; LD A, I; LD A, R; BIT b,s; NEG s. Usual instructions which do not affect the Z bit are: ADD DD,ss; RLA; RLCA; RRA; RRCA; CPL; SCF; CCF; LDI; LDD; LDIR; LDDR: INC DD; DEC DD. Sign (S) This flag reflects the value of the most significant bit of a result or of a byte being transferred (bit seven). In two's complement notation, the most significant bit is used to represent the sign. "0" indicates a positive number and a "1" indicates a negative number. As a result, bit seven is called the sign bit. In the case of most microprocessors, the sign bit plays an important role when communicating with input/output devices. Most microprocessors are not equipped with a BIT instruction for testing the contents of any bits in a register or the memory. As a result, the sign bit is usually the most convenient bit to test. When examining the status of an input/output device, reading the status register will automatically condition the sign bit, which will be set to the value of bit seven of the status register. It can then be tested conveniently by the program. This is why the status register of most input/output chips connected to microprocessor systems have their most important indicator (usually ready/not ready) in bit position seven. A special BIT instruction is provided in the case of the Z80. However, in order to test a memory location (which may be the address of an I/O status register), the address must first be loaded into registers IX, IY or HL. There is no bit instruction provided to test a specified memory address directly (i.e., no direct addressing mode for this instruction). The value of positioning an input/output ready flag in bit position seven, therefore, remains intact, even in the case of the Z80. Finally, the sign flag is used by the special instruction IN, (C) to indicate the sign of the data being read. Instructions which affect the sign bit are: ADD A,s; SUB s; SBC A,s; CP s; NEG; AND s; OR s; XOR s; INC s; DEC m; ADC HL, ss; SBC HL, ss; RL m; RLC m; RR m; RRC m; SLA m; SRA m; SRL m; RLD ; RRD; DAA; IN r,(C); CPR; CPIR; CPD; CPDR; LD A,I; LD A.r; NEG.
178
The flag bits are used to automatically detect special conditions within the ALU of the microprocessor. They can be conveniently tested by specialized instructions, so that specific action can be taken in response to the condition detected. It is important to understand the role of the various indicators available, since most decisions taken within the program will be taken in function of these flag bits. All jumps executed within a program will jump to specified locations depending on the status of these flags. The only exception involves the interrupt mechanism, which will be described in the chapter on input/output and may cause jumping to specific locations whenever a hardware signal is received on specialized pins of the Z80. At this point, it is only necessary to remember the main function of each of these bits. When programming, the reader can refer to the description of the instruction later in this chapter to verify the effect of every instruction of the various flags. Most flags can be ignored most of the time, and the reader who is not yet familiar with them should not feel intimidated by their apparent complexity. Their use will become clearer as we examine more application programs. A summary of the six flags and the way they are set or reset by the various instructions is shown in Figure 4.17.
The Jump Instructions
A branch instruction is an instruction which causes a forced branching to a specified program address. It changes the normal flow of execution of the program from a sequential mode into one where a different segment of the program is suddenly executed. Jumps may be conditional or unconditional. An unconditional jump is one in which the branching occurs to a specific address, regardless of any other condition. A conditional jump is one which occurs to a specific address only if one or more conditions are met. This is the type of jump instruction used to make decisions based upon data or computed results. In order to explain the conditional jump instructions, it is necessary to understand the role of the flags register, since all branching decisions are based upon these flags. This was the purpose of the preceding section. We can now examine in more detail the jump instructions provided by the Z80. Two main types of jump instructions are provided: jump instructions within the main program (they are called "jumps"), and the special 179
ivSN C1 F I I
COMMENTS
MIO . OR c XOR . INC DEC m ADO DO. se ROCK... SRC HL. as ALA: RICA. RRA. ROCA RL rn: RIC rn: RR m: ARC m SCA m; SAA ni; SRL a RLD. PRO ORA CPL SCF CCP IN r. MI INI: IRO; OUTI: OUTO INIR: IND& OTIR; ()TOR LOU. LOO LDIR, LODA CPI. CPIR. CPO. CPOR
o a : I . I :
0-loi add Of add moth mew V 0 V0-en W 0114CF. SU tttttt 111111. I catty. commie and nW .IIPAA.A. Loecal epeanons 0 I And tett thilitnt flag. a a 0 I 0 0 I 0 0 0 . X X X 0 0 0
8-tot ttttt roam B-bl decrement 16-0.1 add 16-ba add mth carry 16-bn iubiract with carry Moan accumulator Rot.,. and Molt location m
I I X X
0
: X X X X I.
Amaze Mot la, t and right Ileci mai Adill111 accumulator Complarnant accumulsior I I carry Coenol.mmt carry 0 Inpui register indium 0 i t Block input and output I I Z 0 ill B t 0 othctwo Z 1 Block Parisi.. smuumion. 01 I NV i .1 BC O. 0111.011. 0 P/V 0
a..
10 A. I LOA A
IFF
BIT b. i NEC
X V
X :
P/V r if BC 0. whom.* PN 0 TM content al the inierrum malt MOM. I I FF I is rand into the P/V hat TM complement ol bid, of la "PIS into Rano, Z flag Neoale ACcumulater
the
2 O
Cany/Iinla Ilse C.I d ih opontran produced a arty ham th. MSB of th. operand or ;OWN. Zap. Ih. tat d Ma rnult al th oprotion n tem. Sign Ilry SwIlltha MSB of ihe ma It is one. Parity'r amrflow. flag. Pray WI and overflows IVI ahem Ow wen. flag. Lorca' oporatsons alum this flag with Ma parity of Ow moult while erithmatse opration. disci thi, flag with th. airflow, al the result. II PN h Ids parity. PN-1 i1 th. maul. of the me Prom(' if 'nub is odd. II PN holds warns, IN. I A the mauls al PM operation produed an crywilmw. Nillscarty Na., Pl I if the add an boars opermion produced a carry bit 4 of Os accumulate.. N 1 if tM proviso. operation yaw aubtrct. Add/Subtract
sale of
barrow from
. nal
X P ~~
to
~~ o nn
, N and fa flip are vied m ovum n wash the decimal 'Mutt smouction IOAAI to mopeds ~~an ah. 'molt into pecked BCO formal fallowing addition or stanrachan using operands with packed BCD lomat. The flag a affected according la the moult of Imo opention. TM flag o unchanied by Ow op..a on. fla. meet byiM aparcrrm. The By o at by the oparation. The flag is a "don't are." PN Bag allemad acmedsng to the overflow rands al Me opeatran. IN 112141hyted according to ti. ploy '.1011 of the operation. Any one of the CPU yawners A, B, CO. E. H. L. , inoructron. Any 8-bit Motion Ion all the ad...easing modes allowed for Ma primulas Any 16-bit Immo, lot all the addrwiing mod., 'Mowed far that instrum11001. Any mu ol the two mdm rep ttttt IX or IT. Ralreth aima. 6-bit alue m 'any <0. ?SS>. 16-bi1 111141111 range CO. 65515>. Any 6-bil location lot NO the addrattng modes allownd In thaigmoicular instrucrion.
180
THE Z80 INSTRUCTION SET type of branch instructions used to jump to a subroutine and to return from it ("call" and "return"). As a result of any jump instruction, the program counter PC will be reloaded with a new address, and the usual program execution will resume from this point on. The full power of the various jump instructions can be understood only in the context of the various addressing modes provided by the microprocessor. This part of the discussion will be deferred until the next chapter, where the addressing modes are discussed. We will only consider here the other aspects of these instructions. Jumps may be unconditional (branching to a specified memory address) or else conditional. In the case of a conditional jump, one of four flag bits may be tested. They are the Z, C, P/V, and S flags. Each of them may be tested for the value "0" or "1". The corresponding abbreviations are: Z = zero (Z = 1) NZ = non zero (Z = 0) C = carry (C = 1) NC = no carry (C = 0 ) P0= odd parity PE = even parity P = positive (S = 0) M = minus (S = 1) In addition, a special combination instruction is available in the Z80 which will decrement the B register and jump to a specified memory address as long as it is not zero. This is a powerful instruction used to terminate a loop, and it has already been used several times in the previous chapter: it is the DJNZ instruction. Similarly, the CALL and the RET (return) instructions may be conditional or unconditional. They test the same flags as the branch instruction which we have already described. The availability of conditional branches is a powerful resource in a computer and is generally not provided on other eight-bit microprocessors. It improves the efficiency of programs by implementing in a single instruction what requires two instructions otherwise. Finally, two special return instructions have been provided in the case of interrupt routines. They are RETI and RETN. They will be described in the section of Chapter 6 on interrupts. The addressing modes and the opcodes for the various branches available are shown in Figure 4.18.
181
CONDITION 4044 cnn CANNY 02 n n 30 .2 PARITY PAil ORD ZERO EVEN C2 n EA n E2 n VON WC FA n vow ros Fl n nt0 0
coma
ZIAla CA n n 78 .2
JUMP
'Jr
NAMED. EXT,
na
Cl DA n nn II .2 30 1.2
JUMP
'211'
RELATIVE PC..
20 .2
JUMP
'JP
DILI
es
DO E9 FD E9 CO n DC n D4 n CC n Cl n EC n E4 n FC n F4 n
JU0
'JP'
REG. INDIR.
OID
JUMP
'Jr
IITI
NAMED. EXT. DECREMENT E. JUMP IF NON ZERO 'Dalt RETURN 'PET' RETURN FROM INT 'REIT
nn
10 4.2 CO Di
ED 40 ED 45
A detailed discussion of the various addressing modes is presented in Chapter 5. By examining Figure 4.18, it becomes apparent that many addressing modes are restricted. For example, the absolute jump JP nn can test four flags, while JR can only test two flags. Note an important observation: JR tends to be used whenever possible as it is shorter than JP (one less byte) and facilitates program relocation. However, JR and JP are not interchangeable: JR cannot test the parity or the sign flags.
182
THE Z80 INSTRUCTION SET One more type of specialized branch is available; this is the restart or RST instruction. It is a one-byte instruction which allows jumping to any one of eight starting addresses at the low end of the memory. Its starting addresses are, in decimal, 0. 8, 16, 24, 32, 40, 48 and 56. It is a powerful instruction because it is implemented in a single byte. It provides a fast branch, and for this reason is used essentially to respond to interrupts. However, it is also available to the programmer for other uses. A summary of the opcodes for this instruction is shown in Figure 4.19.
OP CODE
0000H
C7
'RST 0'
0008H
'AST 8'
A L L 0
0010H
0018H
'RST 16'
'RST 24'
R
E S S
002H
0028H
E7
'RST 32'
'RST 40'
003H 311H FE
'RST 48'
'RST 56'
Input/Output Instructions
Input/output techniques will be described in detail in Chapter 6. Simply, input/output devices may be addressed in two ways: as memory locations, using any one of the instructions that have already 183
PROGRAMMING THE Z80 been described, or using specific input/output instructions. Usual memory addressing instructions use three bytes: one byte for the opcode and two bytes for the address. As a result, they are slow to execute, since they require three memory accesses. The main purpose of specialized input/output instructions is to provide shorter and, therefore faster, instructions. However, input/output instructions have two disadvantages. First, they "waste" several of the precious few opcodes available (since usually only 8 bits are used to supply all opcodes necessary for a microprocessor). Secondly, they require the generation of one or more specialized input/output signals, and therefore "waste" one or more of the few pins available in the microprocessor. The number of pins is usually limited to 40. Because of these possible disadvantages, specific input/output instructions are not provided on most microprocessors. They are, however, provided on the original 8080 (the first powerful eight-bit general-purpose microprocessor introduced) and on the Z80, which we know is compatible with the 8080. The advantage of input/output instructions is to execute faster by requiring only two bytes. However, a similar result can be obtained by supplying a special addressing mode called "page 0" addressing, where the address is limited to a field of eight bits. This solution is often chosen in other microprocessors. The two basic input/output instructions are IN and OUT. They transfer either the contents of the specified I/O locations into any of the working registers or the contents of the register into the I/O device. They are naturally two bytes long. The first byte is reserved for the opcode, the second byte of the instruction forms the low part of the address. The accumulator is used to supply the upper part of the address. It is therefore possible to select one of the 64K devices. However, this requires that the accumulator be loaded with the appropriate contents every time, and this may slow the execution. In the register-input mode, whose format is IN r. (C), the register pair B and C is used as a pointer to the I/O device. The contents of B are placed on the high-order part of the address bus. The contents of the specified I/O device are then loaded into the register designated by r. The same applies to the OUT instruction. Additionally, the Z80 provides a register-indirect mode, plus four specialized block-transfer instructions for input and output. The four block-transfer instructions on input are: INI, INIR (repeated INI), IND and INDR (repeated IND). Similarly, on output,
184
THE Z80 INSTRUCTION SET they are: OUTI, OTIR, OUTD, and OTDR. In this automated block transfer, the register pair H and L is used as a destination pointer. Register C is used as the I/O device selector (one out of 256 devices). In the case of the output instruction, H and L point to the source. Register B is used as a counter and can be incremented or decremented. The corresponding instructions on input are INI when incrementing and IND when decrementing. Ril is an automated single-byte transfer. Register C selects the input device. A byte is read from the device and is transferred to the memory address pointed to by H and L. H and L are then incremented by 1, and the counter B is decremented by I. INIR is the same instruction, automated. It is executed repeatedly until the counter decrements to "0". Thus, up to 256 bytes may be transferred automatically. Note that to achieve a total transfer of exactly 256, register B should be set to the value "0" prior to executing this instruction. The opcodes for the input and output instructions are summarized in Figures 4.20 and 4.21.
Control Instructions
Control instructions are instructions which modify the operating mode of the CPU or manipulate its internal status information. Seven such instructions are provided. The NOP instruction is a no-operation instruction which does nothing for one cycle. It is typically used either to introduce a deliberate delay (4 states = 2 microseconds with a 2MHz clock), or to fill the gaps created in a program during the debugging phase. In order to facilitate program debugging, the opcode for the NOP is traditionally all 0's. This is because, at execution time, the memory is often cleared, i.e., all 0's. Executing NOP's is guaranteed to cause no damage and will not stop the program execution. The HALT instruction is used in conjunction with interrupts or a reset. It actually suspends the operation of the CPU. The CPU will then resume operation whenever either an interrupt or a reset signal is received. In this mode, the CPU keeps executing NOP's. A halt is often placed at the end of programs during the debugging phase, as there is usually nothing else to be done by the main program. The program must then be explicitly restarted. Two specialized instructions are used to disable and enable the internal interrupt flag. They are El and DI. Interrupts will be described in
185
REGISTER
AC
DE
11
I.
DILI
11464E0..
Inl
ICI
03
wr
REG. 1140. OUT' - OUTPUT Int NE. 04 b "TIM - OUTPUT, Inc ML. Can 11, REPEAT IF SEG 1:11.1T0' -OUTPUT DocHL/413 VTDIT - OUTPUT, Des 111. ',REPEAT IF BOO REG. IND. REG. IRO REG. IND, REG. IND. ED 70 ED 4I ED 40 ED Si ED 50 ED 61 ED 69 ED Al ED 83 ED AB ED 88
ICI
ICI
MI
ICI
Inl
a
to
,7
7
CO
II
C ihrvi lEr o
40
ED
y
ED SO to Y ED AO ED ee
INPUT DESTINATION
- NEPA II M. Dec ip
Ow II, IIIII I if' SAO ROS INDIO -1Nrut Om ISO mt. Oft II INDS -PANT Do NE
Doc S. AAAAA t If 5.0
ED AZ ED el Co
AA
Iht.I
ED OA
j
186
THE Z80 INSTRUCTION SET Chapter 6. The interrupt flag is used to authorize or not authorize the interruption of a program. To prevent interrupts from occurring during any specific portion of a program, the interrupt flip-flop (flag) may be disabled by this instruction. It will be used in Chapter 6. These instructions are shown in Figure 4.22.
-Tn 'NOP'
'HALT'
F:5- -
. OB. -.: ED 46 ED 56 ED SE
SET INT MODE 0 IMO' SET INT MODE 1 'IM1' SET INT MODE 2 'IM?
8080A MODE
CALL TO LOCATION 0038H INDIRECT CALL USING REGISTER I AND 8 BITS FROM INTERRUPTING DEVICE AS A POINTER.
Finally, three interrupt modes are provided in the Z80. (Only one is available on the 8080). Interrupt mode 0 is the 8080 mode, interrupt 1 is a call to location 038H, and interrupt mode 2 is an indirect call which uses the contents of the special register I, plus 8 bits provided by the interrupting device as a pointer to the memory location whose contents are the address of the interrupt routine. These modes will be explained in Chapter 6. which will also be explained in Chapter 6. They are the IRQ and the NMI pins.
187
SUMMARY The five categories of instructions available on the Z80 have now been described. The details on individual instructions are supplied in the following section of the book. It is not necessary to understand the role of each instruction in order to start to program. The knowledge of a few essential instructions of each type is sufficient at the beginning. However, as you begin to write programs by yourself, you should learn about all the instructions of the Z80 if you want to write good programs. Naturally, at the beginning, efficiency is not important, and this is why most instructions can be ignored. One important aspect has not yet been described. This is the set of addressing techniques implemented on the Z80 to facilitate the retrieval of data within the memory space. These addressing techniques will be studied in the next chapter.
188
ABBREVIATIONS FLAG Carry Sign Zero Parity ON C (carry) M (minus) Z (zero) PE (even) OFF NC (no carry) P (plus) NZ (non zero) PO (odd)
changed functionally according to operation flag is set to zero flag is set to one flag is set randomly by operation special case, see accompanying note on that page bit positions 3 and 5 are always random
189
ADC A, s
Function: Formal: r n
(HL)
8E
0
(IX + d)
LI
0
I
(IY + d)
0
0
T 111.111
r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
190
THE Z80 INSTRUCTION SET Description: The operand s and the carry flag C from the status register are added to the accumulator, and the result is stored in the accumulator. s is defined in the description of the similar ADD instructions.
Data Flow:
Ar
B
D
AIM
Timing:
M cycles: r n (HL) (IX + d) (IY + d) Addressing Mode: 1 2 2 5 5 T states: 4 7 7 19 19
r: implicit; n: immediate (HL): indirect; (IX + d), (IY + d): indexed. ADC A,r
r: A B C E H
Byte Codes:
8F BB 89 BA BB 8C 80
Flags:
5 Z
N C
Example: ADC A, IA Before:
A 06
After:
13
OBJECT CODE
191
ADC HL, ss
Function:
HL HL + ss + C
Format: byte 1: ED 0
3 5
byte 2
Description:
The contents of the HL register pair are added to the contents of the specified register pair, and then the contents of the carry flag are added. The final result is stored back in HL. ss may be any one of: BC 00 DE 01 HL 10 SP II
Data Flow:
fc ,4r
SP
192
S Z
N C
After:
fS S IAi,
D H 3291
D
H OBJECT CODE
3291 OF18
Attr/
193
ADD A, (HL)
Function: Formai:
86
Description:
The contents of the accumulator are added to the contents of the memory location addressed by the HL register pair. The result is stored in the accumulator.
Data Flow:
DATA AU)
E
MEMORY
Flags:
5 Z
P/0 N C
194
Before:
A 02 9620 A
After:
9620
9620
9620
OBJECT CODE
195
ADD A, (IX + d)
Function:
A 4 A + (IX + d)
Format:
0
0 0
II
0 0 0 0
I I
IT
Description:
The contents of the accumulator are added to the contents of the memory location addressed by the contents of the IX register plus the immediate offset value. The result is stored in the accumulator.
Data Flow:
Timing:
Addressing Mode:
Flags:
5 Z
PeCDNC
196
Example:
ADD A, (IX + 3)
Before:
A IX
After:
A 01361
I II
',AT
A
0861
IX
197
ADD A, (IY + d)
Function:
A 4-- A + (IY + d)
Format:
0 0 a 0 0 byte I: FD byte 2: 86 byte 3: offset value
_I
Description:
The contents of the accumulator are added to the contents of the memory location addressed by the contents of the IY register plus the given offset value. The result is stored in the accumulator.
Data Flow:
DATA
ALU
Iv
ADD
Timing:
Plq) N C
198
Before:
A IX 31 002B A IX
After:
ii
0026
0026 002C
072B 002C
OBJECT CODE
199
ADD A, n
Function: Format:
A 4 A + n
0 0
n
111111
Description:
The contents of the accumulator are added to the contents of the memory location immediately following the op code. The result is stored in the accumulator.
Data Flow:
B D
_ ADD
ALU
MEMORY
Pi N C
Example:
ADD A. E2 Before:
A 43 A
After:
Alr A
OBJECT CODE
200
ADD A, r
Function: Format:
A A + r
Description:
The contents of the accumulator are added with the contents of the specified register. The result is placed in the accumulator. r may be any one of: A1II B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
B
ig
83
84 85
Flags:
S Z
P/0 N C
201
Example:
ADD A, B
Before:
After:
3D 02
tcialm
02
OBJECT CODE
202
ADD HL, SS
Function:
Format:
HL HL + ss
S S
Description:
The contents of the specified register pair are added to the contents of the HL register pair and the result is stored in HL. ss may be any one of: BC 00 DE 01 HL 10 SP 11
Data Flow:
A B D C E
SP
Flags:
S Z
PA/ N C
0 C is set by carry from bit 15, reset otherwise. H is set by a carry from bit 11
203
0681
L H
OD62
OBJECT CODE
204
ADD IX, rr
Function: Format:
IX 4 IX + rr
0 0 0 0 0 0
byte 1: DD byte 2
Description:
The contents of the IX register are added to the contents of the specified register pair and the result is stored back in IX. rr may be anyone of: BC 00 DE 01 IXt0
SP 11
Data Flow:
( SP
Implicit.
BC DE Ix SP
rr
DD- of; 19 29 39
205
0 H is set by carry out of bit 11. C is set by carry from bit 15.
Example:
ADD IX, SP
Before:
ix SP 0000 3021
After: ix
SP 3021
OBJECT CODE
206
ADD IY, rr
Function: Format:
IY
IY + rr
byte 1: FD
0 0 0
byte 2
Description:
The contents of the IY register are added to the contents of the specified register pair and the result is stored back in 1Y. rr may be any one of: BC 00 DE 01 IY 10 SP 11
Datg Flow: A
IB H IIY
g OA
SP
rr: BC DE IY SP FD- o; 19 29 39
207
H is set by carry out of bit 11. C is set by carry out of bit 15.
ADD IY, DE
Example:
Before:
D 6122 3051 E D
After:
6122 9173
OBJECT CODE
208
AND s
Function: Format: r n
i
I
0 0
1 1 1
0 0
1 1
IIIII r
n
III i 1
(HL) (IX + d)
1
0 0
i i
0 1 ,
1 I
:i
III
(IY + d)
1
d L_I
iii
r may be any one of: A Ill B 000 C 001 D 010 Description: E 011 H 100 L 101
The accumulator and the specified operand are logically 'and'ed and the result is stored in the accumulator. s is defined in the description of the similar ADD instructions.
209
A B H C E
(IY + d)
Addressing Mode:
5 5
19 19
9.5 9.5
r: implicit; n: immediate; (HLI: indirect; (IX + d), (IY + d): indexed. AND r
, ABCDE
A7 AO Al HI
Byte Codes:
A2 A3 Ad A5
Flags:
AND 4B Before:
A 36
00
Example:
After:
;"v
OBJECT CODE
210
BIT b, (HL)
Function:
Z (FIL)b
Format: 0
0
0
0
byte 1: CB byte 2
Description:
The specified bit of the memory location addressed by the contents of the HL register pair is tested and the Z flag is set according to the result. b may be any one of: 0 000 1 001 2 010 3 011 4 100 5 101 6 110 111 7
Data Flo w:
A DATA
B D H E
Flags:
S Z
211
CB- 46 4E 56 5E 66 6E 76 7E
Example:
After:
F
I H 6A42
6A42
6A42
6A42
OBJECT CODE
212
BIT b, (IX + d)
Function: Format:
(IX + d)
4 (IX
+ d)b
0 0 0
d 0
I
0 0
Description:
The specified bit of the memory location addressed by the contents of the IX register plus the given offset value is tested and the Z flag is set according to the result. b may be any one of:
0 000
1 001 2 010 3 011 4 100
213
Indexed.
b: 0 I 2 3 4 5 6 7
OD-CB-d- 46 4E
56
SE 66 6E 76 7E
Flags:
S Z
P/V N C
Example:
After:
/ 4F t.:1 1
Ix
AAII
AAII
AA! I
OBJECT CODE
214
BIT b, (IY + d) Test bit b of the indexed addressed memory location (IY + d)
Function: Format:
4--
(IY + d)b
byte 1: FD
0 0 0
6-'I
I
byte 4
Description:
The specified bit of the memory location addressed by the contents of the IY register plus the given offset value is tested and the Z flag is set according to the result. b may be any one of: 0 000 1 001 2 010 3 011 4 100 5 101 6 110 7I11
Data Flow:
A
B
F C
E H
ATLI DATA
IY BIT
215
Indexed.
0 I 2 3 4 5 6 7
46 4ETS6 SE 66 6E 76 7E
Flags:
s z
P/V N C 7
Example:
BIT 0, (IY + 1)
Before:
92 IY FF12 F Y
After:
202;a1 F [ EA, FF12
FF12 FF13
FF12 FF13
OBJECT CODE
216
BIT b, r
Function:
Z rb
Format:
byte I: CB
I I
bI
byte 2
Description:
The specified bit of the given register is tested and the zero flag is set according to the results. b and r may be any one of: b: 0 000 1 001 2 010 3 011 I11 A B-000 C 001 D 010 4 100 5 101 6 110 7111 E 011 H 100 L 101
r:
Data Flow:
A
F C E L
B
H
Timing:
Addressing Mode:
Implicit.
217
dA 4B 52 53
4C 4D 54 55
5A 58 5C 5D 62 63 64 65
5
6
6A bB 6C 6D 72 73 74 75
7A 78 7C 7D
Flags:
BIT 4, B Before:
B 61
PA/ N C 0
Example:
After:
01
61
1551
OBJECT CODE
218
CALL cc, pq
Function:
Format:
I I
I I
I I
Description:
If the condition is met, the contents of the program counter are pushed onto the stack as described for the PUSH instructions. Then, the contents of the memory location immediately following the opcode are loaded into the low order of the PC and the contents of the second memory location after the the opcode are loaded into the high order half of the PC. The next instruction fetched will be from this new address. If the condition is not met, the address pq is ignored and the following instruction is executed. cc may be any one of: NZ 000 Z 001 NC 010 C 011 PO 100 PE 101 P 100 M Ill
An RET instruction can be used at the end of the subroutine being called to restore the PC.
219
a
D
rc
E
FORM LOGIC - -a
a
CALL
PC
5P
MIS
Timing:
M cycles: condition true: condition not true: 5 3 T slates: 17 10
Addressing Mode:
Immediate.
Byte Codes:
CC. NZ . Z NC C PO PE P M Cd I CCI Dd DC
Ed
E-a-v7F-1 -4-13
N C
Flags:
s z
PA/
(no effect)
220
Before:
85 F
After:
F
PC
SP OB04
85
PC
0801
SP
BB12
131312
0010 NI 1 8812
221
CALL pq
Function:
Format:
0 0 byte I: CD 1 .4 1.1 ) byte 2: address, low order byte 3: address, high order
Description:
The contents of the program counter are pushed onto the stack as described for the PUSH instructions. The contents of the memory location immediately following the opcode are then loaded into the low order half of the PC and the contents of the second memory location after the opcode are loaded in the high order half of the PC. The next Instruction will be fetched from this new address.
Data Flow:
A B D E CALL q p
PC
":7 11. 5 /;
P41111111
SP
Timing:
222
P/V N C
(no effect)
Example:
CALL 4061
Before:
PC AA40 PC
After:
SP
0914
SP
ISM
OBI2 OBI3 0814 OBI2 01313 F aro F4 OB14
Pm1 1111111
OBJECT CODE
223
CCF
Function:
C C
Format:
0
3F
Description:
Data Flow:
A B D H
Flags:
PN N C
224
CP s
Function: Format: r
(HL) (IX + d)
0 0 0 d 0
byte 1: BE byte 1: DD
(IY + d) 0
0 0
r may be any one of: A 111 B 000 C 001 D 010 Description: E 01 l H 100 L 101
The specified operand is subtracted from the accumulator, and the result is discarded. s is defined in the description of the similar ADD instructions.
225
Data Flow:
W ri
usec @ 2 MHz: 2
1 2
2 5 5
7 7 19 19
Byte Codes:
CP r:
r: A B C D E BF BB B9 BA BB BC BD
Flags:
N C
Example:
CP (HL)
Before:
A H 96 5203 36 F
After:
AI H
96 Ini,r6, 4 0 P
9203
9203
226
CPD
Function: Format:
0 0 0
byte ED byte 2: A9
[I
Description:
The contents of the memory location addressed by the HL register pair are subtracted from the contents of the accumulator and the result is discarded. Then both the HL register pair and the BC register pair are decremented.
Data Flow:
Addressing Mode:
indirect.
Flags:
s z x 1'
P/V N C
V Reset x II In
227
Example:
2A 3154
06
F C L
A B H
2A
8665
AS 7
6665
8665
OBJECT CODE
228
CPDR
Function: Format:
byte 1: ED byte 2: B9
Description:
The contents of the memory location addressed by the HL register pair are subtracted from the contents of the accumulator and the result is discarded. Then both the BC register pair and the HL register pair are decremented. If BC # 0 and A [HL], the program counter is decremented by two and the instruction is re-executed.
Data Flow:
a 0
Timing:
BC = 0 or A = [1-IL]: 4 M cycles; 16 T states: 8 usec @ 2 MHz BC 0 and A * [HL]: 5 M cycles; 21 T states: 10.5 usec @ 2 MHz
S Z H P/V N C
Flags:
i Set if A = [HL]
229
Example:
CPDR Before:
A B H 9A 0002 6100 00 F C L H A After:
9A
r,"47,
F C
/. I
230
CPI
Function: Format:
A 11-111; HL
HL + 1; BC ^ BC 1
a
I 1 0 I
byte 1: ED byte 2: Al
a o1 o a
Description:
The contents of the memory location addressed by the HL register pair are subtracted from the contents of the accumulator and the result is discarded. The HL register pair is incremented and the BC register pair is decremented.
Data Flow:
/ ,
A C E
a
D
DATA
]x
X I
231
Example:
09 0510 96B9
00
F A C B
09
F C
B H
136B9
86B9
OBJECT CODE
232
CPIR
Function:
0 a
0
0(0
byte 1: ED byte 2: B1
Description:
The contents of the memory location addressed by the HL register pair are subtracted from the contents of the accumulator and the result is discarded. Then the HL register pair is incremented and the BC register pair is decremented. If BC # 0 and A [HL], then the program counter is decremented by 2 and the instruction is re-executed.
Data Flow:
O%/2 /2/7 ./
/ / /
Timing:
BC = 0 or A = [HL] : 4 M cycles; 16 T states: 8 usec 2 MHz BC # 0 and A # [HL] : 5 M cycles; 21 T states: 10.5 usec @ 2 MHz indirect.
Addressing Mode:
233
Flags:
S Z H Pr/ N C
SI X
I X Ii i
Example:
CP IR Before:
A 96 0051 039B OD A
After:
90 004 039D 46
B H
2A 9B 06
234
CPL
Complement accumulator.
Function: Format:
A 4- A
0 0
2F
Description:
The contents of the accumulator are complemented, or inverted, and the result is stored back in the accumulator (one's complement).
Data Flow:
P/V N C
Example:
CPL
Before:
A 3D A
After:
OBJECT CODE
235
DAA
Function: Format:
27
Description:
The instruction conditionally adds "6" to the right and/or left nibble of the accumulator, based on the status register, for BCD conversion after arithmetic operations.
value of value of ft added
C 0 0 0 0 0 0 1 1 1 0 0 1 1
high nibble
ohcc pc; ta. 4 . 4 . eqr? rn c 60 0 ck <l ( 6CS 0 ..:;
H 0 0 1 0 0 1 0 0 1 0 1 0 1
low nibble 0-9 A-F 0-3 0-9 A-F 0-3 0-9 A-F 0-3 0-9 6-F 0-9 6-F
to A 00 06 06 60 66 66 60 66 66 00 FA AO 9A
C after execution 0 0 0 1 1 1 1 1 I 0 0 1 1
Data Flow:
B
MI MI El III
szr wr
236
Addressing Mode:
Implicit.
5 NC
Flags:
Example:
DAA
Before:
A
After:
I 94
F A
B2
OBJECT CODE
237
DEC m
Function: Format: r (HL) (IX + d)
Decrement operand m.
0 0 0 0 0
/
001
Description:
The contents of the location addressed by the specific operand are decremented and stored back at that Iocation.mis defined in the description of the similar INC instructions.
Data Flow.
A 8 D H C E
238
Tuning:
M cycles: r (HLI (IX + d) (IY + d) Addressing Mode: r: dexed. DEC r I 3 6 6 T stales: 4 II 23 23
Byte Codes:
T:ABCOE 111. 3D OS OD 15 ID 25 20
Flags:
5 Z
N C
Example:
DEC C Before:
OF
ar
After:
OBJECT CODE
239
DEC rr
Function: Format:
rr rr
0 0
Description:.
The contents of the specified register pair are decremented and the result is stored back in the register pair. rr may be any one of: BC 00 DE 01 HL 10 SP 11
Data Flow:
Timing:
BC DE HI SP
OB1181 28 38
240
(no effect).
Example:
DEC BC Before: en
3811
After: lc
B
3810 /
OBJECT CODE
241
DEC IX
Function: Format:
Decrement IX.
IX IX I
0 0 0
0 0
byte I: DD byte 2: 2B
Description:
The contents of the IX register are decremented and the result is stored back in IX.
Data Flow:
A
B H
IX
Flags:
S Z
P/V N C
Example:
After:
242
DEC IY
Function: Format:
Decrement IY.
IY
IY 1
0
010
byte FD byte 2: 2B
Description:
The contents of the IY register are decrementea and the result is stored back in IY.
Data Flow:
A B H
IY
Flags:
5 Z
P/V N C
(no effect).
Example:
DEC IY Before:
IY 900F
After: 900E
OBJECT CODE
243
DI
Function: Format:
Disable interrupts.
IFF 4- 0
F3
Description:
The interrupt flip-flops are reset, thereby disabling all maskable interrupts. It is reenabled by an El instruction.
Timing:
Flags:
5 Z
PN N C
(no effect).
244
THE Z80 INSTRUCTION SET DJNZ e Decrement B and jump e relative on no zero.
Function: Format:
B B 1 : if B # 0: PC
PC +e
0 e-2
Description:
The B register is decremented. If the result is not zero, the immediate offset value is added to the program counter using two's complement arithmetic so as to enable both forward and backward jumps. The offset value is added to the value of PC + 2 (after the jump). As a result. the effective offset is -126 to +129 bytes. The assembler automatically subtracts from the source offset value to generate the hex code.
Data Flow:
Timing:
245
(no effect)
Example:
Before:
51 PC 00E1 B
After:
PC
OBJECT CODE
246
EI
Enable interrupts.
Function: Format:
1FF
FB
Description:
The interrupt flip-flops are set, thereby enabling maskable interrupts after the execution of the instruction following the El instruction. In the meantime maskable interrupts are disabled.
1 M cycle; 4 T states; 2 usec @ 2 MHz
Implicit.
s
Flags:
P/V N C
(no effect).
Example:
A usual sequence at the end of an interrupt routine is: EI RET1 The maskable interrupt is re-enabled following completion of RET1.
247
EX AF, AF'
Function:
AF---AF'
Format:
0 0 0 0 Ito 0 0
08
Description:
The contents of the accumulator and status register are exchanged with the contents of the alternate accumulator and status register.
Data Flow:
A B
0 H
F A B' D'
Timing:
Addressing Mode:
Implicit.
Flags:
S Z
P/V N C
Example:
A A
04
81 3A
F A F' A
90 1 3A
04 I 81
90
F'
OBJECT CODE
248
EX DE, HL
Function: Format:
DE
HL
110
EB
Description:
Data Flow:
A C EE L H
Implicit.
Flags:
P/V N
(no effect).
Example:
EX DE, HL
Before:
After:
A4E6 9604 D 9604 AAE6 RL
D
H
HI
OBJECT CODE
249
EX (SP), HL
Function:
Format:
0 0 0
E3
Description:
The contents of the L register are exchanged with the contents of the memory location addressed by the stack pointer. The contents of the H register are exchanged with the contents of the memory location immediately following the one addressed by the stack pointer.
Data Flow:
e
5P
sa /
A-41
Flags:
(no effect).
250
Example:
EX (SP), HL
Before: H
SP 8290
After
L H
vAr
B409
8409
spr
8409 B40A
251
EX
(SP), IX
Function:
Format:
0 0
byte I: DD byte 2: E3
Description:
The contents of the low order of the IX register are exchanged with the contents of the memory location addressed by the stack pointer. The contents of the high order of the IX register are exchanged with the contents of the memory location immediately following the one addressed by the stack pointer.
Data Flow:
A B H C
IX
SP
Flags:
5 Z
H P/V N C
(no effect).
252
Example:
IX
9234
IX
016B
5P
0402
SP
0402
0402 0403
0402 0403
34 92 I
_......,
OBJECT CODE
253
EX (SP), IY
Function: Format:
0 0 0 0
byte FD byte 2: E3
Description:
The contents of the low order of the IY register are exchanged with the contents of the memory location addressed by the stack pointer. The contents of the high order of the IY register are exchanged with the contents of the memory location immediately following the one addressed by the stack pointer.
Data Flow: c
E
5 Z
P/V N C
(no effect).
254
Before:
After:
IY SP
BF03 6211
IY SP
41P,;
6211
6211 6212
6211 6212
OBJECT CODE
255
EXX
Function: Format:
0 0
D9
Description:
The contents of the general purpose registers are exchanged with the contents of the corresponding alternate registers.
Data Flow:
A
B
D H
Flags:
s 2
P/V N C
(no effect).
Example:
EXX Before: 04
B H
39 54 Fl 28 26 02 DO H
After:
F C
A
04
8C 93 4F
28 00 DO E3
2A 00 DO E3
3F 39 54 Fl
2A 26 02 DO
F'
256
HALT
Function: Format:
0 76
Description:
CPU suspends operation and executes NOP's so as to continue memory refresh cycles, until interrupt or reset is received. 1 M cycle; 4 T states; 2 usec @ 2 MHz + indefinite Nop's.
Timing:
Implicit.
S Z
P/V N C
(no effect).
257
IM 0
Function: Format:
0 0 0 0 0
0 0
byte I: ED
byte 2: 46
Description:
Sets interrupt mode 0. In this condition, the interrupting device may insert one instruction onto the data bus for execution, the first byte of which must occur during the interrupt acknowledge cycle. 2 M cycle; 8 T states; 4 usec @ 2 MHz Implicit.
5 Z H P/V N C
(no effect).
258
Function: Format:
byte 1: ED
0
byte 2: 56
Description:
Sets interrupt mode 1. A RST 0038H instruction will be executed when an interrupt occurs.
Data Flow:
00
38 0038 I NT ROUTINE
STACK
Timing:
Addressing Mode:
Implicit.
Flags:
S Z
PN N C
(no effect).
259
IM 2
Function:
Format: 0 0 0
byte I: ED a byte 2: 5E
Description:
Set interrupt mode 2. When an interrupt occurs, one byte of data must be provided by the peripheral which is used as the low order of an address. The high order of this vector address is taken from the contents of the I register. This points to a second address stored in memory,which is loaded into the program counter and begins execution.
2 M cycles; 8 T states; 4 usec @ 2 MHz
Implicit.
S Z H PA/ N C
(no effect)
260
IN r, (C)
Function: Format:
r (C)
1_1
0 I
Jo
I
1 I 121I1 I byte l: ED
O 0
01 byte 2
Description:
The peripheral device addressed by the contents of the C register is read and the result is loaded into the specified register. C provides bits AO to A7 of the address bus. B provides bits A8 to A15.
Data Flow:
A
PORT C E
r may be any one of: A 111 B 000 C 001 D 010 E 011 H 100 L 101
Tinting:
External.
COE HI. 1601 68
r: A 0
ED 78 40 48 501 58
261
Flags:
0
It is important to note that INA,(N) does not have any effect on the flags, while IN r. (C) does.
Example:
IN D, (C)
Before:
A5
After:
A5 PORT D
09
6A A5
6A A5
PORT
OBJECT CODE
262
IN A, (N)
Function: Format:
A (N)
0
I I I I I I I I I
Description:
The peripheral device N. is read and the result is loaded into the accumulator. The literal N is placed on lines AO to A7 of the address bus. A supplies bits A8 to A15.
Data Flow:
After:
Afr
Fl B2
PORT
OBJECT CODE
263
INC r
Function: Format: Description:
Increment register r.
r r + I
I
0 0
The contents of the specified register are incremented. r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A B
Implicit. r:
A B 3C 04 CDE HL
DC 14 1C 24 2C
Flags:
N C
Example:
0
After:
INC D Before:
06
OBJECT CODE
264
INC rr
Function: Format:
rr
rr + I
0 0
0 0
Description:
The contents of the specified register pair are incremented and the result is stored back in the register pair. rr may be any one of: BC 00 DE 01 HL 10 SP 11
Data Flow:
A B C
0 H
SP
Implicit.
BC DE HL SP 03 13 23 33
IT:
265
Flags:
S Z
P/V N C
(no effect).
Example:
INC HL
Before:
H 0014
After:
H ,c. ';;OB15 %
OBJECT CODE
266
INC (HL)
Function: Format:
0 Description:
0 34
The contents of the memory location addressed by the HL register pair are incremented and stored back at that location.
Data Flo w:
A
8
D H
0
Example: INC (HL) Before: After:
06131
0661
0681
0661
OBJECT CODE
267
INC (IX + d)
Function: Format:
0 0 0
T
0
0
0 0
Description:
The contents of the memory location addressed by the contents of the IX register plus the given offset value are incremented and stored back at that location.
Data Flow:
A
B D H
IX
C E
DATA
INC
O
Timing: Addressing Mode: Flags:
268
After:
IX
0381
81
ff; A PRIM
85
OBJECT CODE
269
INC (IY + d)
Function: Format:
Increment indexed addressed memory location (IY + d). (IY +d) (IY + d) + 1
0 0 0
d
0 0
Description:
The contents of the memory location addressed by the contents of the IY register plus the given offset value are incremented and stored back at that location.
Data Flow:
A
B D H
C E
ALU INC
Flags:
5 Z
PAg N C
270
Before: IV
0601 IY
After:
0601
0601 0602
OBJECT CODE
271
INC IX
Function: Format:
Increment IX.
1X 4- IX +
0 0 0 0
0
byte 1: DD byte 2: 23
Description:
The contents of the IX register are incremented and the result is stored back in IX.
Data Flow:
A B D E All)
IX
A 41NEImi
Timing:
(no effect).
Example:
8150
Ix
8101 // A
OBJECT CODE
272
INC IY
Function: Format:
Increment IY
IY 1Y + 1
The contents of the IY register are incremented and the result is stored back in IY.
Data Flow:
A B D H E
Iv
Flags:
5 Z
P/V N C
(no effect).
Example:
IY
36B1
IY
OBJECT CODE
273
IND
Function:
(111,) 4-
(C); B
B 1; HL
HL 1
Description:
The peripheral device addressed by the C register is read and the result is loaded into the memory location addressed by the HL register pair. The B register and the HL register pair are then each decremented.
Data Flow:
Timing:
External.
S Z 7 x
P/V N C
274
Before:
B H AI B5
After: C
H 26 B5 PORT 26 135 PORT AO B5 C
06BA
06BA
06BA
26 /
roll111111
OBJECT CODE
275
INDR
Function:
Format: 0 o
,t 0
byte 1: ED
0
byte 2: BA
Description:
The peripheral device addressed by the C register is read and the result is loaded into the memory location addressed by the HL register pair. Then the B register and the HL register pair are decremented. If B is not zero, the program counter is decremented by 2 and the instruction is re-executed.
Data Flow:
DATA
rr _c3 47
B COUNTER
A
A A
C
PORT .11111111111
B = 0:4 M cycles; 16 T states; 8 usec @ 2 MHz. B A 0:5 M cycles; 21 T states; 10.5 usec @ 2 MHz. Addressing Mode: External
Flags:
P/V N C
276
Example:
INDR
Before:
B H 03 I 09F2 86 56 PORT 56 C B H
After:
P 400 /
09EF
56
t BF 56 PORT
6A
277
INI
Function: Formal:
(HL)
(C); B B 1; HL HL +
byte 1: ED 0 so byte 2: A2
Description:
The peripheral device addressed by the C register is read and the result is loaded into the memory location addressed by the HL register pair. The B register is decremented and the HL register pair is incremented.
The contents of C are placed on the low half of the address bus. The contents of B are placed on the high half. I/O selection is generally made by C, i.e., by AO to A7. B is a byte counter.
Timing:
278
, Before:
B 09 21 C
After:
Ba H
21
Al 12
86
21
i PORT
86 21
PORT
Al 12
A112
OBJECT CODE
279
INIR
Function:
HL HL + I; Repeat
Format: 0
0 0
byte ED
0
0 0
byte 2: B2
Description:
The peripheral device addressed by the C register is read and the result is loaded into the memory location addressed by the HL register pair. The B register is decremented and the HL register pair is incremented. I f B is not zero, the program counter is decremented by 2 and the instruction is reexecuted.
Data Flow:
A B /counte, DATA
PORT
fn /Az' a
Timing:
Addressing Mode:
External.
Flags:
s z
P/V N C
280
Before:
After:
B H
C 9I A5 MPORT 51
B ta,99ra
51 IC
A
ar
W/AIF PORT
51
OBJECT CODE
91A5 91 AE 9IA7
281
JP
CC, pq
Function: Format:
if cc true: PC
pq
Description:
If the specified condition is true, the two-byte address immediately following the opcode will be loaded into the program counter with the first byte following the opcode being loaded into the low order of the PC. If the condition is not met, the address is ignored. cc may be any one of: NZ 000 Z 001 NC 010 C 011 PO 100 PE 101 P 110 M Ill no zero zero no carry carry parity odd parity even plus minus
Duia Flow:
A
I
E
CONTROL LOGIC
2/
282
Tuning:
Immediate.
CC NZ Z NC C PO PE P M C2 CA D2 DA E2 EA F2 I FA
Flags:
12/1 / N C
(no effect)
Evaniple:
JP C, 3824
Before:
51 F
After:
51 F
PC
0032
PC
OBJECT CODE
283
JP pq
Function: Format:
Description:
The contents of the memory location immediately following the opcode are loaded into the low order half of the program counter and the contents of the second memory location immediately following the opcode are loaded into the high order of the program counter. The next instruction will be fetched from this new address.
A
Data Flow:
B H
PC
JP
Tuning:
Addressing Mode: Flags: Example:
After: /302 VA
OBJECT CODE
284
JP (HL)
Function: Format:
Jump to HL.
PCHL
TO -
E9
Description:
The contents of the HL register pair are loaded into the program counter. The next instruction is fetched from this new address.
Data How:
A B 0 H C
(no effect).
Example:
H
E9 PC
0411
0411
8001
PC
we0411
OBJECT CODE
285
JP (IX)
Function: Format:
Jump to IX.
PC 4.-
IX
The contents of the IX register are loaded into the program counter. The next instruction is fetched from this new address.
Data Flow:
A B C
IX
Q
PC
IX PC
130F1
IX
80F I
3B4A
PC
B0F1
OBJECT CODE
286
JP (IV)
Function: Format:
Jump to IY PC IY byte I: FD
1111
Descripoon:
byte 2: E9
The contents of the IY register arc moved into the program counter. The next instruction will be fetched from this new address.
A B D C E
Data How:
IY
PC
(no effect).
Example:
JP (IV) Before:
IY
PC AA4B
After: IY
PC
AA4B
E410
O6B
rf
OBJECT CODE
287
JR cc, e
Function: Format:
if cc true. PC 4 PC + e
C C
0 0 0
III
e-2
Description:
If the specified condition is met, the given offset value is added to the program counter using two's complement arithmetic so as to enable both forward and backward jumps. The offset value is added to the value of PC + 2 (after the jump). As a result, the effective offset is -126 to +129 bytes. The assembler automatically subtracts 2 from the source offset value to generate the hex code. If the condition is not met, the offset value is ignored and instruction execution continues in sequence. cc may any one of: NZ 00 Z 01 NC 10 C II
Data Flo w:
A B D H E JR
CONTROL rl LOGIC i;
Timing:
M cycles:
condition met: condition not met: 3 L 2
T states:
12 7
user @ 2 MHz:
6 3.5
288
Byte Codes:
cc: NZ Z NC C 20 28 30 38
Flags:
S Z
P/V N C
(no effect).
Example: JR NC, $ 3
$ = current PC
After:
F
Before:
00
PC A FD
PC
13000
OBJECT CODE
289
JR e
Function: Format:
Description:
The given offset value is added to the program counter using two's complement arithmetic so as to enable both forward and backward jumps. The offset value is added to the value of PC + 2 (after the jump). As a result, the effective offset is -126 to + 129 bytes. The assembler automatically subtracts 2 from the source offset value to generate the hex code.
Data Flow:
A B E H JR e -2
PC
Tinnng:
Addressing Mode: Flags:
After:
8004
ISE is
D2
OBJECT CODE
290
LD dd, (nn)
Function: Format:
Load register pair dd from memory locations addressed by nn. d dhow (nn); ddhigh (nn +1)
byte I: ED
Oi rid
ell 1 10
Description:
The contents of the memory location addressed by the memory locations immediately following the opcode are loaded into the low order of the specified register pair. The contents of the memory location immediately following the one previously loaded are then loaded into the high order of the register pair. The low order byte of the nn address immediately follows the opcode. dd may be any one of: BC 00 DE 01 HL 10 SP 11
Data Flow:
a
0 H
SP
291
Direct.
4B 58 6B 7B
Flags:
S Z
N C
(no effect)
Example:
LD DE, (5021)
Before:
D
DBE2
After:
,30F4
VA
5021 5022
5021 5022
OBJECT CODE
292
LD dd, nn
Function: Format:
d d
Di_0_1 1 I
I 1
I 1
I 1
A
1
I 1
I 1
I 1
Description:
The contents of the two memory locations immediately following the opcode are loaded into the specified register pair. The lower order byte of the data occurs immediately after the opcode. dd may be any one of: BC 00 DE 01 HL 10 SP II
Data Flow:
A
B
H SP
C E L
Timing:
dd: BC DE HL 5P 01
11
21 31
Flags:
5 Z
PA/ N C
(no effect)
293
Example:
LD DE, 4131
Before:
0394
After:
E D 4131 E
OBJECT CODE
294
LD r, n
Function: Forman:
n
0
Description:
The contents of the memory location immediately following the opcode location are loaded into the specified register. r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A
B
0 H
Byte Codes:
Flags:
S z
P/V N C
(no effect).
295
Exantple:
LD C, 3B Before: C
01
After: C
Ar
OBJECT CODE
296
LD r,
Function: Format:
r 4- r a
I I I I
Description:
The contents of the specified source register are loaded into the specified destination register. r and r' may be any one of: A III B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A
B H
Byte Codes:
A
B C D E H
5A 58 5C 5D 6A 6B 6C 6D
Flags:
P/V N C
(no effect).
297
Before:
After:
A 67
BC
BC
H
OBJECT CODE
BD
'Sr A
298
LD (BC), A
Function: Format:
(BC) 4- A
010 0
0 100
02
Description:
The contents of the accumulator are loaded into the memory location addressed by the contents of the BC register pair.
Data Flow:
Ell I 11-11J
Example: LD (BC), A Before:
3F 4109 C A
(no effect).
After:
3F 4109
4109
4109
OBJECT CODE
299
LD (DE), A
Load indirectly addressed memory location (DE) from the accumulator. (DE) 4- A
0 0 0 0 0 0
12
The contents of the accumulator are loaded into the memory location addressed by the contents of the DE register pair.
Data Flow:
A
B
E H DATA
Timing:
Addressing Mode: Flags:
P/V N C
After:
ED
0392
ED
0392
0392
0392
OBJECT CODE
300
LD (HL), n
Load immediate data n into the Indirectly addressed memory location (HL).
Function: Format:
(HL) n
[ I ,
L _1_1_
Description:
The contents of the memory location immediately following the opcode are loaded into the memory location indirectly addressed by the HL data pointer
Data Flow:
A
ID
B D H
n C E
DATA
r / .1111161 A
Timing: 3 M cycles; 10 T states; 5 usec @ 2 MHz
Addressing Mode:
Immediate/indirect.
Flags:
5 z
P/V N C
(no effect).
301
Before:
H A342 H
After:
A342
A342
OBJECT CODE
302
LD (HL), r
Function:
(HL) 4- r
Format:
I I
I I
Description:
The contents of the specified register are loaded into the memory location addressed by the HL register pair. r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A B D
C
E
DATA
tea NMI
Timing:
303
Flags:
E/V N C
(no effect).
Example:
LD
(HL), B
Before: B
H
81 B
After:
81
0501
C501
C501
0501
OBJECT CODE
304
LD r, (IX + d)
Function:
(IX + d)
Description:
The contents of the memory location addressed by the IX index register plus the given offset value, are loaded into the specified register. r may be any one of: A III B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A B
ix
7E 46 4E 56 5E
66
6E
-d
305
Flags:
P/V N C
(no effect).
Example:
LD E, (IX + 5)
Before:
03
After:
E
IX 3020
IX
3020
3020
3020
3025
306
LD r, (IY + d)
Function:
r (IY + d)
Format: a a byte 1: FD byte 2 byte 3: offset value Description: The contents of the memory location addressed by the IY index register plus the given offset value, are loaded into the specified register. r may be any one of: A 111 B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A B H
IY
Timing:
Addressing Mode:
Indexed.
307
Flags:
S Z
P/V N C
(no effect).
Example:
LD A, (IY + 2)
Before:
A E3 6005
After:
A r IT F9 6005
IT
6005
6005 6007
308
LD (IX + d), n
Function: Format:
(IX + d) n
I I I
0 0
d
D II
Al
1.11 T TIT
A
lit
Description:
The contents of the memory location immediately following the offset are transferred into the memory location addressed by the contents of the index register plus the given offset value.
Data Flow:
A B
r,
DATA
P"'1111
ix
Flags:
s z
P/V N C
(no effect).
309
Before:
After:
8109
IX
8109
IX
8109
8109
8100
1310D
OBJECT CODE
310
LD (IY + d), n
Function: Format:
(IY + d)
0 0 0 0 0
111113
111111
Description:
The contents of the memory location immediately following the offset are transferred into the memory location addressed by the contents of the index register plus the given offset value.
Data Flow:
A
es.
C E d n LD
B D H
IY
DATA
Timing:
P/V N C
(no effect).
311
LD (IY + 3), BA
Before:
After:
0100 IY 0100
IV
0100
0100
0103
0103
OBJECT CODE
312
LD (IX + d),r
Function: Format:
(IX +
byte 1: DD I
I
0
d
Description:
The contents of specified register are loaded into the memory location addressed by the contents of the index register plus the given offset value. r may be any one of: A 111 B 000 C 001 D 010 E 011 H 100 L 101
DATA
Data Flow:
A
B E H
IX
LD
WWI
Timing:
5 M cycles; 19 T states; 9.5 usec @ 2 MHz
313
Indexed.
A B C D E 1-1
OD- 77 70 71 72 73 74 75
-d
Flags:
P/V N C
(no effect).
Example:
After:
C
IX 4462 66
IX
4462
4462 4463
OBJECT CODE
314
LD (IY + d), r
Function: Format:
(IY + d)
0 0 d
Description:
The contents of the specified register are loaded into the memory location addressed by the contents of the index register plus the given offset value. r may be any one of: A 111 B 000 C 001 D 010 E 011 H 100 L 101
DATA
Data Flow:
A B E H IY
WO
315
PN N C
(no effect).
Example:
1 1 + 3), A LD (1 Before:
A 3E A
After:
3E
1Y
5AB4
1Y
5AB4
5A134
ISE
5AB4 21 5AB7
316
LD A, (nn)
Function: Format:
4 (nil)
0
n
I I
byte 1: 3A
I
byte 2: address, low order byte byte 3: address, high order byte
Description:
The contents of the memory location addressed by the contents of the 2 memory locations immediately following the opcode are loaded into the accumulator. The low byte of the address occurs immediately after the opcode.
Data Flow:
A
a
D
rze -
317
Flags:
S Z
P/V N C
(no effect).
Example:
LD A, (3301)
Before: A
After:
OA
3301
3301
OBJECT CODE
318
LD (nn), A
Function:
(nal I A
Format: 0 0 0 0
lIf
Description:
The contents of the accumulator are loaded into the memory location addressed by the contents of the memory locations immediately following the opcode. The low byte of the address immediately follows the opcode.
Data Flow:
A B 0 H
319
Flags:
5 Z
P/V N C
(no effect)
Example.
LD (0321), A
Before:
Al
A4
After:
A Al
0321
0321
OBJECT CODE
320
LD (nn), dd
Function: Format:
ri
0 0 0
n
byte 1: ED byte 2 byte 3: address, low order byte 4: address, high order
Descriptions:
The contents of the low order of the specified register pair are loaded into the memory location addressed by the memory locations immediately following the opcode. The contents of the high order of the register pair are loaded into the memory location immediately following the one loaded from the low order. The low order of the nn address occurs immediately after the opcode.dd may be anyone of: BC 00 HL 10 SP II
DE 01
LD
C E
dd
n
SP
321
dd: BC DE HL SP ED43 53 63 73
Flags:
5 2
P/V N C
(no effect).
Example:
LD (040B), BC
Before:
B
0221
After:
C Bi t 0221
040B 040C
0408 040C
OBJECT CODE
322
LD (nn), HL
Function: Format:
(nn) L. (nn + 1)
0
r
L1 L I I
"
-L
Description:
The contents of the L register are loaded into the memory location addressed by the memory locations immediately following the opcode. The contents of the H register are loaded into the memory location immediately following the location loaded from the L register. The low order of the tin address occurs immediately after the opcode.
Data Flow:
LD
n n
Timing:
323
Flags:
5 Z
(no effect).
Example:
LD (40B9), HL
Before:
H
After:
304A
304A L HE-
4089 408A
OBJECT CODE
324
LD (nn), IX
Function: Format:
0 0 0 0 0
I 0
I , 1o
Description:
The contents of the low order of the IX register are loaded into the memory location addressed by the contents of the memory location immediately following the opcode. The contents of the high order of the IX register are loaded into the memory location immediately following the one loaded from the low order. The low order of the nn address occurs immediately after the op code.
Data Flow:
LO
E H
DATA
325
Flags:
5 Z
L ETNtl
(no effect).
Example:
LD (012B), IX
Before:
IX [ 0406
After:
0406
0128 012C
012B 012C
OBJECT CODE
326
Function: Format:
(nnI
0
o h
byte 1: FD 0 byte 2: 22 byte 3: address. low order byte 4: address, high order
II
n
Description:
The contents of the low order of the IY register are loaded into the memory location addressed by the contents of the memory locations immediately following the opcode. The contents of the high order of the IY register are loaded into the memory location immediately following the one loaded from the low order. The low order of the nn address occurs immediately after the opcode.
Data Flow:
A
L.D
B D
C E
DATA
Tinting:
Addressing Mode:
Direct.
327
(no effect)
Example:
LD (BD04), IY
Before:
IV D204 IY
After:
D204
9004 9005
OBJECT CODE
328
LD A, (BC)
Load accumulator from the memory location indirectly addressed by the BC register pair.
Function: Format:
A (BC)
1 ,10J
Description:
OA
The contents of the memory location addressed by the contents of the BC register pair are loaded into the accumulator.
Data Flow:
A
<
C 1E DATA
(no effect).
Example:
LD A, (BC) Before:
A B AB 32D1 A C B
After:
7.12V A 32DI
3201
32D1
OBJECT CODE
329
LD A. (DE)
Load the accumulator from the memory location indirectly addressed by the DE register pair.
Function: Format:
A 4- (DE)
IA
Description:
The contents of the memory location addressed by the contents of the DE register pair are loaded into the accumulator.
Data Flow:
A7/10(1/ B I 7\i
H
Timing:
After:
icc
6051
6051
6051
6051
OBJECT CODE
330
LD A, I
Function: Format:
A --
byte I: ED byte 2: 57
The contents of the interrupt vector register are loaded into the accumulator.
Data How:
rilT)
LD A,1 Before:
A 30
sz
P/V N C
x A
Example:
After:
i ij dB
7 4
4B
OBJECT CODE
331
LD L A
Function: Format:
A 0 0 byte I: ED byte 2: 47
0 0 0
Description:
The contents of the accumulator are loaded into the Interrupt Vector register.
Data Flow:
A E H
S Z
(no effect)
Example:
LD I, A
Before:
AI 06
After:
D2 IA
06
OBJECT CODE
332
LD A, R
Function: Format:
ASR
Description:
The contents of the Memory Refresh register are loaded into the accumulator.
Data Flow:
A "i":": 2 7 /-
B
E
Tinting:
Addressing Mode: Flags:
x 4
0
set to contents of IFF2
Example:
LD
A, R After:
dA
Before:
Al
62
.R
RI 4A
OBJECT CODE
333
LD HL, (nn)
Function:
(nn): H
(nn + I)
Format: 0 0 0 0 0 byte I: 2A byte 2: address, low order byte 3: address, high order Description: The contents of the memory location addressed by the memory locations immediately after the opcode are loaded into the L register. The contents of the memory location after the one loaded into the L register are loaded into the H register. The low byte of the nn address occurs immediately after the opcode.
Data Flow:
B D
LD
WS
A/
ra 1 immLW4.
fi
(no effect)
334
LD HL, (00241
Before:
H
ONE
After:
L H17 .5 6691/7, L
0024 0025
0024 0025
OBJECT CODE
335
LD IX, nn
Function: Format:
nn
0 0 0 0 0 0 0
I IIIAIII Mil I
byte I: DD byte 2: 21 byte 3. immediate data, low order byte 4: immediate data, high order
Description:
The contents of the memory locations immediately following the opcode are loaded into the IX register. The low order byte occurs immediately after the opcode.
Data Flow:
A B H C t
IX
LD
Immediate.
S Z H P/V N C
(no effect)
336
Example:
LD IX, BOB 1
Before:
IX 306F IX
After:
BOBI
OBJECT CODE
337
LD IX, (nn)
Function: Format:
'Now
(nn); IXhigh
(nn + 1)
ET, 10 Etiflo
EDT c7-1
I I T 1 1 /
byte I: DD
.-1;Trfol byte 2: 2A
Ti
T
-T
Ti
Descriptions:
The contents of the memory location addressed by the memory locations immediately following the opcode are loaded into the low order of the IX register. The contents of the memory location immediately following the one loaded into the low order are loaded into the high order of the IX register. The low order of the nn address immediately follows the opcode.
Data Flow:
A B D H
n
c
IX
4 /1,M-5-7
Timing:
Addressing Mode:
338
Flags:
5 Z
P/V N C
(no effect).
Example:
LD IX, (010B)
Before:
After:
010B 0100
0108 0100
OBJECT CODE
339
LD IY, nn
Function:
Format: 0 byte I: FD byte 2: 21 byte 3: immediate data, low order byte 4: immediate data, high order
Description:
The contents of the memory locations immediately following the opcode are loaded into the IY register. The low order byte occurs immediately after the opcode.
Data Flow:
A
B D
C E
LI)
IY
340
S z
II
P/V N C
(no effect)
Example:
LD IY, 21
Before:
it 0698 IV
After:
e /S665
40
OBJECT CODE
341
LD IV, (nn)
Function: Format:
lYlow
'byte I: FD 0 0 0
0
1
0
t t
I
Description:
The contents of the memory location addressed by the memory locations immediately following the opcode are loaded into the low order of the IY register. The contents of the memory location immediately following the one loaded into the low order are loaded into the high order of the IY register. The low order of the nn address immediately follows the opcode.
Data Flow:
A B H Iv
was
342
Timing:
Addressing Mode:
Flags:
P/V N C
(no effect).
Example:
LD 1Y, (500D)
Before:
IY 6002 IT
After:
500D 500E
500D 500E
OBJECT CODE
343
LD
Function: Format:
Description:
The contents of the accumulator are loaded into the Memory Refresh register.
A B 0 H R C E
Data Flow:
Timing:
(no effect)
Example:
LD R, A
Before:
AI
OF
After:
IR
40
AAl
OBJECT CODE
344
LD SP, HL
Function: Format:
SP HL F9
Description:
The contents of the HL register pair are loaded into the stack pointer.
Data Flow:
A B C
SP
/V
a<
Timing:
L
LD SP, HL
(no effect)
Example:
Before:
After:
4
SP OBJECT CODE
06AF OBOE
1L
H SP
06AF
345
LD SP, IX
Function: Forman:
SP IX
21 1
10
byte 1: DID
N ti byte 2: F9
Description:
The contents of the IX register are loaded into the stack pointer.
Data Flow:
B
C E
H ix SP
SZ
P/V N C
Example:
IX SP OBJECT CODE
0902 54A0
ix SP
0902
OPCn
346
LD SP, IY
Function: Format:
SP 4 IY
byte 1: FD 0 byte 2: F9
Description:
The contents of the IY register are loaded into the stack pointer.
Data Flow:
A C E H
IT SP
(no effect)
Example:
It
09AB
i IT I
09AB
SP OBJECT CODE
6004
aC P9 3 4A
347
LDD
Function:
Format: 0 0
0
byte I: ED 0 byte 2: A8
Description:
The contents of the memory location addressed by HL are loaded into the memory location addressed by DE. Then BC, DE, and I-IL are all decremented.
DATA
Data Flow: a
E DATA
Timing:
Flags.
S Z
P/V N C
348
Example:
0503
6211
6211
349
LDDR
Function:
Description:
The contents of the memory location addressed by HL are loaded into the memory location addressed by DE. Then DE, HL, and BC are all decremented. If BC * 0, then the program counter is decremented by 2 and the instruction reexecuted.
Data Flow:
A B D
j:
(init./Arran;
sbuiCia
Tinting:
BC * 0: 5 M cycles; 21 T states; 10.5 usec @ 2 MHz. BC = 0: 4 M cycles; 16 T states; 8 usec @ 2 MHz Indirect.
PN N C
5 Z
00
350
Before:
After:
C / coo37 r / E Sa %"7 /405r a
0003 0692
C B E D H
9035
06AF
0660
0691 0692
r DE/a
r AirtA
r AW/
BI
351
LDI
Function:
(DE) (HL); DE DE + 1; HL HL + 1; BC 4- BC - I
Format:
0
byte 1: ED
0 0 0
0 0
byte 2: AO
Description:
The contents of the memory location addressed by HL are loaded into the memory location addressed by DE. Then both DE and HL are incremented, and the register pair BC is decremented.
Data Flow:
B COUNTER DESTINATION SOURCE
DATA
A SE ,",
Timing:
Addressing Mode:
Flags:
5 Z
01
X I
352
Example:
LDI
Before:
After:
B H
346B1
34B1
OBJECT CODE
3902
353
LDIR
Function:
Format: 0 0 0 0 0 0
byte I: ED byte 2: BO
Description:
The contents of the memory location addressed by HL are loaded into the memory location addressed by DE. Then both DE and HL are incremented. BC is decremented. If BC # 0 then the program counter is decremented by 2 and the instruction is re-executed.
Data Flow:
A D re/ ,COUNTER DESTINATION / SOURCE E
2 'a -
DATA -J J
Pm11111111
For BC # 0: 5M cycles; 21 T states; 10.5 usec @ 2 MHz. For BC = 0: 4 M cycles; 16 T states; 8 usec @ 2 MHz Indirect.
Timing:
Addressing Mode:
354
Flags:
P/V N C
0 0 0
Example: LD1R
Before:
After:
B D H
C B
E
355
LD r, (HL)
Function: Format:
Description:
The contents of the memory location addressed by HL are loaded into the specified register. r may be any one of: A Ill B 000 C 001
D 010
E 011 H L 101
Data Flow:
A B C DATA
D H
Byte Codes:
r:
A B C DE HI 7E 46 4E
56
5E
66
6E
356
Flags:
S Z
(no effect).
Example:
LD D, (HL) Before:
3A OC
After:
gar, 4
32 L H OC 32
0C32
0C32
OBJECT CODE
357
NEG
Negate accumulator.
Function: Format:
A 4-
0 -
0 0 0 0 0
0 0 0
byte : ED byte 2: 44
Description:
The contents of the accumulator are subtracted from zero (two's complement) and the result is stored back in the accumulator.
Data Flow:
B D
Timing:
Addressing Mode: Flags:
N C
C will be set if A was 0 before the instruction. P will be set if A was 80H. Example: NEG Before:
A 32 A
After:
414,4"I''o
OBJECT CODE
358
NOP
Function: Format:
No operation.
Delay.
1 0 0 0 0 0
010
00
A B
No action
C
(no effect).
359
Function: Format: r n
IT
byte 1: B6 byte 1: DD
(IX + d)
, I 0
0
0
IF T
(IY + d)
0 0
r may be any one of: A Ill B 000 C 001 D 010 Description: E 011 H 100 L 101
The accumulator and the specified operand are logically tor'ed, and the result is stored in the accumulator. s is defined in the description of the similar ADD instructions.
360
Data Flow:
Al';117 4< r -B
D E AID V
r: implicit; n: immediate; (Ht.): ind rect; (IX + d), (IY + dl: indexed. OR r
rABCDE HE B7 BO BI B2 B3 Bd B5
Byte Codes:
Flags:
S Z
edV N C
Example: OR B
0 0
Before:
A B 06 B9 A B
After: :"K A
B9
OBJECT CODE
361
OTDR
Function:
Format:
Description:
The contents of the memory location addressed by the HL register pair are output to the peripheral device addressed by the contents of the C register. Both the B register and the HL register pair are then decremented. If B * 0, the program counter is decremented by 2 and the instruction is reexecuted. C supplies bits AO to A7 of the address bus. B supplies (after decrementation) bits A8 to A15.
Data Flow:
B H
Timing:
Addressing Mode:
External.
Flags:
S Z
P/V N C
362
Before:
B H
02 0051 32 ES ES
After: c
L PORT E5
Br
H
E5 : -47 / 720.01K
I
V PORT
363
OTIR
Function:
B I; HL HL + I; Repeat
Format:
1I FT
T0
byteLED 0 0 byte 2: B3
Description:
The contents of the memory location addressed by the HL register pair are output to the peripheral device addressed by the contents of the C register. The B register is decremented and the HL register pair is incremented. If B # 0. the program counter is decremented by 2 and the instruction is reexecuted. C supplies bits AO to A7 of the address bus. B supplies (after decrementationi bits A8 to A15.
Data Flow.
A B ; ''4Counler D H
/%
B = 0: 4 IVI cycles; 16 T states; 8 usec @ 2 MHz. B # 0: 5 M cycles; 21 T states; 10.5 usec @ 2 MHz Addressing Mode: External.
Flags:
5 z
P/V N C
364
Example:
OTIR
Before:
B H
After:
03 5550
AO
C B L H
re'r A
AO
/1/ 15145"! //
9 AO PORT
85 AO
PORT
365
OUT (C), r
Function: Format:
(C) r
0
0
0
0 0 I
byte 1: ED
byte 2
Description:
The contents of the specified register are output to the peripheral device addressed by the contents of the C register. r may be any one of: A 111
B 000 C 001
D 010 Register C supplies bits AO to A7 of the address bus. Register B supplies bits A8 to A15.
Data Flow:
A
B E H
PORT 16k ,
Timing:
Addressing Mode:
External.
H
P/V N C
Flags:
5 Z
366
OUT (C), B
Before:
B
09 Fl C PORT
After:
B 09 FI
B8 FI OBJECT CODE
09
FI
PORT
367
OUT (N), A
Function: Format:
(N).- A
byte 1: D3
1 I 1 1 1 1
1 1
1 I
1 I
'
Description:
The contents of the accumulator are output to the peripheral device addressed by the contents of the memory location immediately following the opcode.
Data Flow:
A
B H
C E
1. PORT
OUT
Flags:
(no effect).
Example:
After:
FF
OA PORT A 51
V SO
OA
PORT
OBJECT CODE
368
OUTD
Function: Format:
(C)
(HL); BC 4 B HL HL 1
101101
byte 1: ED byte 2: AB
Description:
The contents of the memory location addressed by the HL register pair are output to the peripheral device addressed by the contents of the C register. Then both the B register and the HL register pair are decremented. C supplies bits AO to A7 of the address bus. B supplies (after decrementation) A8 to A15.
Timing:
Addressing Mode:
External.
Flags:
5Z H P/VNC
369
OUTD
Before:
B H
30 228E 9A C B L H
After:
WA EVA
9A
06
9A
PORT
'6"1 /A
PORT
228F
228F
OBJECT CODE
370
OUTI
Function: Format:
(C) (HL); B B 1 ; HL HL + 1
0 0 0
0 0
byte 1: ED byte 2: A3
Description:
The contents of the memory location addressed by the HL register pair are output to the peripheral device addressed by the C register. The B register is decremented and the HL register pair is incremented. C supplies bits AO to A7 of the address bus. B (after decrementationi supplies bits A8 to A15.
Data Flo w:
A B re9upIr / / D E PORT DATA
Time ng:
Addressing Mode:
External.
Flags:
5
P/V N C
371
OUTI
Before:
After:
9A
BB
B/09ea Be
H' z 9 ',.0F913 L
OF9A
02 BB
PORT BB
PORT
OF9A
OF9A
OBJECT CODE
372
POP qq
Function: Format:
qqlow
J E
Description: The contents of the memory location addressed by the stack pointer are loaded into the low order of the specified register pair and then the stack pointer is incremented. The contents of the memory location now addressed by the stack pointer are loaded into the high order of the register pair, and the stack pointer is again incremented. qq may be any one of: BC 00 DE 01 Data Flow:
A B D H F C E
HL 10 AF 1 I
SP
Timing:
373
Flags:
S 2
P/V N C
[-Example:
POP BC
Before:
After:
C Br.
SP
B SP
890A 0156
374
POP IX
Function: Format:
IX low
(SP); IX high
(SP + I); SP SP + 2
byte I: DD
ID j
j byte 2: El
Description:
The contents of the memory location addressed by the stack pointer are loaded into the low order of the IX register, and the stack pointer is incremented. The contents of the memory location now addressed by the stack pointer are loaded into the high order of the IX register, and the stack pointer is again incremented.
Data Flow:
DATA
Timing:
Addressing Mode:
Indirect.
375
Flags:
S
P/V N C
II
(no effect).
Example:
POP IX
Before:
IX SP 0001 0906 IX SP
After:
WIAA,W,vfci-711
i 7 4' lv fi5%%/ al
376
POP IY
Function Format:
IY
low
(SP); IY
high
(SP + I); SP SP + 2
0 0 0 0
byte I: FD byte 2: El
Description:
The contents of the memory location addressed by the stack pointer are loaded into the low order of the IV register, and then the stack pointer is incremented. The contents of the memory location now addressed by the stack pointer are loaded into the high order of the IY register, and the stack pointer is again incremented.
Data Flow:
Flags:
5 Z
P/V N C
(no effect).
377
Example:
POP IY
Before:
IY SP
After:
032A
3004 IY reera rera
sPrepReyS
.___
OBJECT CODE
378
PUSH
Function:
qq low;
Format:
Description:
The stack pointer is decremented and the contents of the high order of the specified register pair are then loaded into the memory location addressed by the stack pointer. The stack pointer is again decremented and the contents of the low order of the register pair are loaded into the memory location currently addressed by the stack pointer. qq may be any one of: BC 00 DE 01 HL 10 AF II
Data Flow:
A B
Pr
SP
SS/ /
3 M cycles; 11 T states 6.5 usec @ 2 MHz
Timing:
Indirect.
DE HI AF
qq: BC
C5 I 05 IES 1 . F5
379
(no effect).
Example:
PUSH DE
Before:
D
SP 1--OA03
After:
OA03 SP
1 30131-
380
PUSH IX
antlion: Format:
byte I: DD o 0 byte 2: E5
Description:
The stack pointer is decremented, and the contents of the high order of the IX register are loaded into the memory location addressed by the stack pointer. The stack pointer is again decremented and then the contents of the low order of the IX register are loaded into the memory location addressed by the stack pointer.
Data Flow:
B C
0
H
IX
DATA
SP
Flags:
S Z
PA/ N C
I.
(no effect)
381
Example:
PUSH IX
Before: F
SP 04A2 Ix
After:
04A2
01294'
DD ES _ / OBJECT CODE
382
PUSH 11 1
Function: Format:
ELL I it L. to
ti i I
byte I: FD byte 2: E5
Description:
The stack pointer is decremented and the contents of the high order of the I Y register are loaded Into the memory location addressed by the stack pointer. The slack pointer Is again decremented and the contents of the low order of the I Y register are loaded into the memory location addressed by the stack pointer.
Data )'low:
A / B D.
Flags:
5 Z I I I
P/V N C
(no effect)
383
Example:
PUSH IY
Before:
IV SP 90BF 0066 IY SP
After:
908F 00
OBJECT CODE
384
RES b, s
Function: Format: s:
r
byte 1: CB byte 2
(HL)
0
0 b 0 0 0 d 0 b
0 0 0 0
(IX + d)
(IY + d)
0
I
byte I: FD byte 2: CB
d b 0
b may be any one of: 0 000 1 001 2 010 3 011 r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 10] 4 5 6 7 100 101 110 Ill
385
The specified bit of the location determined by s is reset. s is defined in the description of the similar BIT instructions.
Data Flow:
A C D H E
ATA
usec @ 2 MHz:
2 4 6 6
8 15 23 23
Byte Codes:
b r. A B C D E 87 BF 2 3
4
H 84 85
80 BB 90 98
81
82
83
89 BA BB BC BD 91 99 92 93 94 95
97 9F
9A 9B
9C 910
A7 AO Al A2 A3 A4 A5 AF
A8
5
6 7
A9 AA AB AC AD B2 B3 B4 135
B7 BO 1111 BF B8
89 BA BB BC BD
b: 0 I 2 3 4 5 6
RES b, (HL)
CB- 86 BE 96 9E A6 AE B6 BE
386
DDCB CB
b: 0 I 2 3 4
5 6
EDCB
I
H
86 I 8E 96 1 9E
A6 AE B6 I BE
S Z
P/V N C
(No effect)
Examples:
RES 1, H
Before:
H 42
After:
OBJECT CODE
387
RET
Function:
Format:
0 0 0
C9
Description:
The program counter is popped off the stack as described for the POP instructions. The next instruction fetched is from the location pointed to by PC.
Data Flow:
A
B
H PC
C E
Timing:
Addressing Mode:
Indirect.
Flags:
388
Example:
RET
Before:
PC 0881 PC
After:
arl
SP
3310
SP
3310 3311
389
RET cc
Function: Format:
(SP); PChigh
(SP + 1);
0
I
Description:
If the condition is met, the contents of the program counter are popped off the stack as described for the POP instructions. The next instruction is fetched from the address in PC. If the condition is not met, instruction execution continues in sequence.
Data Flow: C
E CONTROL LOGIC
WIESSISSM I MS
SP
A
cc may be any one of: NZ 000 Z 001 NC 010 C 011 PO 100 PE 101 P 110 M III
Tinung:
390
Byte Codes:
Flags:
N C
(no effect)
Example:
RET NC
Before:
00
PC 0124
After: co
PC
SP
8511
SP
8511 8512
391
RETI
Function:
Format: 0
0 0 0
0 0
byte 1: ED byte 2: 4D
Description:
The program counter is popped off the stack as described for the POP instructions. This instruction is recognized by Zilog peripheral devices as the end of a peripheral service routine so as to allow proper control of nested priority interrupts. An EI instruction must be executed prior to RETI in order to re-enable interrupts.
Data Flow:
A
B
H
C E
ea ^ 11
4 M cycles; 14 T states; 7 usec @ 2 MHz
Timing:
Flags:
S Z
P/V N C
(no effect).
392
Example:
RETI
Before:
PC SP 84E1 89B2 PC 9
After:
r
89:4 /
OBJECT CODE
393
RETN
Function:
Format:
byte I: ED byte 2: 45
Description:
The program counter is popped off the stack as described for the POP instructions. Then the contents of the IFF2 (storage flip-flop) is copied back into the IFF1 to restore the state of the interrupt flag before the non-maskable interrupt.
Data Flow:
A B
C E
394
S Z
P/V N C
Before:
PC A5F 1 PC
After:
SP
8B4C
SP
884C BB4D
8B4C 884D
OBJECT CODE
395
RL S
Function:
7 0
Format:
r
0 0 0
byte 1: CB byte 2
0
0
(HL)
0 0 0 0
byte 1: CB byte 2: 16
10
(IX + d)
byte 1: DD byte 2: CB
0
I 1 I I 1 1
'
I I
1 I
0 0
(IY + d)
byte 4: 16
r may be any one of: A Ill B 000 C 001 D 010 Description: E 011 H 100 L 101
The contents of the location of the specific operand are shifted left one bit place. The contents of the carry flag are moved to bit 0 and the contents of bit 7 are moved to the carry flag. The final result is stored back in the original location. s is defined in the description of the similar RLC instructions.
396
B
H
Timing:
s: M cycles: T states:
usec @ 2 MHz:
2 4 6 6
8 15 23 23
r: dexed.
RL
Byte Codes:
r: A B C D E Lit CBI 17 10 11 12 13 14 15
Flags:
S Z
e'V N C
RL E Before:
41 6E F
After:
r t i iia AV 4 E
OBJECT CODE
397
RLA
Function:
74-- 0 A
Format:
0 0 0 0
17
Description:
The contents of the accumulator are shifted left one bit position. The contents of the carry flag are moved into bit 0 and the original contents of bit 7 are moved into the carry flag. (9 bit rotation.)
Data Flow:
a nd r m r jf MI 1M ME IM I MI
1 M cycle: 4 T states: 2 usec @ 2 MHz
Implicit.
5 Z H P/V N C
Flags:
0
C is set by bit 7 of A.
Example:
RLA Before:
A OF 01 F A
After:
Ar/
ft
00
OBJECT CODE
398
RLCA
Function:
C-1-17.- 0 -*I
A
Format:
0 0 0 0
07
Description:
The contents of the accumulator are rotated left one bit position. The original contents of bit 7 is moved to the carry flag as well as to bit 0.
Data Flow:
F
C
0 E
Flags:
P/V N C
After:
AD6
Ai00A F
OBJECT CODE
Note: This instruction is identical to RLC A, except for the flags. It is provided for compatibility with the 8080. 399
RLC r
Function:
Format:
0 0 0
I I
byte 1: CB byte 2
0 0
-0-I
Description:
The contents of the specified register are rotated left. The original contents of bit 7 are moved to the carry flag as well as bit 0. r may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
Data Flow:
A
B 0 H
NT
r:
04
05
400
Flags:
S 2
N C
Example:
RLC B
Before:
B
62 F
After:
Cir,A
OBJECT CODE
401
RLC (HL)
Function:
n-41_17 .-- 0
(HL) 0
0 0 Format: 0 0 Description: 0 0
byte 1: CB byte 2: 06
The contents of the memory location addressed by the contents of the HL register pair are rotated left one bit position and the result is stored back at that location. The contents of bit 7 are moved to the carry flag as well as to bit 0.
Data Flow:
A 8
D H E
Indirect.
NC H SZ 0 0
C is set by bit 7 of the memory location.
402
Example:
RLC
(HL)
Before:
After:
I- D3
H
6114
F
L H
1 ' rArr,A F
6114
6114
6114
OBJECT CODE
403
RLC (IX + d)
Function:
F-1-4-17 ct
Format: 0
0 (1X+d)
0 0
d
0 0
r
byte 4: 06
Description:
The contents of the memory location addressed by the contents of the IX register plus the given offset value are rotated left and the result is stored back at that location. The contents of bit 7 are moved to the carry flag as well as to bit 0.
Data Flow:
A B 0 H
C C E L
404
Flags:
S Z
(Pry N C 0
Before:
42
After:
F
IX 0461
Ix
0461
0461 0462
OBJECT CODE
405
RLC (IY + d)
Function:
C IV + di
oF
J
byte I: FD byte 2: CB byte 3: offset value
Format:
0 0 0 0
0 0 0 0 0
byte 4: 06
Description:
The contents of the memory location addressed by the contents of the IY register plus the given offset value are rotated left and the result is stored back at the location. The contents of bit 7 are moved to the carry flag as well as bit 0.
Data Flow:
A B H
406
Tinting:
Addressing Mode:
Indexed.
Flags:
S 2
N C
Before:
C4 Iv 0021
F
After:
/50 %
Iv 0021
F
FD CB 02 06 OBJECT CODE
407
RLD
Function:
43
0 DI Li
Formai:
0
byte I: ED byte 2: 6F
Description:
The 4 low order bits of the memory location addressed by the contents of HL are moved to the high order bit positions of that same location. The 4 high order bits are moved to the 4 low order bits of the accumulator. The low order of the accumulator is moved to the 4 low order bits of the memory location originally specified. All of these operations occur simultaneously.
Data Flotv:
AV 8 0 E ALU DATA
Timing:
408
cry
N C 0
Examples:
RLD
Before:
A 61 8412
After:
64 B4F2
8412
8412
OBJECT CODE
409
RR s
0
0
0
1 ...H
(HL)
0 0
0 0 0 0
I I I I
(IX + d)
0
I I
0
I I
II d I
0 0 0 0
I I
(IY + d)
0
I
-6-1
byte 4: 1E
The contents of the location determined by the specific operand are shifted right. The contents of the carry flag are moved to bit 7 and the contents of bit 0 are moved to the carry flag. The final result is stored back in the original location. s is defined in the description of the similar RLC instructions.
410
Data Flo w:
A Lc. IF
Byte Codes:
r:ABCDE HL CB. IF 18 19 IA 1B 1C ID
Flags:
S Z
P/V N C
After:
F H
OBJECT CODE
411
L
A Cf
Format:
IF
Description:
The contents of the accumulator are shifted rightone bit position. The contents of the carry flag are moved to bit 7 and the contents of bit 0 are moved to the carry flag (9-bit rotation).
Data Flow:
AiX; ,ff B D E ALU
Timing:
Flags:
5 Z
N C
0 0 C is set by bit 0 of A
Example:
RRA Before:
A Fa
After: I
95 F A
Ar
412
RRC s
Function:
LH'
Format: s: s is any of r, (HL), (IX + d), (IY +
r 0 0 0
0l0
0
1 1
byte I: CB
I
0 0 0
(HL)
(IX + d)
0 0
I
0
I
I0
byte 1: DD byte 2: CB
I
1
1
byte 4: OE byte 1: FD
(IY + d)
0
byte 2: CB
1 1
olo
0 0
byte 4: OE
r may be any one of: A III B 000 C 001 D 010 E 011 H 100 L 101
Description:
The contents of the location determined by the specified operand are rotated right and the result is stored back in the original location. The contents of bit 0 are moved to the carry flag as well as to bit 7. s is defined in the description of the similar RLC instructions.
413
c.
wee @ 2 MHz:
r (HL) (IX + d)
(IY + ci)
2 4 6
6
8 15 23
23
4 7.5
11.5 11.5
Addressing Mode: r: implicit; (HL): indirect; (IX + d), (IY + d): in-
dexed.
Byte codes:
RRC r
Flags:
5 Z
-o 1c - To
a11N N C
RRC (HL)
Before:
81
After:
F
3FF2 F
3FF2
IL
3FF2
3FF2
OBJECT CODE
414
RRCA
Function:
L. 7 --01-1-2.-1-1
A
0 0
Format: 01 o OF
Description:
The contents of the accumulator are rotated right one bit position. The contents of bit 0 are moved to the carry flag as well as to bit 7.
la a
Flags:
P/V N C
0
C is set by bit 0 of A. RRCA Before: D4 51
Example:
After: F
AFT7H1BAy:24:
OBJECT CODE
415
RRD
Function:
AL
413 o
[HLI
Format:
0
01
byte I: ED 0 byte 2: 67
Description:
The 4 high order bits of the memory location addressed by the contents of the HL register pair are moved to the low order 4 bits of that location. The 4 low order bits are moved to the 4 low order bits of the accumulator. The low order bits of the accumulator are moved to the 4 high order bit positions of the memory location originally specified. All of the above operations occur simultaneously.
Data Flow:
8 0
Timing:
Addressing Mode:
Indirect.
416
Flags:
S Z
V N C
0 0
Example:
RRD
Before:
After:
A H
92 FEBI
Vvra
FEBI
FEBI
FEBI
OBJECT CODE
417
RST p
Function:
Restart at p.
Format:
p
Description:
The contents of the program counter are pushed onto the stack as described for the PUSH instructions. The specified value for p is then loaded into the PC and the next instruction is fetched from this new address. p may be any one of: OOH 000 08H 001 10H 010 18H 011 20H 100 28H 101 30H 110 381-1 111
This instruction performs a jump to any of eight starting addresses in low memory and requires only a single byte. ft may be used as a fast response to an interrupt.
Data Flow:
A B 0 H P 0 C
la
STACK
SP
ry/
418
Tinting:
Addressing Mode:
Indirect.
Byte Codes:
p:
00 08 10 18 20 28 30 38 C7 CF D7 DF E7 EF F7 FF
Flags:
s z
P/V N C
(no effect).
Example:
RST 38H
Before:
PC ARIA PC
After:
SP
0268
SP
419
SBC A, s
Function: Format: r n
AAsC .5: may be r, n, (HL), (IX + d), or (IY + d) 0 0 0 0 byte I: DE byte 2: immediate data (HL) 0 0 0
0 0
byte 9E 0
0
(IX +
d
III
(IY + d) 0
I
0 0 0
1111.111
may be any one of: A Ill B 000 C 001 D 010 E 011 H 100 L 101
Description:
The specified operand s, summed with the contents of the carry flag, is subtracted from the contents of the accumulator, and the result is placed in the accumulator. s is defined in the description of the similar ADD instructions.
420
B
E
Timing:
M cycles: r n (11L) (IX + d) (IY + d) Addressing Mode: 1 2 2 5 5 T states: 4 7 7 19 19
r: implicit; n: immediate; (HL): indirect; (IX + d), (IY + d): indexed. SBC A r
B C D E H 9F 98 99 9A 98' 9C 9D
Byte Codes:
Flags:
5 Z
PAY) N C
Example:
After:
gr% ZEITiM F
3600
3600
OBJECT CODE
421
SBC
HL, ss
Function: Forniat:
HL HL ss C
byte I: ED s s byte 2
Description:
The contents of the specified register pair plus the contents of the carry flag are subtracted From the contents of the HL register pair and the result is stored back in HL. ss may be any one of: BC 00 DE 01 HL 10 SP II
Data Flow: C
4
F E
A B H
sP
Tinting:
422
pAg N C
H is set if borrow from bit 12. C is set if borrow. Example: SBC HL, DE Before: 66
D
H OBJECT CODE F E L
After:
WOO
D H
0689 3142
0699
423
SCF
Function:
C I
Format:
37
Description: Timing:
Addressing Mode:
Implicit.
H
P/V N C
Flags:
S Z
0 0
424
SET b, s
Function: Format: s: r
0
I r I
(HL)
0
T
0
I
ti
(IX + d)
byte 1: DD byte 2: CB byte 3: offset value a byte 4 byte 1: FD byte 2: CB byte 3: offset value
(IY + d) 0 0
b I
byte 4
r may be any one of: A Ill B 000 C 001 D 010 b may be any one of: 0 000 OW 2 010 3 011 Description: 4 100 5 101 6 110 7 1 1I E 011 H 100 L 101
The specified bit of the location determined by s is set. s is defined in the description of the similar BIT instructions.
425
Timing:
M cycles: r (HL) 2 4 T states:
usec @ 2 MHz: 4
8
15
(IX + d) (IY + d)
Addressing Mode:
6 6
23 23
Byte Codes:
SET
b, r
h: CB0 A C7 CF 2 3 4 B CO C D CI C2 E C3 H C4 C5
CB C9 DI
CA CB CC CD D1 D3 D9 05
07 DO DF E7 EF F7 DB ED EB FO FB
09 DA DB DC DD El E9 El F9 E2 EA F2 FA E3 EB F3 FB E4 EC F4 FC E5 ED F5 ED
FF
b, (HL)
b: 0 I 2 3 4 5 6 7
b, (IX + d) b, (IY + d)
CO
CE
D6
DE
E6
EE
FO
FE
426
Flags:
(no effect)
Evainple:
SET
7, A
Before:
After:
61
OBJECT CODE
427
Function:
E
S.'
Format:
r
0 0
0 0
a
0
(HL)
0 0
0 0
(IX + d)
I I
0 0
I I
11111 00 0 0
byte 4: 26 byte 1: FD
(IY + d)
0 0
byte 4: 26
The contents of the location determined by the specific operand are arithmetically shifted left with the contents of bit 7 being moved to the carry flag and a 0 being forced into bit 0. The final result is stored back in the original location. s is defined in the description of the similar RLC instructions.
428
Data Hou:
A B H
user Ad cycles: r (HL) (IX + d) (IY + d) Addressing Byte Codes: r: dexed. SLA r (H 2 4 6 6 T slates: 8 15 23 23
la 2 MHz:
4 7.5 11.5 11.5
Flags:
S Z
N C
of
SLA (HL) Before:
10 H OFF2
After:
F L H
",/a/3 F
OFF2
OFF2
OFF2
OBJECT CODE
429
SRA s
Function:
rri
0
11.-E .
' Format: r
0
0
0
byte I: CB
I
I
I
I
(H L) 0 (IX + d)
01 I 0 0
0 0 0
I
0
I 1
0 (IY + d) 0 0
0
I
I
I
I
I
0I 0
r may be any one of: A Ill B 000 C 001 D 010 Description: E 011 H 100 L 101
The contents of the location determined by the specific operand are arithmetically shifted right. The contents of bit 0 are moved to the carry flag and the contents of bit 7 remain unchanged. The final result is stored at the original location. s is defined in the description of the similar RLC instructions.
430
Data How:
Al BI D
"sec
@ 2 MHz:
4 7.5 I1.5 11.5
Addressing Mode:
Byte Codes:
SRA r
CB
Flags:
5 Z
H GT N C
01
C is set by bit 0
of source data.
Example:
SRA A Before:
A BB 04 F A
After:
rialleSSAr F
OBJECT CODE
431
SRL S
Function:
Format:
r
0
byte I: CB byte 2
(HL) 0 (IX + d) 0
0 0
0 0 0 0
0 (IY + d)
byte 4: 3E byte I: FD
0
I I I I
0
I
1111111
Description:
The contents of the location determined by the specific operand are logically shifted right. A zero is moved into bit 7 and the contents of bit 0 are moved into the carry flag. The final result is stored back in the original location.
432
Data Flo w:
A
C
C
B D H
Tuning:
A4 cycles: r (HLi (IX + d) (IY + d) Addressing Mode: 2 4 6 6 T states: 8 15 23 23
Byte Codes:
Flags:
5 Z
Ceyv
0 After:
N C
VAarA4F
E
02 OBJECT CODE
433
SUB s
Function: Format: r
r
I I
(HL)
(IX + d) 0
96 byte 1: DD
0
111'1 I r II
(IY + d) 0 0 0
0 0
H 100 L 101
Description:
The specified operand s is subtracted from the accumulator and the result is stored in the accumulator. The operand s is defined in the description of the similar ADD instructions.
434
Addressing Mode:
Byte Codes:
SUB r
r . A B C D E HI 97 90 91 92 93 94 95
Flags:
SUB B
5 Z
PO N C
Example:
Before:
A
After:
A
B0
31
fej,4FW. ,,
31
OBJECT CODE
435
XOR s
Function: Format: r n
(HL) (IX + d)
0 0 0
0 0 0
AE byte 1: DD
111
(IY + d)
0
The accumulator and the specified operand s are exclusive 'or'ed, and the result is stored in the accumulator. s is defined in the description of the similar ADD instructions.
436
Date Flow:
B
E ALU
Timing:
M cycles: r T states:
usec @ 2 MHz:
1 2 2 5 5
4 7 7 19 19
XOR r
r:ABCDE HL AF AB A9 AA AB AC AD
Flags:
5 Z
cpyv N C
0 0
Example:
XOR 13111
After:
A
Before:
A 36
OBJECT CODE
437
5 ADDRESSING TECHNIQUES
INTRODUCTION This chapter will present the general theory of addressing and the various techniques which have been developed to facilitate the retrieval of data. In a second section, the specific addressing modes available in the Z80 will be reviewed, along with their advantages and limitations. Finally, in order to familiarize the reader with the various trade-offs possible, an applications section will demonstrate possible trade-offs between the various addressing techniques by studying specific application programs. Because the Z80 has several 16-bit registers, in addition to the program counter, which can be used to specify an address, it is important that the Z80 user understand the various addressing modes, and in particular, the use of the index registers. Complex retrieval modes may be omitted at the beginning stage. However, all the addressing modes are useful in developing programs far this microprocessor. Let us now study the various alternatives available. POSSIBLE ADDRESSING MODES Addressing refers to the specification, within an instruction, of the location of the operand on which the instruction will operate. The main addressing methods will now be examined. They are all illustrated in Figure 5.1. Implicit Addressing (or "Implied," or "Register") Instructions which operate exclusively on registers normally use 1111pilot addressing. This is illustrated in Figure 5.1. An implicit instruc-
438
ADDRESSING TECHNIQUES tion derives its name from the fact that it does not specifically contain the address of the operand on which it operates. Instead, its opcode specifies one or more registers, usually the accumulator, or else any other register(s). Since internal registers are usually few in number (commcrily eight), this will require a small number of bits. As an example, three bits within the instruction will point to one out of eight internal registers. Such instructions can, therefore, normally be encoded within eight bits. This is an important advantage, since an eight-bit Instruction normally executes faster than any two- or three-byte instruction. An example of an implicit instruction is: LD A, B which specifies "transfer the contents of B into A" (Load A from B.) Immediate Addressing Immediate addressing is illustrated in Figure 5.1. The eight-bit opcode is followed by an 8- or 16-bit literal (a constant). This type of instruction is needed, for example, to load an eight-bit value in an eight-bit register. Since the microprocessor is equipped with 16-bit registers, it may also be necessary to load 16-bit literals. An example of an immediate instruction is:
ADD A, OH The second word of this instruction contains the literal "0", which is added to the accumulator. Absolute Addressing Absolute addressing usually refers to the way in which data is retrieved from or placed in memory, in which an opcode is followed by a 16-bit address. Absolute addressing, therefore, requires three-byte instructions. An example of absolute addressing is: LD (I234H), A It specifies that the contents of the accumulator are to be stored at memory location "1234" hexadecimal. The disadvantage of absolute addressing is to require a three-byte instruction. In order to improve the efficiency of the microprocessor, another addressing mode may be made available, whereby only one word is used for the address: direct addressing. 439
7 IMPLICIT/IMPLIED OPCODE A
0 I R
IMMEDIATE
EXTENDED/ABSOLUTE
DIRECT/SHORT
DISPLACEMENT OR ADDRESS J
440
ADDRESSING TECHNIQUES Direct Addressing (or "Short," or "Relative") In this addressing mode, the opcode is followed by an eight-bit address. This is also illustrated in Figure 5.1. The advantage of this approach is to require only two bytes instead of three for absolute addressing. The disadvantage is to limit all addressing within this mode to addresses 0 to 255 or else 128 to + 127. When using 0 to 255 ("page zero"), this is also called short addressing, or 0-page addressing. Whenever short addressing is available, absolute addressing is often called extended addressing by contrast. The range 128 to + 127 is used with branch instructions. This is called relative addressing. Relative Addressing Normal jump or branch instructions require eight bits for the opcode, plus the I6-bit address to which the program has to jump. Just as in the preceding example, this mode has the disadvantage of requiring three words, i.e., three memory cycles. To provide more efficient branching, relative addressing uses only a two-word format. The first word is the branch specification, usually along with the test it is implementing. The second word is a displacement. Since the displacement must be positive or negative, a relative branching instruction allows a branch forward to 127 locations (seven-bits) or a branch backwards to 128 locations (usually + 129 or 126, since PC will have been increcremented by 2). Because most loops tend to be short, relative branching can be used most of the time and results in significantly improved performance for such short routines. As an example, we have already used the instruction JR NC, which specifies a "jump if no carry" to a location within 127 words of the branch instruction (more precisely + 129 to 126). The two advantages of relative addressing are improved performance (fewer bytes used) and program relocatability (independence from absolute addresses).
Indexed Addressing Indexed addressing is a technique used to access the elements of a block or of a table successively. This will be illustrated by examples later in this chapter. The principle of indexed addressing is that the instruction specifies both an index register and an address. The contents of the register are added to the address to provide the final address. In this way, the address could be the beginning of a table in the memory.
441
PROGRAMMING THE Z80 The index register would then be used to access all the elements of a table successively in an efficient way. (This requires the availability of increment/decrement instructions for the index register). In practice, restrictions often exist which may limit the size of the index register, or the size of the address or displacement field.
OPCODE DISPLACEMENT
I final address
MEMORY
Pre-Indexing and Post-Indexing Two modes of indexing may be distinguished. Pre-indexing is the usual indexing mode in which the final address is the sum of a displacement or address and of the contents of the index register. It is shown in Figure 5.2, assuming an 8-bit displacement field and a 16-bit index register. Post-indexing treats the contents of the displacement field like the address of the actual displacement, rather than the displacement itself. This is illustrated in Figure 5.3. In post-indexing, the final address is the sum of the contents of the index register plus the contents of the memory word designated by the displacement field. This feature utilizes, in fact, a combination of indirect addressing and pre-indexing. But we have not defined indirect addressing yet. Let us do that.
442
ADDRESSING TECHNIQUES
Fry
Y(i ndex)
ADDRESS POiNtER
MOR'
POINTER=
DATA N
443
PROGRAMMING THE Z80 uses an opcode followed by a 16-bit address. This address is used to retrieve a word from the memory. Usually, it will be a 16-bit word (in our case, two bytes) within the memory since it is an address. This is illustrated by Figure 5.4. The two bytes at the specified address Al contain "A2". A2 is then interpreted as the actual address of the data that one wishes to access.
MEMORY
DATA
Fig. 5.4: Indirect Addressing Indirect addressing is particularly useful any time that pointers are used. Various areas of the program can then refer to these pointers to access a word or a block of data conveniently and elegantly. The final address may also be obtained by pointing within the instruction to a 16-bit register in which it is contained. This is called "register indirect." Combinations of Modes The above addressing modes may be combined. In particular, it should be possible in a completely general addressing scheme to use many levels of indirection. The address A2 could be interpreted as an indirect address again, and so on. Indexed addressing can also be combined with indirect access. This allows the efficient access to word n of a block of data, provided one knows where the pointer to the starting address is (see figure 5.2).
444
ADDRESSING TECHNIQUES We have now become familiar with all usual addressing modes that can be provided in a system. Most microprocessor systems, because of the limitation on the complexity of an MPU, which must be realized within a single chip, do not provide all possible modes but only a small subset of these. The Z80 provides a good subset of possibilities. Let us examine them now.
operate exclusively on internal registers, they require only one machine cycle to execute.
Examples of instructions using implied (or "register") addressing are: LD r,r'; ADD Air; ADC A,s; SUB s; SBC A,s; AND s; OR s; XOR s; CPs; INC r. Zilog further distinguishes between "register addressing" and "implied addressing." Implied addressing is then limited, in that definition, to instructions that do not have a specific field to point to an internal register. This introduces one more addressing mode. This is one reason why the number of addressing modes is insufficient to characterize the capabilities of a microprocessor.
445
where nn represents the I6-bit memory address, and (nn) represents the contents of the specified location.
is called "modified zero-page addresing." The RST instruction contains a 3-bit field in bit position b, b, b, used to pint to one of 8 locations in page 0 memory. The effective address is b5 b4b3000 and is loaded into PC. Since it requires only a single byte, this instruction executes rapidly, and is easily generated in hardware. It was generally used to respond to multiple interrupts (up to 8.) Its disadvantage is either to limit the execution sequence to 8 locations, or to require a jump eliminating the speed advantage. This is because each of the 8 branch addresses are 8-bytes apart.
446
ADDRESSING TECHNIQUES struction requires only seven "T cycles." This is because the next instruction to oe executed is already pointed to by the program counter. However, when the test succeeds, i.e., whenever the jump takes place, this instruction requires 12 "T-states"; a new effective address must be computed and loaded into the program counter. When computing the duration of the execution of a program segment, caution must be exercised. Whenever one is not sure whether or not the jump will succeed, one must take into consideration the fact that sometimes the jump will require 11 T-states. (condition met), sometimes 7 (condition not mei). When designing a loop, execution will, therefore, be faster using a JR(Jump Relative) testing a condition usually not met, such as a nonzero condition for the counter. When JR's are used outside of loops, and the condition under test is unknown, an average timing value is often used for the duration ofJR. This timing problem does not apply to the unconditional jump JR e. It does not test any condition, and always lasts 12 T-states. Indexed Addressing (Z80) This addressing mode did not exist in the 8080, and was added to the Z80 (as well as the two index registers). As a result, it became necessary to add an extra byte to the opcode, making it a 16-bit opcode in the Z80 instruction set (LDIR is another example of a I6-bit opcode). The structure of an indexed instruction is shown on Figure 5.5.
OPCODE
BYTE I
OPCODE
BYTE 2
DISPLACEMENT
BYTE 3
LITERAL J
BYTE 4
447
PROGRAMMING THE Z80 Instructions allowing indexed addressing are: LD, ADD, INC, RLC, BIT, SET, CP, and others. This mode will be used extensively in the programs operating on blocks of data, tables or lists. Indirect Addressing (280) The Z80 provides a limited indirect addressing capability called "Register Indirect Addressing." In this mode, each of the 16-bit register pairs BC, DE, HL may be used as a memory address. Whenever they point to 16-bit data, they point to the lower part. The higher part resides at the next (higher) sequential address.
Combinations of Modes
Combinations of modes are essentially non-existent, except that instructions referring to two operands may use a different type of addressing for each. Thus, a load or an arithmetic instruction may access one operand in the immediate mode, and the other one through an indexed access. Also, the bit addressing mechanism may access the eight-bit byte
through one of the three addressing modes, as explained in the following paragraph. The specific addressing modes available for each instruction are indicated in the tables of the preceding chapter.
Bit Addressing
Bit addressing is generally not considered an addressing mode if addressing is defined as accessing a byte. However, whether defined as a mode or a group of instructions, it is a valuable facility. Since it is defined as an "addressing mode" in Zilog nomenclature, it will be so described here. It is specific to the Z80 and was not provided on the 8080. Bit addressing refers to the access mechanism to specified bits. The Z80 is equipped with special instructions for setting, resetting and testing specified bits in a memory location or a register. The specified byte may be accessed through one of three addressing modes: register, register-indirect, and indexed. Three bits are used within the opcode to select one of eight bits.
448
ADDRESSING TECHNIQUES
(NEXT INSTRUCTION) The two-line program above will result in branching to location FAR whenever the carry is set. In the case of the Z80, JP may be used instead of JR to test all conditions and removes this problem. Use of Indexing for Sequential Block Accesses Indexing is primarily used to address successive locations within a table. The restriction is that the maximum length must be less than 256 so that the displacement can reside in an eight-bit index register. We have learned to check for a character. Now we will search a table of 100 elements for the presence of a ''. The starting address for this table is called BASE. The table has only 100 elements. The program appears below: (see flowchart on Figure 5.6): SEARCH LD IX, BASE LD A, '' LD B, COUNT TEST CP (IX) JR Z, FOUND INC IX DEC B JR NZ, TEST NOTFND An improved program will be presented below in the section on Block Transfer, using DJ NZ.
449
YES
STAR FOUND
NOT FOUND
Fig. 5.6: Character Search Flowchart A Block Transfer Routine for Fewer Than 256 Elements We will call "COUNT" the number of elements in the block to be moved. The number is assumed to be less than 256. FROM is the base address of the block. TO is the base of the memory area where it should be moved. The algorithm is quite simple: we will move a ward at a time, keeping track of which word we are moving by storing its position in the counter C. The program appears below: BLKMOV LD IX, FROM IY, TO LD LD BC. COUNT LD A, (IX) NEXT (IY), A LD INC IX INC IY DEC C JR NZ, NEXT Let us examine it: BLKMOV LD IX, FROM LD IY,TO LD C, COUNT These three instructionsinitialize'registers IX, 1Y, and C respectively, as 450
GET WORD
ADDRESSING TECHNIQUES
II MEMORY
COUNT
IX
SOURCE
FROM
IY I
DESTINATION
illustrated in Figure 5.7. Index register IX is used as the source pointer, and will be incremented regularly. Index register IY is used as the destination pointer, and would be incremented regularly. Register C is loaded with the maximum number of elements to be transferred (limited to 256 since this is an eight-bit register) and will be decremented regularly. Whenever C decrements to zero, all elements have been transferred. The next two instructions: NEXT LD A, (IX) LD (IY), A
load the contents of the memory location pointed to by IX into the accumulator, then transfer it into the memory location pointed to by register IY. In other words, these two instructions transfer an element of the source block into the destination block. The two index registers are then incremented:
INC INC
IX IY
And the counter register is decremented: DEC C Finally, as long as the counter is not 0, the program loops back to the label NEXT: JR NZ, NEXT
451
PROGRAMMING THE Z80 This is an example of the possible utilization of index registers. However, let us compare it to the same program written for another microprocessor, the MOS Technology 6502, which is also equipped with an indexing capability, but uses different conventions (i.e., has different limitations on a general-purpose indexing facility).The program appears below: LD X #NUMBER FROM, X LD A TO, X STA DEX BNE NEXT
NEXT
Without going into the details of the above program, the reader will immediately notice how much shorter it is than the previous one. This is because the index register X is used as a variable displacement, whereas FROM and TO are used as the fixed source and destination addresses. This example should point out that although in theory indexing is a powerful facility, it does not necessarily lead to efficient coding, due to the addressing limitations imposed on it in the case of various microprocessors. Truly general-purpose indexing requires the possibility of a I6-bit displacement or address field as well as a 16-bit index register. However, it should be noted that this specific problem is solved, in the Z80 by the presence of specialized instructions. A general-purpose block transfer will now be described which can be implemented in just four instructions. However, to be fair to the Z80, let us suggest additional exercises for the reader: Exercise 5.1: Write the block transfer program for the Z80 in the style of the above program for the 6502, i.e., assuming that the index register contains a displacement. Assume that the source and the destination block are located in page 0, i.e., at addresses 0 to 256. Naturally, it will be assumed that the number of elements within each block is small enough that they do not overlap. Exercise 5.2: Assume now that the source and the destination blocks are located anywhere in the memory, except that they are both within the same page. Rewrite the above program in that case. (Is there a difference, i.e., does page zero play any role for the Z80?)
452
ADDRESSING TECHNIQUES
The program is shown below: LD BC, COUNT LD DE, TO LD HL, FROM LDIR NUMBER OF BYTES DESTINATION ADDRESS START ADDRESS TRANSFER ALL BYTES
Memory used: 11 bytes Timing: 21 cycles/byte transferred The first instruction is: LD BC, COUNT
It loads the number of elements to be transferred (a 16-bit value) into the register pair BC. The next two instructions initialize the register pair DE and the register pair HL respectively: LD LD DE, TO HL, FROM
Finally the fourth instruction: LDIR performs the complete transfer. LDIR is an autonzated block-transfer instruction. Its power should be obvious from this example. LDIR results in the following sequence: The contents of the memory location pointed to by H and L are transferred into the memory location pointed to by DE: (DE) =(HL). Next, DE is incremented: DE = DE + 1. Then, HL is incremented: HL = HL + 1. Next, BC is decremented: BC = BC 1. If BC becomes 0, the instruction is terminated. Otherwise, the instruction is repeated.
B
COUNTER
DESTINATION SOURCE REGISTERS COUNT
D
H
Ellisd
FROM
Lye
TO
A
MEMORY
The value and power of the LDIR instruction should be apparent at this point without further comments. Similarly, our search for the character "star"can be improved by the use of an automated instruction, CPIR, special to the Z80. The corresponding program appears below: LD A. "" LD BC, COUNT LD HL, STRING CPIR JR Z, STAR
STAR NOSTAR
The first instruction loads the accumulator with the code for the character star. Next, the register pair BC is initialized to the count of the number of words to be searched within the block: LD BC, COUNT The register pair H and L is set to the starting address of the block to be searched (STRING). The automated instruction is then executed: LD HL, STRING CPIR The CPIR instruction is an automated compare instruction. The contents of the memory location specified by the address contained in H and L is compared to the contents of the accumulator. If the comparison succeeds, then Z of the flags register will be set to I. Then, the register pair H and L is Incremented and the register pair BC is decremented. The instruction is repeated until either the pair BC goes to 0 or else the comparison succeeds. After the instruction CPIR is executed, it is therefore necessary to test the Z flag to determine whether the comparison has succeeded (the CPIR might have looped through 64K words without success in the extreme case). This is the purpose of the last instruction of the program: JR Z, STAR Exercise 5.3: Rewrite the above program so that a search proceeds
backwards. (Hint Use the CPDR instruction) Continue the block transfer until "1 is found.
Let us now develop a program combining the features of the two previous ones. We will implement the block transfer from location FROM
454
ADDRESSING TECHNIQUES to location TO, which shall stop automatically whenever an escape character, "star", is found. The program appears below: LD BC, COUNT LD HL, FROM LD DE, TO LD A,''
TEST CP (HL)
JR LDI Z, END
JP
PE, TEST
this instruction is that the P/V flag is cleared if BC decrements to "0" and set otherwise. This will be explicitly tested by the last instruction in the program to determine whether exit should occur: JP PE, TEST
Adding Two Blocks
A program will be developed here to add element! by element two blocks starting respectively at addresies BLK1, and BLK2, and having equal numbers of elements, COUNT. The program is shown below: BLKADD LD IX, BLK1 LD IY, BLK2 LD B, COUNT XOR A LOOP LD A, (IX + 0) ADC A, (IY + 0) LD (IX), A DEC IX DEC 1Y DEC B JR NZ, LOOP
COUNTER
IX IY
1 // / / BLK 2
MEMORY
456
ADDRESSING TECHNIQUES The memory layout is shown in Figure 5.9. The program is straightforward. The number of elements to be added is loaded into the counter register B, and the two index registers IX and IY are initialized to their values BLKI and BLK2: BLK ADD LD IX, BLKI LD IY, BLK2 LD B, COUNT The carry bit is then cleared in anticipation of the first addition: XOR A The first element is loaded into the accumulator: LOOP LD A, (IX + 0)
The corresponding element of BLK2 is then added to it: ADC A, (IY +0) and finally saved into the element of BLKI: LD (IX), A The two pointer registers X and Y are decremented: DEC IX DEC IY as well as the counter register: DEC B As long as the counter register is not 0, the addition loop is executed: JR NZ, LOOP Exercise 5.4: Can you use the above program to perform a 32-bit addition? Exercise 5.5: Can you use the above program to perform a 64-bit addition? Exercise 5.6: Modify the above program so that the result is stored in a separate block start mg at address BLK3. Exercise 5.7: Modify the above program to perform a subtraction rather than an addition.
457
PROGRAMMING THE Z80 Exercise 5.8: Modify the original program above so that BLit'/ and BLK2 are at the top of each block rather than the bottom (see Fig.5.10).
A ELEMENT COUNTER
TO
--E.ry
IINATION BLOCK
SUMMARY A complete description of addressing modes has been presented. It. has been shown that the Z80 offers many possible mechanisms, and the specific addressing modes available on the Z80 have been analyzed. Finally, several application programs have been presented to demonstrate the value of the various addressing mechanisms. Programming the Z80 efficiently requires an understanding of these mechanisms. They will be used throughout the programs in the remainder of this book. EXERCISES 5.9: Write a program to add the first 10 bytes of a table stored at location "BASE". The result will have 16 bits. (Pus is a checksum computation). 5.10: Can you solve the same problem without using the Indexing mode?
458
ADDRESSING TECHNIQUES
5.11: Reverse the order of the 10 bytes of this table. Store the result at address "REVER". 5.12: Search the same table for us largest element. Store it at memory address "LARGE". 5.13: Add together the corresponding elements of three tables, whose bases are BASE!, BASE2, BASES. The length of these tables is stored at address "LENGTH"
459
6 INPUT/OUTPUT TECHNIQUES
INTRODUCTION
We have learned so far how to exchange information between the memory and the various registers of the processor. We have learned to manage the registers and to use a variety of instructions to manipulate the data. We must now learn to communicate with the external world. This is called input/output. Input refers to the capture of data from outside peripherals (keyboard, disk, or physical sensor). Output refers to the transfer of data from the microprocessor or the memory to external devices such as a printer, a CRT. a disk, or actual sensors and relays. We will proceed in two steps. First, we will learn to perform the input / output operations required by common devices. Secondly, we will learn to manage several input/output devices simultaneously, i.e., to schedule them. This second part will cover, in particular, polling vs. interrupts. INPUT/OUTPUT In this section we will learn to sense or to generate simple signals, such as pulses. Then we will study techniques for enforcing or measuring correct timing. We will then be ready for more complex types of input/output, such as high-speed serial and parallel transfers. The Z80 Input/Output Instructions The Z80 is equipped with a special set of input and output instructions. Most eight-bit microprocessors are not equipped with a special set of input and output instructions, and use the general instruction set
460
INPUT/OUTPUT TECHNIQUES on input/output devices. The Z80, like the 8080, is equipped with basic input and output instructions. However, the Z80 is also equipped with additional I/O instructions. These will be described in more detail here in order to facilitate understanding of the programs that will be presented throughout this section. The basic input and output instructions are respectively: IN A, (n) and OUT (n),A. These two instructions are inherited from the 8080. They will respectively read or write one byte between the selected port and the accumulator. The actual addressing process is such that the 1,0 device address "n" is gated on lines AO through A7 of the address bus, while the contents of the accumulator appear on address lines A8 through A15. When only 256 devices are addressed, it may be necessary to zero the contents of the accumulator explicitly if any of the address lines A8 through A15 may be decoded by an I/O device. In the simple examples that follow, we will assume that fewer than 256 devices are present and that they are not connected to addresses A8 through A15, so that it will not be necessary to zero the contents of the accumulator explicitly, for example prior to using the IN instruction. A special input instruction: IN r, (C), allows using the contents of register C as the I/O device address. When using this instruction, the contents of register B automatically provide the top part of the address (A8 through A15). The specified register r is loaded from the specified address. "r" may be any of the usual seven general-purpose registers.
Generate a Signal
In the simplest case, an output device will be turned off (or on) from the computer. In order to change the state of the output device, the programmer will merely change a level from a logical "0" to a logical "I", or from "1" to "0". Let us assume that an external relay is connected to bit "0" of a register called "OUTI". In order to turn it on, we will simply write a "1" into the appropriate bit position of the register. We assume here that OUT1 represents the address of this output register within our system. A program which will turn the relay on is: TURNON LD A, 0000000IB OUT (OUTI), A LOAD PATTERN INTO A OUTPUT IT TO DEVICE
where OUT is the output instruction. We have assumed that the state of the other seven bits of the register OUTI is irrelevant. However, this is often not the case. These bits might be connected to other relays. Let us, therefore, improve this simple program. We want to turn the relay on, without changing the state
461
PROGRAMMING THE Z80 of any other bit within this register. We will assume that it is possible to read and write the contents of this register. Our improved program now becomes: TURNON IN A, (OUTI) 0000000 I B OR OUT (OUT!), A READ CONTENTS OF OUT I FORCE BIT "0" TO "I" IN A
The program first reads the contents of location OUT!, then performs an inclusive OR on its contents. This only changes bit position 0 to "1", and leaves the rest of the register intact. (For more details on the OR operation, refer to Chapter 44 This is illustrated by Figure 6.1.
BEM AFTER
DATA BU
RELAY ON
Fig. 6.1: Turning on a Relay Pulses Generating a pulse is accomplished exactly as in the case of the level above. An output bit is first turned on, then later turned off. This results in a pulse. This is illustrated in Figure 6.2. This time, however, an additional problem must be solved: one must generate the pulse for the correct length of time. Let us, therefore, study the generation of a computed delay.
ON OUTPUT PORT REGISTER SIGNAL
0 0
0
0 0 N uSEC --FLA
Oi l INEPROGRAhs SOT I OUTPUT POW tOALICNONT PORT LONER NAN ?ASTERN WAIT BOOR OR N SECT LOAD OUTPUT F011 MTH ZERO ?[TURN
462
INPUT/OUTPUT TECHNIQUES Delay Generation and Measurement A delay may be generated by software or by hardware methods. We will here study the way to perform it by program, and later show how it can also be accomplished with a hardware counter, called a programmable interval timer (PIT). Programmed delays are achieved by counting. A counter register is loaded with a value, then is decremented. The program loops on itself and keeps decrementing until the counter reaches the value "0" The total length of time used by this process will implement the required delay. As an example, let us generate a delay of 82 clock cycles: DELAY LD A, 5 NEXT DEC A JR NZ, NEXT A IS COUNTER DECREMENT NEXT TEST
This program loads A with the value 5. The next instruction decrements A and the following instruction will cause a branch to NEXT to occur as long as A does not decrement to "0". When A finally decrements to zero, the program will exit from this loop and execute whatever instruction follows. The logic of the program is simple and appears in the flowchart of Figure 6.3. Let us now compute the effective delay which will be implemented by the program. In Chapter 4 of the book, we will look up the number of cycles required by each of these instructions: LD in the immediate mode requires seven clock cycles. DEC will use four cycles. Finally, JR will use 12 cycles except during the last iteration, where it will use 7 cycles. When looking up the number of cycles for JR in the table, verify that two possibilities exist: if the branch does not occur, JR will only require seven cycles. If the branch does succeed, which will usually be the case during the loop, then 12 cycles are required. The timing is, therefore, seven cycles for the first instruction, plus 11 cycles for the next two, multiplied by the number of times the loop will be executed, minus an extra five-cycle delay for the last unsuccessful JR: Delay = 7 + 16 x 5 5 = 82 cycles. Assuming a .5 microsecond cycle, this programming delay will be 41 microseconds.
463
COUNTER = VALUE
DECREMENT COUNTER
NO
0? YES OUT
The delay loop which has been described is used by most input/output programs. It should be well understood. Try to do the following exercises: Exercise 6.1: What are the maximum and the minimum delays which can be Implemented milt these three mstruct tons? Exercise 6.2: Modify the program to obtain a delay of about 100 Microseconds.
If one wishes to implement a longer delay, a simple solution is to add extra instructions in the program, before DEC. The simplest way to do so is to add NOP instruction. (The NOP does nothing for four cycles.)
Longer Delays Generating longer delays by software can be achieved through using a wider counter. A register pair can be used to hold a 16-bit count. To
464
INPUT/OUTPUT TECHNIQUES simplify, let us assume that the lower count is "0". The lower byte will be loaded with "0", the maximum count, then go through a decrementation loop. Since the first decrementation results in 00-s-FE and does not affect the Z flag whenever it is decremented to "0", the upper byte of the counter will be decremented by 1. Whenever the upper byte is decremented to the value "0", the program terminates. If more precision is required in the delay generation, the lower count can have a non-null value. In this case, we would write the program just as explained and add at the end the three-line delay generation program, which has been described above. A 24-bit delay program appears below: DEL24 LD B, COUNTH COUNTER HIGH (8 BITS) DEL I6 LD DE, I LOOPA LD HL, COUNTL COUNTER LOW LOOPS ADD HL, DE DECREMENT IT JR C, LOOPS GO ON UNTIL NULL DJNZ LOOPA DECREMENT B AND JUMP Note that DE is loaded with " I", and used to decrement the 16-bit counter HL. Naturally, still longer delays could be generated by using more than three words. This is analogous to the way an odometer works on a car. When the right-most wheel goes from "9" to "0", the next wheel to the left is incremented by 1. This is the general principle when counting with multiple discrete units. However, the main disadvantage of this method is that when one is counting delays, the microprocessor will be doing nothing else for hundreds of milliseconds or even seconds. If the computer has nothing else to do, this is perfectly acceptable. However, in general the microcomputer should be available for other tasks, so that longer delays are normally not implemented by software. In fact, even short delays may be objectionable in a system if it is to provide some guaranteed response time in given situations. Hardware delays must then be used. In addition, if interrupts are used, timing accuracy may be lost if the counting loop can be interrupted.
Exercise 6.3: Write a program to implement a 100 ins delay (typical of a Teletype).
Hardware Delays Hardware delays are implemented by using a programmable interval timer or "timer" in short. A register of the timer is loaded with a value. 465
PROGRAMMING THE Z80 The difference is that the timer will automatically decrement the counter periodically. The period can usually be adjusted or selected by the programmer. Whenever the timer has decremented to "0", it will normally send an interrupt io the microprocessor. It may also set a status bit which can be sensed periodically by the computer. The use of interrupts will be explained later in this chapter. Other timer operating modes may include starting From "0" and counting the duration of the signal, or, counting the number of pulses received. When functioning as an interval timer, the tinier is said to operate in a one-shot mode. When counting pulses, it is said to operate in a pulse counting mode. Some timer devices may even include multiple registers and a number of optional facilities which the programmer can select. Sensing Pulses The problem with sensing pulses is the reverse of that of generating pulses, and includes one more difficulty: whereas an output pulse is generated under program control, input pulses occur asynchronously with the program. In order to detect a pulse, two methods may be used: polling and interrupts. Interrupts will be discussed later in this chapter. Let us now consider the polling technique. Using this technique, the program reads the value of a given input register continuously, testing a bit position, perhaps bit 0. It will be assumed that bit 0 is originally "0". Whenever a pulse is received, this bit will take the value "1" The program continuously monitors bit 0 until it takes the value "I". When a "I" is found, the pulse has been detected. The program appears below: POLL IN A, (INPUT) BIT 0, A JR Z, POLL
ON
Conversely, let us assume that the input line is normally "I" and that we wish to detect a "0". This is the usual case for detecting a START bit, when monitoring a line connected to a Teletype. The program appears below: POLL IN A, (INPUT)
0, A NZ, POLL
466
INPUT/OUTPUT TECHNIQUES Monitoring the Duration Monitoring the duration of the pulse may be accomplished in the same way as computing the duration of an output pulse. Either a hardware or a software technique may be used. When monitoring a pulse by software, a counter is regularly incremented by 1, then the presence of the pulse is verified. If the pulse is still present, the program loops upon itself. Whenever the pulse disappears, the count contained in the counter register is used to compute the effective duration of the pulse. The program appears below: DURTN AGAIN LD IN BIT JR INC IN BIT JR B, 0 CLEAR COUNTER A, (INPUT) READ INPUT 0, A MONITOR BIT 0 Z, AGAIN WAIT FOR A "I" B INCREMENT COUNTER A, (INPUT) CHECK BIT 0 0, A NZ, LONGER WAIT FOR A "0"
LONGER
Naturally, we assume that the maximum duration of the pulse will not cause register B to overflow. If this were the case, the program would have to be changed to take that into account (or else it would be a programming error!). Since we now know how to sense and generate pulses, let us capture or transfer larger amounts of data. Two cases will be distinguished: serial data and parallel data. Then we will apply this knowledge to actual input/output devices. PARALLEL WORD TRANSFER It is assumed here that eight bits of transfer data are available in parallel at address "INPUT" (see Fig. 6.4). The microprocessor must read the data word at this location whenever a status word indicates that it is valid. The status information will be assumed to be contained in bit 7 of address "STATUS". We will here write a program which will read and automatically save each word of data as it comes in. To simplify, we will assume that the number of words to be read is known in advance and is contained in location "COUNT". If this information were not available, we would test for a so-called break character, such as a rubout, or perhaps the character "". We have learned to do this already.
467
COUNT
wy. /
. ..,,,,.z.-../.
.4., ,
:(5
VAUD STATUS
INPUT
2 ;5 v,;( 7
m.47/447,0;;.,..)./zex
0,7 f ,(4 7.
Fig. 6.4: Parallel Word Transfer-The Memory The flowchart appears in Figure 6.5. It is quite straightforward. We test the status information until it becomes "I", indicating that a word is ready. When the word is ready, we read it and save it at, an appropriate memory location. We then decrement the counter and test whether it has decremented to "0". If so, we are finished; if not, we read the next word. A simple program which implements this algorithm appears below: PARAL LD LD WATCH IN BIT JR IN PUSH A, (COUNT) READ COUNT INTO A B IS COUNTER B, A A, (STATUS) LOOK FOR 'DATA READY' 7, A Z, WATCH
A, (INPUT) AF
TRUE BIT 7 IS "1" IF DATA READY DATA VALID? READ DATA SAVE DATA INTO STACK
468
It is assumed that the "data ready" flag is automatically cleared when STATUS is read. The first two instructions initialize the counter register B: PARAL LD A, (COUNT) LD B, A
Note that there is no easy way to load B only from memory. One must either load A, then transfer its contents to B, or load B and C simultaneously.
READ COUNT
NO
TRANSFER WORD
DECREMENT COUNTER
NO
OUT
469
PROGRAMMING THE Z80 The next three instructions of the program read the status information and cause a loop to occur as long as bit seven of the status register is "0". (It is the sign bit, i.e., bit N.) IN A, (STATUS)
BIT JR
7, A
Z, WATCH
The word has now been read from address INPUT where it was, and must be saved. Assuming that a sufficient stack area is available, we can use: PUSH AF which saves A (and F) in the stack. If the stack is full, or the number of words to be transferred is large, we could not push them on the stack and we would have to transfer them to a designated memory area, using, for example, an indexed instruction. However, this would require an extra instruction to increment or decrement the index register. PUSH is faster (only 11 clock cycles). The word of data has now been read and saved. We will simply decrement the word counter and test whether we are finished:
DEC JR NZ,WATCH
This nine-instruction program can be called a benchmark. A benchmark program is a carefully optimized program designed to test the capabilities of a given processor in a specific situation. Parallel transfers are one such typical situation. This program has been designed for maximum speed and efficiency. Let us now compute the maximum transfer speed of this program. We will assume that COUNT is contained in memory. The duration of every instruction is determined by inspecting the tables in Chapter Four and is found to be the following:
PARAL LD A, (COUNT) 13 B, A 4 A, (STATUS) 11 7, A 8 Z, WATCH 7/12
LD WATCH IN BIT JR
470
4 7/12
The minimum execution time is obtained by assuming that data is available every time that we sample STATUS. In other words, the first JP will be assumed to fail every time. Timing is then: 13 + 4 + (11 +8+7+ 11 +4+ 12) COUNT Neglecting the first 17 cycles necessary to initialize the counter register, the time used to transfer one word is 64 clock cycles or 32 microseconds with a 2 MHz clock. The maximum data transfer rate is, therefore: = 31 K bytes per second 32 (1O') Exercise 6.4: Assume thus the number of words to be transferred is greater than 256. Modify the program accordingly and determine the impact un the maximum data transfer rate. Exercise 6.5: Modify this program in order to trim improve its speed: Iusing JR instead of JP 2using DJNZ 3using INI or IND fibs the above program truly optimal? We have now learned to perform high-speed parallel transfers. Let us consider a more complex case. BIT SERIAL TRANSFER A serial input is one in which the bits of information (0's or l's) come in successively on a line. These bits may come in at regular intervals. This is normally called synchronous transmission. Or, they may come as bursts of data at random intervals. This is called asynchronous transmission. We will develop a program which can work in both cases. The principle of the capture of sequential data is simple: we will watch an input line, which will be assumed to be line 0. When a bit of data is detected on this line, we will read the bit in, and shift it into a holding register. Whenever eight bits have been assembled, we will preserve the byte of data into the memory and assemble the next one. In order to simplify, we will assume that the number of bytes to be received is 471
PROGRAMMING THE Z80 known in advance. Otherwise, we might, for example, have to watch for a special break character, and stop the bit-serial transfer at this point. We have learned to do that. The flowchart for this program appears in Figure 6.6. The program appears below: CLEAR INPUT WORD SERIAL LD C, 0 A, (COUNT) LOAD B WITH BYTE COUNT LD B, A LD A, (INPUT) READ PORT LOOP IN BIT 7 IS STATUS, BIT 0 IS DATA 7, A BIT WAIT FOR A "I" Z, LOOP JR SHIFT DATA BIT INTO CARRY A SRL SAVE INPUT B INTO C RL C NC, LOOP CONTINUE UNTIL 8 BITS IN JR
POLLING OR SERVICE REQUEST
NO
NO
DONE
INPUT/OUTPUT TECHNIQUES PUSH BC SAVE WORD IN STACK LD C, 01H RESET MARKER BIT DEC B DECREMENT BYTE COUNTER JR NZ, LOOP ASSEMBLE NEXT WORD This program has been designed for efficiency and will use new techniques which we will explain (see Fig. 6.71. The conventions are the following: memory location COUNT is assumed to contain a count of the number of words to be transferred. Register C will be used to assemble eight consecutive bits coming in. Address INPUT refers to an input register. It is assumed that bit position 7 of this register is a status flag, or a clock bit. When ins "0", data is not valid. When it is "I", the data is valid. The data itself will be assumed to appear in bit position 0 of this same address. in many instances, the status information will appear on a different register than the data register. It should be a simple task, then, to modify this program accordingly. in addition, we will assume that the first bit of data to be received by this program is guaranteed to be a "I". It indicates that the real data follows. If this were not the case, we will later see an obvious modification to take care of it. The program corresponds exactly to the flowchart of Fig. 6.6. The first few lines of the program implement a waiting loop which tests whether a bit is ready. To determine whether a bit is ready, we read the input register, then test the zero bit (Z). As long as this bit is "0", the instruction JR will succeed, and we will branch back to the loop. Whenever the status (or clock) bit becomes true ("I"), then JR willfail and the next instruction will be executed. This initial sequence of instructions corresponds to arrow I in Fig. 6.7. At this point, the accumulator contains a "I" in bit position 7 and the actual data bit in bit position 0. The first data bit to arrive is going to be a "I". However, the following bits may be either "0" or "I". We now wish to preserve the data bit which has been collected in position 0. The instruction: SRL A shifts the contents of the accumulator right by one position. This causes the right-most bit of A, which is our data bit, to fall into the carry bit. We will now preserve this data bit into register C (this process is illustrated by arrows 2 and 3 in Fig. 6.7): RL C
473
COUNT
0
x x
COUNT
tilti
STATUS OR CLOCK
The effect of this instruction is to read the carry bit into the right-most bit position of C. At the same time, the left-most bit of C falls into the carry bit. (If you have any doubts about the rotation operation, refer to Chapter 4!) It is important to remember that a rotation with carry operation will both save the carry bit, here into the right-most bit position, and also recondition the carry bit with the value of bit 7 (or bit 0). Here, a "0" will fall into the carry. The next instruction: JR NC, LOOP
tests the carry and branches back to address LOOP as long as the carry
474
INPUT/OUTPUT TECHNIQUES is "0". This is our automatic bit counter. It can readily be seen that, as a result of the first RL, C will contain "00000001" Eight shifts later, the "1" will finally fall into the carry bit and stop the branching. This is an ingenious way to implement an automatic loop counter without having to waste an instruction to decrement the contents of an index register. This technique is used in order to shorten the program and improve its performance. When JR NC finally fails, 8 bits will have been assembled into C. This value should be preserved in the memory. This is accomplished by the next instruction (arrow 4 on Fig. 6.7): PUSH BC We are here saving the contents of B and C into the stack. Saving into the stack is possible only if there is enough room in the stack. Provided that this condition is met, it is usually the fastest way to preserve a word in the memory, even though we save an unnecessary register (B). The stack pointer is updated automatically. If we were not pushing a word in the stack, we would have to use one more instruction to update a memory pointer. We could equivalently perform an indexed addressing operation, but that would also involve decrementing or incrementing the index, using extra time. After the first word of data has been saved, there is no longer any guarantee that the first data bit to come in will be a "1". It can be anything. We must, therefore, reset the contents to "00000001" so that we can keep using it as a bit counter. This is performed by the next instruction: LD C, 01H Finally, we will decrement the word counter, since a word has been assembled, and test whether we have reached the end of the transfer. This is accomplished by the next two instructions: DEC B JR NZ, LOOP The above program has been designed for speed, so that one may capture a fast input stream of data bits. Once the program terminates, it is naturally advisable to immediately read away from the stack the words that have been saved there and transfer them elsewhere into the memory. We have already learned to perform such a block transfer in Chapter 2.
475
PROGRAMMING THE Z80 Exercise 6.6: Compute the maximum speed at which this program will be able to read serial bus. Look up the number of cycles required by every IIISMI01011 in the table at the end of this book, then compute the time which trill elapse during execution of this program. To compute the length of time which will be used by a loop, simply multiply the total duration of this loop, expressed in microseconds, by the number of tunes it will be executed. Also, when computing the maximum speed, assume that a data bit trill be ready even' tune that the input location is sensed. This program is more difficult to understand than the previous ones. Let us look at it again (refer to Fig. 6.6) in more detail, examining some trade-offs. A bit of data comes into bit position 0 of "INPUT" from time to time. There might be, for example, three "Is" in succession. We must, therefore, differentiate between the successive bits coming in. This is the function of the "clock" signal. The clock (or STATUS) signal tells us that the input bit is now valid. Before reading a bit, we will therefore first test the status bit. If the status is "0", we must wait. If it is "I", then the data bit is good. We assume here that the status sianal is connected to bit 7 of register INPUT. Exercise 6.7: Can you explain why bit 7 is used for status, and but 0 f or data? Does it matter? Once we have captured a data bit, we want to preserve it in a safe location, then shift it left, so that we can get the next bit. Unfortunately, the accumulator is used to read and test both data and status in this program. If we were to accumulate data in the accumulator, bit position 7 would be erased by the status bit. Exercise 6.8: Can you suggest a war to test status without erasing the contents p/ the accumulator (a special instruction/? //'this can be done, could we use the accumulator to accumukite the successive bits coining in? Can you improve speed by using an "automated lump"? Exercise 6.9: Rewrite the program, using the accumulator to store the bits coming in. Compare it to the previous one in terms of speed and number of instructions. Let us address two more possible variations. We have assumed that, in our particular example, the very first bit to come in would be a special signal, guaranteed to be "I". However, in
476
INPUT/OUTPUT TECHNIQUES eeneral, it may be anything. Exercise 6. /0: Modify the program above, assuming that the very first bit to come in is valid data Owl to be discarded), and can be "0" or "I" Hint: our "bit counter" should still work correct Iv, ii/ you iitialize it nuli the correct value. Finally, we have been saving the assembled word in the stack, to gain time. We could naturally save it in a specified memory area. Exercise 6. /1: Madill' the pMMIT1111 above, and save die assembled word ui the memoir area starting at BASE. Exercise 6. /2: illochtv the program above so that the ownsfer when the character "S" is detected in the input strewn. The Hardware Alternative As usual for most standard input/output algorithms, it is possible to implement this procedure by hardware. The chip is called a UART, It will aulornancallv accumulate the bits. However, whin one wishes to reduce the component count, this program, or a variation of it, will be used instead. stop
Exercise 6.13: Modify the program, assummg that data is available m Int
477
SI 'IS NO
(
DATA
outrui
OUTPUT DEVICE
MPU
asynchronous devices, i.e., between any two devices which are not synchronized. For example, if we want to send a word to a parallel printer, we must first make sure that the input buffer of this printer is available. We will, therefore, ask the printer: Are you ready? The printer will say "yes" or "no." If it is not ready we will wait. If it is ready, we will send the data (see Fig. 6.8).
DATA
INNUI ttcrsna
INPUT MPU
al .1, NIS 10 IAM. 1(0151(1
DEVICE
Fig. 6.8a: Handshaking (Input) Conversely, before reading data from an input device, we will verify whether the data is valid. We will ask: "Is data valid?" And the device will tell us "yes" or "no." The "yes or no" may be indicated by status bits, or by other means (see Fig. 6.8a). As an analogy, whenever you wish to exchange information with someone who is independent and might be doing something else at the time, you should ascertain that he is ready to communicate with you. The usual rule of courtesy is to shake his hand. Data exchange may then follow. This is the procedure normally used in communicating with in-
478
INPUT/OUTPUT TECHNIQUES put/output devices. Let us now illustrate this procedure with a simple example. Sending a Character To The Printer The character will be assumed to be contained in memory location CHAR. The program to print it appears below: WAIT IN BIT JR LD OUT JR A, (STATUS) 7, A TEST IF READY Z, WAIT OTHERWISE WAIT A, (CHAR) GET CHARACTER 312NTD), A PRINT IT (1 CO FOR NEXT WAIT
The print program is straightforward and uses the handshaking procedure which has been described above. The data paths are shown in Figure 6.9
STATUS
CHAR
DATA PRNTD
PRINTER
MEMORY
Z80
The character (called DATAI is located at memory location CHAR. First, the status of the printer is checked. Whenever bit 7 of the status
479
register becomes I it indicates that the printer ready for input, i.e., its input buffer is available. At this point, the character is loaded into
the accumulator, then output to the printer, via the accumulator. As long as the status bit remains 0, the program will remain in a loop, called WAIT in the program. Exercise 6.14: How many instructions would be saved in the above program by loading data directly into register C as well as outputing the contents of register C directly? Exercise 6.15: When using an actual printer, it is usually necessary to send a start order before using the device. Modify this program to generate such an order, assuming that the start command is obtained by writing a I in bit position 0 of the STATUS register. which is assumed to be bidirectional. Exercise 6.16: If the BIT instruction were not available, could you use another instruction instead, in line 2 of the program? If so, explain the advantage of using the BIT instruction, if any. Exercise 6.17: Modify the program above to print a string of n characters, where n will he assumed to be less than 255. Exercise 6.18: Modify the above program to print a string of characters until a "carriage-return" code is encountered. Let us now complicate the output procedure by requiring a code conversion and by outputting to several devices at a time:
Output To a Seven-Segment LED A traditional seven-segment light-emitting diode (LED) may display the digits "0" through "9", or even "0" through "F" hexadecimal by lighting combinations of its 7 segments. A seven-segment LED is shown in Figure 6.10. The characters that may be generated with this LED appear in Figure 6.1 I. The segments of an LED are labeled "a" through "g" in Figure 6.10. For example, "0" will he displayed by lighting the segments abcdef. Let us assume, now, that bit "0" of an output port is connected to segment "a", that "I" is connected to segment "b", and so on. Bit 7 is not used. The binary code required to light up fedcba (to display "0") /s, therefore, "011111I" In hexadecimal this is "3F". Do the following exercise.
480
INPUT/OUTPUT TECHNIQUES
A "If "if
D
Fig. 6.10: Seven-Segment LED
481
PROGRAMMING THE Z80 Exercise 6.19: Compute the seven-segment equivalent for the hexadecimal digits "0" through "F". Fill out the table below:
Hex LED code Hex LED code Hex LED code Hex LED code C 3F 4 8 0 D 9 5 1 A E 2 6 F 3 B 7
Let us now display hexadecimal values on several LED's. Driving Multiple LED's An LED has no memory. It will display the data only as long as its segment lines are active. In order to keep the cost of an LED display low, the microprocessor will display information on each of the LED's in turn. The rotation between the LED's must be fast enough so that there is no apparent blinking. This implies that the time spent from one LED to the next is less than 100 milliseconds. Let us design a program which will accomplish this. Register C will be used to point to the LED on which we want to display a digit. The accumulator is assumed to contain the hexadecimal value to be displayed on the LED. Our first concern is to convert the hexadecimal value into its seven-segment representation. In the preceding section, we have built the equivalence table. Since we are accessing a table, we will use the indexed addressing mode, where the displacement index will be provided by the hexadecimal value. This means that the seven-segment code for hexadecimal digit "3" is obtained by looking up the third element of the table after the base. The address of the base will be called SEGBAS. The program appears below: LEDS LD LD LD ADD LD LD DELAY OUT DEC E, A D, 0 HL, SEGBAS HL, DE A, (HL) B, 50H (C), A A CONTAINS HEX DIGIT USE "DE" AS DISPLACEMENT USE "HL" AS INDEX TABLE ADDRESS READ CODE FROM TABLE DELAY VALUE = ANY LARGE NBR OUTPUT FOR SET DURATION DELAY COUNTER
482
INPUT/OUTPUT TECHNIQUES JR LD DEC CP JR LD OUT RET NZ, DELAY KEEP LOOPING A, C C IS PORT NUMBER C MINLED DONE FOR LAST LED? NZ, OUT BC, (MAXLED) IF SO, RESET C TO TOP LED
The program assumes that register C contains the address of the LED to be illuminated next, and that the accumulator A contains the digit to be displayed. The program first looks up the seven-segment code corresponding to the hexadecimal value contained in the accumulator. Registers D and E are used as a displacement field, and registers H and L are used as a 16-bit index register. The hexadecimal digit is added to the base address of the table: LEDS LD LD LD ADD E, A D, 0 HL, SEGBAS HL, DE 7-SEGMENT CODE
A delay loop is then implemented, so that the code obtained from the table is displayed for an appropriate duration. Here the constant "50" hexadecimal has been arbitrarily chosen: LD LD A, (HL) B, 50H READ CODE FROM TABLE DELAY VALUE
The delay is accomplished using a classic delay loop. The first instruction: DELAY OUT (C), A
outputs the contents of the accumulator at the I/O port pointed to by register C (the LED number). The next two instructions implement the delay loop: DEC B NZ, DELAY JR Once the delay has been implemented, we must simply decrement the LED pointer, and make sure that we loop around to the highest LED address if the smallest LED address has been reached: LD A,C
483
PROGRAMMING THE Z80 DEC C CP MINLED NZ, OUT JR BC, (MAXLED) LD OUT RET It is assumed here that the above program has been written as a subroutine, and the last instruction is then RET:" return from subroutine" Exercise 6.20: It is usually necessary to turn off the segment drivers for the LED prior to displaying the digit. Modify the above program by adding the necessary instructions (output "00" as the character code prior to outputting the character). Exercise 6.21: What would happen to the display if the DELAY label were moved up by one line position? Would thus change the tuning? Would this change the appearance of the display? Exercise 6.22: You will notice that the first four instructions of the program are, in fact, performing a 16-1M indexed memory access. However, it seems clumsy, without using the indexing mechanism. Assume that the SEGBAS address is known in advance. Call SEGBSH the high-order part of this address, and SEGBSL the low part of this address. Store SEGBSH in the high-order part of the IX register. Now write the above program, using the Z80 index-addressing mechanism, and using SEGBSL as the displacement field of the instrucion. What are the advantages and disadvantages of this approach? Exercise 6.23: Assuming that the above program is a subroutine, you will notice that it uses registers B, D. E, H and L internally, and modifies their contents. If the subroutine may freely use the memory area designated by address Ti, T2, T3. T4, T5, could you add instructions at the beginning and at the end of this program which will guarantee that. when the subroutine returns, the contents of registers B, D, E, H and L, will be the same as when the subroutine was entered? Exercise 6.24: Same exercise as above, but assume that the memory area Ti. etc., is not available to the subroutine. (Hint: remember that there is a built-in mechanism in every computer for preserving information m a chronological order.) We have now solved common input/output problems. Let us consider the case of a common peripheral: the Teletype.
484
INPUT/OUTPUT TECHNIQUES
Teletype Input-Output The Teletype is a serial device. It both sends and receives words of information in a serial format. Each character is encoded in an 8-bit ASCII format (the ASCII table appears at the end of this book). In addition, every character is preceded by a "start" bit, and terminated by two "stop" bits. In the so-called 20-milliamp current loop interface, which is most frequently used, the state of the line is normally a "I". This is used to indicate to the processor that the line has not been cut. A start is a "1"-to-"0" transition. It indicates to the receiving device that data bits follow. The standard Teletype is a 10-characters-per-second device. We have just established that each character requires II bits. This means that the Teletype will transmit 110 bits per second. It is said to be a 110-baud device. We will design a program to serialize bits out to the Teletype at the correct speed.
START PULSE MARK 2 SPACE 9.09m5 -b-1--1 3 4 5 1 6 7 8 2 STOP PULSES STOP I I STOP 2 9 10
Fig. 6.12: Format of a Teletype Word One-hundred-and-ten bits per second implies that bits are separated by 9.09 milliseconds. This will have to be the duration of the delay loop to be implemented between successive bits. The format of a Teletype word appears in Figure 6.12. The flowchart for bit input appears in Figure 6.13. The program follows: TTY1N IN BIT JR CALL IN OUT CALL LD NEXT IN OUT SRL A, (STATUS) 7, A Z, TTYIN DELAY1 A, (TTYBIT) (TTYBIT), A DELAY9 B, 08H A, (TTYBIT) (TTYBIT), A A
DATA READY^ OTHERWISE WAIT CENTER OF PULSE START BIT ECHO IT NEXT PULSE (9 MS) BIT COUNT READ DATA BIT ECHO IT SAVE IT IN CARRY 485
WAIT 9.09 ms
NO
CHARACTER ASSEMBLED?
I YES
WAIT 9.09 an
WAIT 13.59 ms
486
INPUT/OUTPUT TECHNIQUES
DELAY9
B
PRESERVE IT INTO C NEXT PULSE (9 MS) DECREMENT BIT COUNT READ STOP BIT ECHO IT SKIP SECOND STOP
Fig. 6.14: Teletype Program Let us examine the program in detail. First, the status of the Teletype must be tested to determine if a character is available: IN A, (STATUS) BIT 7, A JR Z, TTYIN The "BIT" instruction is a useful Z80 facility which allows testing any bit in any data register. It does not modify the contents of the register under test. The Z flag is set if the specified bit is 0, and reset otherwise. This program will, therefore, loop until the status finally becomes "1". It is a classic polling loop. Note also that, since the STATUS does not need to be preserved, we could advantageously use AND 10000000B instead of BIT 7, A However, using the AND instruction destroys the contents of A (acceptable here). When optimizing a program, remember that each new instruction may introduce side-effects. Next, a 4.5 ms delay is implemented in order to sense the start bit in the middle of the pulse. CALL DELAYI where DELAYI is the delay subroutine implementing the required delay. The first bit to come is the start bit. It should be echoed to the Teletype, but otherwise ignored. This is done by the next instructions: TTYIN IN A, (TTYBIT) OUT (TTYBIT), A 487 TTYIN
PROGRAMMING THE Z80 We must then wait for the first data bit. The necessary delay is equal to 9.09 milliseconds and is implemented by a subroutine: CALL DELAY9 Register B is used as a counter and is loaded with the value 8 in order to capture the 8 data bits: LD B, 08H
Next, each data bit will be read in turn into the accumulator, then echoed. It is assumed to arrive in bit position 0 of the accumulator. The data bit will then be preserved into register C, where it will be shifted in. The transfer from A to C is performed through the carry bit: NEXT IN A, (TTYBIT) OUT (TTYBIT), A SRL A RR C This sequence is illustrated in Figure 6.15.
A I/O SPACE
x
r
TELETYPE
488
INPUT/OUTPUT TECHNIQUES The program should be examined with attention. The logic is quite simple. The new fact is that whenever a bit is read from the Teletype (at address TTYBIT), it is echoed back to the Teletype. This is a standard feature of the Teletype. Whenever a user presses a key, the information is transmitted to the processor and then back to the printing mechanism of the Teletype. This verifies that the transmission lines are working and that the processor is operating when a character is, indeed, printing correctly on the paper.
ENTER
EXIT
489
PROGRAMMING THE Z80 NEXT OUT (TTYBIT), A OUTPUT CALL DELAY NEXT BIT RRA CARRY = 1 (STOP BIT) SCF BIT COUNT DEC B NZ, NEXT JR RET Register B is used as a bit counter for the transmission. The contents of bit 0 of A will be sent to the Teletype line ("TTYBIT"). Note how the carry is used to provide a ninth bit (the START bit). Also, note that the carry is cleared by: OR A At the end of the program, the carry is set to one by: SCF in order to generate a stop bit.
Exercise 6.27: Modify the program so that it waits for a START bit instead of a STATUS bit.
Printing a String of Characters We will assume that the PRINTC routine (see Exercise 6.26) takes care of printing a character on our printer, or display,or any output device. We will here print the contents of memory locations (START) to (START + N). The program is straightforward (see Figure 6.17): LENGTH OF STRING B, NBR PSTRING LD HL, START BASE ADDRESS LD GET CHARACTER LD A, (HL) NEXT PRINT IT CALL PRINTC NEXT ELEMENT HL INC DEC B DO IT AGAIN NZ, NEXT JR RET
490
INPUT/OUTPUT TECHNIQUES
MEMORY
A COUNTER START
START +N
PERIPHERAL SUMMARY
We have now described the basic programming techniques used to communicate with typical input/output devices. In addition to the data transfer, it will be necessary to condition one or more control registers within each I/O device in order to condition the transfer speeds, the interrupt mechanism, and the various other options correctly. The manual for each device should be consulted. (For more details on the specific algorithms for exchanging information with all the usual peripherals, the reader is referred to our book, C207, Microprocessor Interfacing Techniques.) We have now learned to manage single devices. However, in a real system, all peripherals are connected to the buses , and may request service simultaneously. How are we going to schedule the processor's time?
INPUT/OUTPUT SCHEDULING
Since input/output requests may occur simultaneously, a scheduling mechanism must be implemented in every system to determine in which order service will be granted. Three basic input/output techniques are used, which can be combined with each other. They are: polling, interrupt, DMA. Polling and interrupts will be described here. DMA is purely a hardware technique, and as such will not be described here. (It is covered in the reference books C201 and C207.)
491
Polling Conceptually, polling is the simplest method for managing multiple peripherals. With this strategy, the processor interrogates the devices connected to the buses in turn. If a device requests service, the service is granted. If it does not request service, the next peripheral is examined. Polling is used not just for the devices, but for any device service routine. As an example, if the system is equipped with a Teletype, a tape recorder, and a CRT display, the polling routine would interrogate the Teletype: "Do you have a character to transmit?" It would interrogate the Teletype output routine, asking: "Do you have a character to send?" Then, assuming that the answers are negative so far, it would interrogate the tape-recorder routines, and finally the CRT display. If only one device is connected to a system, polling will be used as well to determine whether it needs service. As an example, the flowcharts for reading a paper-tape reader and for printing on a printer appear in Figures 6.20 and 6.21.
I/O
INTERRUPT I/O
t NT
HOLD MPU
MEMORY
LiT&
492
INPUT/OUTPUT TECHNIQUES Example: a polling loop for devices I. 2, 3, 4 (see Fig. 6.19): POLL4 IN BIT CALL IN BIT CALL IN BIT CALL IN BIT CALL JR A, (STATUS 1) 7,A NZ, ONE A, (STATUS2) 7, A NZ, TWO A, (STATUS3) 7, A NZ, THREE A, (STATUS4) 7, A NZ, FOUR POLL4 GET STATUS OF DEVICE I SERVICE REQUEST? BIT 7 = I? DEVICE 2
DEVICE 3
DEVICE 4
Bit 7 of the status register for each device is "I" when it wants service. When a request is sensed, this program branches to the device handler, at address ONE for device I, TWO for device 2, etc. A fine point is worth noting here. For each instruction, it is important to verify carefully the way in which it affects the condition codes. It should be noted that the IN A instruction does not change the flags.
If an IN r instruction has been used instead of an IN A instruction, bit 7 of the input would automatically be reflected as the SIGN bit in the flags register. The special instruction "BIT 7,A" would become unnecessary. However, because the IN A instruction does not change the flags, this extra test must be included in the program.
In some hardware implementations, input/output devices may be treated as memory devices for purposes of addressing. This is called memory-mapped input/output. In this case, the IN instruction would be replaced by an LD instruction and the rest of the program would be
as above, since LD does not affect the flags. The advantages of polling are obvious: it is simple, does not require
any hardware assistance, and keeps all input/output synchronous with the program operation. Its disadvantage is just as obvious: most of the processor's time is wasted looking at devices that do not need service. In addition, by wasting so much time, the processor might give service to a device too late. Another mechanism is, therefore, desirable in order to guarantee that the processor's time can be used to perform useful computations rather than polling devices needlessly all the time. However, let us stress that polling is used extensively whenever a microprocessor has nothing bet-
493
YES
S
SERVICE ROUTINE FOR DEVICE B
I
SERVICE ROUTINE FOR DEVICE C
READ CHARACTER
494
INPUT/OUTPUT TECHNIQUES
ter to do, as it keeps the overall organization simple. Let us examine the essential alternative to polling: interrupts. Interrupts The concept of interrupts is illustrated in Figure 6.18. A special hardware line, the interrupt line, is connected to a specialized pin of the microprocessor. Multiple input/output devices may be connected to this interrupt line. When any one of them needs service, it sends a level or a pulse on this line. An interrupt signal is the service request from an input/output device to the processor. Let us examine the response of the processor to this interrupt. In any case, the processor completes the instruction that it was currently executing; otherwise, this would create chaos inside the microprocessor. Next, the microprocessor should branch to an interrupt-handling routine which will process the interrupt. Branching to such a subroutine implies that the contents of the program counter must be saved on the stack. An interrupt must, therefore, cause the automatic preservation of the program counter on the stack. In addition, the flag register F should be also preserved automatically, as its contents will be altered by any subsequent instruction. Finally, if the interrupt-handling
495
PROGRAMMING THE Z80 routine should modify any internal registers, these internal registers should also be preserved on the stack (see Figures 6.22 and 6.23). SP PCL PCH Fig. 6.22: Z80 Stack After Interruption
Fig. 6.23: Saving Some Working Registers After all these registers have been preserved, one can branch to the appropriate interrupt-handling address. At the end of this routine, all the registers should be restored, and a special interrupt return should be executed so that the main program will resume execution. Let us examine in more detail the interrupt lines of the Z80. Z80 Interrupts An interrupt is a signal sent to the microprocessor, which may request service at any time and is asynchronous to the program. Whenever a program branches to a subroutine, such branching is synchronous to program execution, i.e., scheduled by the program. An interrupt, however, may occur at any time, and will generally suspend the execution of the current program (without the program knowing it). Because it may happen at any time relative to program execution, it is called asynchronous. Three interruption mechanisms are provided on the Z80: the bus request (BUSRQ), the non-maskable interrupt (NMI) and the usual interrupt (INT). Let us examine these three types.
496
INPUT/OUTPUT TECHNIQUES
The Bus Request The bus request is the highest priority interrupt mechanism on the Z80. The interrupt sequence for the Z80 is shown in Figure 6.24. As a general rule, no interrupt will be sensed by the Z80 until the current machine cycle is completed. The NMI and INT interrupts will not be taken into account until the current instruction is finished. However, the BUSRQ will be handled at the end of the current machine cycle, without necessarily waiting for the end of the instruction. It is used for
497
PROGRAMMING THE Z80 a direct memory access (DMA), and will cause the Z80 to go into DMA mode (see ref. C201 for an explanation of the DMA mechanism). If the end of an instruction has been reached, and if any NMI or INT were pending, they would be memorizedinternally in the Z80 by setting specialized flip-flops: the NMI flip-flop, and the INT flip-flop. In DMA mode, the Z80 suspends operation and releases its data-bus and address-bus in the high-impedance state. This mode is normally used by a DMA controller to perform transfers between a high-speed inputoutput device and the memory, using the microprocessor data-bus and address-bus. The end of a DMA operation is indicated to the Z80 by BUSRQ changing levels. At this point, the Z80 will resume normal operation. In particular, it will first check whether its internal NMI or INT flip-flops had been set and, if so, execute the corresponding interrupts. The DMA should normally not be of concern to the programmer, unless timing is important. If a DMA controller is present in the system, the programmer must understand that the DMA may delay the response to an NMI or an INT.
The Non-Mnskable Interrupt
This type of interrupt cannot be inhibited by the programmer. It is therefore said to be non-maskable, hence its name. It will always be accepted by the Z80 upon completion of the current instruction, assuming no bus request was received. (If an NMI is received during a BUSRQ, it will set the internal NMI flip-flop, and will be processed at the end of the instruction following the end of the BUSRQ.) The NMI will cause an automatic push of the program counter into the stack and branch to address 0066H: the two bytes representing the address 0066H will be installed in the program counter. They represent the start address of the handling routine for the NMI (see figure 6.25). This interrupt mechanism has been designed for speed, as it is used in case of "emergencies". Therefore, it does not offer the flexibility of the maskable interrupt mode, described below. Note also that an interrupt routine must have been loaded at address 0066H prior to using the NMI. NMI will first cause: SP SP I (SP) PCH push PC SP SP I (SP) PCL
498
INPUT/OUTPUT TECHNIQUES
MEMORY IFFI
pc
0066
O
PC
oU
PC - slack (preserve program counter) (preserve IFF) (reset 1FF) (execute interrupt handler)
Fig. 6.25: NMI Forces Automatic Vectoring Then, NMI causes an automatic restart at location 0066H. The complete sequence of events is the following:
PC 0- STACK IFF2 IFFI IFFI 0 JUMP TO 1306614
Also, the status of interrupt-mask-bit flip-flop (IFFI) at the time that NMI was received is preserved automatically into IFF2. Then, IFFI is reset in order to prevent any further interrupts. This feature is important to prevent the loss of lower-priority INT's and simplifies the external hardware: the status of a pending INT is preserved internally in the Z80. The NMI interrupt is normally used for high priority events such as a real-time clock or a power failure. The return from an NMI is accomplished by a special instruction, RETN: "return from non-maskable interrupt." The contents of IFFI are restored from IFF2, and the contents of the program counter PC are restored from their location in the stack. Since IFF1 had been reset during execution of the NMI. no external INT's could be accepted during the NMI (unless the programmer uses an El instruction within the NMI routine): there has been no loss of information. Upon termination of the interrupt handler, the sequence is:
IFFI IFF2 01". PC STACK (restore 1FF) (restore program counter)
Note that, once IFFI is restored, maskable interrupt enable status is restored. 499
PROGRAMMING THE Z80 Interrupt The ordinary. maskable,,interrupt INT may operate in one of three modes. They are specific to the Z80, as the 8080 is equipped with only a single interrupt mode. The ordinary interrupt INT may also be masked selectively by the programmer. Setting the interrupt flip-flops IFFI and IFF2 to a "1" will authorize interruptions. Setting them to a "0" (masking them) will prevent detection of INT. The El instruction is used to set them, and the DI instruction is used to reset them. IFFI and IFF2 are set or reset simultaneously. During execution of the El and DI instructions, INT's are disabled in order to prevent any loss of information. Let us now examine the three interrupt modes: Interrupt Mode 0 This mode is identical to the 8080 interrupt mode. The Z80 will operate in interrupt mode 0 either when initially started (when the RESET signal has been applied) or else when an IMO instruction has been executed. Once mode 0 has been set, an interrupt will be recognized if the interrupt enable flip-flop IFFI is set to 1, provided no bus-request or non-maskable interrupt occurs at the same time. The interrupt will be detected only at the end of an instruction. Essentially, the Z80 will respond to the interrupt by generating an IORQ (and an Ml signal), and then do nothing, except wait. It is the responsibility of an external device to recognize the IORQ and MI (this is called an interrupt acknowledge or INTA) and to place an instruction on the data-bus. The Z80 expects an instruction to be placed on its data bus by the external device within the next cycle. Typically, an RST or a CALL instruction is placed on the bus. Both of these instructions automatically preserve the program-counter in the stack, and cause branching to a specific address. The advantage of the RST instruction is that it resides within a single byte, i.e., it executes rapidly. Its disadvantage is to branch to only one of eight possible locations in page zero (addresses 0 through 255). The advantage of the CALL instruction is that it is a general-purpose branch instruction which specifies a full 16-bit address. However, it requires three bytes and therefore executes less rapidly. Note that once the interrupt processing starts, all further interrupts are disabled. IFFI and IFF2 are automatically set to "0". It is then the responsibility of the programmer to insert an El instruction (Enable In500
INPUT/OUTPUT TECHNIQUES terrupts) at the appropriate location within his program if he wishes to enable interrupts, and, in any case, before returning from the interrupt. The detailed sequence corresponding to the mode 0 interrupt is shown in Figure 6.26.
MODE 0 //COE I MOOR 2 DISABLE INosoun 1,71. ERR] 0
KysTAG
RIAD VECTOR
JUMP TO 033/111
PC -0 STACs
GU STACK-7K
Fig. 6.26: Interrupt Modes The return from the interrupt is accomplished by an RETI instruction. Let us remind the programmer at this point that he/she is usually responsible for explicitly clearing the interrupt which has been serviced on the I/O device, and always for restoring the interrupt disable flag inside the Z80. However, the peripheral controller may use the INTA signal to clear the INT request, thus freeing the programmer of this chore. In addition, should the interrupt-handling routine modify the contents of any of the internal registers, the programmer is specifically responsible for preserving these registers in the stack prior to executing the interrupt-handling routine. Otherwise, the contents of these registers will be destroyed, and when the interrupted program resumes exe-
501
PROGRAMMING THE Z80 cution, it will fail. For example, assuming that registers A, B, C, D, E, H and L will be used within the interrupt handler, they will have to be saved (see Figure 6.27).
Fig. 6.27: Saving the Registers The corresponding program is: SAVREG PUSH AF PUSH BC PUSH DE PUSH HL Upon completion of the interrupt-handling routine, these registers must be restored. The interrupt handler will terminate with the following sequence of instructions: POP POP POP POP El HL DE BC AF (unless El was used earlier in the routine)
Additionally, if registers IX and lY are used by the routine they must also be preserved, then restored.
502
INPUT/OUTPUT TECHNIQUES
Interrupt Mode I
This interrupt mode is set by executing the IM I instruction. It is an automated interrupt handler which causes an automatic branch to location 0038H. It is therefore essentially analogous to the NMI interrupt mechanism except that it may be masked. The Z80 automatically preserves the contents of PC into the stack (see Figure 6.28).
INTERRUPT ROUTINE
PC
LOCATION OF INTERRUPTION
MEMORY
This automated interrupt response, which "vectors" all interrupts to memory location 38H, stems from the early 8080's requirement to minimize the amount of external hardward necessary for using interrupts. Its possible disadvantage is to cause a branch to a single memory location. In case several devices are connected to the INT line, the program starting at location 38H will be responsible for determining which device requested service. This problem will be addressed below. One precaution must be taken with respect to the timing of this interrupt: when performing programmed input/output transfers, the Z80 will ignore any data that may be present in the data bus during the cycle which follows the interrupt (the interrupt acknowledge cycle).
503
PROGRAMMING THE Z80 Interrupt Mode 2 (Vectored Interrupts) This mode is set by executing an IM2 instruction. It is a powerful mode which allows automatic vectoring of interrupts. The interrupt vector is an address supplied by the peripheral device which generated the interrupt, and used as a memory pointer to the start address of the interrupt-handling routine. The addresssing mechanism provided by the Z80 in mode 2 is indirect, rather than direct. Each peripheral supplies a seven-bit branching address which is appended to the 8-bit address contained in the special I register in the Z80. The right-most bit of the final I6-bit address bit 0 is set to "0". This resulting address points to an entry in a table anywhere in the memory. This table may contain
up to 128 double-word entries. Each of these double words is the address of the interrupt handler for the corresponding device. This is illustrated in Figures 6.29 and 6.30.
INT DEVICE r---. 7 BIT VECTOR 2X VECTOR 0 ---
K"-
START ADDRESS
Fig. 6.29: Mode 2 Interrupt The interrupt table may have up to 128 double-word entries. In this mode, the Z80 also automatically pushes the contents of the program counter into the stack. This is obviously necessary, since PC will be reloaded with the contents of the interrupt table entry corresponding to the vector provided by the device. Interrupt Overhead For a graphic comparison of the polling process vs. the interrupt process, refer to Figure 6.18, where the polling process is illustrated on the top, and the interrupt process underneath. It can be seen that in the polling technique the program wastes a lot of time waiting.
504
INPUT/OUTPUT TECHNIQUES
0152
05
PC
01
/
, I
/ //
SP
10
#.7'
a
DEVICE n CONTROLLER
PC
20
04
2004 SP 09 AFTER 98
Fig. 6.30: Mode 2- A Practical Example Using interrupts, the program is interrupted, the interrupt is serviced, then the program resumes. However, the obvious disadvantage of an interrupt is to introduce several additional instructions at the beginning and at the end, resulting in a delay before the first instruction of the device handler can be executed. This is additional overhead. Exercise 6.28: Using the tables indicating the number of cycles per instruction, in Chapter 4, compute how much time will be lost to save and then restore registers A, B, D, H. Having clarified the operation of the interrupt lines, let us now consider two important remaining problems: IHow do we resolve the problem of multiple devices triggering an
505
PROGRAMMING THE Z80 interrupt at the same time? 2How do we resolve the problem of an interrupt occurring while another interrupt is being serviced? Multiple Devices Connected to a Single Interrupt Line Whenever an interrupt occurs, the processor branches to a specified address. Before it can do any effective processing, the interrupt handling routine must determine which device triggered the interrupt. Two methods are available to identify the device, as usual: a software method and a hardware method. In the software method, polling is used: the microprocessor interrogates each of the devices in turn and asks them, "Did you trigger the interrupt?" If the answer is negative, it interrogates the next one. This process is illustrated in Figure 6.31. A sample program is: POLINT IN BIT JP IN BIT JP etc. A, (STATUSI) READ STATUS DID DEVICE REQUEST INT? 7, A HANDLE IT IF SO NZ, ONE A, (STATUS2) 7, A NZ, TWO
The hardward method provides the address of the interrupting device simultaneously with the interrupt request.
INT 1 POLLING
INTERRUPT
VECTORED
WHICH DEVICE]
POLLING ROUTINE 1
SERVICE ROUTINE N
506
INPUT/OUTPUT TECHNIQUES To be more precise, when operating in mode 0, the peripheral device controller will supply a one-byte RST or a three-byte CALL on the data bus in response to the interrupt acknowledge, thus automating the interrupt vectoring, and minimizing the overhead. Note that a subroutine call instruction is required as the Z80 does not save the PC when operating in mode 0. In most cases, the speed of reaction to an interrupt is not crucial, and a polling approach is used. If response time is a primary consideration, a hardware approach must be used.
Simultaneous Interrupts
The next problem which may occur is that a new interrupt can be triggered during the execution of an interrupt-handling routine. Let us examine what happens and how the stack is used to solve the problem. We have indicated in Chapter 2 that this was another essential role of the stack, and the time has come now to demonstrate its use. We will refer to Figure 6.33 to illustrate multiple interrupts. Time elapses from left to right in the illustration. The contents of the stack are shown at the bottom of the illustration. Looking at the left, at time TO, program P is in execution. Moving to the right, at time T1, interrupt II occurs. We will assume that the interrupt mask was enabled, authorizing II. Program P will be suspended. This is shown at the bottom of the illustration. The stack will contain the program counter and the status register of program P, at least, plus any optional registers that might be saved by the interrupt handler or II itself.
--.0".. I/O INTERFACE I/0 INTERFACE Ni k
MPU INT
M IT
Fig. 6.32: Several Devices May Use the Same Interrupt Line
At time T1, interrupt 11 starts executing until time T2. At time T2, interrupt 12 occurs. We will assume that interrupt 12 has a higher priority than interrupt 11. If it had a lower priority, it would be ignored until 11 had been completed. At time T2, the registers for II are stacked, and this appears at the bottom of the illustration. Again, the contents of the program counter and AF are pushed into the stack. In addition, the routine for 12 might decide to save an additional few registers. 12 will now execute to completion at time T3.
507
When 12 terminates (with an RETI), the contents of the stack are automatically popped back into the Z80. and this is illustrated at the bottom of Figure 6.33. Thus, automatically II resumes execution. Unfortunately, at time T4, an interrupt 13 of higher priority occurs again. We can see at the bottom of the illustration that again the registers for 11 are pushed into the stack. Interrupt 13 executes from T4 to T5 and
TIME PROGRAM P INTERRUPT I, INTERRUPT I. INTERRUPT t. 1. 1. T. T. i.
1.
11
STACK P TI
I/
P T.
T.
111
T,
time, the contents of the stack are popped into Z80, and interrupt II resumes execution. This time it runs to completion and terminates at T6. At T6. the remaining registers that have been saved in the stack are popped into Z80, and progam P may resume execution. The reader will verify that the stack is empty at this point. In fact, the number of dashed lines indicating program suspension indicates at the same time how many levels there are in the stack.
Exercise 6.19: Assume that the area available to the stack is limited to 300 locations in a specific program. Assume that all the registers must always be saved and that the programmer allows interrupts to be nested, i.e., to interrupt each other. Which is the maximum number of simultaneous interrupts that can be handled? Will any other factor contribute to still reduce further the 1110X111111111 number of simultaneous interrupts? It must be stressed, however, that, in practice, microprocessor systems are normally connected to a small number of devices using interrupts. It is, therefore, unlikely that a high number of simultaneous interrupts will occur in such a system. We have now solved all the problems usually associated with interrupts. Their use is, in fact, simple and they should be employed to advantage even by the novice programmer. 508
INPUT/OUTPUT TECHNIQUES SUMMARY In this chapter we have presented the range of techniques used to communicate with the outside world. From elementary input/output routines to more complex programs for communication with actual peripherals, we have learned to develop all the usual programs and have even examined the efficiency of benchmark programs in the case of a parallel transfer and a parallel-to-serial conversion. Finally, we have learned to schedule the operation of multiple peripherals by using polling and interrupts. Naturally, many other exotic input/output devices might be connected to a system. With the array of techniques which have been presented so far, and with an understanding of the peripherals involved, it should be possible to solve most common problems. In the next chapter, we will examine the actual characteristics of the input/output interface chips usually connected to a Z80. Then, we will consider the basic data structures that the programmer may use. Exercise 6.30: Compute the overhead when operating in mode 0, assuming that all registers are saved, and that an RST is received in response to the interrupt acknowledge. The overhead is defined as the total delay incurred, exclusive of the instructions required to implement the interrupt processing proper. Exercise 6.31: A 7-segment LED display can also display digits other than the hex alphabet. Compute the codes for: H, I. J. L. O. P, S. U. Y. g, h. r. J, 1, n, 0, p. r, t. u, y. Exercise 6.32: The flowchart for interrupt management appears in Figure 6.34 Answer the following questions: aWhat is done by hardware, what is done by software? bWhat is the use of the mask? cHow many registers should be preserved? dHow is the interrupting device identified? eWhat does the RETI instruction do? How does it differ from a subroutine return? fSuggest a way to handle a stack overflow situation. gWhat is the overhead ("lost lime") introduced by the interrupt mechanism?
509
NEXT INSTRUCTION
SET MMK
UNSET MASK
EXECUTE ROUTING
RESTORE REGISTERS
RETURN
510
7 INPUT/OUTPUT DEVICES
INTRODUCTION
We have learned how to program the Z80 microprocessor in most usual situations. However, we should make a special mention of the input/output chips normally connected to the microprocessor. Because of the progress in LSI integration, new chips have been introduced which did not exist before. As a result, programming a system requires, naturally, first to program a microprocessor itself, and then to program the input/output chips. In fact, it is often more difficult to remember how to program the various control options of an input/ output chip than to program the microprocessor itself! This is not because the programming in itself is more difficult, but because each of these devices has its own idiosyncrasies. We are going to examine here first the most general input/output device, the programmable input/ output chip (in short a "P10"), then some Zilog I/O devices.
511
PROGRAMMING THE Z80 I/O device. The PIO will also use a similar procedure to communicate with the peripheral. Each PIO must, therefore, be equipped with at least two control lines per port to implement the handshaking function. The microprocessor will also need to be able to read the status of each port. Each port must be equipped with one or more status bits. Finally, a number of options will exist within each PIO to configure its resources. The programmer must be able to access a special register within the PIO to specify the programming options. This is the control-register. In some cases the status information is part of the control register.
CRA n DATA Kr
tT
DDRA
PDRA
CAI CA2
,c2
-
IF
> PORT A
CRB
DORE
'DRB
> PORT B
CB2 CBI
Fig. 7.1: Typical PIO One essential faculty of the PIO is the fact that each line may be configured as either an input or an output line. The diagram of a PIO appears in illustration 7.1. The programmer may specify whether any line will be input or output. In order to program the direction of the lines, a data-direction register is provided for each port. On many PIO's, "0" in a bit position of the data-direction register specifies an input. A "1" specifies an output. Zilog uses the reverse convention. It may be surprising to see that a "0" is used for input and a "1" for output when really "0" should correspond to output and "1" to input. This is quite deliberate: whenever power is applied to the system, it is of great importance that all the I/O lines be configured as input. Otherwise, if the microcomputer is connected to some 512
INPUT/OUTPUT DEVICES
dangerous peripheral, it might activate it by accident. When a reset is applied, all registers are normally zeroed and that will result in configuring all input lines of the PIO as inputs. The connection to the microprocessor appears on the left of the illustration. The PIO naturally connects to the 8-bit data bus, the microprocessor address bus, and the microprocessor control-bus. The programmer will simply specify the address of any register that it wishes to access within the P10.
EN RESET
IRQB
513
EN RESET -..
IRQB
IRQB
- CB 1 CB 2
514
INPUT/OUTPUT DEVICES
Fig. 7.5: Using a PIO Read INPUT Programming a PIO A typical sequence, when using a PIO channel, is the following (assuming an input):
Load the control register
This is accomplished by a programmed transfer between a Z80 register (usually the accumulator) and the PIO control register. This sets the options and operating mode of the PIO (see Figure 7.2). It is normally done only once at the beginning of a program.
Load the direction register
This specifies the direction in which the I/O lines will be used. (See Figure 7.3.)
Read the status
The status register indicates whether a valid byte is available on input. (See Figure 7.4).
Read the port
The byte is read into the Z80. (See Figure 7.5). 515
I*
13
A0 A A2
PORI A 1/0
07
PORT B/A SE { CONTROL/DATA SEL PIO CONTROL CHIP ENABLE MI TORO RO INT INT ENABLE IN INT ENABLE OUT cP + 5V GND
LEO - PIO
12 +--q. A 3 10 A A .04. A 5 B A6 A7 ~~
33 36 35 23
24
INTERRUPT CONTROL
22 25 76
PORT 13 1/0
CLOCX
POWER
17
Fig. 7.6: Z80 PIO pinout The Zilog Z80 PIO The Z80 PIO is a two-port PIO whose architecture is essentially compatible with the standard model we have described. The actual pinout is shown in Figure 7.6, and a block diagram is shown in Figure 7.7. Each PIO port has six registers: an 8-bit input register, an 8-bit output register, a 2-bit mode-control register, an 8-bit mask register, an 8-bit input/output select (direction register), and a 2-bit mask-control register. The last three registers are used only when the port is programmed to operate in the bit mode. Each port may operate in one of four modes, as selected by the contents of the mode-control registers (2 bits). They are: byte output, byte input, byte bidirectional bus, and bit mode. The two bits of the mask control register are loaded by the programmer, and specify the high or low state of a peripheral device which is to be monitored, and conditions for which an interrupt can be generated. generated. The 8-bit input/output select register allows any pin to be either an input or an output when operating in the bit mode.
516
INPUT/OUTPUT DEVICES
DATA / BUS \
B U F F E R /2
In
DATA OUT
CONTROL
4
INT INTE-IN INTE-OUT INTERRUPT CONTROL
4
MASK CONTROL
PORT B
O `IO
DATA IN
HANDSHAKE
READY STROBE
TS
517
PROGRAMMING THE Z80 Programming the Zilog PIO A typical sequence for using a PIO, say in bit mode, would be the following: Load the mode control register to specify the bit mode. Load the input/output select register of port A to specify that lines 0-5 are inputs and lines 6 and 7 are outputs. Then a word would be read by reading the contents of the input buffer. Additionally, the mask register could be used to specify the status conditions. For a detailed description of the operation of the PIO, the reader is referred to the companion volume in this series, the Z80 Applications Book.
The Z80 SIO The SIO (Serial Input/Output) is a dual-channel peripheral chip designed to facilitate asynchronous communications in serial form. It includes a UART, i.e., a universal asynchronous receiver-transmitter. Its essential function is serial-to-parallel and parallel-to-serial conversion. However, this chip is equipped with sophisticated capabilities, like automatic handling of complex byte-oriented protocols, such as IBM bisync as well as HDLC and SDLC, two bit-oriented protocols. Additionally, it can operate in synchronous mode like a USRT, and generate and check CRC codes. It offers a choice of polling, interrupt, and block-transfer modes. The complete description of this device is beyond the scope of this introductory book and appears in the Z80 Applications Book.
Other I/O Chips Because the Z80 is commonly used as a replacement for the 8080, it has been designed so that it can be associated with almost any of the usual 8080 input/output chips, as well as the specific I/O chips manufactured by Zilog. All the 8080 input/output chips may be considered for use in a Z80 system.
518
INPUT/OUTPUT DEVICES
SUMMARY
In order to make effective use of input/output components it is necessary to understand in detail the function of every bit, or group of bits, within the various control registers. These complex new chips automate a number of procedures that had to be carried out by software or special logic before. In particular, a good deal of the handshaking procedures are automated within components such as an SIO. Also, interrupt handling and detection may be internal. With the information that has been presented in the preceding chapter, the reader should be able to understand what the functions of the basic signals and registers are. Naturally, still newer components are going to be introduced which will offer a hardware implementation of still more complex algorithms.
519
8 APPLICATION EXAMPLES
INTRODUCTION
This chapter is designed to test your new programming skills by presenting a collection of utility programs. These programs or "routines" are frequently encountered in applications, and are generally called "utility routines." They will require a synthesis of the knowledge and techniques presented so far. We are going to fetch characters from an I/O device and process them in various ways. But first, let us clear an area of the memory (this may not be necessaryeach of these programs is only presented as a programming example).
BASE to address BASE LENGTH, where LENGTH is less than 256. The program is:
ZEROM LD LD
B, LENGTH
A,0 HL, BASE
LOAD B WITH LENGTH CLEAR A POINT TO BASE CLEAR A LOCATION POINT TO NEXT DECREMENT COUNTER
END OF SECTION?
In the above program, the length of the section of memory is assumed to be equal to LENGTH. The register pair HL is used as a pointer to the current word which will be cleared. Register B is used, as
520
APPLICATION EXAMPLES
usual, as a counter. The accumulator A is loaded only once with the value 0 (all zeros), then copied into the successive memory locations. In a memory test program, for example, this utility routine could be used to zero the contents of a block. Then the memory test program would usually verify that its contents remained 0. The above was a straightforward implementation of a clearing routine. Let us improve on it. The improved program appears below. ZEROTA LD B, LENGTH LD HL, BASE LOOP LD (HL), 0 INC HL DJNZ LOOP RET The two improvements were obtained by eliminating the LD A. 0 instruction and loading a "zero" directly into the location pointed to by H and L, and also by using the special Z80 instruction DJNZ. This improvement example should demonstrate that every time a program is written, even though it may be correct, it can usually be improved by examining it carefully. Familiarity with the complete instruc-
tion set is essential for bringing about such improvements. These improvements are not just cosmetic. They improve the execution time of the program, require fewer instructions and therefore less memory space, and also generally improve the readability of the program and,
therefore, its chances of being correct. Exercise 8.1: Write a memory test program which zeroes a 256-word block. then verifies that each location is 0. Then, it will write all l's and verify the contents of the block. Then it will write 01010101 and verify the contents. Finally. it will write 10101010, and verify the contents. Exercise 8.2: Modify the above program so that it will fill the memory section with alternating 0's and l's O's. then all I's). Let us now poll our I/O devices to find which one needs service.
521
TEST
A, (STATUSI) 7. A NZ, FOUND1 A, (STATUS2) 7, A NZ, FOUND2 A, (STATUS3) 7, A NZ, FOUNDS exit)
READ 10 STATUSI TEST "READY" BIT (BIT 7) JUMP TO HANDLER 1 SAME FOR DEVICE 2
The MASK will contain, for example, "10000000" if we test bit position 7. As a result of the BIT instruction, the Z bit of the status flags will be set to 1 if "MASK AND STATUS" is zero, i.e., if the corresponding bit of STATUS matches the one in MASK. The JP NZ instruction (jump if non-equal to zero) will then result in a branch to the appropriate FOUND routine. GETTING CHARACTERS IN Assume we have just found that a character is ready at the keyboard. Let us accumulate characters in a memoryareacalled BUFFER until we encounter a special character called SPC, whose code has been previously defined. The subroutine GETCHAR will fetch one character from the keyboard (see Chapter 6 for more details) and leave it in the accumulator. We assume that 256 characters maximum will be fetched before an SPC character is found.
POINT TO BUFFER GET A CHARACTER CHECK FOR SPECIAL CHAR FOUND IT?
STORE CHAR IN BUFFER NEXT BUFFER LOCATION GET NEXT CHAR
Exercise 8.3: Let us Improve this basic routine: aEcho the character back to the device (for a Teletype, for example). bCheck that the input string is no longer than 256 characters. We now have a string of characters in a memory buffer. Let us
proc-
522
APPLICATION EXAMPLES ess them in various ways. TESTING A CHARACTER Let us determine if the character at memory location LOC is equal to 0, 1, or 2: ZOT LD CP JP CP JP CP JP JP A. (LOC) 00 Z, ZERO 01 Z, ONE 02 Z, TWO NOTFND GET CHARACTER IS IT A ZERO? JUMP TO ROUTINE A ONE? A TWO? FAILURE
We simply read the character, then use the CP instruction to check its value. Let us run a different test now. BRACKET TESTING Let us determine if the ASCII character at memory location LOC is a digit between 0 and 9: BRACK LD AND CP JR CP JR CP OUT RET A. (LOC) 7FH 30H C, OUT 39H NC, OUT A EXIT GET CHARACTER MASK OUT PARITY BIT ASCII 0 CHAR TOO LOW? ASCII 9 CHAR TOO HIGH? FORCE ZERO FLAG
ASCII "0" is represented in hexadecimal by "30" or by "BO", depending upon whether the parity bit is used or not. Similarly, ASCII "9" is represented in hexadecimal by "39" or by "B9". The purpose of the second instruction of the program is to delete bit 7, the parity bit, in case it was used, so that the program is applicable to both cases. The value of the character is then compared to the ASCII values for "0" and "9". When using a comparison instruction, the Z flag is set if the comparison succeeds. The carry bit is set in the case of borrow, and reset otherwise. In other words, when using the CP Instruction, the carry bit will be set if the value of the literal that appears
523
PROGRAMMING THE Z80 in the instruction is greater than the value contained in the accumulator. It will be reset ("0") if less than or equal. The last instruction. CP A, forces a "1" into the Z flag. The Z flag is used to indicate to the calling routine that the character in CHAR was indeed in the interval (0, 9). Other conventions can be used, such as loading a digit in the accumulator in order to indicate the result of the test. Exercise 8.4: Is the following program equivalent to the one above?: A. (CHAR) LD SUB 30H M, OUT JP SUB 10 P, OUT JP ADD 10
Exercise 8.5: Determine if an ASCII character contained in the accumulator is a letter of the alphabet.
When using an ASCII table, you will notice that parity is often used. For example, the ASCII for "0" is "0110000", a 7-bit code. However, if we use odd parity, for example, we guarantee that the total number of ones in a word is odd; then the code becomes: "10110000". An extra "1" is added to the left. This is " BO " in hexadecimal. Let us therefore develop a program to generate parity. PARITY GENERATION This program will generate an even parity with bit position 7: PARITY LD A, (CHAR) GET CHARACTER CLEAR PARITY BIT AND 7FH IP PE, OUT CHECK IF PARITY ALREADY EVEN SET PARITY BIT OR 8014 STORE RESULT OUT LID (LOC), A The program uses the internal parity detection circuit available in the Z80. The third instruction: JP PE, OUT checks whether parity of the word in the accumulator is already even. This instruction will succeed if the parity is even, "PE", and will exit. If the parity is not even. i.e., if the jump instruction failed, then the parity is odd, and a "1" must be written in bit position 7. This is the
524
APPLICATION EXAMPLES purpose of the fourth instruction: OR 80H Finally, the resulting value is saved in memory location LOC. Exercise 8.6: The above problem was too simple to solve, using the internal parity detection circuitry. As an exercise, you are requested to solve the same problem without using this circuitry. Shift the contents of the accumulator, and count the number of I 's in order to determine which bit should be written into the parity position. Exercise 8.7: Using the above program as an example, verify the parity of a word. You must compute tire correct parity, then compare it to the one expected.
AND OFH
LD
Exercise 8.8: Write a program to convert BCD to ASCII. Exercise 8.9: Write a program to convert BCD to binary (more difficult). HinuN, N, N, N. in BCD is (((N, x 10) + N,) x 10 + x 10 + No in binary. To multiply by 10, use a left shift ( = x 2), another left shift ( = x4), an ADC (= x 5), another left shift ( = x 10). In full BCD notation, the first word may contain the count of BCD digits, the next nibble contain the sign, and every successive nibble contain a BCD digit (we assume no decimal point). The last nibble of the block may be unused.
525
PROGRAMMING THE Z80 "B") into the left nibble: AND OFH ADD A, 30H A, 3AH CP M, OUT JP ADD A, 7
hex digits in A).
FINDING THE LARGEST ELEMENT OF A TABLE The beginning address of the table is contained at memory address BASE. The first entry of the table is the number of bytes it contains. This program will search for the largest element of the table. Its value will be left in A. and its position will be stored in memory location INDEX. This program uses registers A, F, B, H and L, and will use indirect addressing, so that it can search a table anywhere in the memory (see Figure 8.1). MAX TABLE ADDRESS LD HL, BASE NBR OF BYTES IN TABLE LD B, (HL) LD A, 0 CLEAR MAXIMUM VALUE INC HL INITIALIZE INDEX LD (INDEX), HL NEXT ENTRY LOOP COMPARE ENTRY CP (HL) JR NC, NOSWITCH JUMP IF LESS THAN MAX LD A, (HL) LOAD NEW MAX VALUE LD (INDEX), HL LOAD NEW MAX VALUE NOSWITCH INC HL POINT TO NEXT ENTRY DECREMENT COUNTER DEC B JR NZ, LOOP KEEP GOING IF NOT ZERO RET
This program tests the nth entry first. If it is greater than 0, the entry goes in A, and its location is remembered into INDEX. The (n-1)st entry is then tested, etc. This program works for positive integers.
Exercise 8.11: Modify the program so that it works also for negative numbers in two's complement. Exercise 8.12: Will this program also work for ASCII characters? Exercise 8.13: Write a program which will sort n numbers in ascending
526
APPLICATION EXAMPLES
CURRENT MAX
COUNTER
EIL
INCREASING ADDRESSES
SUM OF N ELEMENTS This program will compute the 16-bit sum of N positive entries of a table. The starting address of the table is contained at memory address BASE. The first entry of the table contains the number of elements N. The 16-bit sum will be left in memoy locations SUMLO and SUMHI. If the sum should require more than 16 bits, only the lower 16 will be kept. (The high order bits are said to be truncated.) This program will modify registers A, F, B, H. L, IX. It assumes 256 elements maximum (see Figure 8.2). SUMN LD HL, BASE LD B, (HL) INC HL LD IX, SUMLO POINT TO TABLE BASE READ LENGTH INTO COUNTER POINT TO FIRST ENTRY POINT TO RESULT, LOW
SUMIG
527
PROGRAMMING THE Z80 LD (IX+ 0), 0 LD (IX+ 1), 0 ADLOOP LD A, (HL) ADD A, (IX + 0) LD (IX +0), A JR NC, NOCARRY INC (IX + I) NOCARRY INC HL DEC B JR NZ, ADLOOP RET
B COUNT
CLEAR RESULT LOW AND HIGH GET TABLE ENTRY COMPUTE PARTIAL SUM STORE IT AWAY CHECK FOR CARRY ADD CARRY TO HIGH BYTE POINT TO NEXT ENTRY DECREMENT BYTE COUNT KEEP ADDING TILL END
K
BASE Er I-
BASE
HL
IX
SUMLO SUMH I
Fig. 8.2: Sum of N Elements This program is straightforward and should be self-explanatory.
Exercise 8.15: Modify this prograin to: acompute a 24-bit sum Etcompute a 32-bit suet c detect any overflow.
A CHECKSUM COMPUTATION A checksum is a digit or set of digits computed from a block of successive characters. The checksum is computed at the time the data is
528
APPLICATION EXAMPLES stored and put at the end. In order to verify the Integrity of the data, the data is read, then the checksum is recomputed and compared against the stored value. A discrepancy indicates an error or a failure. Several algorithms are used. Here, we will exclusive-OR all bytes in a table of N elements, and leave the result in the accumulator. As usual, the base of the table is stored at address BASE. The first entry of the table is its number of elements N. The program modifies A, F, B, H, L. N must be less than 256 CHKSUM LD HL, BASE LOAD ADDRESS OF TABLE INTO HL LD B, (HL) GET N = LENGTH XOR A CLEAR CHECKSUM INC HL POINT TO FIRST ELEMENT CHLOOP XOR (HLI COMPUTE CHECKSUM INC HL POINT TO NEXT ELEMENT DEC B DECREMENT COUNTER JR NZ, CHLOOP DO IT AGAIN IF NOT END LD (CHECKSUM),A PRESERVE CHECKSUM RET COUNT THE ZEROES This program will count the number of zeroes in our usual table, and leave it in location TOTAL. It modifies A, B, C, H, L, F. ZEROS LD HL, BASE POINT TO TABLE LD B, (HL) READ LENGTH INTO COUNTER LD C, 0 ZERO TOTAL INC HL POINT TO FIRST ENTRY ZLOOP LD A, (HL) GET ELEMENT OR 0 SET ZERO FLAG JR NZ, NOTZ IS IT A ZERO? INC C IF SO, INCREMENT ZERO COUNT NOTZ INC HL POINT TO NEXT ENTRY DEC B DECREMENT LENGTH COUNTER JR NZ, ZLOOP LD A,C LD (TOTAL), A SAVE IT
Exercise 8.16: Modify this program to count athe number of stars (the character "") bthe number of letters of the alphabet cthe number of digits between "0" and "9"
529
PROGRAMMING THE Z80 BLOCK TRANSFER Let us pick up every third entry in the source block at address FROM and store it into a block at address TO: FER3 LD LD LD LOOP LDI INC INC JP HL, FROM DE, TO BC, SIZE HL HL PE, LOOP SET UP POINTERS AUTOMATED TRANSFER SKIP 2 ENTRIES
BCD BLOCK TRANSFER We will push up BCD digits in the memory, i.e, shift 4-bit nibbles (see Figure 8 .3). The program appears below:
COUNT
I BLOCK I
COUNT
einzairmatorz.
Fig. 8.3: BCD Block Transfer -The Memory DMOV LD B, COUNT LD HL, BLOCK A=0 XOR A LOOP RLD POINT TO NEXT BYTE DEC HL DJNZ LOOP DEC COUNT LOOP UNTIL ZERO 530
APPLICATION EXAMPLES The program uses the RLD instruction, which we have not used yet. RLD rotates a BCD digit left between A and (HL). (HL) or M designate the contents of the memory location pointed to by H and L. M LOW goes into M HIGH M HIGH goes into A LOW A LOW goes into M LOW Here, "low" and "high" refer to a 4-bit nibble. In order to use the powerful DJNZ instruction, register B is used as the digit counter. HL is set to point to the beginning of the block. A is used to store the left digit displaced by each rotation between two successive accesses to the block. By convention, "0" will be entered at the bottom of the block.
RLA RET
A, B LD BOTH SIGNS NEG (IY + I) CP RET NZ A, (IX) LD CP (IY) RET The program first tests the signs of Ni and N2. If Ni is negative, a
531
MEMORY
IX
/ HIGH ADDRESSES IY
The same could have been done for NI, except that we will need the value of NI shortly. It is therefore simpler to read NI from memory and preserve it into B: COMP LD B, (IX + 1)
It is necessary to preserve NI into B because the AND may destroy the contents of A: LD A, B AND 80H Note also that a conditional return is used (line 6): RET NZ
532
APPLICATION EXAMPLES This is a powerful feature of the Z80 which simplifies programming. Note that the comparison instruction executes directly on the contents of memory, in indexed mode: CP (IY + 1)
When comparing the two numbers, the most significant byte is compared first, the least significant one second. Note the extensive use of the indexing mechanism in this program, which results in efficient code. BUBBLE-SORT Bubble-sort is a sorting technique used to arrange the elements of a table in ascending or descending order. The bubble-sort technique derives its name from the fact that the smallest element "bubbles up" to the top of the table. Every time it "collides" with a "heavier" element, it jumps over it. A practical example of a bubble-sort is shown on Figure 8.5 The list to be sorted contains: (10, 5, 0, 2, 100), and must be sorted in descending order ("0" on top). The algorithm is simple, and the flowchart is shown on Figure 8.7 The top two (or else bottom two)elements are compared. If the lower one is less ("lighter") than the top one, they are exchanged. Otherwise not. For practical purposes, the exchange, if it occurs, will be remembered in a flag called "EXCHANGED". The process is then repeated on the next pair of elements, etc., until all elements have been compared two by two. This first pass is illustrated by steps 1, 2, 3, 4, 5, 6 on Figure 8.5, going from the bottom up. (Equivalently we could go from the top down.) If no elements have been exchanged, the sort is complete. If an exchange has occurred, we start all over again. Looking at Figure 8.6, it can be seen that four passes are necessary in this example. The process is simple, and is widely used. One additional complication resides in the actual mechanism of the exchange. When exchanging A and B, one may not write A = 13 B = A as this would result in the loss of the previous value of A (try it on an example).
533
to- 1=.4
1=5
2 100 2) 0 NO CHANGE 0
10 0 5 2 1CO EXCHANGED
0
0 10 5 2 TOO IC002: NO CHANGE 0 1=4 1=5
O
END OF PASS I
10 2 5 103 EXCHANGED
0
0 2 10 5 100 2)0: NO CHANGE 12 END OF PASS 2 1=1 1=2
0 2 10 5 100 EXCHANGED
534
APPLICATION EXAMPLES 0
2 10 5 100 1020 5 NO CHANGE 13 I .1
0
2 10 5 100 5. 10 EXCHANGE, la I -3 1=4
0
2
10 1CO EXCHANGED IS
I 5
1= I -441- 1 = 2
0 2 5
1 -3 10 100
10
100
10 100
.111- 1 = 4 1=5
EXCHANGED = 0
R AD ELEMENT E(I)
DECREMENT I
YES
READ F(1)
DONE
YES
EXCHANGED = I
536
APPLICATION EXAMPLES
EXCHANGE/NOT
FLAG IN H
PTR
COUNT
TEMP LIST
NEXT
CURRENT LIST
ICOUNT IX
The register and memory assignments are shown on Figure 8.8, and the program is:
SET FLAG, H
D =CURRENT ENTRY E =NEXT ENTRY COMPARE GO TO NOSWITCH IF CURRENT 3 NEXT STORE NEXT INTO CURRENT STORE CURRENT INTO NEXT EXCHANGED FLAG = I
537
NEXT ENTRY DEC B, CONTINUE UNTIL ZERO EXCHANGED =1? RESTART IF FLAG =1
SUMMARY Common utility routines have been presented in this chapter which use combinations of the techniques we have described in the previous chapters. They should allow you to start designing your own programs now. Many of these routines have used a special data structure, the table. Other possibilities exist for structuring data, and will now be reviewed.
538
9 DATA STRUCTURES
PART I THEORY
INTRODUCTION
The design of a good program involves two tasks: algorithm design and data structures design. In most simple programs, no significant data structures are involved, so the main objective in learning programming is designing algorithms and coding them efficiently in a given machine language. This is what we have accomplished here. However, designing more complex programs also requires an understanding of data structures. Two data structures have already been used throughout the book: the table and the stack. The purpose of this chapter is to present other, more general, data structures that you may want to use. This chapter is completely independent of the microprocessor, or even the computer, selected. It is theoretical and involves the logical organization of data in the system. Specialized books exist on the topic of data structures, just as specialized books exist on the subject of efficient multiplication, division or other usual algorithms. This chapter, therefore, will be limited to essentials only. It does not claim to be complete. The most common data structures will now be reviewed.
POINTERS
A pointer is a number which is used to designate the location of the actual data. Every pointer is an address. However, every address is not necessarily called a pointer. An address is a pointer only if it points at
539
PROGRAMMING THE Z80 some type of data or at structured information. We have already encountered a typical pointer: the stack pointer, which points to the top of the stack (or usually just over the top of the stack). We will see that the stack is a common data structure, called an LIFO structure. As another example, when using indirect addressing, the indirect address is always a pointer to the data that one wishes to retrieve. Exercise 9.1: Examine Fig. 9.1. At address 15 in the memory, there is a pointer to Table T. Table T starts at address 500. What are the actual contents of the pointer to T?
0
15
POINTER TO T
16
500 TABLE T
Sequential Lists
A sequential list, or table, or block, is probably the simplest data structure, and is one that we have already used. Tables are normally ordered in Function of a specific criterion, such as alphabetical ordering or numerical ordering. It is then easy to retrieve an element in a table, using, for example, indexed addressing, as we have done. A block normally refers to a group of data which has definite limits but whose contents are not ordered. It may contain a string of characters; it may
540
DATA STRUCTURES be a sector on a disk; or it may be some logical area (called segment) of the memory. In such cases, it may not be easy to access a random element of the block. In order to facilitate the retrieval of blocks of information, directories are used. Directories A directory is a list of tables or blocks. For example, the file system will normally use a directory structure. As a simple example, the master directory of the system may include a list of the users' names. This is illustrated in Figure 9.2. The entry for user "John" points to John's file directory. The file directory is a table which contains the names of all of John's files and their location. This is, again, a table of pointers. In this case, we have just designed a two-level directory. A flexible directory system will allow the inclusion of additional intermediate directories, as may be found convenient by the user.
USER DN[CAY
XAMil HUNITICMAY
DATA
GMA
Fig. 9.2: A Directory Structure Linked List In a system there are often blocks of information which represent data, events, or other structures which cannot be moved around eas-
541
PROGRAMMING THE Z80 ily. If they could, we would probably assemble them in a table in order to sort or structure them. The problem now is that we wish to leave them where they are and still establish an ordering among them such as first, second, third, fourth. A linked list will be used to solve this problem. The concept of a linked list is illustrated by Figure 9.3. On the illustration, we see that a list pointer, called FIRSTBLOCK, points to the beginning of the first block. A dedicated location within Block I such as, perhaps, the first or the last word in it, contains a pointer to Block 2, called PTRI. The process is then repeated for Block 2 and Block 3. Since Block 3 is the last entry in the list, PTR3, by convention, either contains a special "nil" value, or points to itself, so that the end of the list can be detected. This structure is economical, as it requires only a few pointers (one per block) and frees the user from having to physically move the blocks in the memory.
BLOCK 3
Fig. 9.3: A Linked List Let us examine, for example, how a new block will be inserted. This is illustrated by Figure 9.4. Let us assume that the new block is at address NEWBLOCK, and is to be inserted between Block I and Block 2. Pointer PTRI is simply changed to the value NEWBLOCK, so that it now points to Block X. PTRX will contain the former value of PTRI, i.e., it will point to Block 2. The other pointers in the structure are left unchanged. We can see that the insertion of a new block has simply required updating two pointers in the structure. This is clearly efficient. Exercise 9.2: Draw a diagram showing how Block 1 would be removed from this structure.
NEW BLOCK a-
BLOCK X
FIRST BLOCK
BLOCK I
BLOCK2
BLOCK 3
EEL
542
DATA STRUCTURES Several types of lists have been developed to facilitate specific types of access, insertions, and deletions to and from the list. Let us examine some of the most frequently used types of linked lists. Queue A queue is formally called a FIFO, or first-in-first-out list. A queue is illustrated in Figure 9.5. To clarify the diagram, we can assume, for example, that the block on the left is a service routine for an output device, such as a printer. The blocks appearing on the right are the request blocks from various programs or routines, to print characters. The order in which they will be serviced is the order established by the waiting queue. It can be seen that the first event which will obtain service is Block 1, the next one is Block 2, and the following one is Block 3. In a queue, the convention is that any new event arriving in the queue will be inserted at the end. Here it will be inserted after PTR3. This guarantees that the first block to be inserted in the queue will be the first one to be serviced. It is quite common in a computer system to have queues for a number of events whenever they must wait for a scarce resource, such as the processor or some input/output device.
6LOC6 ]
FIR
543
PROGRAMMING THE Z80 Stack The stack structure has already been studied in detail throughout the book. It is a last-in-first-out structure (LIFO). The last element deposited on top is the first one to be removed. A stack may either be implemented as a sorted block, or it may be implemented as a list. Because most stacks in microprocessors are used for high-speed events, such as subroutines and interrupts, a continuous block is usually allocated to the stack instead of using a linked list. Linked List vs. Block Similarly, the queue could be implemented as a block of reserved locations. The advantage of using a continuous block is fast retrieval and the elimination of the pointers. The disadvantage is that it is usually necessary to dedicate a fairly large block to accommodate the worst-case size of the structure. Also, it makes it difficult or impractical to insert or remove elements from within the block. Since memory is traditionally a scarce resource, blocks have usually been reserved for fixed-size structures or structures requiring the maximum speed of retrieval, such as the stack. Circular List "Round robin" is a common name for a circular list. A circular list is a linked list in which the last entry points back to the first one. This is illustrated in Figure 9.6. In the case of a circular list, a current-block pointer is often kept. In the case of events, or programs, waiting for service, the current-event pointer will be moved by one position to the left or to the right every time. A round robin usually corresponds to a structure in which all blocks are assumed to have the same priority. However, a circular list may also be used as a subcase of other structures simply to facilitate the retrieval of the first block after the last one, when performing a search. As an example of a circular list, a polling program usually goes in a round robin fashion, interrogating all peripherals and then coming back to the first one. Trees Whenever a logical relationship exists among all elements of a structure (this is usually called a syntax), a tree structure may be used. A simple example of a tree structure is a descendant, or genealogical, tree.
544
DATA STRUCTURES
EVENT i
EVENT 2
EVEN N
CURRENT EVENT
This is illustrated in Figure 9.7. It can be seen that Smith has two children: a son, Robert, and a daughter, Jane. Jane, in turn, has three children: Liz, Tom and Phil. Tom, in turn, has two more children: Max and Chris. However, Robert, on the left of the illustration, has no descendants. This is a structured tree. We have, in fact, already encountered an example of a simple tree in Figure 9.2. The directory structure is a twolevel tree. Trees are used to advantage whenever elements may be classified according to a fixed structure. This facilitates insertion and retrieval. In addition, they may establish groups of information in a structured way which may be required for later processing, such as in a compiler or interpreter design.
Fig.
Doubly-Linked Lists Additional links may be established between elements of a list. The
545
simplest example is the doubly-linked list. This is illustrated in Figure 9.8. We can see that we have the usual sequence of links from left to right, plus another sequence of links from right to left. The goal is to allow easy retrieval of the element just before the one which is being processed, as well as just after it. This costs an extra pointer per block.
BLOCK I
BLOCK 2
BLOCK 3
SEARCHING AND SORTING Searching and sorting elements of a list depends directly on the type of structure which has been used for the list. Many searching algorithms have been developed for the most frequently used data structures. We have already used indexed addressing. This is possible whenever the elements of a table are ordered in function of a known criterion. Such elements may then be retrieved by their numbers. Sequential searching refers to the linear scanning of an entire block. This is clearly inefficient but may have to be used when no better technique is available, for lack of ordering of the elements. Binary, or logarithmic, searching attempts to find an element in a sorted list by dividing the search interval in half at every step. Assuming that we are searching an alphabetical list, one might start, for example, in the middle of a table and determine if the name we are looking for is before or after this point. If it is after this point, we will eliminate the first half of the table and look at the middle element of the second half. We compare this entry again to the one we are looking for, and we restrict our search to one of the two halves, and so on. The maximum length of a search is then guaranteed to be log2n, where n is the number of elements in the table. Many other search techniques exist.
SECTION SUMMARY
This section was intended as only a brief presentation of usual data structures which may be used by a programmer. Although most com-
546
DATA STRUCTURES mon data structures have been organized in types and given a name, the overall organization of data in a complex system may use any combination of them, or require the programmer to invent more appropriate structures. The array of possibilities is only limited by the imagination of the programmer. Similarly, a number of well-known sorting and searching techniques have been developed for coping with the usual data structures. A comprehensive description is beyond the scope of this book. The contents of this section were intended to stress the importance of designing appropriate section structures for the data to be manipulated and to provide the basic tools to that effect. Actual programming examples will now be presented in detail.
547
INTRODUCTION
Actual design examples will be presented here for typical data structures: table, sorted list, linked list. Practical searching and insertion and deletion algorithms will be programmed for these structures. The reader interested in these advanced programming techniques is encouraged to analyze in detail the programs presented in this section. However, the beginning programmer may skip this section initially, and come back to it when he feels ready for it. A good understanding of the concepts presented in the first part of this chapter is necessary to follow the design examples. Also, the programs will use all of the addressing modes of the Z80, and integrate many of the concepts and techniques presented in the previous chapters. Three structures will now be introduced: a simple list, an alphabetical list and a linked-list plus directory. For each structure, three programs will be developed: search, enter and delete.
C C C
D
3-byte label Data
548
DATA STRUCTURES
ENTLEN
LENG TH OF ENTRY
TABUN
NUMBER OF ENTRIES
TAB BASE
ENTRY
M BYTES
ENTLEN
ENTLEN
549
PROGRAMMING THE Z80 Each element, or "entry", includes a 3-byte label, and an n-byte block of data, with n between 1 and 253. Thus, at most, each entry uses one page (256 bytes). Within each list, all elements have the same length (see Figure 9.10). The programs operating on these two simple lists use some common variable conventions: ENTLEN is the length of an element. For example, if each element has 10 bytes of data, ENTLEN = 3 + 10 = 13 TABASE is the base of the list or table in the memory POINTR is a running pointer to the current element OBJECT is the current entry to be located, inserted or deleted TABLEN is the number of entries. All labels are assumed to be distinct. Changing this convention would require a minor change in the programs.
IRE
SP.CI
550
DATA STRUCTURES
A SIMPLE LIST The simple list is organized as a table of n elements. The elements are not sorted (see Figure 9.11). When searching, one must scan through the list until an entry is found or the end of the table is reached. When inserting, new entries are appended to the existing ones. When an entry is deleted, the entries in higher memory locations, if any, will be shifted up to keep the table continuous. Searching A serial search technique is used. Each entry's label field is compared in turn to the OBJECT's label, letter by letter. The running pointer POINTR is initialized to the value of TABASE.
SEARCH
COUNTER =
COUNTER = COUNTER - I
FAILURE EXIT
551
The search proceeds in the obvious way, and the corresponding flowchart is shown on Figure 9.12. The program appears on Figure 9.16 at the end of this section (program "SEARCH"). A sample run of the program is shown in Figure 9.17.
Inserting
When inserting a new element, the first available memory block of (ENTLEN) bytes at the end of the list is used (see Figure 9.11). The program first checks that the new entry is not already in the list (all labels are assumed to be distinct in this example). If not, it increments the list length TABLEN, and moves the OBJECT to the end of the list. The corresponding flowchart is shown in Figure 9.13. The program is shown in Figure 9.16. It is called "NEW" and resides at memory locations 0135 to 015E. The index register IY points to the source. HL and DE are destination pointers.
XII
INSERT OBJECT
ENO
552
DATA STRUCTURES
Deleting
In order to delete an element from the list, the elements following it in the list at higher addresses are merely moved up by one element position. The length of the list is decremented. This is illustrated on Figure 9.14. The corresponding program is straightforward and appears on Figure 9.16. It is called "DELETE", and resides at memory addresses 015F to 0187. The flowchart is shown in Figure 9.15. Memory location TEMPTR is used as a temporary pointer pointing to the element to be moved up. During the transfer, POINTR always points to the "hole" in the list, i.e., the destination of the next block transfer. The Z flag is used to indicate a successful deletion upon exit. Note how the LDIR instruction is used for efficient automated block transfer (refer to address 0178 in Figure 9.16). LD A, B BLOCK COUNTER NEWBLOC LD BC, (ENTLEN ) BLOCK LENGTH LDIR DEC A JP NZ, NEWBLOC
BEFORE
AFTER
O
DELETE
0
0 0
MOVE
TEMPTR
0 0 0 0 0
O
0
MOVE
553
FIND ENTRY
NO FOUND? OUT
YES EXIT
NO COUNT = 0? OUT
554
DATA STRUCTURES
0000 1011371 10109/ 10113A1 10IBC1 0100 0102 0105 0106 0107 0100 010C 010F 0112 0113 0118 011B 011E 0121 0124 0127 0120 0129 012D 012F 0132 0134 1600 JAB901 A7 CB 47 DD2A0A01 D07E00 FDBE00 C2270I 1D7C01 FDDE01 C22701 m7E02 FDBE02 CA3201 05 CB ED5P0701 DD19 C30001 16FF C9 ENTLEN TADLEN TADASE TEMP SEARCH ORG DL DL DL DL LD LD 0100H ENDER ENDER-12 ENDER+3 ENDERI5 11.0 111.1TABLEN1 A Z Bra 1%11701105E1 ArLIX+01 fIY+01 NZ.NEXTONE A.II%Ill 119111 NZ,NEXTONE ApCIX421 119421 ZrFOUND 11 Z DE.(EHTLENI IXrDE LOOP DrOFFH ;CLEAR 0 /CHECK FOR A ZERO TABLE LENGTH MET FLAGS (STORE TABLE LENGTH ;PUT BASE ADDR. IN IX :CHECK FIRST LETTER OF ENTRY !CHECK 2110 LETTER /CHECK 3RD LETTER ;EXIT IF ALL LETTERS MATCH /DECREMENT TABLE LENGTH COUNTER (EXIT IF AT END OF TABLE ;SET IX TO NEXT ENTRY ADDR. /TRY AGAIN ;SET D TO SNOW TX CONTAINS AIMR. r..OF ENTRY IN TABLE
AND
RET LD LD LD CF
LOOP
JP
LD CP JF LD CP JF NEXTONE DEC RET LD ADD JP FOUND LD RET
0135 0138 0139 013C 013F 0140 0141 0144 0146 0149 01411 014E 014F 0151 0155 0157 0150 0159 015P 015E
CD0001 II cnsEos 3A0901 SF 3C 328901 1600 2A8A01 ED4118701 41 19 !OFD 1400701 FDE5 DI EP EDBO OIFFFF C9
HEW
LOOPE
OUTE
SEARCH n ZpOUTE ArlTABLEN1 ErA A (TABLENI.A 0.0 HLr/TABASE/ BCr1ENTLEN1 B.0 HL.BE LOOPE Kr/ENT/in/ IY DE DE.HL BC.OFFFFH
/SEE IF OBJECT IS THERE IIF D WAS FF. EXIT ;LOAD E WITH TABLE LENOTH /INCREMENT TABLE LENGTH
;SET B TO LENGTH OF AN ENTRY ;ADD HL TO CENTLENnTABLEN1 MOUE IY TO DE MOUE MEMORY FROM OBJECT TO END 1..OF TABLE
015F 0162 0163 0166 0169 016A 016D 016E 0171 0173 0174 0177 0178 0179 0170 017F 0100 0103 0186 0107
C00001 14 020601 3A0901 3D 328901 05 CA8301 DIES DI 2A870I 19 70 ED4BE1701 EDBO 3D C27901 OIFFFF C9 (00001
DELETE
CALL INC
JP
LD DEC LD DEC JP PUSH POP LD ADD LD NEOPLOC LD LAIR DEC JP EXIT LP OUT WET
SEARCH D 117rOWT ApITABLEN1 A 1TABLEP-OrA ZrEXIT IX DE IlLrIENTLEN; HL,DE ArB DCr1ENTLE111 A tarNELIBLOC BCrOFFFFH
:DECREMENT TABLE LENGTH ID NOUNS OF ENTRIES LEFT IN TABLE i..AFTER ONE TO BE DELETED
;NINE IX TO DE
;SET It ONE ENTRY AHEAD OF DE /SET BLOCh COUNTER ;SET BLOCK LENGTH COUNTER ISHIFT 1 ENTRY OF TABLE ;SHIFT ANOTHER BLOCK ;SHOW THAT IT WAS DONE
ENDER
END
555
IF 41 4F 4E 4E 00 00 00
4E 44 4D 43 54 00 00 00
31 32 33 34 35 00 00 00
31 32 33 34 35 00 00 00
31 32 33 34 35 00 00 00
31 32 33 34 35 00 00 00
P.0196 0196 Run 'INSERT' Dale coal ginsiion -011400 0100 53 0410 00 0420 DO 0430 00 0440 00 0450 00 0460 00 0470 00 eta program run 4F 00 00 00 00 00 00 00 4E 00 00 00 00 00 CO 00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 31-31 00-00 00-00 00-00 00-00 00-00 00-00 00-00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 CO 00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 SON1111111111
P..0196 o176 Run 'INSERT' Table configuration slier second lawn -DM400 0100 53 0410 32 0420 00 0430 00 0440 00 0450 00 0460 00 0470 OD 4F 32 00 CC 00 OD 00 00 4E 32 DO CC 00 00 00 00 31 32 00 00 00 00 00 00 31 32 00 00 00 00 00 00 31 32 00 00 00 00 00 00 31 32 00 00 00 00 00 00 31-31 32-32 00-00 00-00 00-00 00-00 00-00 00-00 31 32 00 00 00 00 00 00 31 00 00 00 00 00 00 00 31 00 00 00 00 00 00 DO 31 00 00 00 00 00 00 00 44 00 00 00 00 00 00 00 41 00 00 00 00 00 00 00 44 00 00 00 00 00 00 00 SON1111111111DAD
-011400 0400 53 0410 32 0420 34 0430 33 0440 35 0450 00 0460 00 0470 00
(Moreinsertionsl
31 32 34 41 00 00 00 00 31 32 34 4E 00 00 00 00 31 32 34 54 00 00 00 00 31-31 32-32 40-4F 35-35 00-00 00-00 00-00 00-00 31 32 40 35 00 00 00 00
TRW coal/under' .)ter 'ever.) Inert. 31 55 33 35 00 00 00 00 31 4E 33 35 00 00 00 00 31 43 33 35 00 00 00 00 44 34 33 35 00 00 00 00 41 34 33 35 00 00 00 00 44 34 33 35 00 00 DO 00 SON11111111110A8 UNC444 4 444444 MO11333333 33331017555555555 5
4F 32 34 33 00 00 00 00
4E 32 34 33 00 00 00 00
31 32 34 33 00 00 00 00
DATA STRUCTURES
-DR N
Neahicrcumen0 0.40 DC=02FF DE=FFOO HL=0341. S=0100 P-0193 0193' CALL 0135 A'=00 10.0000 10=0000 10.0000 2=0427 Y.0320 (.00 10135'1
Address of Object
-0196/199 P=0199 0199' -DM400 0400 53 0410 32 0420 34 0430 35 0440 35 0450 00 0460 00 0470 00 Run 'DELETE' 4E 32 34 35 DO 00 00 00 31 32 34 35 00 00 00 00 Takconftgur41100 aficrdrkllo0 4F 32 34 35 00 00 OD 00 31 32 34 41 00 00 00 Oa 31 32 34 4E 00 00 00 00 31 32 34 54 00 00 00 00 31-31 32-32 41-4E 35-35 00-00 00-00 00-00 00-00 31 32 54 35 00 00 00 00 31 55 35 35 00 00 00 00 AI 31 4E 43 35 35 35 35 00 00 00 00 00 00 00 00 44 34 35 35 00 00 00 00 41 34 35 35 00 00 00 00 44 34 35 35 00 00 00 00 SONI111111111DAD UNC444 555555 5555010555555555 5
-SY A=0240 340 -6196/199 P.0199 0199' -00400 0400 53 0410 32 0420 34 0430 35 0440 35 0450 00 0460 00 0470 00
4F 4E 31 32 32 32 34 34 34 35 35 35 00 00 00 00 00 00 00 OD 00 00 00 00
31 32 34 41 00 00 00 00
31 32 34 4E 00 00 00 DO
31 32 34 54 00 00 00 00
31 32 54 35 00 00 00 00
31 31 31 55 4E 43 35 35 35 35 35 35 00 00 OD 00 00 00 00 00 00 00 00 00
44 34 35 35 00 OD 00 00
41 34 35 35 00 DO 00 00
44 34 35 35 00
00
00 DO
Memory location 'TABLEN' shows true length of table Run 'SEARCH' for deleted Object Dshows that Object was not found
- IM Z N
A.55 DC.00FF DE=00 D MA=0441 S=0100 P=0193 0193' 0 ..00 D'.0000 11'=0000 10-0000 2.041A Y.0340 1=00
CALL
0135 (0135'1
557
ALPHABETIC LIST The alphabetic list, or "table," unlike the previous one, keeps all its elements sorted in alphabetic order. This allows the use of faster search techniques than the linear one. A binary search is used here. Searching The search algorithm is a classic binary search. Let us recall that the technique is essentially analogous to the one used to find a name in a telephone book. One usually starts somewhere in the middle of the book, and then, depending on the entries found there, goes either backwards or forward to find the desired entry. This method is fast and reasonably simple to implement. The binary seach flowchart is shown in Fig. 9.18, and the program is shown in Fig. 9.23. This list keeps the entries in alphabetical order and retrieves them by using a binary or "logarithmic" search. An example is shown in Figure 9.19. The search is somewhat complicated by the need to keep track of several conditions. The major problem to be avoided is searching for an object that is not there. In such a case, the entries with immediately higher and lower alphabetic values could be alternately tested forever. To avoid this, a flag is maintained in the program to preserve the value of the carry flag after an unsuccessful comparison. When the INCMNT value, which shows by how much the pointer will next be incremented reaches a value of "1", another flag called "CLOSENOW", which we will abbreviate to "CLOSE", is set to the value of the COMPRES flag Thus, since all further increments will be "1", if the pointer goes past the point where the object should be, COMPRES will no longer equal CLOSE and the search will terminate. This feature also enables the NEW routine to determine where the logical and physical pointers are located, relative to where the object will go. Thus, if the OBJECT searched for is not in the table, and the running pointer is incremented by one, the CLOSE flag will be set. On the next pass of the routine, the result of the comparison will be opposite to the previous one. The two flags will no longer match, and the program will exit indicating "not found".
558
DATA STRUCTURES
3
FLAGS .. 0
3
POINT TO TABLE BASE
f
INCREMENT VALUE = INCREMENT VALUE/2
(ENTRY)
FOUND
559
(NEXT TEST)
LUST NEI
CLOSEPKW/ COMPINS
NOT 'Our
RS
IF
ADO
ti
UPOATF pONIERS
'EMIR VI
.ES
Tq
NTOATL TVINil
560
DATA STRUCTURES
The other major problem that must be dealt with is the possibility of running off one end of the table when adding or subtracting the increment value. This is solved by performing a test "add" or "subtract" using the logical pointer and length value which record the actual number of entries, not the physical positions in memory used by the physical pointers. In summary, two flags are used by the program to memorize infor-
(0121)
LD SRL ADC LD
A, C A 0 C, A
OBJECT
TABASE
IND) TES
INOI
%YE
561
PROGRAMMING THE ZBO mation: COMPRES and CLOSE. The COMPRES flag is used to preserve the fact that the carry was either "0" or "1" after the most recent comparison. This determines if the element under test was larger or smaller than the one with which it was compared. The C indicates the relation. Whenever the carry C was "1", and the element was smaller than the object COMPRES is set to "1". Whenever the carry C was "0", indicating that the element was greater than the object, COMPRES will be set to "FF". The second flag used by the program is CLOSE. This flag is set equal to COMPRESS when the search increment INCMNT becomes equal to "I". It will detect the fact that the element has not been found if COMPRES is not equal to CLOSE the next time around. Other variables used by the program are: LOGPOS which indicates the logical position in the table (element number) INCMNT which represents the value by which the running pointer will be incremented or decremented if the next comparison fails TABLEN represents as usual the total length of the list. LOGPOS and INCMNT will be compared to TABLEN in order to assure that the limits of the list are not exceeded. The program called "SEARCH" is shown on Figure 9.23. It resides at memory locations 0100 to OICF, and deserves to be studied with care, as it is much more complex than in the case of a linear search. An additional complication is due to the fact that the search interval may at times be either even or odd. When it is odd, a correction must be introduced. (It cannot, for instance, point to the middle element of a four-element list.) When it is odd, a "trick" is used to point to the middle element: the division by 2 is accomplished by a right shift. The bit "falling off" into the carry after the SRL instruction will be "1" if the interval was odd. It is merely added to the pointer. The OBJECT is then matched against the entry in the middle of the new search interval. If the comparison succeeds, the program exits. Otherwise ("NOGOOD"), the carry is set to "0" if the OBJECT is less than the entry. Whenever the INCMNT becomes "I", the CLOSE flag (which had been initialized to "0") is then checked to see if it was set. If it was not, it gets set. If it was set, a check is run to determine whether we passed the location where the OBJECT should have been but is not.
562
DATA STRUCTURES Also note that when the carry was "1", the running pointer will point to the entry below the OBJECT.
Element Insertion In order to insert a new element, a binary search is conducted. If the element is found in the table, it does not need to be inserted. (We assume here that all elements are distinct). If the element was not found in the table, it must be inserted immediately before or immediately after the last element to which it was compared. The value of the COMPRES flag after the search indicates whether it should be inserted immediately before or immediately afterwards. All the elements following the new location where it is going to be placed are moved down by one block position, and the new element is inserted.
NEW ELEMENT
OBJECT H
BAC
MOVE DOWN
563
The insertion process is illustrated in Figure 9.20, and the corresponding program appears in Figure 9.23. The program is called NEW, and starts at memory location OIDO. Note that the automated Z80 instructions LDDR and LDIR are used for efficient block transfers. Element Deletion Similarly, a binary search is conducted to find the object. If the search fails, it does not need to be deleted. If the search succeeds, the element is deleted, and all the following elements are moved up by one block position. A corresponding example is shown in Figure 9.21, and the program appears in Figure 9.23. The flowchart is shown in Fig. 9.22. The program is called "DELETE" and resides at address 0221. A sample run of the above programs is shown in Fig. 9.24.
BEFORE
AFTER
AAA
AAA
MOVE UP
ABC
ABC
BAC
111,
BAT
BAT
TAR
TAR
ZAP
ZAP
DELETE
564
DATA STRUCTURES
DELETE
.0
TES
DECREMENT LOGPOS
RTS
565
SEARCH ID 3E00 Lp 324012 LD 324P02 LD 57 2041102 ID in 304CO2 S141 CD3F ADC CE00 LA IF LD 47 CRIMOI in 5F 1p AEC EAU CD111101 ADD 19 ENTRY FUSA E5 WWI LD 27 SRL CB3F nn[ CE00 LD IF LI. 11117(00 CP FIME00 C24201 Jr U. DA7101 CP FI*E01 C24201 JP LT. 1102102 CP F01.102 cADC01 LI' N00000 3E01 Jr 1104901 LA 3EFF LI. TESTS 3241102 LA 79 DEC 30 [26901 Lli 304002 mu, 07 Jr CA6301 LD 57 LD 304002 SUP 92 CA6901 JF JP C3BA0I NOICLOSE LD 304002 Lb 324002 DOES IIEXTEST NMI El FOE Mt 59 C1111001 CALL 3A41402 LD INC 3C C29601 Jr 78 LP SuP 91 JP CA8501 JP 1108501 47 LA SAC ED52 C31E01 Jr TOOLOW LA 78 DEC 3I. Jr CA0101 10504E02 LD SCF 37 [CF 3F E052 SIC DEC 05 C3AFOI JP
;INITIALIZE OL ;DIVIDE DT :ADD I'S PIT HAM, IN :STORE AS INCREMFHT vAmil ;STORE AS LOGICAL rMilinin VALUE ;CHECK IF LENGTH IS ZERO ;NUMMI 11-11mENTLEN
/SET CLOSE FLAG TO DIRECTION OF r..SEARCH TO ITEVEN1 REPETITION ;PREPARE HL AND IW FOR Ma. nR ...SOD OF INCREMENT VALUE
/TEST IF WANT
TO 01111 OR SUB
;SET NEW LOGICAL POSITION VALUE ;CHANGE ADDREss ITSELF MEE IF POSITION IS I
Ill SO. EXIT
AMDE P REALCLOS
566
DATA STRUCTURES
0196 0199 019A 0190 1119E 0191 0160 11161 0162 01AS 01A6 0109 01Ali Or AE 01AF 011.1 011 ,4 1107 IDA 011.1 011.1. ni riF 0 I DF OICI 01C4 0101 01E9 A ICA OICC "ICI. IICF 0I CI A1101 I
30400? 90 91 rinnn01 19 7B B1 47 1.31E01 VI CA10101 FIISI.4102 19 04 0E01 3114002 324.102 011101 1611 C9 1!. CS 1600 210000 11.404102 41 19 1010 11 I7. II 1 C9
1_1.
111/11 MID ADD LI. API. III
A.( I A01.1.111
PI
LI IL. I IN SEI It C11ICRE111 MS11MM AIM?: IND:1 /11111 WI I lilt PAST ...101. (IP 1111 1 AIN 1 :IS Ilk. CHANGE AC MAI ADDRESS 11.11(1/11i1 1111311.0 POS. VALIT1
ii.n
1.:11. II 11151111111 15 AT 101 111
11111;7 C ....111111' HUM. LP 1,111.1411.1/11 API. HI 1.1 I NCpi REAl 1:1 (IS LI. C.. I 10 A..1:11/1110 n I IM ICI Ilti111111J1 .A Jr 1/111:7 Nor/ (110111 1 I, ii.0/111 m. 1 FlIMI. 111111110H nil' 11011 rural I111:11 I 0 1.0 11, I II Alili NMI? 1111 r. 1.1 I In 1.1: 1.10 111 .00011 DC I 11111 NI ii.1. In air 61101/1 Or LT .111 III
1401 PI
C00001 14 I:7200? 1/14r.112 A7 CA01702 :MOM, CA11.01 11.,71.007 19 C.11101 05 11141:02 90 CA0102 Sr 001.1.01 19 20 EH 27.4107. 19 III F044102 Frain 3t 120102 21
OF LI
P. M' I Ill Jr LP
SF rtIo711
:SI 1
II
111110
II! Iiil 1
A., TAN 1 III / . I P.SEIL I el. crilM1 REID
;171111:1, I /IP
I AM 1
Ain.
LI' 1111: Jr I 1. Min IIISI0F !V HIP 1.11. 10 OIII. 1.I. CAI I ADP 1.11: EX 1 li API' EX I0 1.101k licr. Jr INC PUSH Cx Lb 1 0IR LM INC L0 IO RF1
n
7.111S101 OF 111911 I 111...1.1 SF 1111 Pr Pi / 'INS! III Firs MIN 1 111_ ... 01 HI 1.1.111 HI ...1.1111//i 111 OE lir HI DC . I ENTI / FIT A N7./.1111.11 /1 HI IT LIE 0/.111. DI: . 11.1111 [II ri. ( TAPLEN I A I FAHI FOP .0 liC.0111111 L511 III_ III I nnI '(1511 ION IN Lfin I
nIE:'
0117. 01E9 01111 0110 01E1 011 i DIF 2 OILS 0116 0119 01111 (TIFF' 01117 OIFF 0200 0901 0205 0207 0700 02011 020C 0201 020F 0210 0214 0216 0219 071A 0211' 0220
NI
IJKI lel
A...1AM1 id i
MOVES
ISHII 1
UP
Flirt
DI 11. 10404102 10.00 304107 3C 324E02 011111 C9
IfISF:k I
IREPFAI II ?IF CCESIierRY PIO in FRONT 111 NOY [MCI Y SPACE I LOAD 0.0.11 -CT INTO EMPTY SPACE
I
:F NI:R1MENT 1/11.11:
I FIIIITI1 DONE
:SHOW THAT
I1 LIAS
III/I
567
0271 0224 0225 0220 022C 022D 022E 0231 0232 0235 0239 0238 023C 023F 0242 0243 0246 0249 024A
CD0001 14 CA4907 EDSP4F02 EP 19 3A4CO2 90 CA3F02 ED4B4F02 EDBO 30 C23502 3A4CO2 3D 324002
DELETE
SHIFTIN
DOWNTAB
OIFFFF
C9 (0000) OUTE ENDED
SEARCH D Z.OUTE DE.CENTLEN; DE.NL HL.DE ArCTABLEN; B Z.DOWNTAD BC.IENTLEN) A NZ,SHIFTIN Ar1TABLEN; A ITABLENIIA BCrOFFFFH
IDE IS LOC. OF OBJECT. HL IS ..ONE ENTRY OBOVE ISEE HOU MANY ENTRIES ARE LEFT
SYMBOL TABLE ADDER DOWNTA MISIDE NEXTES OUTS TABASE 01C9 023F OIED 0169 0249 0244 ADDIT ENDED INSERT N00000 REALCL TABLED 0196 024A 020C 0142 01AF 024C CLOSEN ENTLEN MOVED HOTEL SEARCH TESTS 024A 024F 0201 0163 0100 0149 COMPRE ENTRY /JULY NOTFOU SETUP TOOHIG 02411 011E 011141 01BA 0/EE 0165 DELETE FOUND NEW OUT SHIFT! TOOLOW 0221 01BC 0100 0220 0235 0105
LINKED LIST
The linked list is assumed to contain, as usual, the three alphanumeric characters for the label, followed by one to 250 bytes of data, followed by a two-byte pointer which contains the starting address of the next entry, and lastly followed by a one-byte marker. Whenever this one-byte marker is set to "1", it will prevent the insert-routine from substituting a new entry in the place of the existing one. Further, a directory contains a pointer to the first entry for each letter of the alphabet, in order to facilitate retrieval. It is assumed in the program that the labels are ASCII alphabetic characters. All pointers at the end of the list are set to a NIL value which has been chosen here to be equal to the table base, as this value should never occur within the linked list. The insertion and the deletion programs perform the obvious pointer manipulations. They use the flag INDEXED to indicate if a pointer pointing to an object came from a previous entry in the list or from the directory table. The corresponding programs are shown in Figure 9.29. The data structure is shown in Figure 9.25.
568
DATA STRUCTURES
401400 0400 00 00 00 00 00 00 00 00-00 00 00 00 00 00 OD as 0410 00 00 00 00 00 an 00 00-00 00 00 00 00 00 00 OD 0420 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 0430 00 00 00 00 00 00 00 00-00 00 00 00 CO 00 00 CO 0440 00 DO 00 CC 00 00 00 00-00 00 00 00 00 00 00 00 0450 00 00 Oa 00 00 OD 00 00-00 00 00 00 00 00 00 00 0460 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 DO 0470 00 00 00 00 On 00 00 00-00 Oa 00 00 00 00 00 00
WOW /9W
1.19Ungarablech mildlheirlormilonf in merno11 -10300 0300 53 4F IE 31 31 31 31 31-3I 31 31 31 31 00 00 00 SON 0310 44 41 44 3? 37 37 3? 37-37 3? 32 37 32 00 00 an DAD 0370 45 IF 45 33 33 33 33 33-33 33 33 33 .13 00 00 00 /10113333333333... 0330 55 IE 43 34 34 34 34 34-34 34 34 34 34 00 00 00 I/ . . 0340 41 4E 51 35 35 35 35 35-35 35 35 35 35 00 00 00 ANT5555555555 ... 0350 00 00 00 00 DO 00 00 00-00 00 00 00 00 00 00 00 0360 00 00 00 00 00 as 00 00-00 00 00 00 00 00 00 00 0370 00 00 00 na oo nn 00 00-00 00 00 On 00 00 00 00 -54 Y.0000 320 -G2634200 3-11266 0266' -1m400 0400 ID 4F D 33 33 33 33 33-33 33 33 33 13 00 00 00 0410 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 0420 00 00 00 00 00 00 00 00-00 00 00 Oa 00 00 00 00 0430 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 OD 0440 00 00 00 OD 00 00 00 00-00 00 00 00 00 00 00 00 0450 00 DO 00 00 00 00 00 00-00 00 00 00 00 00 00 00 0440 On co 00 00 Oa On na 00-00 00 00 00 00 00 00 00 0470 00 00 00 00 On 00 00 00-00 00 00 CO 00 00 00 00 0.0320 310 -02631266 .'=0.166 0266' Tshle ..... InserlIon 11003333333333-
Run 'INSERT
K ke11101phabelk -5/1400 0400 44 41 44 32 32 32 32 32-32 32 32 32 32 40 IF 45 OAD 0410 3] 33 33 33 33 33 33 33-33 33 00 00 00 00 00 00 3333333333 0420 00 CO 00 DO 00 00 00 00-00 00 00 00 00 00 00 00 0430 CO On 00 00 an 00 nn 00-00 00 00 00 00 00 00 Oa 0440 00 00 00 nn 00 00 00 00-00 00 00 00 00 00 00 00 0450 00 00 00 00 00 00 no 00-00 00 Oa 00 00 00 00 00 0440 00 00 On 00 00 00 00 00-00 00 00 00 00 00 00 00 0470 00 00 on 00 00 00 no 00-00 na 00 00 On 00 00 00
569
Tabkconfigurafion atier all Objects have beep lnnnled 4E 32 33 31 00 00 54 32 33 31 00 00 35 32 33 31 00 00 35 32 33 55 00 00 35 32 33 4E 00 00 35 32 33 43 00 00 35-35 32-32 53-4F 34-34 00-00 00-00 35 32 4E 34 00 00 35 40 31 34 00 00 35 4F 31 34 00 00 35 44 41 1 33 31 31 34 34 00 00 00 00 41 33 31 34 00 00 44 33 31 34 00 ANT55555555550AD 14014333 33333335014 11111H1C444444444 4
00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00
Found
A=4E DC-0401 01:1100D 14L=0427 5=0100 P=0263 0263' CALL OIDO COIDO'l 01'=00 Ir=0000 DP=0000 14'=0000 X=0427 1=0300 1=00
dbregarded
4E 32 33 34 00 00 OD 00 54 32 33 34 00 00 00 00 35 32 33 34 00 00 00 00 35 32 33 55 . 00 CO OD 00 35 32 33 4E 00 OD 00 00 35 32 33 43 00 00 00 00 .550AD 35-35 35 35 35 35 44 41 44 ANT55555555 11011333 32-32 32 40 4F ID 33 33 33 55-4E 43 34 34 34 34 34 34 3333333UNE 444444 34-34 34 34 34 34 34 34 34 4444UNE 444444444 00-00 00 00 00 00 00 OD 00 4 00-00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
A=FE DE=0401 DE=FFOD NL=0427 5=0100 P=0263 0263' CALL 0100 101/10'/ A'=00 0'=0000 0'=0000 H'=0000 X=0427 1=0300 1=00
-D11400
0400 0410 0420 41 4E 54 35 35 35 35 32 32 32 32 32 32 32 33 33 33 33 33 33 33 31 31 31 31 55 4E 43 35-35 35 35 35 35 44 41 /4 32-32 32 ID 4F 40 33 33 33
ANT55555555551A11 014333
53-4F 4E 31 31 31 31 31 31
34-34 34 34 34 34 34 34 34
34 00 00 00 00 00 00 00-00 00 Oa 00 00 00 00 00 00 00 00 00 00 00 00 00-00 Oa 00 00 00 00 00 00
00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
- OR
A.05 DE=FEFF DE=0434 NL=03011 5=0100 P=0266 0266' CALL 0221 A'=00 0P=0000 0'.0000 N'0000 X=0427 Y=0300 1=00 10221'/
570
DATA STRUCTURES
DIRECTORY A POINTER
POINTER
R POINTER NIL
NIL
Fig. 9.25: Linked List Structure An application for this data structure would be a computerized address book, where each person is represented by a unique three-letter code (perhaps the usual initials) and the data field contains a simplified address, plus the telephone number (up to 250 characters). Let us examine the structure in more detail. The entry format is:
Nsiyaair
As usual the conventions are: ENTLEN: total element length (in bytes) TABASE: address of base of list The address of the OBJECT is always assumed to reside in the IY register prior to entering the program. Here, REFBASE points to the base address of the directory, or "reference table." Each two-byte address within this directory points to the first occurrence of the letter to which it corresponds in the list. Thus, each group
571
PROGRAMMING THE Z80 of entries with an identical first letter in their labels actually forms a separate list within the whole structure. This feature facilitates searching and is analogous to an address book. Note that no data are moved during an insert or delete. Only pointers are changed, as in every wellbehaved linked list structure. If no entry starting with a specific letter is found, or if there is no entry alphabetically Following an existing one, their pointers will point to the beginning of the table ( = "NIL"). At the bottom of the table, by convention a value is stored such that the absolute value of the difference between it and "Z" is greater than the difference between "A" and "Z". This represents an End Of Table (EOT) marker. The EOT value is assumed here to occupy the same amount of memory as a normal entry but could be just one byte if desired. The letters are assumed to be alphabetic letters in ASCII code. Changing this would require changing the constant in the PRETAB routine. The end-of-table marker is set to the value of the beginning of the table ("NIL"). By convention, the "NIL pointers", found at the end of a string, or within a directory location which does not point to a string, are set to the value of the table base to provide a unique identification. Another convention could be used. In particular, a different marker for EOT results in some space savings, as no NIL entries need be kept for nonexisting entries. Insertion and deletion are performed in the usual way (see Part I of this chapter) by merely modifying the required pointers. The INDEXED flag is used to indicate if the pointer to the object is in the reference table or another string element. Searching The SEARCH program resides at memory locations 0100 to 0155 an uses subroutine PRETAB at address 01D2. The search principle is straightforward: IGet the directory entry corresponding to the letter of the alphabet in the first position of the OBJECT's label. 2Get the pointer. Access the element. If NIL, the entry does not exist. 3If not NIL, match the element against the OBJECT. If a match is found, the search has succeeded. If not, get the pointer to the next entry down the list. 4Go back to 2. An example is shown in Figure 9.26.
572
DATA STRUCTURES
A.POINTER B.POINTER
ABC
L 1-
Q STEPS REQUIREDI
OBJECT -61
AUG
Fig. 9.26: Linked ListA Search Inserting The insertion is essentially a search followed by an insertion once a "NIL" has been found. A block of storage for the new entry is allocated past the EOT marker by looking for an occupancy marker set at "available" The program is called "NEW" in Figure 9.29 and resides at addresses 0156 to 1A3. An example is shown in Figure 9.27.
BOOR!
~~ 11601.NTER [-POINTER
CAI NA
CRS NIL
OBACI
AFTER
CAB
AP.
NIL
573
Deleting The element is deleted by setting its occupancy marker to "available" and adjusting the pointer to it From the directory or else the previous element. The program is called "DELETE", and resides at addresses 01A4 to OIDI. An example of a deletion is shown in Figure 9.28.
MI ORE
DAF NINIER
t
DOC POINTER NIL
ft
DOC PO IIR NR
DAf
!ERE
574
DATA STRUCTURES
0000 101/ . 0 11 / 101( AI 10111'. 0100 010/ 0103 0104 0107 0104 01111. .11111: .1101. X101 010F 0110 ni 0117. <11 1 ' 1111A 0110 017'0 01'/1 JI IA 011" 01:I f 0/ 7 . 4 014: i 01741 "I 01 IF 0140 0141 0144 014. ; 0141. 0147 0440 0141 .1141 /11140 017.1 .1110 47 It 1110:011 IA
.sr
14 14 111 1 1 101 It r AI 1 0
I 1,
1 IL IA 6: tr, 144 I OP 4 00 1E71' fintOl 144 -4 on F1.1400 1.41101 r7..%01 41.71.01 F1.14 01 1.0.140 len /1 07 1- AI/1101 1014 % 41 2041:0e II 41 71 46 1.141 41 00 1:1.011 4.11201
1041
1:11.10 1..1
on 44 1 1. II. 11.4 111001 111 t I, 11. .1.1. It 011 11 , 1 1 11111 0001. As. 1I0 1 1-0 II10110 1:1 11' 4 - 001-41111. N .411111 01100 1 leA.11411) ell i DI 1,111411/411. 11:1014141.101. t AIve:I. 1 -11' 1 ;'.1 Horn.
711- 1.411114 00
14.11.- Y
/oft/ /WI
110611111.
11 '0 on 4114111 111 .14 I .1111 I IN 111 14: i A.0 11414 .1 1.11111-A/0I II
mini
14 111d. II
114 I-11101F1
ik1 .11 I
1 AI.
0 017 ..../ 01 SA
010
..11.1
01 intsi
01111.1' 411144. IN IN v1111). 18/141 IF 101, lirnel IU 111,101 111F 11F1J :merit III 0 140 Is / I 1014. ;Mole 1 FOC CI A/ 1101.111 11. I1111.1
01 An '1167 '1141' 1111.0 .11741 0141 01/4 01/1 017/ 41 01/1 , I/1 /1 '11)1 01)1 01 )1' 0/00 0101
I 10
yin/ 111104.
I1.0.6 11001:1 111111 14/1 11 II .11 AI14 IN 111111 AF IF. /Ili N/ -1 ...no 011111.4 111..111.0.1
1 1601
575
Sr TINS
r INTIM MO
01A4 [MAO I 0107 04 0100 C7Ir10 I 01AD O0E5 01.10 El OIAE EMI1ECO1 0102 09 0103 4E 0104 23 HIPS 46 11106 23 0107 3600 01119 30E701 01PE 31' 0 1 BD C2C70 I oicn 1:11701 OICJ ER mu 1.311101 MEMO 0107 own 19 0111' 71 v 1 rs 23 OICD '0 01 CT 0 IFFFF OHO C9
DELETE
CALL SEARCH (NC k JP N2. CUTE PUSH IX POP HL PE. I ERTL EN 1 L 11 ADD HL . I'll C. 1111.) L0 INC M P. c HL 1 IA INC M. 1.11 (HLI.0 A. I I NDEXE 01 LD n vrr IF flz . COWMEN CALL PRET/11. 17X MOIL JP MDV CHANGEM L0 11L.(EAREN1 AD HL .IF 011 1.c HOW I u LP INC III OIL 1. 0 LII DC .01 11FFH L0 MOE GET
oT PMnVE mourn/my HARAER :SEE IF INDEX NEEDS EHAN011111 y Fn .PIII ADTT 111111 HI
011c2 Ln 0103 F07E00 co vo 30 ril D / 1e.411 n 1 VP I:027 0 IM. 2(1E001 IDE as 01)1 61 1 01E0 D21:41/1 01E3 24 n114 Fl. nit', El 0116 CY
PRET AD
1 1 11401
111511 III. A.( 19101 LIP A TIEC !RIP 4011 SEA A 1.1' III (III 1 1 1/ASE I ADD I. I.0 I .A HE' F 111A Jr II I NC Ex DE. HI POE' III Fir T
1011 F FPS1 LEI TEN IIF muinvp ASCII LEADER 1/1111 !IM 1 ( BY
Loup r.v
01E7 10000) 1:141.111 [NI! SWUM! 1AM F CHANGE OIC 7 1 101 SR 0100 NEW 0156 MITE 0101 10005E otro CORPAR 0112 F MUT' 01E4 NEXT ON 0161 FREI 01. 0107 MI FM DIA4 mop 0153 unsnap O1 3F RrEPAS Di En MMER 01E7 INDEX1 DIE' worm' DIPS SEARCH 01 On EMI LEN 1 EC MOWN Di CP M1 Pi AG SETINY 11 )^11
576
DATA STRUCTURES
1.6ungnrOblev
01101113313331...
11111.
00 00 no
r --E0Tchlimarrm Intact leble Ninon (non ou on nn nn on on on oo no on an an no on 0.110 on an nn nn no on nn on on no on on on nn un 0470 on nu nu nu nu on nn 00-no on on on nu no on ncin no on on 00 00 00 00 on-an on no no an on oo 0440 on no an no on no on n0 -nn no on on no on no 0450 no oo an nn on no no on-on no an no no on on oann on op or. 00 no on nn on 00 on an no on on nn nano on no no an no nn no on no 00 00 on on no on no no on on an oo no no
no 04 no n4 an nn on on oo on no no no On 00 DO on nn on no nu nn no on nn on no on
..........
44 41 51 41 , 53 41
36 31 33
0.1.40 1'27317771
} Delete an entry
131400 0400 0416 41 11470 44 0430 41 .3440 53 0450 41, 3430 1,1 0470 41
no 41: 41 41 41 nr 49
Unitchange an 00 00 no on no on an no nn un I 1r. .45 15 "10 04 01 AUT557555555550 .12 .17 37 .0:' .17 3? on 04 CB.. lifelP:!:`,":7 77:!7? 13 13 16-13 16 16 :06 ln 10 04 01 nonnosAnnAni.e 11 11 00 04 0/ onoilm 31 11 11 31 .11 11 . 1.1 11 Al 11 .1.1 A1 .11 11 00 04 nl 31111111.113833 In 311 111 - 111 111 in lir ar 40 04 01 nroonnoonormno 1? 1/ 1? -.1 1? 17 .1? -17 00 04 n1 1371717777,763
577
-0720/223
nrs H
Not found
A-37 BC-0011 DE-0400 1iL-0000 5=0100 170223 0223' CALL. 0171 (01711 0' 7 00 14'70000 D'-0000 1C70000 Xv0400 170310 1700
rcEntry found
,-0721 0223' CALL 0171 0=54 PC=F110 1IE70430 HL-0431 5-0100 1 7. 0 10171'1 W=00 10=0000 1I 7 0000 11.-0000 X=0410 Y-0340 1-00 - 0226/279 11
- DU
Delete
1 -0229 0229'
Nolcamognin -05400 0400 711 0410 41 0420 44 0430 41 04, 10 53 0450 411 0460 53 0470 II painien 00 41 41 41 41 IF 49 50 00 54 44 43 41 40 44 50 00 00 35 35 17 32 In 36 11 31 43 .13 30 3E1 37 37 00 35 37 36 31 33 30 37 00 an 37 36 31 33 30 37 00-00 35-35 32-37 36-36 31-31 13-33 30-30 37-37 00 35 37 36 31 33 38 37 00 35 32 36 31 33 30 3? 00 35 37 36 31 33 30 37 On 35 32 36 31 33 30 37 00 00 00 70 04 no 00 On 00 70 04 01 00 04 ni 00 04 01 40 04 0! 00 04 01
SUMMARY
The beginning programmer need not concern himself yet with the details of data structures implementation and management. However, efficient programming of non-trivial algorithms requires a good understanding of data structures. The actual examples presented in this chapter should help the reader achieve such an understanding and solve all the common problems encountered with reasonable data structures.
578
10 PROGRAM DEVELOPMENT
INTRODUCTION All the programs we have studied and developed so Far have been developed by hand without the aid of any software or hardware resource. The only improvement over straight binary coding has been the use of mnemonic symbols, those of the assembly language. For effective software development, it is necessary to understand the range of hardware and software development aids. It is the purpose of this chapter to present and evaluate these aids.
579
PROGRAMMING THE Z80 In short, whenever the resources of the user are limited and no assembler is available, he will have to translate the program by hand into hexadecimal. This can reasonably be done for a small number of instructions, such as, perhaps, 10 to 100. For larger programs, this process is tedious and error-prone, so that it tends not to be used. However, nearly all single-board microcomputers require the entry of programs in hexadecimal mode. They are not equipped with an assembler and a full alphanumeric keyboard, in order to limit their cost. In summary, hexadecimal coding is not a desirable way to enter a program in a computer. It is simply an economical one. The cost of an assembler and the required alphanumeric keyboard is traded-off against increased labor required to enter the program in the memory. However, this does not change the way the program itself is written. The program is still written in assembly-level language so that it can be examined by the human programmer and be meaningful.
580
PROGRAM DEVELOPMENT
SYMBOLIC
ASSEMBLY-LEVEL
High-Level Language A program may be written in a high-level language such as BASIC, APL, PASCAL, or others. Techniques for programming in these various languages are covered by specific books and will not be reviewed here. We will, therefore, only briefly review this mode of programming. A high-level language offers powerful instructions which make programming much easier and faster. These instructions must then be translated by a complex program into the final binary representation that a microcomputer can execute. Typically, each high-level instruction will be translated into a large number of individual binary instructions. The program which performs this automatic translation is called a compiler or an interpreter. A compiler will translate all the instructions of a program in sequence into object code. In a separate phase, the resulting code will then be executed. By contrast, an interpreter will interpret a single instruction, then execute it, then "translate" the next one, then execute it. An interpreter offers the advantage of interactive response, but results in low efficiency compared to a compiler. These topics will not be studied further here. Let us revert to the programming of an actual microprocessor in the assembly-level language.
581
SOFTWARE SUPPORT
We will review here the main software facilities which are (or should be) available in the complete system for convenient software development. Some of the definitions have already been introduced. They will be summarized here and the rest of the important programs will be defined before we proceed. The assembler is the program which translates the mnemonic representation of instructions into their binary equivalent. It normally translates one symbolic instruction into one binary instruction (which may occupy I, 2 or 3 bytes). The resulting binary code is called object code. It is directly executable by the microcomputer. As a side effect, the assembler will also produce a complete symbolic listing of the program, as well as the equivalence tables to be used by the programmer and the symbol occurrence list in the program. Examples will be presented later in this chapter. In addition, the assembler will list syntax errors such as instructions misspelled or illegal, branching errors, duplicate labels or missing labels. It will not delete logical errors (this is your problem). A compiler is the program which translates high-level language instructions into their binary form. An interpreter is a program similar to a compiler, which also translates high-level instructions into their binary form but does not keep the intermediate representation and executes them immediately. In fact, it often does not even generate any intermediate code, but rather executes the high-level instructions directly. A monitor is the basic program which is indispensable for using the hardware resources of this system. It continuously monitors the input devices for input and manages the rest of the devices. As an example, a minimal monitor for a single-board microcomputer, equipped with a keyboard and with LED's, must continuously scan the keyboard for a user input and display the specified contents on the light-emitting diodes. In addition, it must be capable of understanding a number of limited commands from the keyboard, such as START, STOP, CONTINUE, LOAD MEMORY, EXAMINE MEMORY. On a large system, the monitor is often qualified as the executive program, when complex file management or task scheduling is also provided. The overall set of facilities is called an operating system. If files are residing on a disk, the operating system is qualified as the disk operating system, or DOS.
582
PROGRAM DEVELOPMENT
An editor is the program designed to facilitate the entry and the modification of text or progams. It allows the user to enter characters conveniently, append them, insert them, add lines, remove lines, search for characters or strings. It is an important resource for convenient and effective text entry. A debugger is a facility necessary for debugging programs. When a program does not work correctly, there may typically be no indication whatsoever of the cause. The programmer, therefore, wishes to insert breakpoints in his program in order to suspend the execution of the program at specified addresses, and to be able to examine the contents of registers or memory at this point. This is the primary function of a debugger. The debugger allows for the possibility of suspending a program, resuming execution, examining, displaying and modifying the contents of registers or memory. A good debugger will be equipped with a number of additional facilities, such as the ability to examine data in symbolic form, hex, binary, or other usual representations, as well as to enter data in this format. A loader, or linking loader, will place various blocks of object code at specified positions in the memory and adjust their respective symbolic pointers so that they can reference each other. It is used to relocate programs or blocks in various memory areas. A simulator or an emulator program is used to simulate the operation of a device, usually the microprocessor, in its absence, when developing a program on a simulated processor prior to placing it on the actual board. Using this approach, it becomes possible to suspend the program, modify it, and keep it in RAM memory. The disadvantages of a simulator are that: IIt usually simulates only the processor itself, not input/output devices 2The execution speed is slow, and one operates in simulated time. It is therefore not possible to test real-time devices, and synchronization problems may still occur even though the logic of the program may be found correct. An emulator is essentially a simulator in real time. It uses one processor to simulate another one, and simulates it in complete detail. Utility routines are essentially all the routines which are necessary in most applications and that the user wishes the manufacturer had provided! They may include multiplication, division and other arithmetic operations, block move routines, character tests, input/output device handlers (or "drivers"), and more.
583
584
PROGRAM DEVELOPMENT simply re-enter the editor and modify the required lines, then go through the preceding sequence again. In some systems, the memory available may not be large enough, so that it is necessary to flush out the symbolic representation of the program onto a disk or cassette prior to executing the object code. Naturally, in such a case, one would have to reload the symbolic representation of the program from its support medium prior to entering the editor again. The above procedure will be repeated as long as necessary until the results of the program are correct. Let us stress that prevention is much more effective than cure. A correct design will typically result in a program which runs correctly very soon after the usual typing mistakes or obvious coding errors have been removed. However, sloppy design may result in programs which will take an extremely long time to be debugged. The debugging time is generally considered to be much longer than the actual design time. In short, it is always worth investing more time in the design in order to shorten the debugging phase. However, using this approach, it is possible to test the overall organization of the program, but not to test it in real time with input/output devices. If input/output devices are to be tested, the direct solution consists of transferring the program onto EPROM's and installing it on the board and then watching whether it works. There is a better solution. It is the use of an in-circuit emulator. An in-circuit emulator uses the Z80 microprocessor (or any other one) to emulate a Z80 in (almost) real time. It emulates the Z80 physically. The emulator is equipped with a cable terminated by a 40-pin connector, exactly identical to the pin-out of a Z80. This connector can then be inserted on the real application board that one is developing. The signals generated by the emulator will be exactly those of the Z80, only perhaps a little slower. The essential advantage is that the program under test will still reside in the RAM memory of the development system. It will generate the real signals which will communicate with the real input/output devices that one wishes to use. As a result, it becomes possible to keep developing the program using all the resources of the development system (editor, debugger, symbolic facilities, file system) while testing input/output in real time. In addition, a good emulator will provide special facilities, such as a trace. A trace is a recording of the last instructions or status of various data busses in the system prior to a breakpoint. In short, a trace provides the film of the events that occurred prior to the breakpoint or the malfunction. It may even trigger a scope at a specified address or upon the occurrence of a specified combination of bits. Such a facility is of
585
PROGRAMMING THE Z80 great value, since when an error is found it is usually too late. The instruction, or the data, which caused the error has occurred prior to the detection. The availability of a trace allows the user to find which segment of the program caused the error to occur. If the trace is not long enough, we will simply set an earlier breakpoint.
NON 031511Ne
001
CA% 0.1.111
0,101.01111
viena. CIBULCNI
01.00A. CO!TCT
This completes our description of the usual sequence of events involved in developing a program. Let us now review the hardware alternatives available for developing programs.
586
PROGRAM DEVELOPMENT
HARDWARE ALTERNATIVES
Single-Board Microcomputer The single-board microcomputer offers the lowest cost approach to program development. It is normally equipped with a hexadecimal keyboard, plus some function keys, plus 6 LED's which can display address and data. Since it is equipped with a small amount of memory, an assembler is not usually available. At best, it has a small monitor and virtually no editing or debugging facilities, except for a very few commands. All programs must, therefore, be entered in hexadecimal form. They will also be displayed in hexadecimal form on the LED's. A single-board microcomputer has, in theory, the same hardware power as any other computer. Simply because of its restricted memory size and keyboard, it does not support all the usual facilities of a larger system and makes program development much longer. Because it is tedious to develop programs in hexadecimal format, a single board microcomputer is best suited for education and training where programs of limited length have to be developed and their short length is not an obstacle to programming. Single-boards are probably the cheapest way to learn programming by doing. However, they cannot be used for complex program development unless additional memory boards are attached and the usual software aids are made available.
The Development System A development system is a microcomputer system equipped with a significant amount of RAM memory (32K, 48K) as well as the required input/output devices, such as a CRT display, a printer, disks, and, usually, a PROM programmer, as well as, perhaps, an in-circuit emulator. A development system is specifically designed to facilitate program development in an industrial environment. It normally offers all, or most, of the software facilities that we have mentioned in the preceding section. In principle, it is the ideal software development tool. The limitation of a microcomputer development system is that it may not be capable of supporting a compiler or an interpreter. This is because a compiler typically requires a very large amount of memory, often more than is available on the system. However, for developing programs in assembly-level language, it offers all the required facilities. But because development systems sell in relatively small numbers compared to hobby computers, their cost is significantly higher.
587
Hobby-Type Microcomputers The hobby-type microcomputer hardware is naturally exactly analogous to that of a development system. The main difference lies in the fact that it is normally not equipped with the sophisticated software development aids which are available on an industrial development system. As an example, many hobby-type microcomputers offer only elementary assemblers, minimal editors, minimal file systems, no facilities to attach a PROM programmer, no in-circuit emulator, no powerful debugger. They represent, therefore, an intermediate step between the single-board microcomputer and the full microprocessor development system. For a user who wishes to develop programs of modest complexity, they are probably the best compromise, since they offer the advantage of low cost and a reasonable array of software development tools, even though they are quite limited as to their convenience. Time-Sharing System It is possible to rent terminals from several companies which will connect to time-sharing networks. These terminals share the time of the larger computer and benefit from all the advantages of large installations. Cross assemblers are available for all microcomputers on virtually all commercial time-sharing systems. A cross assembler is simply an assembler for, say, a Z80 which resides, for example, in an IBM370. Formally, a cross assembler is an assembler for microprocessor X, which resides on processor Y. The nature of the computer being used is irrelevant. The user still writes a program in Z80 assembly-level language, and the cross assembler translates it into the appropriate binary pattern. The difference, however, is that the program cannot be executed at this point. It can be executed by a simulated processor, if one is available, provided it does not use any input/output resources. This solution is used, therefore, only in industrial environments. In-House Computer Whenever a large in-house computer is available, cross assemblers may also be available to facilitate program development. If such a computer offers time-shared service, this option is essentially analogous to the one above. If it offers only batch service, this is probably one of the most inconvenient methods of program development, since submitting programs in batch mode at the assembly level for a microprocessor results in a very long development time.
588
PROGRAM DEVELOPMENT
Front Panel or No Front Panel? The front panel is a hardware accessory often used to facilitate program debugging. It has traditionally been a tool for conveniently displaying the binary contents of a register or of memory. However, all the functions of the control panel may be accomplished from a terminal, and the dominance of CRT displays now offers a service almost equivalent to the control panel by displaying the binary value of bits. The additional advantage of using the CRT display is that one can switch at will from binary representation to hexadecimal, to symbolic, to decimal (if the appropriate conversion routines are available, naturally). The disadvantage of the CRT is that one must hit several keys to obtain the appropriate display rather than turn a knob. However, since the cost of providing a control panel is quite substantial, most recent microcomputers have abandoned this debugging tool. The value of the control panel is often considered more on the basis of emotional arguments influenced by one's own past experience than by the use of reason. It is not indispensable. Summary of Hardware Resources Three broad cases may be distinguished. If you have only a minimal budget and if you wish to learn how to program, buy a single-board microcomputer. Using it, you will be able to develop all the simple programs in this book and many more. Eventually, however, when you want to develop programs of more than a few hundred instructions, you will feel the limitations of this approach. If you are an industrial user, you will need a full development system. Any solution short of the full development system will cause a significantly longer development time. The trade-off is clear: hardware resources vs. programming time. Naturally, if the programs to be developed are quite simple, a less expensive approach may be used. However, if complex programs are to be developed, it is difficult to Justify any hardware savings when buying a development system, since the programming costs will be by far the dominant cost of the project. For a personal computerise, a hobby-type microcomputer will typically offer sufficient, although minimal, facilities. Good development software is still to come for many of the hobby computers. The user will have to evaluate his system in view of the comments presented in this chapter. Let us now analyze in more detail the most indispensable resource: the assembler.
589
PROGRAMMING THE Z80 THE ASSEMBLER We have used assembly-level language throughout this book without presenting the formal syntax or definition of assembly-level language. The time has come to present this definition. An assembler is designed to allow the convenient symbolic representation of the user program, and yet to make it simple for the assembler program to convert these mnemonics into their binary representation.
Assembler Fields When typing in a program for the assembler, we have seen that fields are used. They are: The label field. optional, which may contain a symbolic address for the instruction that follows. The instruction field, which includes the opcode and any operands. (A separate operand field may be distinguished.) The C0111111elli field. far to the right, which is optional and is intended to clarify the program. These fields are shown on the programming form in Figure 10.3. Once the program has been fed to the assembler, the assembler will produce a listing of it. When generating a listing, the assembler will provide three additional fields, usually on the left of the page. An example appears on Figure 10.4. On the far left is the line number. Each line which has been typed by the programmer is assigned a symbolic line number. The next field to the right is the actual address field, which shows in hexadecimal the value of the program counter which will point to that instruction. Moving still further to the right, we find the hexadecimal representation of the instruction. This shows one of the possible uses of an assembler. Even if we are designing programs for a single-board microcomputer which accepts only hexadecimal, we should still write the program in assembly-level language, providing we have access to a system equipped with an assembler. We can then run the programs on the system, using the assembler. The assembler will automatically generate the correct hexadecimal codes on our system. This shows, in a simple example, the value of additional software resources.
590
PROGRAM DEVELOPMENT
PROGRAMMING THE Z80 Tables When the assembler translates the symbolic program into its binary representation, it performs two essential tasks: 1It translates the mnemonic instructions into their binary encoding. 2It translates the symbols used for constants and addresses into their binary representation. In order to facilitate program debugging, the assembler shows at the end of the listing the equivalence between the symbol used and its hexadecimal value. This is called the symbol table. Some symbol tables will not only list the symbol and its value, but also the line numbers where the symbol occurs, thereby providing an additional facility. Error Messages During the assembly process, the assembler will detect syntax errors and include them as part of the final listing. Typical diagnostics include: undefined symbols, label already defined, illegal opcode, illegal address, illegal addressing mode. Many more detailed diagnostics are naturally desirable and are usually provided. They vary with each assembler. The Assembly Language Opcodes have already been defined. We will here define the symbols, constants and operators which may be used as part of the assembler syntax. Symbols Symbols are used to represent numerical values, either data or addresses. Symbols may include up to six characters, and must start with an alphabetical character. The characters are restricted to letters of the alphabet and numbers. Also, the user may not choose names identical to the opcodes utilized by the Z80, the names of registers such as A,B, C,D,E,H,L, B.C. DE, HL, AF, BC, DE, IX, IY. SP, as well as the various short names used as pseudo-operators by the assembler. The names of these assembler "directives" are listed below in the corresponding sections. Also, the abbreviations used to designate the flags should not be used as symbols: C,Z.NI,PE,NC.P,PO,NZ,M.
592
PROGRAM DEVELOPMENT
Assigning a Value to a Symbol
Labels are special symbols whose values do not need to be defined by the programmer. The value will automatically be defined by the assembler program whenever it finds that label. The label value thus automatically corresponds to the address of the instruction generated at the line where it appears. Special pseudo-instructions are available to force a new starting value for labels, or to assign them a specific value.
0900 401,30, 10201,1 !09011 0100 0101 010A 0100 010( 0101 0111 011.1 0114 4116 F0400002 06011 r0S1.070? 1600 210000 LPAY 3001 19
000/ 000: !WRA0 0003 nrIMP 0riA0 100% . 0006 MAIM 0007 0000 0009 .010 1011 NM 8 0011 0013 0014 rumbh 0015 !air .co: v01n 00/9
elltl111 090011 079:0 Pc,,m1,01., hat Pr. 11010/.. 11..0 M .0 10..1111(.04! m .19: :1 1131. fill 1 i,1119 1010 HI 5 An I ilAP /01111- 1.1.90/1. 111113 .0 LAI .511 1.1 .all '01111 n1111111 111< 101 1010 rearin 1L1 5:01.1.1 M 4:0111 Mt 1.f11 ; . ...193. 011 1:1 se
...I ill n1 01 'MI 1 1 1000 .11111 ! .:ot .: I .
..
9 0:.001 . .14.5.40, .1k
Fig.
10.4:
Assembler
OutputAn Example
593
PROGRAMMING THE Z80 However, other symbols used for constants or memory addresses must be defined by the programmer prior to their use. A special assembler directive may be used to assign a value to any symbol. A directive is essentially an instruction to the assembler which will not be translated into an executable statement. For example, the constant LOG will be defined as: LOG DFW 3002H This assigns the value 3002 hexadecimal to the variable LOG. The assembler directives will be examined in detail in a later section. Constants or Literals Constants may traditionally be expressed either in decimal, in hexadecimal, in octal, or in binary, or as alphanumeric strings. In order to differentiate between the base used to represent the number, a symbol must be used. To load "0" into the accumulator, we will simply write: LD A, 0 Optionally a "D" may be used at the end of the constant. A hexadecimal number will be terminated by the symbol "H". To load the value "FF" into the accumulator, we will write: LD A, OFFH An octal symbol is terminated by the symbol "0" or "Q". A binary symbol is terminated by "B". For example, in order to load the value "11111111" into the accumulator, we will write: LD A, 1111111IB Literal ASCII characters may also be used in the literal field. The ASCII symbol must be enclosed in single quotes. For example, in order to load the symbol "S" into the accumulator, we will write: LD A, 'S'
Exercise 10.1: Will the following two instructions load the same value in the accumulator: LD A. '5', and LD A, 5H?
594
PROGRAM DEVELOPMENT
Note that in the Zilog convention, parentheses denote an address. For example: LD A, (10) specifies that the accumulator is loaded from the contents of memory location 10 (decimal). Operators In order to further facilitate the writing of symbolic programs, assemblers allow the use of operators. At a minimum, they should allow plus and minus so that one can specify, for example: LD A, (ADDRESS) LD A, (ADDRESS +I) It is important to understand that the expression ADDRESS + I will be computed by the assembler in order to determine the actual memory address which must be inserted as the binary equivalent. It will be computed at assembly time, not at program-execution time. In addition, more operators may be available, such as multiply and divide, a convenience when accessing tables in memory. More specialized operators may be also available, such as greater than and less than, which truncate a two-byte value respectively into its high and low byte. Naturally, an expression must evaluate to a positive value. Negative numbers may normally not be used and should be expressed in a hexadecimal format. Finally, a special symbol is traditionally used to represent the current value of the address of the line: "8". This symbol should be interpreted as "current location" (value of PC). Exercise 10.2: What is the difference between the following instructions? LD A, 10101010B LD A, (10101010B) Exercise 10.3: What is the effect of the following instruction? JR NC, $ 2 Expressions The Z80 assembler specifications allow a wide range of expressions
595
PROGRAMMING THE Z80 with arithmetic and logical operations. The assembler will evaluate the expressions in a left-to-right manner, using the priorities specified by the table in Figure 10.5. Parentheses may be used to enforce a specific order of evaluation. However, the outermost parentheses will denote that the contents are to be treated as an address. Assembler Directives Directives are special orders given by the programmer to the assembler, which result either in storing values into symbols or into the memory, or in controlling the execution or printing modes of the assembler. The set of commands which specifically controls the printing modes of the assembler is also called "commands" and is described in a separate section. To provide a specific example, let us review here the 11 assembler directives available on the Zilog development system: ORG nn This directive will set the assembler address counter to the value nn. In other words, the first executable instruction encountered after this directive will reside at the value nn. It can be used to locate different segments of a program at different memory locations. EQU nn This directive is used to assign a value to a label. DEFL nn This directive also assigns a value nn to a label, but may be repeated within the program with different values for the same label, whereas EQU may be used only once. DEFB 'S' This directive assigns eight-bit contents to a byte residing at the current reference counter. DEFB 'S' assigns the ASCII value of "S" to the byte. DEFW nn This assigns the value nn to the two-byte word residing at the current reference counter and the following location.
596
PROGRAM DEVELOPMENT
OPERATOR
FUNCTION
PRIORITY
+ . NOT. or \ . RES. " / .MOD. .SHR. .SHL. + .AND. orb .OR. or I .XOR. .EQ. or = .GT. or > .LT. or < .UGT. .ULT.
UNARY PLUS UNARY MINUS LOGICAL NOT RESULT EXPONENTIATION MULTIPLICATION DIVISION MODULO LOGICAL SHIFT RIGHT LOGICAL SHIFT LEFT ADDITION SUBTRACTION LOGICAL AND LOGICAL OR LOGICAL XOR EQUALS GREATER THAN LESS THAN UNSIGNED GREATER THAN UNSIGNED LESS THAN
I I I I 2 3 3 3 3 3 4 4 5 6 6 7 7 7 7 7
Fig. 10.5: Operator Precedence DEFS nn reserves a block of memory size nn bytes, starting at the current value of the reference counter. DEFM `S' stores into memory the string 'S' starting at the current reference counter. It must be less than 63 in length. MACRO PO PI ...Pn is used to define a label as a macro, and to define its formal parameter list. Macros are defined in another section below. END indicates the end of the program. Any other statements following it will be ignored. ENDM is used to mark the end of a macro definition.
597
PROGRAMMING THE Z80 Assembler Commands Commands are used to modify the format of the listing to control the printing modes of the assembler. All commands start with a star in column one. Seven commands are provided by the Z80 assembler. Typical examples are: EJECT which causes the listing to move to the top of the next page; and LIST OFF which causes the printing to be suspended, effective with this command. The others are: "*HEADING S", "LIST ON", "MACLIST ON", "MACLIST OFF", "INCLUDE FILENAME". Macros A macro is simply a name assigned to a group of instructions. It is a convenience to the programmer. If a group of instructions is used several times in a program, we could define a macro to represent them, instead of always having to write this group of instructions. As an example, we could write: SAVREG MACRO PUSH AF PUSH BC PUSH DE PUSH HL ENDM then simply write the name "SAVREG" instead of the above instructions. Any time that we write SAVREG, the five corresponding lines will get substituted instead of the name. An assembler equipped with a macro facility is called a macro-assembler. When the macro assembler encounters a SAVREG, it performs a mere physical substitution of equivalent lines. Macro or Subroutine? At this point, a macro may seem to operate in a way analogous to a subroutine. This is not the case. When the assembler is used to produce the object code, any time that a macro name is encountered, it will be replaced by the actual instructions that it stands for. At execution time, the group of instructions will appear as many times as the name of the macro did.
598
PROGRAM DEVELOPMENT
By contrast, a subroutine is defined only once, and then it can be used repeatedly; the program will jump to the subroutine address. A macro is called an assembly-time facility. A subroutine is an executionrune facility. Their operation is quite different.
Macro Parameters Each macro may be equipped with a number of parameters. As an example, let us consider the following macro: SWAP MACRO NM, #N, NT LD A, A4 LD tn., A LD A, #1s1 LD #M, A LD A, rr LD #N, A END
This macro will result in swapping (exchanging) the contents of memory locations M and N. A swap between two registers, or two memory locations, is an operation which is not provided by the Z80. A macro may be used to implement it. "T" in this instance is simply the name for a temporary storage location required by the program. As an example, let us swap the contents of memory locations ALPHA and BETA. The instruction which does this appears below: SWAP (ALPHA), (BETA), (TEMP) In this instruction, TEMP is the name of some temporary storage location, which we know to be available and which can be used by the macro. The resulting expansion of the macro appears below: LD LD LD LD LD LD A, (ALPHA) (TEMP), A A, (BETA) (ALPHA), A A, (TEMP) (BETA), A
The value of a macro should now be apparent: it is convenient for the programmer to use pseudo-instructions, which have been defined with macros. In this way, the apparent instruction set of the Z80 can be expanded at will. Unfortunately, one must bear in mind that each macro
599
PROGRAMMING THE Z80 directive will expand into whatever number of instructions were used. A macro will, therefore, run more slowly than any single instruction. Because of its convenience for the development of any long program, a macro facility is highly desirable for such applications. Additional Macro Facilities Many other directives and syntactic facilities may be added to a simple macro facility; macros may be nested, i.e., a macro call may appear within a macro definition. Using this facility, a macro may modify itself with a nested definition! A first call will produce one expansion, whereas subsequent calls will produce a modified expansion of the same macro. This is allowed by the Z80 assembler, but nested definitions are not allowed.
CONDITIONAL ASSEMBLY
Conditional assembly is another facility provided in the Z80 assembly. With a conditional assembly facility, the programmer can devise programs for a variety of cases, and then conditionally assemble the segments of codes required by a specific application. As an example, an industrial user might design programs to take care of any number of traffic lights at an intersection, for a variety of control algorithms. He will then receive the specifications from the local traffic engineer, who specifies how many traffic lights there should be and which algorithms should be used. The programmer will then simply set parameters in his program and assemble conditionally. The conditional assembly will result in a "customized" program which will retain only those routines which are necessary for the solution to the problem. Conditional assembly is, therefore, of specific value to industrial program generation in an environment where many options exist and where the programmer wishes to assemble portions of programs quickly and automatically in response to external parameters. Only two conditional pseudo-OPs are provided in the standard micro-assembler version supplied by Zilog. They are respectively: COND NN and ENDC where NN represents an expression. The pseudo-OP "COND NN" will result in the evaluation of the expression NN. As long as the expression evaluates to a true value (non-zero), the statement following the COND will be assembled. However, if the expression should be false, i.e., eval-
600
PROGRAM DEVELOPMENT uate to a zero value, the assembly of all subsequent statements will be disabled up to the ENDC instruction. ENDC is used to terminate a COND, so that the assembly of subsequent statements is re-enabled. The COND pseudo-OP's cannot be nested. In theory, more powerful conditional assembly facilities could exist, with "IF" and "ELSE" specification. They may become available in future versions of the assembler.
SUMMARY This chapter has presented the techniques and the hardware and software tools required to develop a program, along with the various tradeoffs and alternatives. These range at the hardware level from the single-board microcomputer to the full development system; at the software level, from binary coding to high-level programming. You will have to select them on the basis of your goals and resources.
601
CHAPTER 11 CONCLUSION
We have now covered all important aspects of programming, from definitions and basic concepts to the internal manipulation of the Z80 registers, to the management of input/output devices, as well as the characteristics of software development aids. What is the next step? Two views can be offered, the first one relating to the development of technology, the second one relating to the development of your own knowledge and skill. Let us address these two points.
TECHNOLOGICAL DEVELOPMENT
The progress of integration in MOS technology makes it possible to implement more and more complex chips. The cost of implementing the processor function itself is constantly decreasing. The result is that many of the input/output chips or the peripheral-controller chips used in a system now incorporate a simple processor. This means that most LSI chips in the system are becoming programmable. An interesting conceptual dilemma is now developing. In order to simplify the software design task, as well as to reduce the component count, the new 1/O chips now incorporate sophisticated programmable capabilities: many programmed algorithms are now integrated within the chip. However, as a result, the development of programs is complicated by the fact that all these input/output chips are radically different and need to be studied in detail by the programmer! Programming the system is no longer programming the microprocessor alone, but also programming all the other chips attached to it. The learning time for every chip can be significant. Naturally, this is only an apparent dilemma. If these chips were not available, the complexity of the interface to be realized, as well as of the corresponding programs, would be still greater. The new complexity that is introduced is the need to program more than just a processor,
602
CONCLUSION and to learn the various features of the different chips in a system. However, it is hoped that the techniques and concepts presented in this book will make this a reasonably easy task.
603
APPENDIX A
HEXADECIMAL CONVERSION TABLE
HEX
1 . ; CIrvn vnbnm en <CO U0 11.11
0122 4 5 5 7 5 012 3 456 7 6 16 17 18 19 20 21 22 23 24 32 33 34 35 36 37 38 39 40 48 49 50 51 52 53 54 55 56 64 65 66 67 66 69 70 71 72 BO 81 82 83 54 05 86 87 161 96 97 98 99 100 101 102 103 104 112 113 114 115 116 117 118 119 120 128 129 130 131 132 133 134 135 135 144 145 145 147 146 149 150 151 152 160 161 162 163 164 165 IN 167 160 175 177 176 179 MO MI 13k 18] 184 192 193 194 195 195 197 MB 199 200 208 209 210 211 212 213 214 215 216 224 225 226 227 228 229 230 231 232 240 241 242 243 244 245 246 247 246
9 A BCPEE 9M11 12 13 14 15 25 26 27 20 29 30 31 41 42 43 44 45 46 47 57 58 59 60 61 62 63 73 74 75 76 77 78 79 89 90 91 92 93 94 95 to 106 107 10B 109 no III 121 122 123 124 125 126 127 137 130 139 140 141 142 143 153 154 155 156 157 1511 159 169 170 171 172 173 174 175 MS 106 187 188 189 190 191 201 202 203 204 205 206 207 217 218 219 220 221 222 223 233 234 235 236 237 238 239 249 250 251 252 253 254 255
00
000
0
256 512 765 1024 1280 1535 092 2045 2304 2560 2016 3072 3328 3584 3810
0
40% 8192 12286 16384 20480 24575 28572 32768 36564 40960 45056 49152 53248 57344 51440
4 DEC
3 HEXI DEC 0 I 2 3 4 5 6 7 8
9
2 HEX 0 I 2 3 4 5 6 7 8 9 A B C D E F DEC 0 256 512 768 1,024 1.280 1,536 1,792 2,048 2,304 2,560 2.816 3,072 3,328 3,584 3.840 HEX 0 1 2 3 4 5 6
7
I DEC 0 16 32 48 64 80 96 112 128 144 160 176 192 20B 224 240 HEX 0 I 2 3
4
0 DEC 0 I 2 3 4 5 6
7
0 1,048.576 2,097,152 3.145.728 4,194,304 5,242,880 6.291,456 7 7,340,032 8 8,388.608 9 9,437,184 A 10,485.760 B 11.534.336
0 0 I 65,536 2 131,072 3 196,608 4 262,144 5 327,680 6 393.216 7 458,752 8 524,288 9 589.824 A 655,360 B 720,896 C 786,432 D 851,968 E 917,504 F 983,040
A B C D E F
0 4,096 8,192 12.288 16,384 20,480 24.576 28,672 32.768 36.864 40,960 45.056 49,152 53,248 57,344 61,440
5 6
7
8 9 A B C D E F
8 0 A B C D E F
8 0 10 11 12 13 14 15
604
APPENDIX B
ASCII CONVERSION TABLE
HEX
MSD
BITS 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110
0
000 NUL SOH SD( ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO
LSO
0 1 2 3 4 5 6 7 8 9 A 13 C D E
1111
SI
1 001 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
2 010 SPACE I # $ % 8 ( ) +
/
7 111 p q r S t u v w x y z { .._ 1
.. o DEL
605
APPENDIX C
RELATIVE BRANCH TABLES
V.:
0 2 3 4 5 6 7
0 0 16 32 48 64 BO 96 112
I i 12 33 49 65 81 97 113
7 2 18 34 50 66 E12 98 114
3 3 19 35 51 07 03 99 115
7 7 23 N 55 71
11 8 24 40 So
9 9 25 .11 57
CI 13 29 45 61 77 93 109 125
ei
103 119
n ea
606
APPENDIX D
DECIMAL TO BCD CONVERSION
DECIMAL
BCD
DEC
BCD
DEC
BCD
0
I 2 3 4 5 6 7 8 9
0000
0001 0010 0011 0100 0101 0110 0111 1000 1001
10 11 12 13 14 15 16 17 18 19
00010000 00010001 00010010 00010011 00010100 00010101 00010110 00010111 00011000 00011001
90 91 92 93 94 95 96 97 98 99
10010000 10010001 10010010 10010011 10010100 10010101 10010110 1001011? 10011000 10011001
607
APPENDIX E
Z80 INSTRUCTION CODES
(The literal d is shown as 05 in the object code.) OBJ CODE SOURCE STATEMENT OBJ CODE E620 C846 DOC80546 FOCI:10546 C1347 CB40 CB41 CB42 CB43 C844 C1345 CB4E ODCB0545 FDCB054E CB4F CB48 CB49 CB4A CB4B CB4C CB4D CB66 DDCB0556 FDC130556 CE157 CBSD CEI51 CBS2 CBS3 CB54 CB5E CBSE DDCB055E F DCBOSSE GIME CBS8 C1359 CBSA CI3513 CBSC CBSD CB66 D0CB0566 FDCB0566 CB67 CB6O CB61 CB62 SOURCE STATEMENT AND BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT n OAHU 0,11X+d) 0.11Y+d1 0.A 0.13 0,C 0.0 0.E O.H O,L 1H LI .IIX+dl ,A .I3 .0 .D .E .L 2.1H LI 2.11X.d/ 2,11Y+d1 2,A 2,8 2.0 2.D 2,E 2.H 2,L 3.IHLI 3.11X+d1 3,11Y+d1 3.A 3.B 3,C 3.D 3,E 3,H 3.L 4,Il /OA) 4.11Y+d1 4.A 4,B 4.0 4.D
ADC AMU BE AA I Xedl ADC DDBEOS F D8E05 ADC AIIYdI ADC AA BF A.B ADC B8 ADC A.0 89 ADC A.D BA ADC A,E BB A ,H BC ADC ADC A.L so ADC An CE20 HL.13C ADC EO4A ADC HL.DE ED5A FILM L ADC ED6A ED7A ADC HL.SP B6 ADD A.IHLI 008605 ADD A.IIX+d) ADD A.11Y+dl F0EI605 87 ADD A.A 80 ADO A.B 81 ADD AC B2 ADD AD 83 ADD A,E A./I 84 ADD 85 ADD A.L ADD An C520 09 19 29 39 0009 131319 D029 0039 F1309 FD19 F029 F039 A6 1313A605 FDA605 Al AO Al A2 A] A4 AS ADD H L.BC HL,DE ADD ADD HL,HL ADD HL.SP ADD IX ,BC I X.DE ADD I LI X ADD ADD ILSE IY.Bc ADD I Y,DE ADD I Y,IY ADD I Y,SP ADD AND IHL1 I IX+dl AND AND IIY+dl AND A AND B AND C AND 0 AND E AND H AND L
608
APPENDIX
SOURCE STATEMENT BIT BIT BIT BIT BIT BIT 4,E 4,H 4.L 5,IHLI X+Ell 5.(1Y+911 5,A 5.5 5.0 5.0 5.E 5.H 5.L 6.IHLI 6.IIX+dl
OBJ CODE
SOURCE STATEMENT
CB6F BIT CBES BIT BIT CB69 CNA BIT BIT CB6B BIT CB6C C136D BIT CB76 BIT BIT DDCB0576 FOCB0576 BIT BIT CB77 6A 0070 BIT 6.5 C071 BIT 6.0 CB72 BIT 5.D CB73 BIT 6.E BIT CB74 6.H CB75 BIT 6.L CB7E BIT TIM LI DDCB057E BIT 7.11X+41 FOCB057E BIT 7.11Y.d) CB7F BIT 7.A C137E1 BIT 7.B CB79 BIT 7.0 CB7A BIT 7.0 CB7B BIT 7.E CB7C BIT C13713 BIT 7.L DCB905 CA LL C." FC8405 CA LL CALL NC.nn D4B405 NZ,nn C98405 CA LL F48405 CA LL P.nn ECB405 CALL PE nn E48405 CALL PO nn CC8905 CALL Z.nn C08405 CALL nn 3F CCF BE CP IHLI IIX+dI DDBE05 CP IlY(d1 FDBE05 CP A BF CP 58 CP B9 CP BA CP BB CP BC CP BD CP F E20 CP CPO EDA9 EDB9 CPOR
EDB1 CPIR EDA I CPI 2F CPL 27 DAA 35 DEC IHLI DD3505 DEC 11X+91/ FD35D5 DEC IIY+d) 30 DEC A 05 DEC B OB DEC BC OD DEC C 15 DEC 0 IS DEC DE 10 DEC E 25 DEC H 2B DEC HL DOM DEC IX F02B IT DEC 20 DEC 3B SP DEC F3 DI 102E DJNZ FB El E3 EX ISPI ,HL DDE3 EX ISPI.IX FOE] EX (SPLIT AF ,AF' OB EX 613 EX [WEIL DO EXX 76 HALT ED46 M 0 ED56 FOSE M 2 ED78 N AJCI ENO N B.ICI 6048 N C.ICI E D50 N 0.1C1 ED58 N E.ICI EDGO ED6B N L .ICI 34 NC IHLI DD]405 11%441 NC IlYsg9 F D3405 NC 3C NC A 04 NC 03 NC BC DC NC 14 NC 13 NC DE 1C NC 24 NC 23 NC HL 0023 NC IX FD23 IV NC 2C NC 3] NC SP 01320 N A In I
609
OBJ CODE E L1AA EDBA EDA2 E0B2 C38405 E9 DDE9 F DE9 0A8405 F A8405 028405 C28405 F28405 E A8405 E28405 CA8405 182E 307E 202E 282E 1826 02 12 77 70 71 72 73 74 75 3620 007705 D07005 007105 007205 007305 007405 D07505 00360520 F D7705 F07005 F D7105 F07205 F07305 F D7405 F D7505 F D350520 328405 E0438405 E05313905 228405 00228405 F0228405 E0738405 OA 1A 7E
nn IHLI 11X1 11'1 Olin Mon NC nn NZ,nn P nn PE nn PO.nn Z.nn NC." NZ .e 2,4 ,, ..IL 1dCi A I DE1,4 1FILIA CHUM IHLI,C 1HLI.D !MLLE CHUM IHL1.L (KOJI 11X+d),A 11X+111.13 11X+c1LC 11X+1:11,0 II Widl.E I I X+d1.14 11X+d1.1_ 0 /0:11.n IIY+d1,A 11Y411,B 11Y+dl,C 11Y+ c11.0 0 Y+dI.E 11Y+dl,H 1IY+df,L 11Y+d),n 1nn1,A InnI,BC Inn),DE Inn! HL Inn1.17( Inn1.1Y Innl.SP &MCI AIDE) 4,1111.1
610
APPENDIX
OBJ CODE 5B 5C SO 1E20 66 0136605 FI36605 67 60 61 62 63 64 65 2620 2A8405 218405 ED47 002A13405 00216405 F D2A8405 F D218405 GE CID6E05 F 06E05 6F 66 69 6A 68 SC SO 2E20 FDA F E07613405 F9 ODF9 FDF9 318405 EOA8 WEB EDAO EDBO E044 00 86 0138605 FD8605 B7 BO 61 82 83 84 85 F620 EOBB SOURCE STATEMENT LD LD LD LD LO LD LD LO LD LO LC LD LD LD LO LD LO LO LC/ LO LO LD LD LD LD LO LD LD LD LO LD LO LO LP LO LD LD LO LD LDD LO OR WI LDIR NEG NOP OR OR OR OR OR OR OR OR OR OR OR OT DR E,E E ,H E.L E,n 11,01L1 H,(1X+E0 H,IIYdl H.A H.6 KC H.0 H.E HH H.L H,n HL.Innl HL,nn IA 1X,Innl I X.nn IY.Innl I Y.nn OHL) L.I1XMII LI I `MAI LA L.B L.0 L.I3 L. E L.H L,L Ln R,A SP,Inn) SP HL SP,I X SP.I Y SP,nn OBJ CODE E083 E079 ED41 ED49 ED51 E059 ED61 EDGY D320 EDAB EDA]
Fl
SOURCE STATEMENT OT I R OUT OUT OUT OUT OUT OUT OUT OUT OUTO OUTI POP POP POP POP POP POP PUSH PUSH PUSH PUSH PUSH PUSH RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES RES (chi% (CIA ICI.0 10.0 ICI.E IC1.11 IC1.1. In1A
AF BC DE HL IX IY AF BC DE HL IX 1 OM LI 0.IIX+d) D.lIVdI 0,A 0.8 0,C MD 0.E 0.H 01 ANL/ IY.E11 A .B .0 .0 .E .L 2 ,IHL I 2,IIXdI 2.IIVdI 2,A 2.8 2.0 2.0 2.E 2.H 2.L 3 LI 3.IIX+d) 3.11Yedl
CI D1 EI 0DE1 FDE1 F5 CS 05 E5 ODES FOES CE386 ODCB0586 F DCB0586 CB87 CB80 0981 C682 C883 C884 COBS CORE DDCBOSBE F DCB058E CBBF CB138 CE189 CUBA C886 CB8C CHO C696 DDCB0596 F DCB 0596 CR97 CB90 C891 CR92 CO93 C894 CR95 C89E EIDCB059E FDCB059E
611
CHF RES 3,A 3.9 RES CB98 3.0 RES CR99 RES 3.0 CB9A 3.E RES CHB RES 3.H CR9C 3.L RES CB9D RES 4,1H LI CRAG 4,11%4E0 RES DDC1305A6 4.11Y+d) F DCB05A6 RES 4.A RES CBA7 RES 4,9 CBAO RES 4.0 CBA1 4,O RES CBA2 4,E RES CBA3 4,H RES CBA4 4,L RES GRAS 5.111 RES CBAE 5.11X+41 RES ODC805AE RES 5.11 N 410 F DC805AE 5.A RES CRAF RES 5.B CBA8 5.0 RES CBA9 RES 5,D CRAA 5.E RES CRAB CRAC RES SS RES 5.L CBAD CBB6 RES UHL) RES 6.11%44 DDC1305136 RES 6,11Y+d) FDCB05E16 RES 6.A CE1B7 RES 6.B CBE RES 6.0 C13131 RES 6.0 CB82 RES 6.E C13133 RES 6.H CB94 RES 6.L CBB5 7,(HL) RES CBBE 7,11X+41 RES DDCBOSBE 7,11Y+4) FOCBOSBE RES 7,A RES CRRF RES 7,B CLOS CBB9 RES 7.0 7.0 RES CBBA RES 7.E GLOB RES 7.H CBBC C131113 RES 7,L RET CO RET C 08 F8 RET M RET NC 00 RET NZ CO RET P FO RET PE EB RET PO E0 RET Z C8
612
APPENDIX
013.1 CODE 9E DO9E05 F D9E0S 9F 98 99 9A 9B 9C 90 ED42 ED52 ED62 ED72 37 CRCS DOCB05C6 F DC605C6 C8C7 SOURCE STATEMENT SAC SAC SAC SAC SAC SBC SAC SAC SBC SBC SAC SAC SAC 513C SCF SET 5ET SET A .1F1L) A.11)(410 A.IIY+dI A .A A,13 A.0 A.D A,E A,H A ,L. HLAC HL.DE HL.H L H LSE 0.IH L) 0.11 Xell OM Y+dl
08.1 CODE DOCB05E6 F DCB05E6 CBE] COED CBE I CBE2 CBE3 CBE4 CBES CBEE ODCB05EE F DCBOSEE CBEF CEEB CB E9 CB EA CBEB CBEC COED CBES DOCB05F6 F DCBO5F6 Cl3F7 CBFO CBF I CBF2 CL4F3 CBF4 CB F5 CB FE DDCBOSF E FOCBO5F E CB FF CBF8 CBF9 CB F A CB FB CBFC COED CO25 ODC50526 FOCB0526 CB27 CB20 CO21 C822 C823 CB24
SOURCE STATEMENT SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SLA SLA SLA SLA SLA SLA SLA SLA SLA C E H 4.11X+d1 Al IYd1 4.A 4.B 4,C 4,0 4,E 4,H 4.L 5.0-1 LI 5.IIX+dI 5.11Y+d1 5.A 5,8 5,C 5.0 5.E 5,H 5,L 6.1H L / 6,11X+d) 6.111 , 4-di 6,a 6.8 6.0 6.0 6,E 5.H 6.L 7.111L1 7.11)(4d1 7.11Y+d) 7.A 7.B 7,C 7,D 7,E 7,H 7.L 1H LI DX+d} IIY +di A
SET 0.A CBCO SET OR CBC1 SET 0,C CBC2 SET 0,D CBC3 SET 0,E CBC4 SET 0,H CBC5 CBCE DIDCBOSCE F DCB05CE CBCF COCA COGS CBCA COCA CBCC CBCO CBD6 DOC1305D6 F DC80506 CB 117 C600 CBD1 CAM CBD3 CBD4 CADS CADS CBDE SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET SET 0.L UHL] I,IIX+d) 1,11Y+d) 1.13 1,0 I ,E I ,H I .L 2.11.1 LI 2.11X+dl 2.1IY +di 2,A 2,B 2,C 2,D 2.E 2,H 2.L 3.I3
3.1H LI DOCBOSIDE SET 3.11X.d) FOCAOSDE SET 3.11Y+th CBDF SET 3,A CB D9 SET 3,C CODA SET 3.13 CODE SET 3,E CHOC SET 3M CE1013 SET 3.L CBES SET 4 ,CHL /
CB25 SLA L CB2E SRA (HU ODCB1352E SRA II /DO FDCB052E SRA 11'010 CB2F SRA A GBH SRA B CB29 SRA C CB2A SRA
613
CB2C SRA H SRA CE4213 IHLI SRL CB3E ODCB0536 FOCB053E CB3F CB3B CB39 CB3A CB3B CB3C CUD 96 OD9505 F09505 97 90 91 92 93 94 95 D620 AE OOAEOS FDAE05 AF AB A9 AA AB AC AD EE20 SRL SRL SRL SRL SRL SRL SRL SRL SRL SUB SUB SUB SUB SUB SUB SUB SUB SUB SUB SUB XOR XOR XOR XOR XOR C XOR D XOR E XOR H XOR L XOR n IHLI IIXndl IIY+d1 K 11)0E11 IIYdl A
XOR A
614
APPENDIX F
Z80 to 8080 EQUIVALENCE
Z80
ADC A, (HE) ADC A n ADC A. ADD A. )HL) ADD A. n ADD A.. ADD HI. BC ADD HI, DE ADD HL. HL ADD HL. SP AND n AND r AND (HL I CALL C. nn CALL M. nn CALL NC, nn CALL nn CALL NZ. nn CALL P nn CALL K. nn CALL PO. nn CALL Z. 'in CCF CP r CP (HU CPI. CP n DAA DEC BC DEC DE DEC Ill DEC. DEC SP DEC (HO DI El EX DE HL
8080
ADC M A01821 ADC. ADD M ADI 1621 ADD r DAD B DAD D DAD H DAD SP ANI 1821 ANA r ANA M CC IB21 [531 CM 1621(6]1 CNC 11321(6]1 CALL CH21132111131 CP 1521(6]1 CPE 1621 [VI CP011321[631 CZ 1671[631 CMC UV. CMP M CMA CPI 1621 DAA OCX 5 DCX D DCX H DCR r DCX SP OCR M DI El XCHG
zoo
EX (SP). HL HALT IN A,(n) INC BC INC DE INC HL INC. INC SP INC (HLI JP C. nn JP M. nn JP NC. nn JP nn JP NZ. nn JP P nn JP PE. nn JP PC, nn JP Z. nn JP (HL1 LD A, (DE1 U3A. inn/ LD DE, nn ID SA nn IM (BC). A ID (13E). A ID (AI.. LD (nn). A LD inn). HL ID A. (BC) LD BC, ,in ID H) inn) LD HL. nn LD r. (HC) LD r, n 113 r. i 1 ID SP, Hl NOP
8080
%TPA HLT N 1621 N%8 NX D NX H NR r NX SP NR M C (132) [631 M18211831 NC 182) (631 MP 1132((B]1 N21821[031 P11121 [E131 PE 1B2((831 PO 11321[1331 2 11321 [B31 PCHL DAN DA 11321[631 XID, 11371(0]) IX! SP. 1B2( [13]1 STAX B STAN D MOV IA.. STA MI [B31 SHLD 1571(0]1 LDAX B IX113, 18211831 Lnto 10X(6]1 IX! H 1132)(031 MOV I, M MVI r. 1621 MOVrl. .2 SPHT
NOP
zoo
OR n OR r OR (HO OUT (n). A POP AF POP BC POP DE POP HL PUSH AC PUSH BC PUSH DE PUSH HL RET RET C REIM RET NC RET NZ RET P RET PE RET PO RET Z RLA RICA RRA RRCA PST P 55C A, (HI) SBC A. n SBCA,. SCE SUB n SUB r SUB (HQ XOR n XOR r XOR (HL)
8080
ORi 162 I ORA r ORA M OUT 11321 POP PSW POP B POP 0 POP II PUSH PSW PUSH 13 PUSH 0 PUSH H RET RC RM RNC
RNZ
RP RPE RPO R2 RAL PLC RAR RRC RST P 566M 5511621 SBB r STC SUI1821 SUB r SUB M XRI 1621 XRA e XRA M
615
APPENDIX G
8080 to Z80 EQUIVALENCE
8080
ACI 1121 ADC M ADC. ADD M ADD, ADI 1821 ANA M ANA r AN1 1821 CALL
zoo
ADC A, n ADC A. (Hl) ADO A. (Nil ADD A. n AND (HI) AND, AND n CALL nn CALL C. nn CALL M. nn CPE CCF CP (11L) CP r CALL NC. nn CALL 842, nn CALL P. nn CALL PE. nn CP n CALI. PO, nn CALI. 2. nn DAA ADD HI.. BC ADD HI DE ADO HI.. Hl ADO HI. SP DEC (HI) DEC. DEC BC DEC DE DEC HI DEC SP DI El HIT
8080
N 1121 NR M NR NX B NXD NXH NX SP JC 1821 [B.11 .IM 1821 [B31 JMP 1621 [B31 JNC (12) (83) JNZ 10)(131 JP HU) (831 1PE 1121 [B31 WO (02)1B31 JZ (32) (1331 LOAM) (1331 LDAX B LDAX LH U3 re2j [MI
Z80
N A, (n1 NC (HI) NC. NC BC NC DE NC HI NC SP P C. nn PM. nn P nn P NC, nn P NZ. nn P P. nn P PE. 'In P PO, nn P Z. nn 0 A, (no (3 A. (BC) 0 A. (DE) D HL. (nn I
son
POP H POP PSW PUSH B PUSH D PUSH H PUSH PSW RAL RAR RC RET RIC RM RNC ANC RP RPE RPO RRC RST RZ SHIM SIB,
zoo
POP HL POP AT PUSH BC PUSH DE PUSH HE PUSH AF PEA RRA RET C RET RICA RETM RET NC RET N2 RET P RET PE RET PO RRCA RST P RET Z SIC A. (MCI SBC A.. SRC A. n
CC 1821 CM 0311 [1131 CMA CMC CMP M CMP t CNC 182) (11.31 CNZ 8321(831 CP Illf [B31 CPE 1321(153) CM 1821 CPO 11121 [831 , CZ 1621 [B31 DAA DADB DAD D DAD H DAD SP OCR M DCR r DCX B DCX DCX H DCX SP DI El HALT
[831
UCI B 1B21 [B31 LD BC. nn WID 1E121 (B3) ID DE. nn IXl H B21 (B.11 LD HL. nn I.X1 SP 1132) (B31 LO SP. 'In MOV M.. LEI (LILL MOV r M ID r. (HI) MOV r I. r2 1.0 r, .' MVI M MVI r 1121 NOP ORA M 1.0 (HO. n LO r. n NOP OR (HO
581 1121 SHLD 11321(831 ED (nnl. HI SPILL STA 182) [B31 STAX B SIPA, D STC SUB M SUB' LD SP. HI LD Inn). A ID (BC), A LD (DE). A SCF SUB (HL) SUB'
ORA
OR1 132( OUT 182) PCIA POPE POP D
OR r
OR n OUT (n). A JP (FR) POP BC POP CIE
5111 1011
%CNC XRA M XRA r XR11821 XD1L
SUB fl
EX DE, HI XOR (HO XOR r XOR n EX (SP]. HI.
616
INDEX
A absolute addressing ACT accumulator ADC ADC, A, s ADC HL, ss ADD ADD A, (HLI 108, 439, 446 61 439 101 190 192 101 84, 194 B B 62 banks of registers 62 24 BASIC 46 basic architecture basic concepts 15 basic programming choices 579 basic programming techniques 94 BCD 35, 37, 525 107, 110 BCD addition BCD arithmetic 107 BCD black transfers 530 112 BCD flags BCD representation 35 BCD subtraction 110 BCD table 35 470 benchmark 20, 21, 22, 41, 45 binary binary code 19 18 binary digit binary division 133 18 binary logic 41 binary representation binary search 546, 558, 559, 560, 561 , 566, 567, 568 BIT b, (HL) 211 BIT b, (IX + dl 213 215 BIT b, (IY + dl 217 BIT b, r bit 18, 20, 41 448 bit addressing bit manipulation 172, 173 471, 472 bit serial transfer 540, 542, 544 block block transfer 450, 451, 453, 458, 530 block transfer instructions bootstrap bracket testing branch instruction branching point break character 163, 450, 452 48 523 441 115 467
196 ADD A, (IX + d) ADD A, (IY + d) 198 67, 200 ADD A, n ADD A, r 67, 75, 76, 201 ADD HL, ss 203 ADD IX, rr 205 ADD IY, rr 207 addition 58, 95, 100, 105 47 address bus address registers 51 438, 442 addressing addressing modes 438, 440, 444, 445 addressing techniques 438 15, 16, 114, 539 algorithm alphabetic list 558, 565, 569, 570 alphanumeric data 39 ALU 46, 77, 85 AND 166, 167 ANDS 209 application examples 520 46, 61 arithmetic-logical unit 94 arithmetic programs arithmetic shift 119 ASCII 39, 524, 525 40 ASCII conversion table assembler 96, 582, 590 assembler directives 596, 598 assembler fields 590 assembly-language 67, 580, 592 assigning a value 593 471, 496, 518 asynchronous automated Z80 142,453,455 instructions
617
PROGRAMMING THE Z80 584, 586 breakpoint 533, 534, 535, 536, 537 bubble-sort 59, 61 buffer register 49 buffered 61 buffers 497 bus request 92, 497 BUSRQ 18, 19, 41, 444 byte C 28, 30, 31, 62, 73 C 145, 156, 446, 500 CALL 219 CALL cc, pq 222 CALL pq 224 CCF 143, 144, 145 CALL SUB 22, 23, 26, 28, 30, 174 carry 46 central-processing unit 528 chccksum computation 544,545 circular list 154 classes of instructions 520 clearing memory 47 clock 69 clock cycles 86 clock-synchronous logic 525 code conversion 16 coding 48 combination chips commands 16 590 comment field 531 compare compiler 545,581,582 COND 600 602 conclusion conditional assembly conditional instruction constants control box control bus control instructions control registers control signals control unit count the zeroes counter CP CP s CPO CPDR 600 50 439,445,594 49 47 157,185 512,513,515 91 46 529 463,465 166 225 227 229 CPI CPIR CPL CPU critical race CRT display crystal CU 23 i 233 165, 235 46, 187 60 44, 587 47 46
D
62, 74 109, 236 DAA 511 data buffer 47 data bus 51 data counters 512 data direction register 155 data processing 164 data processing instructions 469 data ready 548 data representation 539 data structures 154, 158, 160 data transfers 583 debugger 18 debugging 20, 21, 22 decimal 238 DEC m 240 DEC rr 242 DEC IX 243 DEC I Y 71, 86 decode 56 decoding 49 decoding logic decrement 164, 442 DEFB 596 596 DEFL 597 DEFM DEFS DEFW delay generation delay loop deleting design examples destination register development systems DFB DI direct addressing direct binary direction register 597 596 463 464, 483 553, 565, 574 548 67 587 596 244 439,441 19 515
618
INDEX
directives 146, 571, 580, 594 directories 541, 545 disk operating system 541, 582 displacement 63 displacement field 442 DINZ c 245 DMA 491,498 documenting 97 DOS 582 doubly-linked lists 545,546 double-precision format 34 drivers 49 F F 61 fetch 55, 70, 84 fetch-execute overlap 78 FIFO 543 file directory 541 flags 31, 50, 51, 179, 180 flags register 61 flip-flops 51 floating point representation 37, 38 flowcharting 16, 17, 114, 450, 464, 469, 494, 559 front panel 45, 589 C general purpose registers getting characters in 62 39 486 583 247 95 134, 137 564 550, 563 583 597 600 597 585 596 586 592 162 162 31 249 16 71 56, 69, 599 55 37, 38 250 252 254 160, 441, 446 41,44 256 H H half-carry flag (H) HALT handshaking hardware hardware delays hardware organization hardware resources HEX hexadecimal hexadecimal coding high byte high level language
E E EBCDIC echo editor El 8-bit addition 8-bit division element deletion element insertion emulator END ENDC EN DM EPROM's EQU error error messages EX AF, AFB exchange instructions Exclusive ORing EX DE, HL executable statements execute execution execution cycle exponent EX (SP), HL EX (SP), IX EX (SP), 1Y extended addressing external representation of information EXX
51 522
62,176 176 92,185,257 477,478,511 93 465 46 587,589 525 41,42,481 43,579 103 581
63 I FF I 499 I FF2 499 illegal code 107 IMO 258 IM I 259 1M 2 260 immediate addressing 108,159,439,445 immediate operation 69 implicit addressing 438, 445 implied addressing 438 improved multiplication 126, 128, 129 IN r, (CI 261 IN A, (N) 263 in-circuit emulator 585 INC (HL) 267
619
264 INC r 164, 442 increment 57 incrementer INC rr 265 268 INC (IX + d) 270 INC (IY + dl 272 INC IX 273 INC IY 274 IND 53, 63, 441, 442 index register indexed addressing 160, 441, 447, 540 63 indexing indirect addressing 443, 444, 448, 540 443 indirect indexed addressing 499 Indirect memory access 276 INDR information representation in-house computer 18 588 278
interrupt table interrupt vector interrupts I/O control IORQ IR IX 1Y .1 JP cc, pq JP nn JP pq JP (HL) JP (IX) JP (IY) JR cc, e IR e JUMP lump instruction Jump relative (112) K IK L L label field largest element LD A, (n, n1 LD D, C LDD LDDR LD1 LDIR LD dd, (nnl LD dd, nn LD r, n LD r, r LD r, r1 LD (BC), A LD (DE), A LD (HL), n LD (HL), r LD r, (HL1 LD r, (IX + d) LD r, (IY + dl LD (IX + d), n LD (IY + d), n
282 89 284 285 286 287 288 290 90, 172, 179,441 156, 182 446, 447
INI INIR 280 input/output 157, 460, 518 511, 521 Input/output devices input/output instructions 183, 460 input register 466 inserting 552, 573 instruction 96 instruction field 590 instruction formats 66 instruction register 55, 64 instruction set 154 instruction types 112 INT 91 internal control registers 51, 513 Internal representation of information 18 interpreted 69 interpreter 545, 581, 582 interrupt 466, 496, 497, 500, 505, 508, 509, 511 interrupt acknowledge 500 interrupt flag 187 interrupt handler 502 interrupt logic 510 interrupt-mask-bit 499 interrupt mode 0 500 Interrupt mode I 503 interrupt model 504 interrupt overhead 504 interrupt-page addressing register 63
24
62 590 526, 527 69, 86 72 164 164 164 142, 164 291 293 295 66 297 299 300 301 303 356 305 307 309 311
620
INDEX
LD (IX + d), r 313 LD (IY + d), r 315 317 LD (nn), A 319 LD (nn), A 321 LD (nn), dd LD (nn), 1-11. 323 LD (nn), IX 325 327 LD (nn), IY 329 LD A, (BC) 330 LD A, (DE) 331 LD A,1 332 LD t, A 333 LD A, R 334 LD HL, (nn) 336 LD IX, nn 338 LD IX, (nn) 340 LD fY, (nn) 342 LD IY, nn 344 LD 12, A 345 LD SP, HL 346 LD SP, IX 347 LD SP, IY 348 LDD 350 LDDR 352 LDI 354 LDIR 41,480 LED 540,544 LIFO structure 41 light emitting diodes linked list 542, 544, 568, 571, 573, 574, 577, 578 linked loader 583 540, 548, 549, 550, 555, 556, 557 list 590 listing 542 list pointer 69,439,455,594 literal 96,106 load 583 loader 546,562 logarithmic searching 166,558 logical 582 logical errors 141 logical operations 119 logical shift 449 long addressing 464 longer delay M machine cycle MACRO 69 597, 598, 600 mantissa 38 MASK 168, 522 memory cycles 55 memory map 453, 586 memory-mapped I/O 157 memory-refresh register 64 micro instructions 86 mnemonic 67, 579 MI 92 444 modes monitor 48, 582 467 monitoring MOS Technology 6502 452 MPU 52, 59 MPU mom 91 MREQ 92 multiple devices 506 482 multiple LED's multiple precision 98 multiplexer 52, 62 multiplication 113, 114, 115, 116, 124, 151, 152, 153 MUX 52, 62 N N NEG negative nested calls nibble NMI nonmaskable interrupt nonrestoring method NOP NOPs normalize normalized mantissa
0 41, 42 octal 465 odometer 25 one's complement 466 one-shot 66, 86, 439, 444, 446 opcode 100, 102, 438, 439 operand 582 operating system 587 operator precedence 166, 168 OR 360 OR s
621
Q
queue R R RAM 543, 544
P packed BCD 36, 107 packed BCD subtract 110, III 494 paper-tape readers 48 parallel input/output parallel work transfer 467, 468, 469 parity bit 39, 40 parity generation 524 parity/overflow (P/V) 175 PC 52 PIC 446, 506 PIO 48, 511, 512, 513, 514, 515, 518 pointers 51, 62, 444, 539, 544, 550, 551 polling 466, 469, 492, 521, 544 polling loop 493, 494 POP qq 373 POP IX 375 POP IY 377 pop 53, 76, 154 port 511, 515, 516 positional notation 20 positive 24, 26, 32 post-indexing 442, 443 power failures 48 pre-indexing 442 printer 44, 479, 495 program 16, 48 program counter 52 program development 579, 584 program loops 63, 121 programmable input/output chip 511 programmable interval timer (PIT) 463, 465 programmer's model 94 programming IS, 16, 515, 518, 602 programming language 16 pseudo-instructions 98
random element RLCA RD 92 read operation 96, 515 read-only memory 48 read-write memory 48, 75 recursion 148 reference table 571 register addressing 438 register indirect addressing 444, 448 register-interrupt 184 register pairs 51 registers 31, 51, 149, 439, 474 relative addressing 441, 446 relative Jump 156 relays 461, 462 request blocks 543 RES b, s 386 RESET 92 restoring method 133 RET 389 RET cc 391 RETI 181, 393, 501 RETN 181, 395, 499 RETURN 144, 145 RFSH 93 RL s 397 RLA 399 RLC r 103 RLC (HL) 402 RLC (IX + d) 404 RLC (IY + dl 406 RLD 408 ROM 48 rotation 120, 155, 170, 171
622
INDEX rotate round robin RR s RR A RRC s RRCA RRD RST RST p rubout 50, 156 544,545 410 412 413 415 416 183, 500 418 467 SRA s 430 432 SRL s stack 53, 146, 149, 496, 508, 539, 544 stack pointer 53,540 49 standard architecture standard PIO 511 31, 85, 476, 515 status status bits 50, 512 status register 50 102 storing operands 490 string of characters 434 SUB A, s 143, 146 subroutine call subroutine library subroutine mechanism subroutine parameters 15U 144 149
S S 178 saving the registers 502 SBC A, s 420 SBC I-11, ss 422 SCF 424 scheduling 491 searching 551, 558, 572 segment drivers 484 segments 480,541 sensing pulses 466 sequential lists 540 sequential searching 546 service routing 492 SET b, s 425 seven-segment light-emitting diode (LED) 480, 481 shift 50, 118, 120, 155. 156 short addressing 441, 446, 449 19 short instruction sign 178 signal 461 signed binary 24, 25 signed numbers 532 551 simple list simulator 583 simultaneous interrupts 507 single-board microcomputers 587 103 I6-bit accumulator 16 by 8 division 134, 135 130,131 16 by 16 multiplication skew operations 169 157 skip 428 SLA s software aids 582, 587 SP 53 172 special digit instructions 476 speed
subroutines 142, 147, 443, 598 subtraction 104 subtract (N) 175 sum of N elements 527, 528 symbolic 41,44 symbols 592, 593 synchronous 471, 496 syntactic ambiguity 16 syntax 544 system architecture 46
T 526, 539, 540, 551, 554, 592 tables technological development 602 teletype 466, 485, 487, 488, 489 temporary register 61 16, 156. 172 test 523 testing a character 465 timer time-sharing system 588 timing 463 585 trace 52 transfers 544, 545 trees 34 truncating truth table two's complement two-level directory U UART underflow utility routines 167 25, 26, 27, 29 541
623
B7 92 496 92
624
INTRODUCTION TO WORDSTAR
by Arthur Neiman 200 pp., 30 illustr., Ref. W110 Makes it easy to learn how to use WordStar, a powerful word processing program for personal computers.
6502 GAMES
by Radon); Zaks 300 pp., 140 lllustr., Ref. G402 Third in the 6502 series. Teaches more advanced programming techniques, using games as a framework for learning.
SlINTRODUCTION TO MICROPROCESSORS
How microprocessors work, including basic concepts, applications, advantages and disadvantages.
S2PROGRAMMING MICROPROCESSORS
The companion to SI . How to program any standard microprocessor, and how it operates internally. Requires a basic understanding of microprocessors.
SB3MICROPROCESSORS
This seminar teaches all aspects of microprocessors: from the operation of an MPU to the complete interconnect of a system. The basic hardware course. (12 hours)
SB2MICROPROCESSOR PROGRAMMING
The basic software course: step by step through all the important aspects of microcomputer programming. (10 hours)
ADVANCED COURSES:
Each includes a 300-500 page workbook and three orfour C90 cassettes.
SB5-BIT-SLICE
Learn how to build a complete system with bit slices. Also examines innovative applications of bit slice techniques. (6 hours)
SB7-MICROPROCESSOR INTERFACING
Explains how to assemble, interface and interconnect a system. (6 hours).
U.S.A 2344 Sixth Street Berkeley, California 94710 Tel: (415) 848-8233 Telex: 336311
SYBEX-EUROPE 4 Place Felix Eboue 75583 Paris Cedex 12 Tel: 1/347-30-20 Telex: 211801
SYBEX-VERLAG Heyestr. 22 4000 Dusseldorf 12 West Germany Tel: (0211) 287066 Telex: 08 588 163
SEX
PROGRAMMING THE ;
has been designed as an educational text and a self-contained reference manual. This book presents a thorough introduction to machine language programming, from basic concepts to advanced data structures and techniques. Detailed illustrative examples and numerous programs show the reader how to write clear, well-organized programs in the language of the Z80. This book is the result of the author's extensive experience in the fields of education and programming, and it has been designed for clarity and readability. All concepts are explained in simple yet precise terms, building progressively toward more complex techniques. The reader will gain not only an understanding of programming in the language of the Z80, but also a detailed understanding of the way a microprocessor actually executes instructions. Among the subject areas covered in PROGRAMMING THE Z80 are: Z80 Hardware Organization Input/Output Techniques Complete Instruction Set Z80 Addressing Modes Data StructuresTheory and Design Applications Examples
With over 200 illustrations, a thorough index and 7 appendices, PROGRAMMING THE Z80 is an indispensable work for engineers, students, home computerists and anyone interested in learning machine language programming skills.
THE AUTHOR
Dr. Rodnay Zaks has been involved with the industrial use of microprocessors since their initial development. He is the author of a number of best-selling books on all aspects of microprocessors, and has taught microprocessor courses to several thousand people internationally, ranging from the introductory level to bit-slice microprogramming techniques. He holds a Ph.D. in Computer Science from the University of California, Berkeley, and is a member of ACM and IEEE.
ISBN 0-89588-047-4