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!
=== Programming model and register set === [[File:Z80 arch.svg|thumb|upright=1.95|An approximate block diagram of the Z80: There is no dedicated adder for offsets or separate incrementer for R, and no need for more than a single 16-bit temporary register WZ (although the incrementer latches are also used as a 16-bit temporary register, in other contexts). It is the PC and IR registers that are placed in a separate group, with a detachable bus segment, to allow updates of these registers in parallel with the main register bank.<ref>{{Cite web |last=Shiriff |first=Ken |title=Down to the silicon: how the Z80's registers are implemented |url=https://www.righto.com/2014/10/how-z80s-registers-are-implemented-down.html |url-status=live |archive-url=https://web.archive.org/web/20231105135940/http://www.righto.com/2014/10/how-z80s-registers-are-implemented-down.html |archive-date=November 5, 2023}}</ref>]] The programming model and register set of the Z80 are fairly conventional, ultimately based on the register structure of the [[Datapoint 2200]]. The Z80 was designed as an extension of the Intel 8080, created by the same engineers, which in turn was an extension of the [[Intel 8008|8008]]. The 8008 was basically a [[PMOS logic|PMOS]] implementation of the TTL-based CPU of the Datapoint 2200.{{efn|The related [[Intel 8086|8086]] family also inherited this register design.}} The 2200 design allowed 8-bit registers H and L (High and Low) to be paired into a 16-bit address register HL.{{efn|This variable HL pointer was actually the only way to access memory (for data) in the Datapoint 2200, and hence also in the Intel 8008. No direct addresses could be used to access data.}} In the 8080, this pairing was added to the BC and DE pairs as well, while HL was generalized to allow use as a 16-bit accumulator, not just an address register. The 8080 also introduced immediate 16-bit data for BC, DE, HL, and SP loads. Furthermore, direct 16-bit copying between HL and memory was now possible, using a direct address. The Z80 [[Orthogonal instruction set|orthogonalized]] this further by making all 16-bit register pairs, including IX and IY, more general purpose, as well as allowing 16-bit copying directly to and from memory for all of these pairs. The 16-bit IX and IY registers in the Z80 are primarily intended as base address-registers, where a particular instruction supplies a constant offset that is added to the previous values, but they are also usable as 16-bit accumulators, among other things. A limitation is that all operand references involving IX or IY require an extra instruction prefix byte, adding at least four clock cycles over the timing of an instruction using HL instead; this sometimes makes using IX or IY less efficient than a method using only the 8080-model registers. The Z80 also introduced a new signed [[overflow flag]] and complemented the fairly simple 16-bit arithmetics of the 8080 with dedicated instructions for ''signed'' 16-bit arithmetics.[[File:Z80 pinout.svg|thumb|upright=1.5|The Z80's original [[dual in-line package|DIP40]] chip package pinout]]The 8080-compatible registers AF, BC, DE, HL are duplicated as a separate register file in the Z80,<ref>{{Cite book |title=Kilobaud |date=1977 |publisher=1001001 |page=22}}</ref> where the processor can quickly (in four t-states, the least possible execution time for any Z80 instruction) switch from one bank to the other;<ref>{{Cite book |last=Zaks |first=Rodnay |url=https://archive.org/details/Programming_The_Z80_Third_Edition_Rodnay_Zaks/ |title=Programming the Z80 |date=1982 |publisher=SYBEX |isbn=978-0-89588-069-7 |edition=3rd |page=62}}</ref> a feature useful for speeding up responses to single-level, high-priority interrupts. The dual register-set is useful in the embedded role, as it improves interrupt handling performance, but found widespread use in the personal computer role as an additional set of general registers for complex code like [[floating-point arithmetic]] or home computer games. The duplicate register file is often referred to as the "alternate register set" (by some, the "primed" register file since the apostrophe character is used to denote them in assembler source code and the Zilog documentation). This emphasizes that only one set is addressable at any time. However, the 8-bit accumulator A with its flag register F is bifurcated from the "general purpose" register pairs HL, DE and BC. This is accomplished with two separate instructions used to swap their accessibilities: <code>EX AF,AF'</code> exchanges only register pair AF with AF', while the <code>EXX</code> instruction exchanges the three general purpose register pairs HL, DE and BC with their alternates HL', DE' and BC'. Thus the accumulator A can interact independently with any of the general purpose 8-bit registers in the alternate (or primed) register file, or, if HL' contains a pointer to memory, some byte there (DE' and BC' can also transfer 8-bit data between memory and accumulator A). This can become confusing for programmers because after executing <code>EX AF,AF'</code> or <code>EXX</code>, the contents of the alternate (primed) registers are now in the main registers, and vice versa. The only way for the programmer to understand and track this swapped condition is to trace through the code flow, noting each occurrence of a register swap instruction. Obviously if jump and call instructions are made within these code segments it can quickly become difficult to tell which register file is in context unless carefully commented. Thus it is advisable that exchange instructions be used directly and in short discrete code segments. The Zilog Z280 instruction set includes <code>JAF</code> and <code>JAR</code> instructions which jump to a destination address if the alternate registers are in context (thus officially recognizing this programming complication). ==== Registers ==== {| class="floatright" style="font-size:88%; border: 1px solid #a2a9b1;" |+ '''Zilog Z80 registers''' |- | {| style="font-size:88%;" |- | style="width:10px; text-align:center;"| <sup>1</sup><sub>5</sub> | style="width:10px; text-align:center;"| <sup>1</sup><sub>4</sub> | style="width:10px; text-align:center;"| <sup>1</sup><sub>3</sub> | style="width:10px; text-align:center;"| <sup>1</sup><sub>2</sub> | style="width:10px; text-align:center;"| <sup>1</sup><sub>1</sub> | style="width:10px; text-align:center;"| <sup>1</sup><sub>0</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>9</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>8</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>7</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>6</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>5</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>4</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>3</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>2</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>1</sub> | style="width:10px; text-align:center;"| <sup>0</sup><sub>0</sub> | style="width:auto;" | ''(bit position)'' |- |colspan="17" | '''Main registers''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| Accumulator (A) | style="text-align:center;background:#DDD" colspan="8"| Flags (F) | style="background:white; color:black;"| '''AF''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| B | style="text-align:center;" colspan="8"| C | style="background:white; color:black;"| '''BC''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| D | style="text-align:center;" colspan="8"| E | style="background:white; color:black;"| '''DE''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| H | style="text-align:center;" colspan="8"| L | style="background:white; color:black;"| '''HL''' |- |colspan="17" | '''Alternate (shadow) registers''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| Accumulator' (A') | style="text-align:center;background:#DDD" colspan="8"| Flags' (F') | style="background:white; color:black;"| '''AF{{'}}''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| B' | style="text-align:center;" colspan="8"| C' | style="background:white; color:black;"| '''BC{{'}}''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| D' | style="text-align:center;" colspan="8"| E' | style="background:white; color:black;"| '''DE{{'}}''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| H' | style="text-align:center;" colspan="8"| L' | style="background:white; color:black;"| '''HL{{'}}''' |- |colspan="17" | '''Index registers''' |- style="background:silver;color:black" | style="text-align:center;" colspan="16"| Index X | style="background:white; color:black;"| '''IX''' |- style="background:silver;color:black" | style="text-align:center;" colspan="16"| Index Y | style="background:white; color:black;"| '''IY''' |- style="background:silver;color:black" | style="text-align:center;" colspan="16"| Stack Pointer | style="background:white; color:black;"| '''SP''' |- |colspan="17" | '''Other registers''' |- style="background:silver;color:black" | style="text-align:center;" colspan="8"| Interrupt vector | style="text-align:center;" colspan="8"| Refresh counter | style="background:white; color:black;"| '''I/R''' |- |colspan="17" | '''Program counter''' |- style="background:silver;color:black" | style="text-align:center;" colspan="16"| Program Counter | style="background:white; color:black;"| '''PC''' |- |colspan="17" | '''Status register''' |- style="background:silver;color:black" | style="background:white; color:black;" colspan="8"| <!--NEED TO ADD INTERRUPT STATUS/MODE BITS--> | style="text-align:center;"| [[Sign flag|S]] | style="text-align:center;"| [[Zero flag|Z]] | style="text-align:center;"| - | style="text-align:center;"| [[Adjust flag|H]] | style="text-align:center;"| - | style="text-align:center;"| [[Parity flag|P]]/[[Overflow flag|V]] | style="text-align:center;"| N | style="text-align:center;"| [[Carry flag|C]] | style="background:white; color:black" | '''F'''lags |} |} As on the 8080, 8-bit registers are typically paired to provide 16-bit versions. The 8080 compatible registers<ref name="Heath 2003">{{Cite book |last=Heath |first=Steve |url=https://archive.org/details/embeddedsystemsd0000heat |title=Embedded systems design |date=2003 |publisher=Newnes |isbn=978-0-7506-5546-0 |location=Oxford |page=21 |url-access=registration}}</ref> are: * <code>AF</code>: 8-bit [[Accumulator (computing)|accumulator]] (A) and flag bits (F) carry, zero, minus, parity/overflow, half-carry (used for [[Binary-coded decimal|BCD]]), and an Add/Subtract flag (usually called N) also for BCD * <code>BC</code>: 16-bit data/address register or two 8-bit registers * <code>DE</code>: 16-bit data/address register or two 8-bit registers * <code>HL</code>: 16-bit accumulator/address register or two 8-bit registers * <code>SP</code>: [[stack pointer]], 16 bits * <code>PC</code>: program counter, 16 bits The new registers introduced with the Z80 are: * <code>IX</code>: 16-bit index or base register for 8-bit immediate offsets * <code>IY</code>: 16-bit index or base register for 8-bit immediate offsets * <code>I</code>: interrupt vector base register, 8 bits * <code>R</code>: DRAM refresh counter, 8 bits ([[Most significant bit|msb]] does not count) * <code>AF'</code>: alternate (or shadow) accumulator and flags (''toggled in and out with EX AF,AF' '') * <code>BC'</code>, <code>DE'</code> and <code>HL'</code>: alternate (or shadow) registers (''toggled in and out with EXX'') * Four bits of interrupt status and interrupt mode status The ''refresh register'', <code>R</code>, increments each time the CPU fetches an opcode (or an opcode prefix, which internally executes like a 1-byte instruction) and has no simple relationship with program execution. This has sometimes been used to generate [[pseudorandom]] numbers in games, and also in software protection schemes.{{Citation needed|date=February 2012}} It has also been employed as a "hardware" counter in some designs; an example of this is the [[ZX81]], which lets it keep track of character positions on the TV screen by triggering an interrupt at [[integer overflow|wrap around]] (by connecting INT to A6). The ''interrupt vector register'', <code>I</code>, is used for the Z80 specific mode 2 interrupts (selected by the <code>IM 2</code> instruction). It supplies the high byte of the base address for a 128-entry table of [[interrupt service routine|service routine]] addresses which are selected via an index sent to the CPU during an [[interrupt]] acknowledge cycle; this index is simply the low byte part of the pointer to the tabulated indirect address pointing to the service routine.<ref name="Wai-Kai 2002" /> The pointer identifies a particular peripheral chip or peripheral function or event, where the chips are normally connected in a so-called [[Daisy chain (electrical engineering)|daisy chain]] for priority resolution. Like the refresh register, this register has also sometimes been used creatively; in interrupt modes 0 and 1 (or in a system not using interrupts) it can be used as simply another 8-bit data register. The instructions <code>LD A,R</code> and <code>LD A,I</code> affect the Z80 flags register, unlike all the other <code>LD</code> (load) instructions. The Sign (bit 7) and Zero (bit 6) flags are set according to the data loaded from the Refresh or Interrupt source registers. For both instructions, the Parity/Overflow flag (bit 2) is set according to the current state of the IFF2 flip-flop.<ref>{{Cite web |last=Rison |first=Mark |editor-last=Young |editor-first=Sean |title=Z80 Flag Affection |url=http://www.z80.info/z80sflag.htm |url-status=live |archive-url=https://web.archive.org/web/20231223185036/http://z80.info/z80sflag.htm |archive-date=December 23, 2023 |access-date=June 14, 2016 |website=z80.info |publisher=Thomas Scherrer}}</ref> ==== Microarchitecture ==== Although the Z80 is generally considered an eight-bit CPU, it has a four-bit [[Arithmetic logic unit|ALU]], so calculations are done in two steps.<ref>{{Cite web |last=Shirriff |first=Ken |title=The Z-80 has a 4-bit ALU. Here's how it works. |url=http://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html |archive-url=https://web.archive.org/web/20130909224112/http://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html |archive-date=September 9, 2013 |access-date=November 16, 2021}}</ref>
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)