Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Zilog Z80
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Instruction set and encoding === The Z80 uses 252 out of the available 256 codes as single byte opcodes ("root instruction" most of which are inherited from the 8080); the four remaining codes are used extensively as [[opcode prefix]]es:<ref name="Zilog 1995">{{Cite web |year=1995 |title=Z80 CPU Introduction |url=http://www.z80.info/z80brief.htm |url-status=live |archive-url=https://web.archive.org/web/20231220144519/http://www.z80.info/z80brief.htm |archive-date=December 20, 2023 |publisher=[[Zilog]] |quote=It has a language of 252 root instructions and with the reserved 4 bytes as prefixes, accesses an additional 308 instructions.}}</ref> CB and ED enable extra instructions, and DD or FD select IX+d or IY+d respectively (in some cases without displacement d) in place of HL. This scheme gives the Z80 a large number of permutations of instructions and registers; Zilog categorizes these into 158 different "instruction types", 78 of which are the same as those of the Intel 8080<ref name="Zilog 1995" /> (allowing operation of all 8080 programs on a Z80). The Zilog documentation<ref>{{Cite web |year=1976 |title=Z80-CPU Instruction Set |url=https://usermanual.wiki/Document/ZilogZ80CPUTechnicalManual.2406416115/view#23 |url-status=live |archive-url=https://web.archive.org/web/20231105184525/https://usermanual.wiki/Document/ZilogZ80CPUTechnicalManual.2406416115/view#23 |archive-date=November 5, 2023 |access-date=July 20, 2021 |publisher=[[Zilog]] |page=19 |type=PDF}}</ref> further groups instructions into the following categories (most from the 8080, others entirely new like the block and bit instructions, and others 8080 instructions with more versatile addressing modes, like the 16-bit loads, I/O, rotates/shifts and relative jumps): * Load and exchange * Block transfer and search * Arithmetic and logical * Rotate and shift * Bit manipulation (set, reset, test) * Jump, call and return * Input/output * Basic CPU control No explicit multiply instructions are available in the original Z80,<ref>{{Cite book |last1=Sanchez |first1=Julio |title=Software Solutions for Engineers And Scientists |last2=Canton |first2=Maria P. |date=2008 |publisher=Taylor & Francis |isbn=978-1-4200-4302-0 |page=65 |quote=The 8-bit microprocessors that preceded the 80x86 family (such as the Intel 8080, the Zilog Z80, and the Motorola) did not include multiplication.}}</ref> though registers A and HL can be multiplied by powers of two with ADD A,A and ADD HL,HL instructions (similarly IX and IY also). Shift instructions can also multiply or divide by powers of two. Different sizes and variants of additions, shifts, and rotates have somewhat differing effects on flags because most of the flag-changing properties of the 8080 were copied. However, the parity flag bit P of the 8080 (bit 2) is called P/V (parity/overflow) in the Z80 as it serves the additional purpose of a twos complement overflow indicator, a feature lacking in the 8080. Arithmetic instructions on the Z80 set it to indicate overflow rather than parity, while bitwise instructions still use it as a parity flag. (This introduces a subtle incompatibility of the Z80 with code written for the 8080, as the Z80 sometimes indicates signed overflow where the 8080 would indicate parity, possibly causing the logic of some practical 8080 software to fail on the Z80.{{efn|For example, on the 8080, a programmer might test the parity of a byte by {{code|ADD}}ing zero to it, by {{code|SUB}}tracting zero from it, or by {{code|OR}}ing or {{code|XOR}}ing it with zero; all of these are single-instruction operations of the same speed and size, on both the 8080 and the Z80. If the programmer happened to choose to test parity by {{code|OR}}ing or {{code|XOR}}ing with zero, then the Z80 will execute the program correctly, but if the programmer chose to test parity by {{code|ADD}}ing or {{code|SUB}}tracting zero, then the Z80 will always reset the P/V flag to zero (since adding or subtracting zero never causes an overflow or underflow) instead of assigning P to correctly indicate the parity of the byte (as the 8080—or 8085—would), and the program may fail. Nothing in the Intel programming manuals or other documentation for the 8080 discouraged use of arithmetic instructions, or prescribed using logical instructions, to test parity, so there is no reason that an 8080 programmer exercising recommended good programming practice should be expected to have chosen one of the ways that will work on the Z80 over one of the ways that will not work.}}) This new overflow flag is used for all new Z80-specific 16-bit operations ({{code|ADC}}, {{code|SBC}}) as well as for 8-bit arithmetic operations, while the 16-bit operations inherited from the 8080 ({{code|ADD}}, {{code|INC}}, {{code|DEC}}) do not affect it. Also, bit 1 of the flags register (a spare bit on the 8080) is used as a flag N that indicates whether the last arithmetic instruction executed was a subtraction or addition. The Z80 version of the {{code|DAA}} instruction (decimal adjust accumulator for BCD arithmetic) checks the N flag and behaves accordingly, so a (hypothetical) subtraction followed later by {{code|DAA}} will yield a different result on an old 8080 than on the Z80. However, this would likely be erroneous code on the 8080, as {{code|DAA}} was defined for addition only on that processor. The Z80 has six new {{code|LD}} instructions that can load the DE, BC, and SP register pairs from memory, and load memory from these three register pairs—unlike the 8080.<ref name="Durda 2012" /> As on the 8080, load instructions do not affect the flags (except for the special-purpose I and R register loads). A result of a regular encoding (common with the 8080) is that each of the 8-bit registers can be loaded from themselves (e.g. {{code|LD A,A}}). This is effectively a {{code|NOP}}. New block transfer instructions can move up to 64 kilobytes from memory to memory or between memory and I/O peripheral ports. Block instructions {{code|LDIR}} and {{code|LDDR}} ('''l'''oa'''d''', '''i'''ncrement/'''d'''ecrement, '''r'''epeat) use HL to point to the source address, DE to the destination address, and BC as a byte counter. Bytes are copied from source to destination, the pointers are incremented or decremented, and the byte counter is decremented until BC reaches zero. Non-repeating versions {{code|LDI}} and {{code|LDD}} move a single byte and bump the pointers and byte counter, which if it becomes zero resets the P/V flag. Corresponding memory-to-I/O instructions {{code|INIR}}, {{code|INDR}}, {{code|OTIR}}, {{code|OTDR}}, {{code|INI}}, {{code|IND}}, {{code|OUTI}} and {{code|OUTD}} operate similarly, except that B, not BC, is used as the byte counter.{{sfnp|Ciarcia|1981|p=86}}<ref>{{Cite book |last=HAYES |first=JOHN P. |title=Computer Architecture and Organization |year=1978 |isbn=0-07-027363-4 |page=423}}</ref> The Z80 can input and output any register to an I/O port using register C to designate the port. (The 8080 only performs I/O through the accumulator A, using a direct port address specified in the instruction; a self-modifying code technique is required to use a variable 8080 port address.) The last group of block instructions perform a {{code|CP}} compare operation between the byte at (HL) and the accumulator A. Register pair DE is not used. The repeating versions {{code|CPIR}} and {{code|CPDR}} only terminate if BC goes to zero or a match is found. HL is left pointing to the byte after ({{code|CPIR}}) or before ({{code|CPDR}}) the matching byte. If no match is found, the Z flag is reset. There are non-repeating versions {{code|CPI}} and {{code|CPD}}. Unlike the 8080, the Z80 can jump to a relative address ({{code|JR}} instead of {{code|JP}}) using a shorter instruction with a signed 8-bit displacement. There are unconditional and conditional forms of this instruction. Only the zero and carry conditions can be tested. (All 8080 jumps and calls, conditional or not, are three-byte instructions.) If jump is taken, the two-byte {{code|JR}} instructions are slower than the 8080-style three-byte {{code|JP}} instructions; if not taken, {{code|JR}} instructions are quicker. A two-byte instruction specialized for program looping is also new to the Z80: {{code|DJNZ}} ('''d'''ecrement '''j'''ump if '''n'''on-'''z'''ero) takes a signed 8-bit displacement as an operand. The B register is decremented, and if the result is nonzero, then program execution jumps relative to PC; the flags remain unaltered. To perform an equivalent loop on an 8080 requires separate {{code|DEC}} and conditional jump (to a two-byte absolute address) instructions (totalling four bytes), and the {{code|DEC}} alters the flag register. The index register (IX/IY, often abbreviated XY) instructions can be useful for accessing data organised in fixed heterogenous structures (such as [[record (computer science)|records]]) or at fixed offsets relative a variable base address (as in [[recursive]] [[stack frame]]s) and can also reduce code size by removing the need for multiple short instructions using non-indexed registers. However, although they may save speed in some contexts when compared to long/complex "equivalent" sequences of simpler operations, they incur a lot of additional CPU time (e.g., 19 T-states to access one indexed memory location vs. as little as 11 to access the same memory using HL and {{code|INC}} to point to the next). Thus, for simple or linear accesses of data, use of IX and IY tend to be slower and occupy more memory. Still, they may be useful in cases where the "main" registers are all occupied, by removing the need to save/restore registers. Their officially undocumented 8-bit halves (see below) can be especially useful in this context, for they incur less slowdown than their 16-bit parents. Similarly, instructions for 16-bit additions are not particularly fast (11 clocks) in the original Z80 (being 1 clock slower than in the 8080/8085); nonetheless, they are about twice as fast as performing the same calculations using 8-bit operations, and equally important, they reduce register usage. It was not uncommon for programmers to "poke" different offset displacement bytes (which were typically calculated dynamically) into indexed instructions; this is an example of [[self-modifying code]], which was regular practice on nearly all early 8-bit processors with non-[[Instruction pipelining#Special situations|pipelined]] execution units. The index registers have a parallel instruction to {{code|JP (HL)}}, which is {{code|JP (XY)}}. This is often seen in stack-oriented languages like [[Forth (programming language)|Forth]], which at the end of every Forth word (atomic subroutines comprising the language) must jump unconditionally back to their thread interpreter routines. Typically this jump instruction appears hundreds of times in an application, and using {{code|JP (XY)}} rather than {{code|JP THREAD}} saves a byte and two T-states for each occurrence. This naturally makes the index register unavailable for any other use, or else the need to constantly reload it would negate its efficiency. The 10-year-newer microcoded [[Z180]] design could initially afford more "chip area", permitting a slightly more efficient implementation (using a wider [[Arithmetic logic unit|ALU]], among other things); similar things can be said for the [[Zilog Z800|Z800]], [[Z280]], and [[Z380]]. However, it was not until the fully pipelined [[Zilog eZ80|eZ80]] was launched in 2001 that those instructions finally became approximately as cycle-efficient as it is technically possible to make them, i.e. given the Z80 encodings combined with the capability to do an 8-bit read or write every clock cycle.{{Citation needed|date=July 2011}} ==== Undocumented instructions ==== The index registers, IX and IY, were intended as flexible 16-bit pointers, enhancing the ability to manipulate memory, stack frames and data structures. Officially, they were treated as 16-bit only. In reality they were implemented as a pair of 8-bit registers,<ref>{{Cite book |last=Froehlich |first=Robert A. |url=https://archive.org/details/freesoftwarecata0000froe/ |title=The free software catalog and directory |date=1984 |publisher=Crown Publishers |isbn=978-0-517-55448-7 |page=133 |quote=Undocumented Z80 codes allow 8 bit operations with IX and IY registers. |url-access=registration}}</ref> in the same fashion as the HL register, which is accessible either as 16 bits or separately as the ''H''igh and ''L''ow registers. The binary opcodes (machine language) were identical, but preceded by a new opcode prefix.<ref name="undocz80">{{Cite web |last=Bot |first=Jacco J. T. |title=Z80 Undocumented Instructions |url=http://www.z80.info/z80undoc.htm |url-status=live |archive-url=https://web.archive.org/web/20231223185034/http://z80.info/z80undoc.htm |archive-date=December 23, 2023 |website=Home of the Z80 CPU |quote=If an opcode works with the registers HL, H or L then if that opcode is preceded by #DD (or #FD) it works on IX, IXH or IXL (or IY, IYH, IYL), with some exceptions. The exceptions are instructions like LD H,IXH and LD L,IYH.}}</ref> Zilog published the opcodes and related mnemonics for the intended functions, but did not document the fact that every opcode that allowed manipulation of the H and L registers was equally valid for the 8 bit portions of the IX and IY registers. For example, the opcode 26h followed by an immediate byte value {{code|(LD H,n)}} will load that value into the H register. Preceding this two-byte instruction with the IX register's opcode prefix, DD, would instead result in the most significant 8 bits of the IX register being loaded with that same value. A notable exception to this would be instructions similar to {{code|LD H,(IX+d)}} which make use of both the HL and IX or IY registers in the same instruction;<ref name="undocz80" /> in this case the DD prefix is only applied to the (IX+d) portion of the instruction. The halves of the XY registers could also hold operands for 8-bit arithmetic, logical and compare instructions, sparing the regular 8-bit registers for other use. The undocumented ability to increment and decrement the upper half of an index register made it easy to expand the range of the normal indexed instructions, without having to resort to the documented {{code|ADD/SBC XY,DE}} or {{code|ADD/SBC XY,BC}}. There are several other undocumented instructions as well.<ref>Robin Nixon ''The Amstrad Notepad Advanced User Guide'', Robin Nixon, 1993, {{ISBN|1-85058-515-6}}, pages 219–223.</ref> Undocumented or [[illegal opcode]]s are not detected by the Z80 and have various effects, some of which are useful. However, as they are not part of the formal definition of the instruction set, different implementations of the Z80 are not guaranteed (or especially likely) to work the same way for every undocumented opcode. ==== Bugs ==== The {{code|OTDR}} instruction does not conform to the Z80 documentation. Both the {{code|OTDR}} and {{code|OTIR}} instructions are supposed to leave the carry (C) flag unmodified. The {{code|OTIR}} instruction operates correctly; however, during the execution of the {{code|OTDR}} instruction, the carry flag takes the results of a spurious compare between the accumulator (A) and the last output of the {{code|OTDR}} instruction.<ref name="Young 1998" />
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)