Zilog Z80 Undocumented Features For the Virtual MSX MSX emulator, I've done some research to the undocumented features of the Z80. There are a number of undocumented instructions and flags. I've extracted some information from the comp.sys.sinclair Sinclair ZX Spectrum FAQ v.2.0, which is maintained by Marat Fayzullin (fms@freeflight.com). There are a number of additions and corrections I've made. I also have made an Microsoft Word 6.0 for Windows document, with all the instructions in clear tables, just like in the Zilog Z80 Technical Manual. It's stored in a ziped Rich Text Format file, so it should be platform independent. You can download it by clicking here. There is also a list of all the instructions of the Z80 click here (plain ascii). Opcodes Prefixes There are four opcode prefixes: CB, DD, ED and FD. CB Prefixes There are 248 different CB opcodes. The block CB 30 to CB 37 is missing from the official list. These instructions, usually denoted by the mnemonic SLL, Shift Left Logical, shift left the operand and make bit 0 always one. These instructions are quite commonly used. DD and FD Prefixes The DD and FD opcodes precede instructions using the IX and IY registers. If you look at the instructions carefully, you see how they work: 2A nn LD HL,(nn) DD 2A nn LD IX,(nn) 7E LD A,(HL) DD 7E d LD A,(IX+d) If the HL register is used, then if the opcode is preceded by a DD, the instruction uses the IX register in stead of the HL register. And, if HL was used as a memory reference (indirectly), a displacement d is added. There are two exceptions to this rule, however: the EX DE,HL and EXX instructions. Also, in the JP (HL) instruction HL is not used indirectly. If the instruction does not use the HL register, it is executed as without the prefix. But, if the instruction uses the H or L registers, the lower part or the upper part of the IX register is used. 44 LD B,H FD 44 LD B,IYh These types of unofficial instructions are used in very many programs. ED Prefix There are a number of unofficial ED instructions, but none of them are very useful. The ED opcodes in the range 00-3F and 80-FF (except for the block instructions of course) do nothing at all but taking up 8 T states and incrementing the R register by 2. Most of the unlisted opcodes in the range 40-7F do have an effect, however. The complete list: (* = not official) 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 * RET 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 * RET ED4E * IM 0/1 ED6E * IM 0/1 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 * RET ED75 * RET 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 * RET ED7D * RET ED5E IM 2 ED7E * IM 2 ED5F LD A,R ED7F * NOP The ED70 instruction reads from port (C), just like the other instructions, but does not store the result. It does change the flags in the same way as the other IN instructions, however. The ED71 instruction OUTs a byte zero to port (C), interestingly. These instructions "should", by regularity of the instruction set, use (HL) as operand, but since from the processor's point of view accessing memory or accessing I/O devices is almost the same thing, and since the Z80 cannot access memory twice in one instruction (disregarding instruction fetch of course) it can't fetch or store the data byte (A hint in this direction is that, even though the NOP-synonyms LD B,B, LD C,C etcetera do exist, LD (HL),(HL) is absent and replaced by the HALT instruction.). The IM 0/1 instruction puts the processor in either IM 0 or 1. I cannot figure it out on my MSX (IM 0 operates the same as IM 1, as the only interrupting device always provides value FFh (RST 38h) ). FDCB and DDCB Prefixes The rotate, shift, SET and RES instructions have some unofficial versions which do not only store the result of the operation in (IX+d), but also in an 8 bit register. For instance, for the RLC (IX+d), the unofficial instructions are: FDCB d 00 B = RLC (IY + d)* FDCB d 01 C = RLC (IY + d)* FDCB d 02 D = RLC (IY + d)* FDCB d 03 E = RLC (IY + d)* FDCB d 04 H = RLC (IY + d)* FDCB d 05 L = RLC (IY + d)* FDCB d 06 RLC (IY + d) FDCB d 07 A = RLC (IY + d)* The "x = " means that the value after the rotation is not only stored in (IY + d) but also in the x reg. For the BIT n,(IX+d) instructions, the 8 instructions are identical. In the Opcode List you can find all DDCB and FDCB instructions. Combinations of Prefixes Multiple DD or FD opcodes after each other will effectively be NOPs, doing nothing except repeatedly setting the flag "treat HL as IX" (or IY) and taking up 4 T states. A DD or FD before a ED opcode has no effect (it will effectively be a NOPs). Also, a DD or FD before a CB opcode has no effect. About the R register This is not really an undocumented feature, although I have never seen any thorough description of it anywhere. The R register is a counter that is updated every instruction, where DD, FD, ED and CB are to be regarded as separate instructions. So shifted instruction will increase R by two. There's an interesting exception: doubly-shifted opcodes, the DDCB and FDCB ones, increase R by two too. LDI increases R by two, LDIR increases it by 2 times BC, as does LDDR etcetera. The sequence LD R,A/LD A,R increases A by two, except for the highest bit: this bit of the R register is never changed. This is because in the old days everyone used 16 Kbit chips. Inside the chip the bits where grouped in a 128x128 matrix, needing a 7 bit refresh cycle. Therefore Zilog decided to count only the lowest 7 bits. Undocumented flags Bits 3 and 5 of the F register are not used. They can contain information, as you can readily figure out by PUSHing AF onto the stack and then POPping some it into another pair of registers. Furthermore, sometimes their values change. I found the following empirical rule: The values of bits 7, 5 and 3 follow the values of the corresponding bits of the last 8 bit result of an instruction that changed the usual flags. For instance, after an ADD A, B those bits will be identical to the bits of the A register (Bit 7 of F is the sign flag, and fits the rule exactly). This rule applies to the following instructions: LD A, R CPL LD A, I RLCA ADD A, x RLA ADC A, x RLA SUB A, x RRCA SBC A, x RRA AND x RLC x OR x RL x XOR x RRC x CP x (see below) RR x INC x (8 bit) SLA x DEC x (8 bit) SLL x DAA SRA x NEG SRL x IN x,(C) RRD x IN (C) / IN F,(C) RLD x An exception is the CP x instruction. In this case the bits are copied from the argument. If the instruction is one that operates on a 16 bit word, the 8 bits of the rule are the highest 8 bits of the 16 bit result - that was to be expected since the S flag is extracted from bit 15. This applies to all 16 bits additions and subtractions. Interrupt flip-flops IFF1 and IFF2 There seems to be a little confusion about these. These flip flops are simultaneously set or reset by the EI and DI instructions. IFF1 determines whether interrupts are allowed, but its value cannot be read. The value of IFF2 is copied to the P/V flag by LD A, I and LD A, R. When an NMI occurs, IFF1 is reset, thereby disallowing further [maskable] interrupts, but IFF2 is left unchanged. This enables the NMI service routine to check whether the interrupted program had enabled or disabled maskable interrupts. Other pages about the Z80 Official Zilog Home Page Marat's Home Page - Sinclair FAQ / Z80 emulator in C http://www.cs.unc.edu/~llopis/cpc/cpcdocs/z80.html. Z80 COMMAND SET Z80 FAQ Back to hardware Home Page Back to Home Page This page is maintained by Sean Young. Please send mail to syoung@cs.vu.nl or 101461.16@CompuServe.COM. Last update: August 20, 1996.