Z80 Undocumented Features (in software behaviour) ================================================= By Sean Young (sean@msxnet.org) Version 0.3 October 1998 This document describes all I know about undocumented features of the Z80. Almost everything is taken from other people's pages, so don't think this all my own stuff. However, I think there is some new stuff here too; about interrupts and flag affection and some other stuff. All information has a references to where I got it from. It's marked with [number], which refers to the references at the end of this document (5.3). For example, [5] indicates I've figured it out myself by experimenting. As you've probably noticed, I'm no (true) native English speaker. Any comments, additions, about technical stuff or language is very welcome. You can always find the latest version of this document at: http://www.msxnet.org/tech/ 1) Undocumented Opcodes 1.1) Prefixes in general 1.2) CB Prefix 1.3) DD Prefix 1.4) FD Prefix 1.5) ED Prefix 1.6) DDCB Prefix 1.7) FDCB Prefix 1.8) Combinations of prefixes 2) Undocumented Flag affection & operation 2.1) Flag register bits 2.2) All instructions that affect the flags 2.2.1) 8 Bit arthmetic and logical 2.2.2) 16 Bit arithmetic 2.2.3) BIT instruction 2.2.4) Other non-block instructions 2.2.5) Memory block instructions 2.2.6) I/O block instructions 2.3) Undocumented operation 2.3.1) DAA 2.3.2) I/O Instructions 2.3.3) Block instructions 3) Interrupts and I register 3.1) Non-maskable Interrupts (NMI) 3.2) Maskable Interrupts (INT) 3.4) Things affecting the IFFs 3.5) HALT instruction 3.6) Where can interrupts occur? 4) Timing and R register 4.1) R register and memory refresh 4.2) Instruction timings 5) Other information 5.1) Power on defaults 5.2) Errors in official documentation 5.3) References and other resources 1) Undocumented Opcodes [1] --------------------------- There are quite a few undocumented opcodes/instructions to the Z80. This section should describe every possible opcode (so you know what instruction will be executed, whatever the combination of values is). Check out my Z80 Opcodes list for a complete list of all instructions. http://www.msxnet.org/tech/Z80/z80opcod.txt 1.1) Prefixes in General [1] There are the following prefixes: CBh, EDh. DDh. FDh. DDCBh and FDCBh. Prefixes change the way the following opcodes are interpreted. All instructions without a prefix (without anything like the above before it) are documented in the official documentation. 1.2) CB Prefix [1] An opcode with a CBh prefix is a rotate, shift or bit test/set/reset instruction. There are a few instructions missing from the official list, which are usually denoted with SLL (Shift Logical Left). It works like SLA, for one exception: it sets bit 0 (SLA resets it). CB30 SLL B CB31 SLL C CB32 SLL D CB33 SLL E CB34 SLL H CB35 SLL L CB36 SLL (HL) CB37 SLL A 1.3) DD Prefix [1] In general, after a DD prefix the instruction is executed as if the DD weren't there. There are some exceptions: * Any access to HL is treated as an access to IX (except EX DE,HL and EXX and the ED prefixed instructions that use HL). * Any access to (HL) is changed to (IX+d), where d is a signed displacement byte placed after the main opcode (except JP (HL), which isn't indirect anyways. * Any access to H is treated as an access to IXh (the high byte of IX) Except if (IX+d) is accessed. * Any access to L is treated as an access to IXl (the low byte of IX) Except if (IX+d) is accessed. * A DD prefix before a CB selects a completely different instruction set (see 1.5). So for some examples: Without DD prefix With DD prefix LD H,(HL) LD H,(IX+d) LD H,A LD IXh,A LD L,H LD IXl,IXh JP (HL) JP (IX) LD DE,0 LD DE,0 LD HL,0 LD IX,0 Note LD IXl,IYh is not possible: only IX or IY is accessed in one instruction. 1.3) FD Prefix [1] This prefix has the same effect as the DD prefix, though IY is used in stead of IX. 1.4) ED Prefix [1] There are a number of undocumented EDxx instructions, of which most are duplicates of documented instructions. Any instruction not listed has no effect (just like 2 NOP instructions). The complete list except for the block instructions: (* = undocumented) ED40 IN B,(C) ED60 IN H,(C) ED41 OUT (C),B ED61 OUT (C),H ED42 SBC HL,BC ED62 SBC HL,HL ED43 LD (nn),BC ED63 LD (nn),HL ED44 NEG ED64 * NEG ED45 RETN ED65 * RETN ED46 IM 0 ED66 * IM 0 ED47 LD I,A ED67 RRD ED48 IN C,(C) ED68 IN L,(C) ED49 OUT (C),C ED69 OUT (C),L ED4A ADC HL,BC ED6A ADC HL,HL ED4B LD BC,(nn) ED6B LD HL,(nn) ED4C * NEG ED6C * NEG ED4D RETI ED6D * RETN ED4E * IM 0 ED6E * IM 0 ED4F LD R,A ED6F RLD ED50 IN D,(C) ED70 * IN (C) / IN F,(C) ED51 OUT (C),D ED71 * OUT (C),0 ED52 SBC HL,DE ED72 SBC HL,SP ED53 LD (nn),DE ED73 LD (nn),SP ED54 * NEG ED74 * NEG ED55 * RETN ED75 * RETN ED56 IM 1 ED76 * IM 1 ED57 LD A,I ED77 * NOP ED58 IN E,(C) ED78 IN A,(C) ED59 OUT (C),E ED79 OUT (C),A ED5A ADC HL,DE ED7A ADC HL,SP ED5B LD DE,(nn) ED7B LD SP,(nn) ED5C * NEG ED7C * NEG ED5D * RETN ED7D * RETN ED5E IM 2 ED7E * IM 2 ED5F LD A,R ED7F * NOP The ED70 instruction reads from I/O port C, but does not store the result. It just affects the flags like the other IN x,(C) instruction. ED71 simply outs the value 0 to I/O port C. The ED63 is a duplicate of the 22 instruction (LD (nn),HL) just like the ED6B is a duplicate of the 2A instruction. Of course the timings are different. These instructions are listed in the official documentation. According to Gerton Lunter (gerton@math.rug.nl): The instructions ED 4E and ED 6E are IM 0 equivalents: when FF was put on the bus (physically) at interrupt time, the Spectrum continued to execute normally, whereas when an EF (RST #28) was put on the bus it crashed, just as it does in that case when the Z80 is in the official interrupt mode 0. In IM 1 the Z80 just executes a RST #38 (opcode FF) no matter what is on the bus. [5] All the RETI/RETN instructions are the same, all like the RETN instruction. So they all, including RETI, copy IFF2 to IFF1. More information on RETI and RETN and IM x is in the part about Interrupts and I register (3). 1.5) DDCB Prefixes [1][5] The undocumented DDCB instructions store the result (if any) of the operation in one of the seven all-purpose registers, which one depends on the lower 3 bits of the last byte of the opcode (not operand, so not the offset). 000 B 001 C 010 D 011 E 100 H 101 L 110 (none: documented opcode) 111 A The documented DDCB0106 is RLC (IX+01h). So, clear the lower three bits (DDCB0100) and something is done to register B. The result of the RLC (which is stored in (IX+01h)) is now also stored in register B. Effectively, it does the following: LD B,(IX+01h) RLC B LD (IX+01h),B So you get double value for money. The result is stored in B and (IX+01h). The most common notation is: RLC (IX+01h),B I've once seen this notation: RLC (IX+01h) LD B,(IX+01h) That's not correct: B contains the rotated value, even if (IX+01h) points to ROM memory. The DDCB SET and RES instructions do the same thing as the shift/rotate instructions: DDCB10C0 SET 0,(IX+10h),B DDCB10C1 SET 0,(IX+10h),C DDCB10C2 SET 0,(IX+10h),D DDCB10C3 SET 0,(IX+10h),E DDCB10C4 SET 0,(IX+10h),H DDCB10C5 SET 0,(IX+10h),L DDCB10C6 SET 0,(IX+10h) DDCB10C7 SET 0,(IX+10h),A So the value of (IX+10h) with bit 0 set, is also stored in register A. The DDCB BIT instructions do not store any value; the merely test a bit. That's why the undocumented DDCB BIT instructions are no different from the official ones: DDCB d 78 BIT 7,(IX+d) DDCB d 79 BIT 7,(IX+d) DDCB d 7A BIT 7,(IX+d) DDCB d 7B BIT 7,(IX+d) DDCB d 7C BIT 7,(IX+d) DDCB d 7D BIT 7,(IX+d) DDCB d 7E BIT 7,(IX+d) - official one DDCB d 7F BIT 7,(IX+d) 1.6) FDCB Prefixes [1] Same as for the DDCB prefix, though IY is used in stead of IX. 1.7) Combinations of Prefixes [5] This part may be of some interest to emulator coders. Here we define what happens if strange sequences of prefixes appear in the instruction cycle of the Z80. In general, DD and FD can change the following instruction a bit, (use IX or IY in stead of HL), and ED and CB select a completely different set of instructions. EDxx: Any DD or FD prefix before it is ignored, no matter how many. A CBh prefix can't appear before it because CBED is interpreted as SET 5,L; a separate instruction. If the second byte of an EDxx opcode is CB, DD, FD or ED, it has no effect on following instructions: EDFD210000 NOP; LD HL,0 FDxx/DDxx: Any DD or FD before the FDxx/DDxx is ignored; in a sequence of DDs and FDs, it is only the last one that counts. The ones before just act like NOPs. CB before an DD or FD is not possible (as a prefix) because CBDD and CBFD are instructions in themselves, so is EDFD and EDDD. CBxx: DD and FD prefixes are possible, with the effect as stated above. ED isn't possible; EDCB is an instruction in itself (which doesn't do anything). 2) Undocumented flag affection & operation [5][3] ------------------------------------------------- 2.1) Flag register bits [5][3] The F (flag) register has the following bits: F 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 -----------+-----+------+-----+-----+-----+-----+----- flag S | Z | 5 | H | 3 | P/V | N | C S flag: set if the 2-complement value is negative. It's simply a copy of the most significant bit. Z flag: Set if the value is zero. 5 flag: A copy of bit 5 of the result. H flag: The half-carry of an addition/subtraction (from bit 3 to 4). Needed for DAA correction. 3 flag: A copy of bit 3 of the result. P/V flag: This flag can either be the parity of the result, or the 2-compliment signed overflow (2-compliment value doesn't fit in the register). N flag: Shows whether the last operation was an addition (0) or an subtraction (1). This information is needed for DAA. C flag: The carry flag, set if there was a carry after the most significant bit. In this part, the following notation is used for flag affection: * indicates the effect is non-standard (see the notes). 0 indicates the flag is reset. 1 indicates the flag is set. - indicates the flag is not affected. S,Z,5,H,3,P,V,N,C indicate the flag is set as above. Notice there's no ``unknown'' or ``undefined'' here. :) 2.2) All instructions that affect the flags [1][2][3] This section lists all the instructions that affect the flags, and how they do that. 2.2.1) 8 Bit arithmetic and logical The 8 bit arithmetic group is straightforward: ADD/ADC/SUB/SBC SZ5H3VNC All standard flags .. CP r SZ*H*VNC A CP is simply a SUB with the result thrown away. Flag 5 and 3 are copied from the operand, not the result (which is thrown away anyways). INC/DEC r SZ5H3VN- AND r SZ513P00 OR/XOR r SZ503P00 RLCA/RLA/RRCA/RRA --503-0C RLC/RL/RRC/RR r SZ503P0C SLA/SLL/SRA/SRL r SZ503P0C SLL is like SLA except bit 0 gets set RRD/RLD SZ503P0- Flags set on result in A 2.2.2) 16 Bit arithmetic The 16 bit additions are a bit more complicated. 16 bit additions are done in two stages: first the lower bytes are added, then the two higher bytes. The S,5,H,3 flags are affected as by the second 8 bit addition. Z is set if the whole 16 bit result is 0. ADD s --***-0C ADC/SBC s SZ***VNC 2.2.3) BIT instruction [5] [6] BIT n,r *Z513*0- r is one of the 8 bit registers. BIT behaves much AND r,2^n with the result throw away and the C flag is unaffected. So in effect: Z = set if the tested bit is reset. S = set if n=7 and tested bit is set. 5 = set if n=5 and tested bit is set. 3 = set if n=3 and tested bit is set. P/V = set like Z. BIT n,(IX/IY+d) *Z*1**0- Again, P/V is set like Z and S is if set n=7 and the tested bit is set. But the 5 and 3 flags are different: they are a copy of bit 5 and 3 of the high byte of IX/IY+d (the value after the addition of d to IX or IY). BIT n,(HL) *Z*1**0- P/V, Z, S set as the other BIT instructions, but the 5 and 3 flags are different. Okay, brace yourself. They are a copy of an internal register of the Z80, which is set as follows: ADD HL,xx (use high byte of HL, i.e. H, before the addition) LD r,(IX/IY+d) (use high byte of the resulting address IX/IY+d) JR d (use high byte target address of the jump) LD r,r' (not affected) others not tested -- any additions welcome! 2.2.4) Other non-block instructions [2] [5] CCF --***-0* C=1-C, H as old C. 5, 3 from A register SCF --*0*-01 CPL --*1*-1- 5, 3 from A register. NEG SZ5H3V1C DAA SZ5*3P-* See below (2.3) for more information. LD A,R/LD A,I SZ503*0- P/V contains a copy of IFF2. IN r,(C) SZ503P0- Also true for IN F,(C) / IN (C). 2.2.5) Memory block instructions [2] [5] LDI/LDIR/LDD/LDDR --*0**0- P/V set if BC not 0 5 is bit 1 of (transferred byte + A) 3 is bit 3 of (transferred byte + A) So add A to the (last) transferred byte (from (HL)), and bit 1 of that 8 bit value is flag 5, and bit 3 is flag 3. CPI/CPIR/CPD/CPDR SZ*H**1- P/V set if BC not 0 S,Z,H from (A - (HL) ) as in CP (HL) 3 is bit 3 of (A - (HL) - H) 5 is bit 1 of (A - (HL) - H) CPI instructions are weird too. The test is simply like a CP (HL). Flag 3 and 5 are set like this: Take A, subtract the last (HL), and then decrease it with 1 if the H flag was set (/after/ the CP). Bit 1 of this value is flag 5, bit 3 is flag 3. 2.2.6) I/O Block instructions [5] [6] INI/INIR/IND/INDR SZ5*3*** Flags affected as in DEC B OUTI/OTIR/OUTD/OTDR SZ5*3*** Flags affected as in DEC B Another weird one. S,Z,5,3 are affected by the decrease of B, like in DEC B. The N flag is a copy of bit 7 of the last value read from/written too the I/O port. The C and H flag is set as follows: Take register C, add one to it if the instruction increases HL otherwise decrease it by one. Now, add the the value of the I/O port (read or written) to it, and the carry of this last addition is copied to the C and H flag (so C and H flag are the same). Beats me, but tests show it to be true. Pedro Gimeno (pgimeno@geocities.com) has figured out how the P/V flag is affected. The result depends on the B register, the lower 3 bits of the C register and the lower 3 bits of the value from the I/O port. This next part is written by him. Whatever he says about INI/INIR is true for OUTI/OTIR, and what he says about IND/INDR is true for OUTD/OTDR. I use the notation C.2 to mean bit 2 of C. "inp" is the byte being input. First, look at bits 1 and 0 of both C and inp and look up this table to obtain a temporary result: C.1 C.0 inp.1 inp.0 Temp1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 You'll need also an additional temporary result which depends on B (all of its bits), according to the following pseudocode: If B.3 = B.2 = B.1 = B.0 = 0 then [i.e. if B and 0Fh = 0 then] let Temp2 = Parity(B) xor (B.4 or (B.6 and not B.5)) else let Temp2 = Parity(B) xor (B.0 or (B.2 and not B.1)) where Parity(B) is defined as not (B.0 xor B.1 xor B.2 xor B.3 xor B.4 xor B.5 xor B.6 xor B.7), i.e. 1 if B has an even number of bits = 1, and 0 otherwise (the usual parity function). Note that I obtained the operation (B.0 or (B.2 and not B.1)) from the next table using Karnaugh maps: B.2 through B.0 000 001 010 011 100 101 110 111 Value 0 1 0 1 1 1 0 1 For completeness here's the full table of values of Temp2 according to B: 0123456789ABCDEF <- (low nibble) 00 0011010011001011 10 0100101100110100 20 1100101100110100 30 1011010011001011 40 0100101100110100 50 1011010011001011 60 0011010011001011 70 0100101100110100 80 1100101100110100 90 1011010011001011 A0 0011010011001011 B0 0100101100110100 C0 1011010011001011 D0 0100101100110100 E0 1100101100110100 F0 1011010011001011 ^ (high nibble) And finally, the value of the P/V flag is: P/V = Temp1 xor Temp2 xor C.2 xor inp.2 IND / INDR: The operations to obtain the P/V flag are the same as for INI/INIR but the table used to lookup Temp1 is different: C.1 C.0 inp.1 inp.0 Temp1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 0 1 1 1 1 1 2.3) Undocumented operation [1][5] 2.3.1) DAA [4] [5] This instruction is useful when you're using BCD values. After an addition or subtraction, DAA makes the correction so the value is the correct BCD value again. The correction done is as in the following table [4]: N | C | high | H | low | # added | C after | | nibble | | nibble | to A | execution --+---+--------+---+--------+---------+----------- add, adc, inc operands: 0 0 0-9 0 0-9 00 0 0 0-8 0 a-f 06 0 0 0-9 1 0-3 06 0 0 a-f 0 0-9 60 1 0 9-f 0 a-f 66 1 0 a-f 1 0-3 66 1 1 0-2 0 0-9 60 1 1 0-2 0 a-f 66 1 1 0-3 1 0-3 66 1 ------------------------------------------------- sub, sbc, dec, neg operands: 1 0 0-9 0 0-9 00 0 0 0-8 1 6-f fa 0 1 7-f 0 0-9 a0 1 1 6-f 1 6-f 9a 1 This table is all I know about DAA operation. Emulator builders: this instruction is hard to emulate. The Intel 80x86 equivalents are more or less the same, but differ for some input values (not in the table?). If you're not using assembly, the best way IMHO is to put all possible output values (for A and F registers) in a table. The output depends on the following inputs: A register and H,N,C flags. That's 11 bits in total, so the table will have size: 2^11*2 = 4096 bytes, which isn't too bad. 2.3.2) I/O Instructions The I/O instructions use the whole of the address bus, not just the lower 8 bits. So in fact, you can have 65536 I/O ports in a Z80 system (the Spectrum uses this). IN r,(C), OUT (C),r and all the I/O block instructions put the whole of BC on the address bus. IN A,(n) and OUT (n),A put A*256+n on the address bus. 2.3.3) Block instructions The repeated block instructions simply decrease the PC by two so the instruction is simply re-executed. So interrupts can occur during block instructions. So, LDIR is simply LDI + if BC is not 0, decrease PC by 2. 3) Interrupts and I register [4] -------------------------------- For the interrupts, the following things are important: Interrupt Mode (set with the IM instructions), the interrupt flip-flops (IFF1 and IFF2), and the I register. There are two types of interrupts, maskable and non-maskable. The maskable type is ignored if IFF1 is reset. Non-maskable interrupts (NMI) will always occur, and they have a higher priority, so if the two are requested at the same time the NMI will occur. 3.1) Non-maskable interrupts (NMI) [4] When a NMI is accepted, IFF1 is reset. At the end of the routine, IFF1 must be restored (so the running program is not affected). That's why IFF2 is there; to keep a copy of IFF1. An NMI is accepted when the NMI pin on the Z80 is made low. The Z80 responds to the /change/ of the line from +5 to 0. When this happens, a call is done to address 0066h and IFF1 is reset so the routine isn't bothered by maskable interrupts. The routine should end with an RETN (RETurn from Nmi) which is just a usual RET, but also copies IFF2 to IFF1, so the IFFs are the same as before the interrupt. You can check whether interrupts were disabled or not during an NMI by using the LD A,I or LD A,R instruction. These instructions copy IFF2 to the P/V flag. 3.2) Maskable interrupts (INT) [4] If the INT line is 0 volt and IFF1 is set, a maskable interrupt is accepted - whether or not the the last INT routine has finished. That's why you should never enable interrupts during such a routine, and make sure that the device that generated it has put the INT line up to +5 volt again before ending the routine. When an INT is accepted, both IFFs are cleared, preventing another interrupt from occurring which would end up as an infinite loop. What happens next depends on the Interrupt Mode. IM 0: The instruction on the bus is executed (usually an RST instruction, but it can be anything else -- even instructions larger than one byte). The I register is ignored. IM 1: An RST 38h is executed, no matter what value is put on the bus or what value the I register has. IM 2: A call is made to the address read from memory. What address is read from is calculated as follows: (I register) * 256 + (value on bus). Of course a word (two bytes) are read, comprising an address where the call is made to. In this way, you can have a vector table for interrupts. At the end of a maskable interrupt, the interrupts should be enabled again. You can assume that was the state of the IFFs because otherwise the interrupt wasn't accepted. (snappy huh). So, an INT routine always ends with an EI and a RET (RETI according to the official documentation, more about that later): INT: . . . EI RETI (or RET) Note a fact about EI: a maskable interrupt isn't accepted directly after it, so the next opportunity for an INT is after the RETI. This is very useful; if the INT is still low, an INT is generated again. If this happens a lot and the interrupt is generated before the RETI, the stack could overflow (since the routine is called again and again). But this property of EI prevents this. DI is not necessary at the start of the interrupt routine: the Z80 disables them when accepting the interrupt. You can use RET in stead of RETI too, it depends on hardware setup. RETI is only useful if you have something like a Z80 PIO to support daisy-chaining: queueing interrupts. The PIO can detect that the routine has ended by the opcode of RETI, and let another device generate an interrupt. That is why I called all the undocumented EDxx RET instructions RETN: All of them operate like RETN, the only difference to RETI is its specific opcode. (Which the Z80 PIO recognises.) 3.3) Things affecting the IFFs [4] All the IFF related things are: IFF1 IFF2 /CPU reset 0 0 DI 0 0 EI 1 1 Accept INT 0 0 Accept NMI 0 - RETI/N IFF2 - All the EDxx RETI/N instructions LD A,I/LD A,R - - Copies IFF2 into P/V flag Note the fact about RETI/N: all the EDxx RET instructions copy IFF2 into IFF1, even RETI! The other one-byte RET commands (RET, RET NZ etc.) don't do this. Since every INT routine must end with this sequence: EI RETI (or RET, but RETI officially) It does not matter that RETI copies IFF2 into IFF1; both are set anyways. [5] There seems to be some dispute about whether or not when an NMI is accepted, IFF1 is copied into IFF2 before clearing IFF1. Some official docs even states this, but I've been experimenting with nested NMIs (if it were correct, the IFF states would be lost after a nested NMI) and I've found it to be wrong. Only IFF1 is reset, that's all. If you're working with a Z80 system without NMIs (like the MSX), you can forget all about the two separate IFFs; since a NMI isn't ever generated, the two will always be the same. 3.5) HALT instruction [4] The HALT instruction halts the Z80; it starts executing NOPs, until a maskable or non-maskable interrupt is accepted. Only then does the Z80 increase the PC and continues with the next instruction. During the HALT state, the HALT line is set. The PC is increased before the interrupt routine is called. 3.6) Where can interrupts occur? [5] During execution of instructions, interrupts won't be accepted. Only /between/ instructions. This is also true for prefixed instructions. Directly after an EI or DI instruction, interrupts aren't accepted. They're accepted again after the instruction after the EI (RET in this example). So for example, look at this MSX2 routine that reads a scanline from the keyboard: LD C,A DI IN A,(0AAh) AND 0F0h ADD A,C OUT (0AAh),A EI IN A,(0A9h) RET You can assume that there never is an interrupt after the EI, before the IN A,(0A9h) -- which would be a problem because the MSX interrupt routine reads the keyboard too. Using this feature of EI, it is possible to check whether it is true that interrupts are never issued during instructions: DI EI INT: RET And yes, for all instructions, including the prefixed ones, interrupts are never issued during an instruction. Only after the tested instruction. Remember that block instructions simply re-execute themselves (by decreasing the PC with 2) so an interrupt is accepted after each iteration. Another predictable test is this: at the insert a large sequence of EI instructions. Of course, during execution of the EI instructions, no interrupts are accepted. But now for the interesting stuff. EDED or CBCB are just instructions in themselves, so interrupts are issued after them. But DD and FD are just prefixes, which only slightly affects the next opcode. If you test a large sequence of DDs or FDs, the same happens as with the EI instruction: no interrupts are accepted during the execution of these sequences. This makes sense, if you think of DD and FD as a prefix which set the "use IX instead of HL" or "use IY instead of HL" flag. If an interrupt was issued after DD or FD, this flag information would be lost, and: DD 21 00 00 LD IX,0 could be interpreted as a simple LD HL,0, if the interrupt was after the last DD. Which never happens, so the implementation is correct. Because of this, DD DD 21 00 00 is also always executed as LD IX,0 and never as LD HL,0. For the same reason, NMIs aren't accepted after a DD or FD too (I haven't tested this but I can't imagine otherwise). The Z80 docs say that no interrupts are accepted after EI or DI, which also includes NMIs (also not tested). 4) Timing and R register [1] ---------------------------- 4.1) R register and memory refresh [1][4] During every first machine cycle (beginning of an instruction or part of it -- prefixes have their own M1 two), the memory refresh cycle is issued. The whole of IR is put on the address bus, and the _RFSH is lowered. It unclear whether the Z80 increases the R register before or after putting IR on the bus. The R register is increased at every first machine cycle (M1). Bit 7 of the register is never changed by this; only the lower 7 bits are included in the addition. So bit 7 stays the same, but it can be changed using the LD R,A instruction. Instructions without a prefix increase R by one. Instructions with an ED, CB, DD, FD prefix, increase R by two, and so do the DDCBxxxx and FDCBxxxx instructions (weird enough). Just a stray DD or FD increases the R by one. LD A,R and LD R,A access the R register after it is increased (by the instruction itself). Remember that the block instructions simply decrease the PC with two, so the instructions are re-executed. So LDIR increased R by BC times 2 (note that in the case of BC = 0, R is increased by 10000h times 2, effectively 0). Accepting an maskable or non-maskable interrupt increases the R by one. After a hardware reset, or after power on, the R register is reset to 0. That should cover all there is to say about the R register. It is often used in programs for a random value, which is good but of course not truly random. 4.2) Instruction timings [1][4] Not much stuff here, as I'm no cycle expert. The opcode list does show the timings of all instructions though: http://www.msxnet.org/tech/Z80/z80opcod.txt Undocumented timings: * Stray DD or FD: same as a NOP (increases R by one). * EDxx (not one of the list above or block instruction): Same as two NOPs. Increases R by 2. * Accepting interrupts (all one M1 and thus increase R by one): (T states) IM 0: 13 (assuming the instruction is a RST) IM 1: 13 IM 2: 19 NMI : 11 5) Other Information -------------------- 5.1) Power on defaults [4] After a reset (a hard reset of course) or power on, all registers are set to 0, the IFFs are reset and the interrupt mode is 0. So, since the PC is 0, the Z80 starts executing code at address 0. 5.2) Errors in official documentation [5] In different official (?) documentation, I've seen some errors. Some don't have all of these mistakes, so your documentation may not be flawed but these are just things to look out for. * The Flag affection summary table shows that LDI/LDIR/LDD/LDDR instructions leave the S and Z in an undefined state. This is not correct; the S and Z flags are unaffected (like the same documentation says). * Similary, the same table shows that CPI/CPIR/CPD/CPDR leave the S and H flags in an undefined state. Not true, they are affected as defined elsewhere in the documentation. * Also, the table says about INI/OUTD/etc "Z=0 if B <> 0 otherwise Z=0"; of course the latter should be Z=1. * The INI/INIR/IND/INDR/OUTI/OUTD/OTIR/OTDR instructions do affect the C flag (some official documentation says they leave it unaffected, important!) and the N flag isn't always set but may also be reset (see above for exact operation). * When an NMI is accepted, the IFF1 isn't copied to IFF2. Only IFF1 is reset. * In the 8-bit Load Group, the last two bits of the second byte of the LD r,(IX + d) opcode should be 10 and not 01. * In the 16-bit Arithmetic Group, bit 6 of the second byte of the ADD IX, pp opcode should be 0, not 1. * IN x,(C) resets the H flag, it never sets it. Some documentation states it is set according to the result of the operation; bullocks, no arithmetic is done in this instruction. 5.3) References and other resources Here are a few locations on the web, with information about the Z80. The references in this document are marked here two. They are in no particular order, and maybe I made a mistake somewhere too.. So include the Standard Disclaimer. http://www.acorn.co.uk/~mrison/en/cpc/tech.html [3] Mark Rison Z80 page for !CPC. ftp://ftp.ping.de/pub/misc/emulators/yaze-1.10.tar.gz [2] YAZE (Yet Another Z80 Emulator). This is a CPM emulator by Frank Cringle. It emulates almost every undocumented flag, very good emulator. Also includes a very good instruction exerciser. http://www.geocities.com/SiliconValley/Peaks/3938/z80_home.htm Z80 Family Official Support Page by Thomas Scherrer. Very good, a lot information there. http://www.kendalls.demon.co.uk/cssfaq/tech_z80.html Spectrum FAQ technical information. ftp://ftp.void.jump.org/pub/sinclair/emulators/pc/dos/z80-400.zip [1] Gerton Lunter's Spectrum emulator (Z80). In the package there is a file TECHINFO.DOC, which contains a lot of interesting information. http://users.aol.com/autismuk/emu.html A TRS80 (Z80 based) emulator in assembly. http://www.zilog.com/ Guess what, the makers of the little bastard. Not much information here (you can order technical books though). http://www.msxnet.org/tech/ [5] My own (Sean Young) Z80 page. You can find this document there and some other stuff. Mostek Z80 Programming Manual [4] A /very/ good reference book to the Z80. Pedro Gimeno (pgimeno@geocities.com) [6]