Disclaimer: This information is provided as is. There may be errors in this information. You may use this information only if you agree that Minimalist / Coinop.org, its employees, and noted authors will never be held responsible for any damage, injury, death, mayhem, etc. caused by errors in the information. When working with high voltage, never work alone and always follow safety precautions.

Document Title: [Z80undoc.txt (text file)]

            _F_r_o_m _N_O_R_T_H_E_R_N _B_Y_T_E_S _- _V_o_l_u_m_e _3 _N_u_m_b_e_r _1_0 _(_O_c_t_. _'_8_2_)

          UNDOCUMENTED Z-80 OPCODES by Bill  Smythe  is  reprinted
          from the CHICATRUG NEWS (Chicago TRS-80  Users'  Group).
          NORTHERN  BYTES  editor's  note:   This  is   the   most
          comprehensive article that I have seen to date  covering
          this subject!

          If you are willing to set  aside  your  Editor/Assembler
          for a while and take a direct look at the Z-80  opcodes,
          certain patterns will become apparent.  For example,  of
          the 256 possible opcodes (00 through FF)  all  but  four
          are in use as  one-byte  instructions.   Some  of  these
          stand alone;  others are followed by  one-  or  two-byte
          operands.  For example:

                  13           INC DE           (no operand)
                  3E nn        LD A,nn          (1-byte operand)
                  10 dd        DJNZ dd          (1-byte operand)
                  01 nn mm     LD BC,mmnn       (2-byte operand)

          The four missing opcodes are CB, DD, ED, and FD.   These
          serve as  "escape  codes"  to  alert  the  Z-80  that  a
          two-byte instruction is coming up.  Examples:

               CB C0           SET 0,B
               DD 21 nn mm     LD IX,mmnn
               ED 80           LDIR
               FD 2B           DEC IY

          Like the one-byte instructions, some two-byters are used
          with operands, while others stand alone.

          One of the first observations made by any Z-80 hacker is
          the parallel among HL, IX, and IY instructions:

                  21 nn mm     LD HL,mmnn
               DD 21 nn mm     LD IX,mmnn
               FD 21 nn mm     LD IY,mmnn
                  77           LD (HL),A
               DD 77 jj        LD (IX+jj),A
               FD 77 jj        LD (IY+jj),A

          Almost any instruction referring to HL can be changed to
          the corresponding instruction for IX or IY by  prefixing
          DD or FD, respectively.  When HL appears in parentheses,
          it becomes  (IX+jj)  or  (IY+jj),  where  the  index  jj
          appears in the opcode as the second byte  following  the
          DD or FD.  Meanwhile,  the  two-byte  opcodes  beginning
          with CB form an  orderly  set  of  shift,  rotate,  set,
          reset, and bit-test instructions, while  the  relatively
          disorganized ED set performs a variety of useful tasks.

          And then there are the combined prefixes DDCB and  FDCB.
          Their relationship to the CB codes are pretty much  what
          you would expect:

                  CB 46        BIT 0,(HL)
               DD CB jj 46     BIT 0,(IX+jj)
               FD CB jj 46     BIT 0,(IY+jj)

                               _T_h_e _F_u_n _B_e_g_i_n_s

          Everything said so far is pretty much common  knowledge,
          well-documented by Zilog, the  Z-80  manufacturer.   But
          what happens when DD or FD is prefixed to an instruction
          not containing HL?

                  37           SCF
                  C3 nn mm     JP mmnn
               DD 37           ?????
               FD C3 nn mm     ?????

          As far as I can determine, the prefixes in  these  cases
          have  no  effect.   The  two  instructions  shown   here
          continue to function as SCF and JP mmnn, respectively.

          But what if the instruction deals with either  H  or  L,
          but not HL?

                  24           INC H
                  2E nn        LD L,nn

          Just  as  the  register  pair  HL  is  made  up  of  two
          registers, H and  L,  it  appears  that  the  16-bit  IX
          register consists of two 8-bit registers, which I  shall
          call  HX  and  LX.   Similarly  for   IY.    The   above
          instructions become:

               DD 24           INC HX
               DD 2E nn        LD LX,nn
               FD 24           INC HY
               FD 2E nn        LD LY,nn

          The last instruction, for example, loads  the  low-order
          half of the IY register with the value nn while  leaving
          the high-order half untouched.

          If, however, an instruction contains both H and (HL), or
          both L and (HL), then only the (HL) part is affected  by
          the addition of DD or FD:

                  66           LD H,(HL)
               DD 66 jj        LD H,(IX+jj)
               FD 66 jj        LD H,(IY+jj)

          Adding a second DD or FD  in  front  has  no  additional
          effect.  Apparently, there are no such  instructions  as
          LD HX,(IX+jj) or LD HY,(IY+jj).

                           _W_h_a_t_'_s _Y_o_u_r _C_B _H_a_n_d_l_e_?

          The CB instructions are divided into four groups:

               CB00 through CB3F:     rotate and shift group
               CB40 through CB7F:     BIT testing
               CB08 through CBBF:     RESet group
               CBC0 through CBFF:     SET group

          Of these four groups, all seem complete except  for  the
          first.  The first group is divided into eight  subgroups
          of eight instructions each:

               CB00-CB07:      RLC (rotate left circular)
               CB08-CB0F:      RRC (rotate right circular)
               CB10-CB17:      RL  (rotate left through carry)
               CB18-CB1F:      RR  (rotate right through carry)
               CB20-CB27:      SLA (shift left arithmetic)
               CB28-CB2F:      SRA (shift right arithmetic)
               CB30-CB37:      ???????
               CB38-CB3F:      SRL (shift right logical)

          The missing CB30 group looks as though it ought to be  a
          shift left logical, whatever that is.  Trouble  is,  SLA
          (shift left arithmetic) is already pretty  logical.   So
          what's left for SLL to do?  As might  be  expected,  SLL
          shifts bits 0 through 6 leftward into bits 1 through  7,
          while bit 7 goes into the carry flag.   But  then  comes
          the surprise -- bit 0 is set.  Yes, Virginia, regardless
          of the previous status of any bit, or of any flag, bit 0
          is turned on.  Thus SLL, in effect, multiplies by 2  and
          adds 1.  As with the other CB instructions, the affected
          register is B, C, D, E, H, L, (HL), or  A  depending  on
          which instruction, CB30 through CB37, is used.

                     _C_o_m_b_i_n_a_t_i_o_n_s _a_n_d _M_o_r_e _C_o_m_b_i_n_a_t_i_o_n_s

          Of the combined opcodes,  DDCBjjxx  and  FDCBjjxx,  only
          every eighth one is documented by Zilog:

               DD CB jj 06     RLC (IX+jj)
               DD CB jj 0E     RRC (IX+jj)

          One might not expect much from those not  on  the  list,
          since the corresponding  DD-less  CB  instructions  have
          nothing to do with HL.  Not so,  however  --  a  lot  of
          weird stuff is going on here:

               DD CB jj 00     RLC B,(IX+jj)
               DD CB jj 01     RLC C,(IX+jj)
               DD CB jj 02     RLC D,(IX+jj)
               DD CB jj 03     RLC E,(IX+jj)
               DD CB jj 04     RLC H,(IX+jj)
               DD CB jj 05     RLC L,(IX+jj)
               DD CB jj 06     <documented, as above>
               DD CB jj 07     RLC A,(IX+jj)

          -- and similarly for RRC, RL, RR,  SLA,  SRA,  SLL,  and
          SRL.  But what does that mean, "RLC B,(IX+jj)"?   THat's
          just a name I chose for a peculiar phenomenon  in  which
          (IX+jj) is rotated left cirular, then copied into B.  In
          other words, RLC B,(IX+jj) is like RLC (IX+jj)  followed
          by LD B,(IX+jj).

          The SET and RESet instructions are even more curious:

               DD CB jj 80     RES B,0,(IX+jj)
               DD CB jj 81     RES C,0,(IX+jj)
               DD CB jj 82     RES D,0,(IX+jj)
               DD CB jj 83     RES E,0,(IX+jj)
               DD CB jj 84     RES H,0,(IX+jj)
               DD CB jj 85     RES L,0,(IX+jj)
               DD CB jj 86     <documented:  RES 0,(IX+jj)>
               DD CB jj 87     RES A,0,(IX+jj)

          I don't know how many Editor/Assemblers could  handle  3
          operands, even if they recognized undocumented  opcodes.
          I couldn't think  of  any  other  way  to  express  what
          happens -- (IX+jj) first has bit 0 reset, then is copied
          into the indicated register (e.g.  B).   The  action  is
          equivalent to RES 0,(IX+jj) followed  by  LD  B,(IX+jj).
          Of course, the same can be done with bits 1  through  7,
          with SET as well as RESet, and with IY as well as IX.

          The BIT instructions are less interesting.  Undocumented
          codes  DDCBjj40  through  DDCBjj47  turn   out   to   be
          equivalent to the documented version.  No  copying  into
          registers B, C, D, etc.  is done:

               DD CB jj 40     BIT 0,(IX+jj)
               DD CB jj 41     BIT 0,(IX+jj)
               DD CB jj 42     BIT 0,(IX+jj)
               DD CB jj 43     BIT 0,(IX+jj)
               DD CB jj 44     BIT 0,(IX+jj)
               DD CB jj 45     BIT 0,(IX+jj)
               DD CB jj 46     BIT 0,(IX+jj)  <documented>
               DD CB jj 47     BIT 0,(IX+jj)

                           _L_o_t_s _o_f _R_o_o_m _f_o_r _M_o_r_e

          My investigations into the ED group  yielded  little  of
          interest.  There were some duplications;   for  example,
          the eight instructions ED44,  ED4C,  ED54,  ED5C,  ED64,
          ED6C, ED74, ED7C all turned out to be NEG,  even  though
          only the first is documented  as  such.   I  also  found
          duplicates for RETN, RETI, IM 0, IM 1, and IM 2.   There
          were also a couple of "expected" duplicates:

               ED 63 nn mm     LD (mmnn),HL
               ED 6B nn mm     LD HL,(mmnn)

          -- but these instructions  already  exist,  and  execute
          faster, in the non-ED set.

          The ED group did provide a couple of lone curiosities:

               ED 70           IN --,(C)
               ED 71           OUT (C),--

          These appear where you would  expect  the  "missing"  IN
          (HL),(C) and OUT (C),(HL).  Nothing happens  with  (HL),
          though.  IN --,(C) appears to function like IN A,(C), IN
          B,(C),  etc.,  except  that  the  result  does  not   go
          anywhere.  The flags, however, are set as expected.  OUT
          (C),-- seems to output a zero to the port.

          I could not detect any action for the first  and  fourth
          quarters  of  the  ED  set,  ED00-ED3F  and   EDC0=EDFF.
          Three-fourths of the third quarter is also "missing", as
          are two instructions in the  second  quarter,  ED77  and
          ED7F.  This leaves room for  178  more  instructions  --
          anyone for an upgrade?  I'd  like  to  see  instructions
          like LD B,(DE) and CP (DE) and SUB (DE).


          I said that any HL instruction could be changed to IX or
          IY by simply prefixing DD or  FD.   That  was  a  little
          white  lie.   The   following   instructions   are   not
          convertible because they begin with ED:

               ED 42           SBC HL,BC
               ED 4A           ADC HL,BC
               ED 52           SBC HL,DE
               ED 5A           ADC HL,DE
               ED 62           SBC HL,HL
               ED 6A           ADC HL,HL
               ED 72           SBC HL,SP
               ED 7A           ADC HL,SP
               ED 67           RRD  <rotate right decimal (HL)>
               ED 6F           RLD  <rotate left decimal (HL)>

          In  addition,  the  following  instructions  cannot   be
          converted even though they are one-byters:

                  D9           EXX  <exchange all registers>
                  EB           EX DE,HL

          -- and the JP (HL) instruction becomes  JP  (IX)  or  JP
          (IY), not JP (IX+jj) or JP (IY+jj):

                  E9           JP (HL)
               DD E9           JP (IX)
               FD E9           JP (IY)

                           _O_n_e _a_t _a _t_i_m_e_, _P_l_e_a_s_e

          Except for  DDCB  and  FDCB,  there  is  no  benefit  in
          combining two or more of the four escape  codes.   There
          are three cases:

            (1) In the event of multiple DDs and/or FDs, all but
            the last will be ignored.

            (2) EDCB, EDDD,  EDED,  and  EDFD  will  be  ignored
            entirely since they lie in  the  inoperative  fourth
            quarter of the ED set.

            (3) If either DD or FD precedes ED, the former  will
            be ignored.

                             _A _W_o_r_d _o_f _C_a_u_t_i_o_n

          To any machine-language programmers whose appetites  may
          have been whetted:  Most Z-80 Editor/Assemblers  do  not
          recognize undocumented opcodes, so you'll have to  enter
          these codes as DEFBs.  More important, it is conceivable
          that not all Z-80s will respond to these  codes  in  the
          same way.  If you plan to sell your programs,  the  best
          advice is not to use undocumented instructions.

                _S_u_m_m_a_r_y _o_f _U_s_e_f_u_l _U_n_d_o_c_u_m_e_n_t_e_d _Z_-_8_0 _O_p_c_o_d_e_s

          DD24     INC HX     DD62  LD HX,D       DD8C  ADC A,HX
          DD25     DEC HX     DD63  LD HX,E       DD8D  ADC A,LX
          DD26 nn  LD HX,nn   DD64  LD HX,HX      DD94  SUB HX
          DD2C     INC LX     DD65  LD HX,LX      DD95  SUB LX
          DD2D     DEC LX     DD67  LD HX,A       DD9C  SBC A,HX
          DD2E nn  LD LX,nn   DD68  LD LX,B       DD9D  SBC A,LX
          DD44     LD B,HX    DD69  LD LX,C       DDA4  AND HX
          DD45     LD B,LX    DD6A  LD LX,D       DDA5  AND LX
          DD4C     LD C,HX    DD6B  LD LX,E       DDAC  XOR HX
          DD4D     LD C,LX    DD6C  LD LX,HX      DDAD  XOR LX
          DD54     LD D,HX    DD6D  LD LX,LX      DDB4  OR HX
          DD55     LD D,LX    DD6F  LD LX,A       DDB5  OR LX
          DD5C     LD E,LX    DD7C  LD A,HX       DDBC  CP HX
          DD5D     LD E,LX    DD7D  LD A,LX       DDBD  CP LX
          DD60     LD HX,B    DD84  ADD A,HX
          DD61     LD HX,C    DD85  ADD A,LX

          The corresponding instructions for  HY  and  LY  may  be
          obtained by using FD in place of DD.

                   CB30   SLL B            CB34   SLL H
                   CB31   SLL C            CB35   SLL L
                   CB32   SLL D            CB36   SLL (HL)
                   CB33   SLL E            CB37   SLL A
                     DDCBjj00-DDCBjj07   RLC r,(IX+jj)
                     DDCBjj00-DDCBjj0F   RRC r,(IX+jj)
                     DDCBjj10-DDCBjj17   RL r,(IX+jj)
                     DDCBjj18-DDCBJJ1F   RR r,(IX+jj)
                     DDCBjj20-DDCBjj27   SLA r,(IX+jj)
                     DDCBjj28-DDCBjj2F   SRL r,(IX+jj)
                     DDCBjj30-DDCBjj37   SLL r,(IX+jj)
                     DDCBjj38-DDCBjj3F   SRL r,(IX+jj)
                     DDCBjj80-DDCBjj87   RES r,0,(IX+jj)
                     DDCBjj88-DDCBjj8F   RES r,1,(IX+jj)
                     DDCBjj90-DDCBjj97   RES r,2,(IX+jj)
                     DDCBjj98-DDCBjj9F   RES r,3,(IX+jj)
                     DDCBjjA0-DDCBjjA7   RES r,4,(IX+jj)
                     DDCBjjA8-DDCBjjAF   RES r,5,(IX+jj)
                     DDCBjjB0-DDCBjjB7   RES r,6,(IX+jj)
                     DDCBjjB8-DDCBjjBF   RES r,7,(IX+jj)
                     DDCBjjC0-DDCBjjC7   SET r,0,(IX+jj)
                     DDCBjjC8-DDCBjjCF   SET r,1,(IX+jj)
                     DDCBjjD0-DDCBjjD7   SET r,2,(IX+jj)
                     DDCBjjD8-DDCBjjDF   SET r,3,(IX+jj)
                     DDCBjjE0-DDCBjjE7   SET r,4,(IX+jj)
                     DDCBjjE8-DDCBjjEF   SET r,5,(IX+jj)
                     DDCBjjF0-DDCBjjF7   SET r,6,(IX+jj)
                     DDCBjjF8-DDCBjjFF   SET r,7,(IX+jj)

          In the last 3 tables, the corresponding instructions for
          (IY+jj) may be obtained by using FD in place of DD.  The
          value of r is determined as follows:

                     Last digit of opcode:    register r:
                             0 or 8               B
                             1 or 9               C
                             2 or A               D
                             3 or B               E
                             4 or C               H
                             5 or D               L
                             6 or E            (blank)
                             7 or F               A