<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Mon, 06 Jul 1992 11:35:03 GMT
From   : cis.ohio-state.edu!zaphod.mps.ohio-state.edu!cs.utexas.edu!qt.cs.utexas.edu!yale.edu!ira.uka.de!news.belwue.de!news.uni-stuttgart.de!ifistg!weberj%dia.informatik.uni-stuttgart.de@ucbvax. (Weber)
Subject: undocumented Z80 Ops

As several people have asked me about the undocumented
Z80 Codes I know, here there is a description.
Also I appended a mail of Louis van Dompselaar who
tested them.
I am going to include further undocumented codes
into my Z80 emulator ZSIM (which you can get at
SIMTEL20 (192.88.110.20) in direct. pd1:<msdos.emulators>)

Juergen



Description of undocumented Z80 Op-Codes (as far as I know them)

The IX,IY registers can be used as 8 bit registers XL,XH,YL,YH
analoguous to H and L. They are coded as the corresponding H/L
operations with 0ddh/0fdh prefix for IX/IY.

e.g.:   8D  ADC A,L     ->     FD 8D  ADC A,LY


This works with all 8080 (that means no Z80 commands with CB or ED
prefix) commands that use the 8 bit register H or L. But note the
restriction, that only one register of the set { H,L,HX,LX,HY,LY } may
appear in the command. E.g.  LD L,LX does not work.
As far as I know  LD {LX,..,LY},immediate8 doesn't work either. (?)

TSTI (C) (Code ED 70) sets the flags corresponding to the value of
         port (C).

SLIA s   (shift left inverted arithmetic) works like SLA but
         bit 0 := 1
         It is coded as  CB 00110rrr  (rrr coded as in SLA).


The fellowing I learned some weeks ago (I found it in the German
magazine mc, 1/1982 page 27) but couldn't test any more as I
have sold my Z80 machine (and is NOT implemented in my 
Z80 emulator ZSIM12 at SIMTEL) 

DD CB ofs XX with XX=10bbbrrr,11bbbrrr [rrr=110 for (HL) is the
documented BIT|SET b,(IX+d) ] works as
CB ofs XX ( RES|SET (ix|y+d)) but afterwards rrr:=(ix|y+d). )
                     ^
                     |
                     The article I got the information had an L here
                     for LX but this seems to be a typing error.

I wonder if XX=01bbbrrr for BIT works too ?


DD CB ofs XX with XX=00cccrrr works as CB ofs XX with a CMD of
{RLCA,...,SRL, and SLIA}, but afterwards rrr:=(IX|Y+d).
With rrr=110 you get the documented CMD (IX|Y+d)
e.g. DD CB ofs 00101110 = SRA (IX+offs).

If you have access to a Zilog Z80 (I don't think that clones understand
the illegals) maybe you could test the codes I could not try.

If you execute DD CB 00 87 with IX=1080 and (0080)=FF and (1080)=0F
there should be FE in A afterwards or 0E if there was no typing error in
the magazine.

Please mail me the results. Thanks.


----- Louis van Dompselaar writes:  


  As I had some time left, I started working through the undocumented
  opcodes on both the Zilog Z80 and the SGS (not NEC) Z80B.
  Results for the other Z80s (yes, there seems to be yet another
  type in another machine, apart from the Sharp) will follow later:

  > The IX,IY registers can be used as 8 bit registers XL,XH,YL,YH
  > analoguous to H and L. They are coded as the corresponding H/L
  > operations with 0ddh/0fdh prefix for IX/IY.
  >
  These work on both the Zilog and the SGS.

  > appear in the command. E.g.  LD L,LX does not work.

  I figure this performs LD LX,LX, so it actually works, but doesn't
  really do anything

  > As far as I know  LD {LX,..,LY},immediate8 doesn't work either. (?)
  >
  This one DOES work! This means that LX etc. can be used (almost) as
  any other 8 bit register. However, something like LD (IX+d),LY won't
  work. I haven't tried LD (HL),LX though.

  > TSTI (C) (Code ED 70) sets the flags corresponding to the value of
  >          port (C).
  >
  Can't get this working on the SGS one yet, but no problems on the
  Zilog. Might be a did something wrong in the test routine (the SGS
  chip is in a system which I can only reach by downloading the
  testsoftware to it, and then receiving the results. It is connected
  to a main computer via a parallel (buffered) connection. I made
  this testroutine rather quick, so I might have confused something.

  > SLIA s   (shift left inverted arithmetic) works like SLA but
  >          bit 0 := 1
  >          It is coded as  CB 00110rrr  (rrr coded as in SLA).
  > 
  > 
  This one if a rather ordinary 'extra', because it has an opcode
  of its own. Supported by both the Zilog and the SGS.

  > DD CB ofs XX with XX=10bbbrrr,11bbbrrr [rrr=110 for (HL) is the
  > documented BIT|SET b,(IX+d) ] works as
  > CB ofs XX ( RES|SET (ix|y+d)) but afterwards rrr:=(ix|y+d). )
  >                      ^
  >                      |
  >                      The article I got the information had an L here
  >                      for LX but this seems to be a typing error.
  >
  IX or IY would indeed be the logical choice, and indeed this is what
  it turns out to be. I have only tested this on the Zilog so far, and
  it works fine with RES and SET.

  > I wonder if XX=01bbbrrr for BIT works too ?
  >
  You can use the opcodes with BIT, however, it doesn't load the
  result in a register, so it acts just like the documented one.

  > DD CB ofs XX with XX=00cccrrr works as CB ofs XX with a CMD of
  > {RLCA,...,SRL, and SLIA}, but afterwards rrr:=(IX|Y+d).
  > With rrr=110 you get the documented CMD (IX|Y+d)
  > e.g. DD CB ofs 00101110 = SRA (IX+offs).
  >
  They all work. Seeing this, I thought it was a rather logical thing
  to put into the Z80, as the result of a SLA (IX+d) (or whatever) is
  available in the ALU anyway, so putting it in a register might have
  its advantages while it doesn't cost any extra time.

  BTW, here's how I'm gonna try to speed up my system using these 
  opcodes. As mentioned, subsystems are connected to the main by
  means of parallel conections. These have a 1 byte buffer which has
  a 'full' flag. When transmitting large amounts of data, the routine
  would look something like this:

        LD C,<port>
        LD B,<2**bit>
        .
        .
  LOOP:  IN A,(C)
        AND  B
        JR NZ,LOOP
        IN A,(<inputport>)
         <store data>

  This could now be:

        LD C,<port>
        .
        .
  LOOP:  TSTI (C)
        JR NZ,LOOP
        IN A,(<inputport>)
         <store data>

  Provided that the right bit goes into the zero flag, of course. But as 
  these inputlines are still rather flexible, I can make them go there
  (or into the carry flag). Don't know the cycle times for TSTI, but
  it'll be faster than the IN/AND combination. When transmitting 64k of
  data, this saves a lot of AND's (64k, of course :-) ).

  (And I'll have to write my own assembler to handle them, or use defb's.
   Anyway, it's nice to see what disassemblers make of these:

   TSTI (C)  becomes  IN (HL),(C)   a logical 'error'
   LD A,LX   becomes  LD A,L        it just ignores the 0xDD
   A=(SET (IX+d),b) becomes  SET (IX+d),n  again, it ignores the register
difference
   SLIA C    becomes  ?????         it can't figure this one out!
   ).

   Anyway, I'll let you know the results for the other Z80s, and the rest
   of the SGS results later.

   Louis


-- 
-- 

Juergen G. Weber
Student am Institut fuer Informatik
Universitaet Stuttgart - Germany


End of INFO-CPM Digest V92 Issue #60
************************************
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>