Initial commit, subset of mame.git commit e17ff48, z80pack.git commit aca63ff
authorNick Downing <nick@ndcode.org>
Sat, 2 Mar 2019 23:15:41 +0000 (10:15 +1100)
committerNick Downing <nick@ndcode.org>
Sat, 2 Mar 2019 23:15:41 +0000 (10:15 +1100)
45 files changed:
LICENSE [new file with mode: 0644]
LICENSE.md [new file with mode: 0644]
iodevices/COPYING [new file with mode: 0644]
iodevices/unix_terminal.c [new file with mode: 0644]
iodevices/unix_terminal.h [new file with mode: 0644]
sim/COPYING [new file with mode: 0644]
sim/Makefile.bsd [new file with mode: 0644]
sim/Makefile.cygwin [new file with mode: 0644]
sim/Makefile.linux [new file with mode: 0644]
sim/Makefile.osx [new file with mode: 0644]
sim/Makefile.solaris [new file with mode: 0644]
sim/config.c [new file with mode: 0644]
sim/config.h [new file with mode: 0644]
sim/iosim.c [new file with mode: 0644]
sim/lnsrc [new file with mode: 0755]
sim/memory.c [new file with mode: 0644]
sim/memory.h [new file with mode: 0644]
sim/sim.h [new file with mode: 0644]
sim/sim0.c [new file with mode: 0644]
sim/sim1.c [new file with mode: 0644]
sim/sim1a.c [new file with mode: 0644]
sim/sim2.c [new file with mode: 0644]
sim/sim3.c [new file with mode: 0644]
sim/sim4.c [new file with mode: 0644]
sim/sim5.c [new file with mode: 0644]
sim/sim6.c [new file with mode: 0644]
sim/sim7.c [new file with mode: 0644]
sim/simctl.c [new file with mode: 0644]
sim/simfun.c [new file with mode: 0644]
sim/simglb.c [new file with mode: 0644]
sim/simglb.h [new file with mode: 0644]
sim/simint.c [new file with mode: 0644]
sim/ulnsrc [new file with mode: 0755]
z180/z180.cpp [new file with mode: 0644]
z180/z180.h [new file with mode: 0644]
z180/z180cb.hxx [new file with mode: 0644]
z180/z180dasm.cpp [new file with mode: 0644]
z180/z180dasm.h [new file with mode: 0644]
z180/z180dd.hxx [new file with mode: 0644]
z180/z180ed.hxx [new file with mode: 0644]
z180/z180fd.hxx [new file with mode: 0644]
z180/z180op.hxx [new file with mode: 0644]
z180/z180ops.h [new file with mode: 0644]
z180/z180tbl.h [new file with mode: 0644]
z180/z180xy.hxx [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..9ad2f49
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 1987-2017 Udo Munk
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644 (file)
index 0000000..b039d95
--- /dev/null
@@ -0,0 +1,366 @@
+The source code to MAME is provided under the GNU General Public License version 2 or later as of Git revision 35ccf865aa366845b574e1fdbc71c4866b3d6a0f and the release of MAME 0.172. Source files may also be licensed as specified in the file header. This license does not apply to prior versions of MAME.
+
+MAME is a registered trademark of Gregory Ember.
+
+The text of version 2 of the GNU General Public License follows.
+
+    Copyright (C) 1997-2019  MAMEDev and contributors
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+GNU GENERAL PUBLIC LICENSE
+==========================
+Version 2, June 1991
+
+> Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+# Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+#                     GNU GENERAL PUBLIC LICENSE                    #
+## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ##
+
+- *0\.* This License applies to any program or other work which contains
+       a notice placed by the copyright holder saying it may be distributed
+       under the terms of this General Public License.  The "Program", below,
+       refers to any such program or work, and a "work based on the Program"
+       means either the Program or any derivative work under copyright law:
+       that is to say, a work containing the Program or a portion of it,
+       either verbatim or with modifications and/or translated into another
+       language.  (Hereinafter, translation is included without limitation in
+       the term "modification".)  Each licensee is addressed as "you".
+
+       Activities other than copying, distribution and modification are not
+       covered by this License; they are outside its scope.  The act of
+       running the Program is not restricted, and the output from the Program
+       is covered only if its contents constitute a work based on the
+       Program (independent of having been made by running the Program).
+       Whether that is true depends on what the Program does.
+
+- 1\. You may copy and distribute verbatim copies of the Program's
+       source code as you receive it, in any medium, provided that you
+       conspicuously and appropriately publish on each copy an appropriate
+       copyright notice and disclaimer of warranty; keep intact all the
+       notices that refer to this License and to the absence of any warranty;
+       and give any other recipients of the Program a copy of this License
+       along with the Program.
+
+       You may charge a fee for the physical act of transferring a copy, and
+       you may at your option offer warranty protection in exchange for a fee.
+
+- 2\. You may modify your copy or copies of the Program or any portion
+       of it, thus forming a work based on the Program, and copy and
+       distribute such modifications or work under the terms of Section 1
+       above, provided that you also meet all of these conditions:
+
+               a) You must cause the modified files to carry prominent notices
+               stating that you changed the files and the date of any change.
+
+               b) You must cause any work that you distribute or publish, that in
+               whole or in part contains or is derived from the Program or any
+               part thereof, to be licensed as a whole at no charge to all third
+               parties under the terms of this License.
+
+               c) If the modified program normally reads commands interactively
+               when run, you must cause it, when started running for such
+               interactive use in the most ordinary way, to print or display an
+               announcement including an appropriate copyright notice and a
+               notice that there is no warranty (or else, saying that you provide
+               a warranty) and that users may redistribute the program under
+               these conditions, and telling the user how to view a copy of this
+               License.  (Exception: if the Program itself is interactive but
+               does not normally print such an announcement, your work based on
+               the Program is not required to print an announcement.)
+
+       These requirements apply to the modified work as a whole.  If
+       identifiable sections of that work are not derived from the Program,
+       and can be reasonably considered independent and separate works in
+       themselves, then this License, and its terms, do not apply to those
+       sections when you distribute them as separate works.  But when you
+       distribute the same sections as part of a whole which is a work based
+       on the Program, the distribution of the whole must be on the terms of
+       this License, whose permissions for other licensees extend to the
+       entire whole, and thus to each and every part regardless of who wrote it.
+
+       Thus, it is not the intent of this section to claim rights or contest
+       your rights to work written entirely by you; rather, the intent is to
+       exercise the right to control the distribution of derivative or
+       collective works based on the Program.
+
+       In addition, mere aggregation of another work not based on the Program
+       with the Program (or with a work based on the Program) on a volume of
+       a storage or distribution medium does not bring the other work under
+       the scope of this License.
+
+- 3\. You may copy and distribute the Program (or a work based on it,
+       under Section 2) in object code or executable form under the terms of
+       Sections 1 and 2 above provided that you also do one of the following:
+
+       a) Accompany it with the complete corresponding machine-readable
+       source code, which must be distributed under the terms of Sections
+       1 and 2 above on a medium customarily used for software interchange; or,
+
+       b) Accompany it with a written offer, valid for at least three
+       years, to give any third party, for a charge no more than your
+       cost of physically performing source distribution, a complete
+       machine-readable copy of the corresponding source code, to be
+       distributed under the terms of Sections 1 and 2 above on a medium
+       customarily used for software interchange; or,
+
+       c) Accompany it with the information you received as to the offer
+       to distribute corresponding source code.  (This alternative is
+       allowed only for noncommercial distribution and only if you
+       received the program in object code or executable form with such
+       an offer, in accord with Subsection b above.)
+
+       The source code for a work means the preferred form of the work for
+       making modifications to it.  For an executable work, complete source
+       code means all the source code for all modules it contains, plus any
+       associated interface definition files, plus the scripts used to
+       control compilation and installation of the executable.  However, as a
+       special exception, the source code distributed need not include
+       anything that is normally distributed (in either source or binary
+       form) with the major components (compiler, kernel, and so on) of the
+       operating system on which the executable runs, unless that component
+       itself accompanies the executable.
+
+       If distribution of executable or object code is made by offering
+       access to copy from a designated place, then offering equivalent
+       access to copy the source code from the same place counts as
+       distribution of the source code, even though third parties are not
+       compelled to copy the source along with the object code.
+
+- 4\. You may not copy, modify, sublicense, or distribute the Program
+       except as expressly provided under this License.  Any attempt
+       otherwise to copy, modify, sublicense or distribute the Program is
+       void, and will automatically terminate your rights under this License.
+       However, parties who have received copies, or rights, from you under
+       this License will not have their licenses terminated so long as such
+       parties remain in full compliance.
+
+- 5\. You are not required to accept this License, since you have not
+       signed it.  However, nothing else grants you permission to modify or
+       distribute the Program or its derivative works.  These actions are
+       prohibited by law if you do not accept this License.  Therefore, by
+       modifying or distributing the Program (or any work based on the
+       Program), you indicate your acceptance of this License to do so, and
+       all its terms and conditions for copying, distributing or modifying
+       the Program or works based on it.
+
+- 6\. Each time you redistribute the Program (or any work based on the
+       Program), the recipient automatically receives a license from the
+       original licensor to copy, distribute or modify the Program subject to
+       these terms and conditions.  You may not impose any further
+       restrictions on the recipients' exercise of the rights granted herein.
+       You are not responsible for enforcing compliance by third parties to
+       this License.
+
+- 7\. If, as a consequence of a court judgment or allegation of patent
+       infringement or for any other reason (not limited to patent issues),
+       conditions are imposed on you (whether by court order, agreement or
+       otherwise) that contradict the conditions of this License, they do not
+       excuse you from the conditions of this License.  If you cannot
+       distribute so as to satisfy simultaneously your obligations under this
+       License and any other pertinent obligations, then as a consequence you
+       may not distribute the Program at all.  For example, if a patent
+       license would not permit royalty-free redistribution of the Program by
+       all those who receive copies directly or indirectly through you, then
+       the only way you could satisfy both it and this License would be to
+       refrain entirely from distribution of the Program.
+
+       If any portion of this section is held invalid or unenforceable under
+       any particular circumstance, the balance of the section is intended to
+       apply and the section as a whole is intended to apply in other
+       circumstances.
+
+       It is not the purpose of this section to induce you to infringe any
+       patents or other property right claims or to contest validity of any
+       such claims; this section has the sole purpose of protecting the
+       integrity of the free software distribution system, which is
+       implemented by public license practices.  Many people have made
+       generous contributions to the wide range of software distributed
+       through that system in reliance on consistent application of that
+       system; it is up to the author/donor to decide if he or she is willing
+       to distribute software through any other system and a licensee cannot
+       impose that choice.
+
+       This section is intended to make thoroughly clear what is believed to
+       be a consequence of the rest of this License.
+
+- 8\. If the distribution and/or use of the Program is restricted in
+       certain countries either by patents or by copyrighted interfaces, the
+       original copyright holder who places the Program under this License
+       may add an explicit geographical distribution limitation excluding
+       those countries, so that distribution is permitted only in or among
+       countries not thus excluded.  In such case, this License incorporates
+       the limitation as if written in the body of this License.
+
+- 9\. The Free Software Foundation may publish revised and/or new versions
+       of the General Public License from time to time.  Such new versions will
+       be similar in spirit to the present version, but may differ in detail to
+       address new problems or concerns.
+
+       Each version is given a distinguishing version number.  If the Program
+       specifies a version number of this License which applies to it and "any
+       later version", you have the option of following the terms and conditions
+       either of that version or of any later version published by the Free
+       Software Foundation.  If the Program does not specify a version number of
+       this License, you may choose any version ever published by the Free Software
+       Foundation.
+
+- 10\. If you wish to incorporate parts of the Program into other free
+       programs whose distribution conditions are different, write to the author
+       to ask for permission.  For software which is copyrighted by the Free
+       Software Foundation, write to the Free Software Foundation; we sometimes
+       make exceptions for this.  Our decision will be guided by the two goals
+       of preserving the free status of all derivatives of our free software and
+       of promoting the sharing and reuse of software generally.
+
+
+## NO WARRANTY
+
+- 11\. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+       FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+       OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+       PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+       OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+       MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+       TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+       PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+       REPAIR OR CORRECTION.
+
+- 12\. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+       WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+       REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+       INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+       OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+       TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+       YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+       PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGES.
+
+##                      END OF TERMS AND CONDITIONS                      ##
+
+---------------------------------------------------------------------------
+
+###            How to Apply These Terms to Your New Programs            ###
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+  Also add information on how to contact you by electronic and paper mail.
+
+  If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+  The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+  You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+       Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+       `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+       <signature of Ty Coon>, 1 April 1989
+       Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/iodevices/COPYING b/iodevices/COPYING
new file mode 100644 (file)
index 0000000..9df1384
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 2008-2017 Udo Munk
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/iodevices/unix_terminal.c b/iodevices/unix_terminal.c
new file mode 100644 (file)
index 0000000..b8e370f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Common I/O devices used by various simulated machines
+ *
+ * Copyright (C) 2008-2017 by Udo Munk
+ *
+ * This module contains initialisation and reset functions for
+ * the POSIX/BSD line discipline, so that stdin/stdout can be used
+ * as terminal for ancient machines.
+ *
+ * History:
+ * 24-SEP-08 first version finished
+ * 16-JAN-14 discard input at reset
+ * 15-APR-14 added some more c_cc's used on BSD systems
+ * 24-FEB-17 set line discipline only if fd 0 is a tty
+ */
+
+#include <unistd.h>
+#include <termios.h>
+
+struct termios old_term, new_term;
+
+static int init_flag;
+
+void set_unix_terminal(void)
+{
+       if (init_flag || !isatty(0))
+               return;
+
+       tcgetattr(0, &old_term);
+       new_term = old_term;
+
+       new_term.c_lflag &= ~(ICANON | ECHO);
+       new_term.c_iflag &= ~(IXON | IXANY | IXOFF);
+       new_term.c_iflag &= ~(IGNCR | ICRNL | INLCR);
+       new_term.c_oflag &= ~(ONLCR | OCRNL);
+
+       /* these are common for all UNIX's nowadays */
+       new_term.c_cc[VMIN] = 1;
+       new_term.c_cc[VINTR] = 0;
+       new_term.c_cc[VSUSP] = 0;
+
+       /* some newer ones from BSD's */
+#ifdef VDSUSP
+       new_term.c_cc[VDSUSP] = 0;
+#endif
+#ifdef VDISCARD
+       new_term.c_cc[VDISCARD] = 0;
+#endif
+#ifdef VLNEXT
+       new_term.c_cc[VLNEXT] = 0;
+#endif
+
+       tcsetattr(0, TCSADRAIN, &new_term);
+
+       init_flag++;
+}
+
+void reset_unix_terminal(void)
+{
+       if (!init_flag || !isatty(0))
+               return;
+
+       tcsetattr(0, TCSAFLUSH, &old_term);
+
+       init_flag--;
+}
diff --git a/iodevices/unix_terminal.h b/iodevices/unix_terminal.h
new file mode 100644 (file)
index 0000000..855007e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Common I/O devices used by various simulated machines
+ *
+ * Copyright (C) 2008-2017 by Udo Munk
+ *
+ * This module contains initialisation and reset functions for
+ * the POSIX/BSD line discipline, so that stdin/stdout can be used
+ * as terminal for ancient machines.
+ *
+ * History:
+ * 24-SEP-08 first version finished
+ * 16-JAN-14 discard input at reset
+ * 15-APR-14 added some more c_cc's used on BSD systems
+ * 24-FEB-17 set line discipline only if fd 0 is a tty
+ */
+
+#include <termios.h>
+
+extern struct termios old_term, new_term;
+
+extern void set_unix_terminal(void);
+extern void reset_unix_terminal(void);
diff --git a/sim/COPYING b/sim/COPYING
new file mode 100644 (file)
index 0000000..9ad2f49
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 1987-2017 Udo Munk
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/sim/Makefile.bsd b/sim/Makefile.bsd
new file mode 100644 (file)
index 0000000..b69bee0
--- /dev/null
@@ -0,0 +1,113 @@
+# system wide location for machines configuration files
+CONF=/usr/local/share/cpmsim/conf
+
+# system wide location for disk images
+DISKS=/usr/local/share/cpmsim/disks
+
+CC = cc
+
+# Development
+#CFLAGS = -O3 -c -Wall -Wextra -Wno-self-assign -fstack-protector-all -D_FORTIFY_SOURCE=2 -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Production
+CFLAGS = -O3 -c -Wall -Wextra -Wno-self-assign -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+LFLAGS =
+
+OBJ =   sim0.o \
+       sim1.o \
+       sim1a.o \
+       sim2.o \
+       sim3.o \
+       sim4.o \
+       sim5.o \
+       sim6.o \
+       sim7.o \
+       simctl.o \
+       simint.o \
+       memory.o \
+       iosim.o \
+       simfun.o \
+       simglb.o \
+       unix_terminal.o \
+       config.o
+
+all: /tmp/.z80pack/cpmsim.auxin /tmp/.z80pack/cpmsim.auxout ../cpmsim
+       @echo
+       @echo "Done."
+       @echo
+
+/tmp/.z80pack/cpmsim.auxin:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxin || mkfifo /tmp/.z80pack/cpmsim.auxin
+
+/tmp/.z80pack/cpmsim.auxout:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxout || mkfifo /tmp/.z80pack/cpmsim.auxout
+
+../cpmsim : $(OBJ)
+       $(CC) $(OBJ) $(LFLAGS) -o ../cpmsim
+
+sim0.c:
+       ./lnsrc
+
+sim0.o : sim0.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim0.c
+
+sim1.o : sim1.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1.c
+
+sim1a.o : sim1a.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1a.c
+
+sim2.o : sim2.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim2.c
+
+sim3.o : sim3.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim3.c
+
+sim4.o : sim4.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim4.c
+
+sim5.o : sim5.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim5.c
+
+sim6.o : sim6.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim6.c
+
+sim7.o : sim7.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim7.c
+
+simctl.o : simctl.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) simctl.c
+
+simint.o : simint.c sim.h simglb.h
+       $(CC) $(CFLAGS) simint.c
+
+memory.o : memory.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) memory.c
+
+iosim.o : iosim.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) iosim.c
+
+simfun.o : simfun.c sim.h
+       $(CC) $(CFLAGS) simfun.c
+
+simglb.o : simglb.c sim.h
+       $(CC) $(CFLAGS) simglb.c
+
+unix_terminal.o : ../../iodevices/unix_terminal.c
+       $(CC) $(CFLAGS) ../../iodevices/unix_terminal.c
+
+config.o : config.c
+       $(CC) $(CFLAGS) config.c
+
+clean:
+       rm -f *.o
+       ./ulnsrc
+
+allclean:
+       make -f Makefile.bsd clean
+       rm -f ../cpmsim
+       rm -f ../auxiliaryin.txt ../auxiliaryout.txt ../printer.txt
+       rm -f ../disks/drive*.dsk
diff --git a/sim/Makefile.cygwin b/sim/Makefile.cygwin
new file mode 100644 (file)
index 0000000..9809c79
--- /dev/null
@@ -0,0 +1,113 @@
+# system wide location for machines configuration files
+CONF=/usr/local/share/cpmsim/conf
+
+# system wide location for disk images
+DISKS=/usr/local/share/cpmsim/disks
+
+CC = gcc
+
+# Development
+#CFLAGS = -O3 -c -Wall -Wextra -fstack-protector-all -D_FORTIFY_SOURCE=2 -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Production
+CFLAGS = -O3 -c -Wall -Wextra -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+LFLAGS =
+
+OBJ =   sim0.o \
+       sim1.o \
+       sim1a.o \
+       sim2.o \
+       sim3.o \
+       sim4.o \
+       sim5.o \
+       sim6.o \
+       sim7.o \
+       simctl.o \
+       simint.o \
+       memory.o \
+       iosim.o \
+       simfun.o \
+       simglb.o \
+       unix_terminal.o \
+       config.o
+
+all: /tmp/.z80pack/cpmsim.auxin /tmp/.z80pack/cpmsim.auxout ../cpmsim
+       @echo
+       @echo "Done."
+       @echo
+
+/tmp/.z80pack/cpmsim.auxin:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxin || mknod /tmp/.z80pack/cpmsim.auxin p
+
+/tmp/.z80pack/cpmsim.auxout:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxout || mknod /tmp/.z80pack/cpmsim.auxout p
+
+../cpmsim : $(OBJ)
+       $(CC) $(OBJ) $(LFLAGS) -o ../cpmsim
+
+sim0.c:
+       ./lnsrc
+
+sim0.o : sim0.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim0.c
+
+sim1.o : sim1.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1.c
+
+sim1a.o : sim1a.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1a.c
+
+sim2.o : sim2.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim2.c
+
+sim3.o : sim3.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim3.c
+
+sim4.o : sim4.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim4.c
+
+sim5.o : sim5.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim5.c
+
+sim6.o : sim6.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim6.c
+
+sim7.o : sim7.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim7.c
+
+simctl.o : simctl.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) simctl.c
+
+simint.o : simint.c sim.h simglb.h
+       $(CC) $(CFLAGS) simint.c
+
+memory.o : memory.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) memory.c
+
+iosim.o : iosim.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) iosim.c
+
+simfun.o : simfun.c sim.h
+       $(CC) $(CFLAGS) simfun.c
+
+simglb.o : simglb.c sim.h
+       $(CC) $(CFLAGS) simglb.c
+
+unix_terminal.o : ../../iodevices/unix_terminal.c
+       $(CC) $(CFLAGS) ../../iodevices/unix_terminal.c
+
+config.o : config.c
+       $(CC) $(CFLAGS) config.c
+
+clean:
+       rm -f *.o
+       ./ulnsrc
+
+allclean:
+       make -f Makefile.cygwin clean
+       rm -f ../cpmsim.exe
+       rm -f ../auxiliaryin.txt ../auxiliaryout.txt ../printer.txt
+       rm -f ../disks/drive*.dsk
diff --git a/sim/Makefile.linux b/sim/Makefile.linux
new file mode 100644 (file)
index 0000000..d76b24a
--- /dev/null
@@ -0,0 +1,116 @@
+# system wide location for machines configuration files
+CONF=/usr/local/share/cpmsim/conf
+
+# system wide location for disk images
+DISKS=/usr/local/share/cpmsim/disks
+
+CC = gcc
+
+# Development
+#CFLAGS = -O3 -c -Wall -Wextra -fstack-protector-all -D_FORTIFY_SOURCE=2 -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Production
+CFLAGS = -O3 -c -Wall -Wextra -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Debugging
+#CFLAGS = -g -c -Wall -Wextra -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+LFLAGS =
+
+OBJ =   sim0.o \
+       sim1.o \
+       sim1a.o \
+       sim2.o \
+       sim3.o \
+       sim4.o \
+       sim5.o \
+       sim6.o \
+       sim7.o \
+       simctl.o \
+       simint.o \
+       memory.o \
+       iosim.o \
+       simfun.o \
+       simglb.o \
+       unix_terminal.o \
+       config.o
+
+all: /tmp/.z80pack/cpmsim.auxin /tmp/.z80pack/cpmsim.auxout ../cpmsim
+       @echo
+       @echo "Done."
+       @echo
+
+/tmp/.z80pack/cpmsim.auxin:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxin || mknod /tmp/.z80pack/cpmsim.auxin p
+
+/tmp/.z80pack/cpmsim.auxout:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxout || mknod /tmp/.z80pack/cpmsim.auxout p
+
+../cpmsim : $(OBJ)
+       $(CC) $(OBJ) $(LFLAGS) -o ../cpmsim
+
+sim0.c:
+       ./lnsrc
+
+sim0.o : sim0.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim0.c
+
+sim1.o : sim1.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1.c
+
+sim1a.o : sim1a.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1a.c
+
+sim2.o : sim2.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim2.c
+
+sim3.o : sim3.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim3.c
+
+sim4.o : sim4.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim4.c
+
+sim5.o : sim5.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim5.c
+
+sim6.o : sim6.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim6.c
+
+sim7.o : sim7.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim7.c
+
+simctl.o : simctl.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) simctl.c
+
+simint.o : simint.c sim.h simglb.h
+       $(CC) $(CFLAGS) simint.c
+
+memory.o : memory.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) memory.c
+
+iosim.o : iosim.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) iosim.c
+
+simfun.o : simfun.c sim.h
+       $(CC) $(CFLAGS) simfun.c
+
+simglb.o : simglb.c sim.h
+       $(CC) $(CFLAGS) simglb.c
+
+unix_terminal.o : ../../iodevices/unix_terminal.c
+       $(CC) $(CFLAGS) ../../iodevices/unix_terminal.c
+
+config.o : config.c
+       $(CC) $(CFLAGS) config.c
+
+clean:
+       rm -f *.o
+       ./ulnsrc
+
+allclean:
+       make -f Makefile.linux clean
+       rm -f ../cpmsim
+       rm -f ../auxiliaryin.txt ../auxiliaryout.txt ../printer.txt
+       rm -f ../disks/drive*.dsk
diff --git a/sim/Makefile.osx b/sim/Makefile.osx
new file mode 100644 (file)
index 0000000..b171976
--- /dev/null
@@ -0,0 +1,113 @@
+# system wide location for machines configuration files
+CONF=/usr/local/share/cpmsim/conf
+
+# system wide location for disk images
+DISKS=/usr/local/share/cpmsim/disks
+
+CC = gcc
+
+# Development
+#CFLAGS = -O3 -c -Wall -Wextra -Wno-self-assign -fstack-protector-all -D_FORTIFY_SOURCE=2 -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Production
+CFLAGS = -O3 -c -Wall -Wextra -Wno-self-assign -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+LFLAGS =
+
+OBJ =   sim0.o \
+       sim1.o \
+       sim1a.o \
+       sim2.o \
+       sim3.o \
+       sim4.o \
+       sim5.o \
+       sim6.o \
+       sim7.o \
+       simctl.o \
+       simint.o \
+       memory.o \
+       iosim.o \
+       simfun.o \
+       simglb.o \
+       unix_terminal.o \
+       config.o
+
+all: /tmp/.z80pack/cpmsim.auxin /tmp/.z80pack/cpmsim.auxout ../cpmsim
+       @echo
+       @echo "Done."
+       @echo
+
+/tmp/.z80pack/cpmsim.auxin:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxin || mkfifo /tmp/.z80pack/cpmsim.auxin
+
+/tmp/.z80pack/cpmsim.auxout:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxout || mkfifo /tmp/.z80pack/cpmsim.auxout
+
+../cpmsim : $(OBJ)
+       $(CC) $(OBJ) $(LFLAGS) -o ../cpmsim
+
+sim0.c:
+       ./lnsrc
+
+sim0.o : sim0.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim0.c
+
+sim1.o : sim1.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1.c
+
+sim1a.o : sim1a.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1a.c
+
+sim2.o : sim2.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim2.c
+
+sim3.o : sim3.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim3.c
+
+sim4.o : sim4.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim4.c
+
+sim5.o : sim5.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim5.c
+
+sim6.o : sim6.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim6.c
+
+sim7.o : sim7.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim7.c
+
+simctl.o : simctl.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) simctl.c
+
+simint.o : simint.c sim.h simglb.h
+       $(CC) $(CFLAGS) simint.c
+
+memory.o : memory.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) memory.c
+
+iosim.o : iosim.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) iosim.c
+
+simfun.o : simfun.c sim.h
+       $(CC) $(CFLAGS) simfun.c
+
+simglb.o : simglb.c sim.h
+       $(CC) $(CFLAGS) simglb.c
+
+unix_terminal.o : ../../iodevices/unix_terminal.c
+       $(CC) $(CFLAGS) ../../iodevices/unix_terminal.c
+
+config.o : config.c
+       $(CC) $(CFLAGS) config.c
+
+clean:
+       rm -f *.o
+       ./ulnsrc
+
+allclean:
+       make -f Makefile.osx clean
+       rm -f ../cpmsim
+       rm -f ../auxiliaryin.txt ../auxiliaryout.txt ../printer.txt
+       rm -f ../disks/drive*.dsk
diff --git a/sim/Makefile.solaris b/sim/Makefile.solaris
new file mode 100644 (file)
index 0000000..8d0e631
--- /dev/null
@@ -0,0 +1,113 @@
+# system wide location for machines configuration files
+CONF=/usr/local/share/cpmsim/conf
+
+# system wide location for disk images
+DISKS=/usr/local/share/cpmsim/disks
+
+CC = gcc
+
+# Development
+#CFLAGS = -O3 -m64 -c -Wall -Wextra -fstack-protector-all -D_FORTIFY_SOURCE=2 -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+# Production
+CFLAGS = -O3 -m64 -c -Wall -Wextra -U_FORTIFY_SOURCE -DCONFDIR=\"${CONF}\" -DDISKSDIR=\"${DISKS}\"
+
+LFLAGS = -m64 -lsocket -lnsl
+
+OBJ =   sim0.o \
+       sim1.o \
+       sim1a.o \
+       sim2.o \
+       sim3.o \
+       sim4.o \
+       sim5.o \
+       sim6.o \
+       sim7.o \
+       simctl.o \
+       simint.o \
+       memory.o \
+       iosim.o \
+       simfun.o \
+       simglb.o \
+       unix_terminal.o \
+       config.o
+
+all: /tmp/.z80pack/cpmsim.auxin /tmp/.z80pack/cpmsim.auxout ../cpmsim
+       @echo
+       @echo "Done."
+       @echo
+
+/tmp/.z80pack/cpmsim.auxin:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxin || /usr/sbin/mknod /tmp/.z80pack/cpmsim.auxin p
+
+/tmp/.z80pack/cpmsim.auxout:
+       test -d /tmp/.z80pack || mkdir /tmp/.z80pack
+       test -f /tmp/.z80pack/cpmsim.auxout || /usr/sbin/mknod /tmp/.z80pack/cpmsim.auxout p
+
+../cpmsim : $(OBJ)
+       $(CC) $(OBJ) $(LFLAGS) -o ../cpmsim
+
+sim0.c:
+       ./lnsrc
+
+sim0.o : sim0.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim0.c
+
+sim1.o : sim1.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1.c
+
+sim1a.o : sim1a.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim1a.c
+
+sim2.o : sim2.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim2.c
+
+sim3.o : sim3.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim3.c
+
+sim4.o : sim4.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim4.c
+
+sim5.o : sim5.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim5.c
+
+sim6.o : sim6.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim6.c
+
+sim7.o : sim7.c sim.h simglb.h config.h memory.h
+       $(CC) $(CFLAGS) sim7.c
+
+simctl.o : simctl.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) simctl.c
+
+simint.o : simint.c sim.h simglb.h
+       $(CC) $(CFLAGS) simint.c
+
+memory.o : memory.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) memory.c
+
+iosim.o : iosim.c sim.h simglb.h memory.h
+       $(CC) $(CFLAGS) iosim.c
+
+simfun.o : simfun.c sim.h
+       $(CC) $(CFLAGS) simfun.c
+
+simglb.o : simglb.c sim.h
+       $(CC) $(CFLAGS) simglb.c
+
+unix_terminal.o : ../../iodevices/unix_terminal.c
+       $(CC) $(CFLAGS) ../../iodevices/unix_terminal.c
+
+config.o : config.c
+       $(CC) $(CFLAGS) config.c
+
+clean:
+       rm -f *.o
+       ./ulnsrc
+
+allclean:
+       make -f Makefile.solaris clean
+       rm -f ../cpmsim
+       rm -f ../auxiliaryin.txt ../auxiliaryout.txt ../printer.txt
+       rm -f ../disks/drive*.dsk
diff --git a/sim/config.c b/sim/config.c
new file mode 100644 (file)
index 0000000..2033fb8
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 2016 by Udo Munk
+ *
+ * This module reads the system configuration file and sets
+ * global variables, so that the system can be configured.
+ *
+ * History:
+ * 20-DEC-16 dummy, no configuration implemented yet
+ */
+
+void config(void)
+{
+}
diff --git a/sim/config.h b/sim/config.h
new file mode 100644 (file)
index 0000000..2b4649f
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 2016 by Udo Munk
+ *
+ * This module reads the system configuration file and sets
+ * global variables, so that the system can be configured.
+ *
+ * History:
+ * 20-DEC-16 dummy, no configuration implemented yet
+ */
+
+extern void config(void);
diff --git a/sim/iosim.c b/sim/iosim.c
new file mode 100644 (file)
index 0000000..ba4bdd4
--- /dev/null
@@ -0,0 +1,2754 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * This module contains a complex I/O-simulation for running
+ * CP/M, MP/M, UCSD p-System...
+ *
+ * Please note this doesn't emulate any hardware which
+ * ever existed, we've got all virtual circuits in here!
+ *
+ * History:
+ * 28-SEP-1987 Development on TARGON/35 with AT&T Unix System V.3
+ * 19-MAY-1989 Additions for CP/M 3.0 and MP/M
+ * 23-DEC-1990 Ported to COHERENT 3.0
+ * 10-JUN-1992 Some optimisation done
+ * 25-JUN-1992 Flush output of stdout only at every OUT to port 0
+ * 25-JUN-1992 Comments in english and ported to COHERENT 4.0
+ * 05-OCT-2006 modified to compile on modern POSIX OS's
+ * 18-NOV-2006 added a second harddisk
+ * 08-DEC-2006 modified MMU so that segment size can be configured
+ * 10-DEC-2006 started adding serial port for a passive TCP/IP socket
+ * 14-DEC-2006 started adding serial port for a client TCP/IP socket
+ * 25-DEC-2006 CPU speed option and 100 ticks interrupt
+ * 19-FEB-2007 improved networking
+ * 22-JUL-2007 added second FDC sector port for implementing large harddisks
+ * 30-OCT-2007 printer port returns EOF on input
+ * 03-SEP-2007 improved the clock chip for support of other OS's
+ * 19-SEP-2007 delay circuit modified to delay x * 10ms
+ * 05-DEC-2007 fixed socket shutdown issues for NetBSD
+ * 06-DEC-2007 added hardware control port to reset I/O, CPU and reboot and such
+ * 07-DEC-2007 conditional compile pipes for aux device, problems with Cygwin
+ * 17-DEC-2007 conditional compile async TCP/IP server, problems with Cygwin
+ * 03-FEB-2008 added hardware control port to reset CPU, MMU and abort sim
+ * 07-APR-2008 added port to set/get CPU speed
+ * 13-AUG-2008 work on console I/O busy waiting detection
+ * 24-AUG-2008 changed terminal line discipline to not add CR if LF send
+ * xx-OCT-2008 some improvements here and there
+ * xx-JAN-2014 some improvements here and there
+ * 02-MAR-2014 source cleanup and improvements
+ * 03-MAI-2014 improved network code, telnet negotiation rewritten
+ * 16-JUL-2014 unused I/O ports need to return FF, see survey.mac
+ * 17-SEP-2014 FDC error 8 for DMA overrun, as reported by Alan Cox
+ * 17-SEP-2014 fixed bug in MMU bank select, as reported by Alan Cox
+ * 31-JAN-2015 took over some improvements made for the Z-1 emulation
+ * 28-FEB-2015 cleanup for 1.25 release
+ * 09-MAR-2016 moved pipes to /tmp/.z80pack
+ * 14-MAR-2016 renamed the used disk images to drivex.dsk
+ * 12-MAY-2016 find disk images at -d <path>, ./disks and DISKSDIR
+ * 22-JUL-2016 added support for read only disks
+ * 21-DEC-2016 moved MMU out to the new memory interface module
+ * 20-MAR-2017 renamed pipes for auxin/auxout
+ * 29-JUN-2017 system reset overworked
+ */
+
+/*
+ *     This module contains the I/O handlers for a simulation
+ *     of the hardware required for a CP/M / MP/M system.
+ *
+ *     Used I/O ports:
+ *
+ *      0 - console status
+ *      1 - console data
+ *
+ *      2 - printer status
+ *      3 - printer data
+ *
+ *      4 - auxiliary status
+ *      5 - auxiliary data
+ *
+ *     10 - FDC drive
+ *     11 - FDC track
+ *     12 - FDC sector (low)
+ *     13 - FDC command
+ *     14 - FDC status
+ *
+ *     15 - DMA destination address low
+ *     16 - DMA destination address high
+ *
+ *     17 - FDC sector high
+ *
+ *     20 - MMU initialisation
+ *     21 - MMU bank select
+ *     22 - MMU select segment size (in pages a 256 bytes)
+ *     23 - MMU write protect/unprotect common memory segment
+ *
+ *     25 - clock command
+ *     26 - clock data
+ *     27 - 10ms timer causing maskable interrupt
+ *     28 - x * 10ms delay circuit for busy waiting loops
+ *     29 - hardware control
+ *     30 - CPU speed low
+ *     31 - CPU speed high
+ *
+ *     40 - passive socket #1 status
+ *     41 - passive socket #1 data
+ *     42 - passive socket #2 status
+ *     43 - passive socket #2 data
+ *     44 - passive socket #3 status
+ *     45 - passive socket #3 data
+ *     46 - passive socket #4 status
+ *     47 - passive socket #4 data
+ *
+ *     50 - client socket #1 status
+ *     51 - client socket #1 data
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <time.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include "sim.h"
+#include "simglb.h"
+#include "memory.h"
+
+#define BUFSIZE 256            /* max line length of command buffer */
+#define MAX_BUSY_COUNT 10      /* max counter to detect I/O busy waiting
+                                  on the console status port */
+
+extern int boot(void);
+extern void reset_cpu(void);
+
+static BYTE drive;             /* current drive A..P (0..15) */
+static BYTE track;             /* current track (0..255) */
+static unsigned int sector;    /* current sector (0..65535) */
+static BYTE status;            /* status of last I/O operation on FDC */
+static BYTE dmadl;             /* current DMA address destination low */
+static BYTE dmadh;             /* current DMA address destination high */
+static BYTE clkcmd;            /* clock command */
+static BYTE clkfmt;            /* clock format, 0 = BCD, 1 = decimal */
+static BYTE timer;             /* 10ms timer */
+static int drivea;             /* fd for file "drivea.dsk" */
+static int driveb;             /* fd for file "driveb.dsk" */
+static int drivec;             /* fd for file "drivec.dsk" */
+static int drived;             /* fd for file "drived.dsk" */
+static int drivee;             /* fd for file "drivee.dsk" */
+static int drivef;             /* fd for file "drivef.dsk" */
+static int driveg;             /* fd for file "driveg.dsk" */
+static int driveh;             /* fd for file "driveh.dsk" */
+static int drivei;             /* fd for file "drivei.dsk" */
+static int drivej;             /* fd for file "drivej.dsk" */
+static int drivek;             /* fd for file "drivek.dsk" */
+static int drivel;             /* fd for file "drivel.dsk" */
+static int drivem;             /* fd for file "drivem.dsk" */
+static int driven;             /* fd for file "driven.dsk" */
+static int driveo;             /* fd for file "driveo.dsk" */
+static int drivep;             /* fd for file "drivep.dsk" */
+static int printer;            /* fd for file "printer.txt" */
+static int speed;              /* to reset CPU speed */
+static char fn[4096];          /* path/filename for disk images */
+
+#ifdef PIPES
+static int auxin;              /* fd for pipe "auxin" */
+static int auxout;             /* fd for pipe "auxout" */
+static int aux_in_eof;         /* status of pipe "auxin" (<>0 means EOF) */
+static int pid_rec;            /* PID of the receiving process for auxiliary */
+#else
+static int aux_in;             /* fd for file "auxiliaryin.txt" */
+static int aux_in_lf;          /* linefeed flag for aux_in */
+static int aux_out;            /* fd for file "auxiliaryout.txt" */
+#endif
+
+#ifdef NETWORKING
+
+#define TELNET_TIMEOUT 800     /* telnet negotiation timeout in milliseconds */
+
+static int ss[NUMSOC];         /* server socket descriptors */
+static int ssc[NUMSOC];                /* connected server socket descriptors */
+static int ss_port[NUMSOC];    /* TCP/IP port for server sockets */
+static int ss_telnet[NUMSOC];  /* telnet protocol flag for server sockets */
+static int cs;                 /* client socket #1 descriptor */
+static int cs_port;            /* TCP/IP port for cs */
+static char cs_host[BUFSIZE];  /* hostname for cs */
+
+#ifdef CNETDEBUG
+static int cdirection = -1; /* protocol direction, 0 = send, 1 = receive */
+#endif
+
+#ifdef SNETDEBUG
+static int sdirection = -1; /* protocol direction, 0 = send 1 = receive */
+#endif
+
+#endif
+
+struct dskdef disks[16] = {
+       { "drivea.dsk", &drivea, 77, 26 },
+       { "driveb.dsk", &driveb, 77, 26 },
+       { "drivec.dsk", &drivec, 77, 26 },
+       { "drived.dsk", &drived, 77, 26 },
+       { "drivee.dsk", &drivee, -1, -1 },
+       { "drivef.dsk", &drivef, -1, -1 },
+       { "driveg.dsk", &driveg, -1, -1 },
+       { "driveh.dsk", &driveh, -1, -1 },
+       { "drivei.dsk", &drivei, 255, 128 },
+       { "drivej.dsk", &drivej, 255, 128 },
+       { "drivek.dsk", &drivek, -1, -1 },
+       { "drivel.dsk", &drivel, -1, -1 },
+       { "drivem.dsk", &drivem, -1, -1 },
+       { "driven.dsk", &driven, -1, -1 },
+       { "driveo.dsk", &driveo, -1, -1 },
+       { "drivep.dsk", &drivep, 256, 16384 }
+};
+
+/*
+ *     Forward declaration of the I/O handlers for all used ports
+ */
+static BYTE io_trap_in(void);
+static void io_trap_out(BYTE);
+static BYTE cond_in(void), cons_in(void);
+static void cond_out(BYTE), cons_out(BYTE);
+static BYTE prtd_in(void), prts_in(void);
+static void prtd_out(BYTE), prts_out(BYTE);
+static BYTE auxd_in(void), auxs_in(void);
+static void auxd_out(BYTE), auxs_out(BYTE);
+static BYTE fdcd_in(void);
+static void fdcd_out(BYTE);
+static BYTE fdct_in(void);
+static void fdct_out(BYTE);
+static BYTE fdcs_in(void);
+static void fdcs_out(BYTE);
+static BYTE fdcsh_in(void);
+static void fdcsh_out(BYTE);
+static BYTE fdco_in(void);
+static void fdco_out(BYTE);
+static BYTE fdcx_in(void);
+static void fdcx_out(BYTE);
+static BYTE dmal_in(void);
+static void dmal_out(BYTE);
+static BYTE dmah_in(void);
+static void dmah_out(BYTE);
+static BYTE mmui_in(void), mmus_in(void), mmuc_in(void);
+static void mmui_out(BYTE), mmus_out(BYTE), mmuc_out(BYTE);
+static BYTE mmup_in(void);
+static void mmup_out(BYTE);
+static BYTE clkc_in(void), clkd_in(void);
+static void clkc_out(BYTE), clkd_out(BYTE);
+static BYTE time_in(void);
+static void time_out(BYTE);
+static BYTE delay_in(void);
+static void delay_out(BYTE);
+static BYTE hwctl_in(void);
+static void hwctl_out(BYTE);
+static BYTE speedl_in(void), speedh_in(void);
+static void speedl_out(BYTE), speedh_out(BYTE);
+static BYTE cond1_in(void), cons1_in(void);
+static void cond1_out(BYTE), cons1_out(BYTE);
+static BYTE cond2_in(void), cons2_in(void);
+static void cond2_out(BYTE), cons2_out(BYTE);
+static BYTE cond3_in(void), cons3_in(void);
+static void cond3_out(BYTE), cons3_out(BYTE);
+static BYTE cond4_in(void), cons4_in(void);
+static void cond4_out(BYTE), cons4_out(BYTE);
+static BYTE netd1_in(void), nets1_in(void);
+static void netd1_out(BYTE), nets1_out(BYTE);
+
+/*
+ *     Forward declaration of support functions
+ */
+static int to_bcd(int), get_date(struct tm *);
+static void int_timer(int);
+
+#ifdef NETWORKING
+static void net_server_config(void), net_client_config(void);
+static void init_server_socket(int), telnet_negotiation(int);
+#ifdef TCPASYNC
+static void int_io(int);
+#endif
+#endif
+
+/*
+ *     This array contains function pointers for every
+ *     input port.
+ */
+static BYTE (*port_in[256]) (void) = {
+       cons_in,                /* port 0 */
+       cond_in,                /* port 1 */
+       prts_in,                /* port 2 */
+       prtd_in,                /* port 3 */
+       auxs_in,                /* port 4 */
+       auxd_in,                /* port 5 */
+       io_trap_in,             /* port 6 */
+       io_trap_in,             /* port 7 */
+       io_trap_in,             /* port 8 */
+       io_trap_in,             /* port 9 */
+       fdcd_in,                /* port 10 */
+       fdct_in,                /* port 11 */
+       fdcs_in,                /* port 12 */
+       fdco_in,                /* port 13 */
+       fdcx_in,                /* port 14 */
+       dmal_in,                /* port 15 */
+       dmah_in,                /* port 16 */
+       fdcsh_in,               /* port 17 */
+       io_trap_in,             /* port 18 */
+       io_trap_in,             /* port 19 */
+       mmui_in,                /* port 20 */
+       mmus_in,                /* port 21 */
+       mmuc_in,                /* port 22 */
+       mmup_in,                /* port 23 */
+       io_trap_in,             /* port 24 */
+       clkc_in,                /* port 25 */
+       clkd_in,                /* port 26 */
+       time_in,                /* port 27 */
+       delay_in,               /* port 28 */
+       hwctl_in,               /* port 29 */
+       speedl_in,              /* port 30 */
+       speedh_in,              /* port 31 */
+       io_trap_in,             /* port 32 */
+       io_trap_in,             /* port 33 */
+       io_trap_in,             /* port 34 */
+       io_trap_in,             /* port 35 */
+       io_trap_in,             /* port 36 */
+       io_trap_in,             /* port 37 */
+       io_trap_in,             /* port 38 */
+       io_trap_in,             /* port 39 */
+       cons1_in,               /* port 40 */
+       cond1_in,               /* port 41 */
+       cons2_in,               /* port 42 */
+       cond2_in,               /* port 43 */
+       cons3_in,               /* port 44 */
+       cond3_in,               /* port 45 */
+       cons4_in,               /* port 46 */
+       cond4_in,               /* port 47 */
+       io_trap_in,             /* port 48 */
+       io_trap_in,             /* port 49 */
+       nets1_in,               /* port 50 */
+       netd1_in,               /* port 51 */
+       io_trap_in,             /* port 52 */
+       io_trap_in,             /* port 53 */
+       io_trap_in,             /* port 54 */
+       io_trap_in,             /* port 55 */
+       io_trap_in,             /* port 56 */
+       io_trap_in,             /* port 57 */
+       io_trap_in,             /* port 58 */
+       io_trap_in,             /* port 59 */
+       io_trap_in,             /* port 60 */
+       io_trap_in,             /* port 61 */
+       io_trap_in,             /* port 62 */
+       io_trap_in,             /* port 63 */
+       io_trap_in,             /* port 64 */
+       io_trap_in,             /* port 65 */
+       io_trap_in,             /* port 66 */
+       io_trap_in,             /* port 67 */
+       io_trap_in,             /* port 68 */
+       io_trap_in,             /* port 69 */
+       io_trap_in,             /* port 70 */
+       io_trap_in,             /* port 71 */
+       io_trap_in,             /* port 72 */
+       io_trap_in,             /* port 73 */
+       io_trap_in,             /* port 74 */
+       io_trap_in,             /* port 75 */
+       io_trap_in,             /* port 76 */
+       io_trap_in,             /* port 77 */
+       io_trap_in,             /* port 78 */
+       io_trap_in,             /* port 79 */
+       io_trap_in,             /* port 80 */
+       io_trap_in,             /* port 81 */
+       io_trap_in,             /* port 82 */
+       io_trap_in,             /* port 83 */
+       io_trap_in,             /* port 84 */
+       io_trap_in,             /* port 85 */
+       io_trap_in,             /* port 86 */
+       io_trap_in,             /* port 87 */
+       io_trap_in,             /* port 88 */
+       io_trap_in,             /* port 89 */
+       io_trap_in,             /* port 90 */
+       io_trap_in,             /* port 91 */
+       io_trap_in,             /* port 92 */
+       io_trap_in,             /* port 93 */
+       io_trap_in,             /* port 94 */
+       io_trap_in,             /* port 95 */
+       io_trap_in,             /* port 96 */
+       io_trap_in,             /* port 97 */
+       io_trap_in,             /* port 98 */
+       io_trap_in,             /* port 99 */
+       io_trap_in,             /* port 100 */
+       io_trap_in,             /* port 101 */
+       io_trap_in,             /* port 102 */
+       io_trap_in,             /* port 103 */
+       io_trap_in,             /* port 104 */
+       io_trap_in,             /* port 105 */
+       io_trap_in,             /* port 106 */
+       io_trap_in,             /* port 107 */
+       io_trap_in,             /* port 108 */
+       io_trap_in,             /* port 109 */
+       io_trap_in,             /* port 110 */
+       io_trap_in,             /* port 111 */
+       io_trap_in,             /* port 112 */
+       io_trap_in,             /* port 113 */
+       io_trap_in,             /* port 114 */
+       io_trap_in,             /* port 115 */
+       io_trap_in,             /* port 116 */
+       io_trap_in,             /* port 117 */
+       io_trap_in,             /* port 118 */
+       io_trap_in,             /* port 119 */
+       io_trap_in,             /* port 120 */
+       io_trap_in,             /* port 121 */
+       io_trap_in,             /* port 122 */
+       io_trap_in,             /* port 123 */
+       io_trap_in,             /* port 124 */
+       io_trap_in,             /* port 125 */
+       io_trap_in,             /* port 126 */
+       io_trap_in,             /* port 127 */
+       io_trap_in,             /* port 128 */
+       io_trap_in,             /* port 129 */
+       io_trap_in,             /* port 130 */
+       io_trap_in,             /* port 131 */
+       io_trap_in,             /* port 132 */
+       io_trap_in,             /* port 133 */
+       io_trap_in,             /* port 134 */
+       io_trap_in,             /* port 135 */
+       io_trap_in,             /* port 136 */
+       io_trap_in,             /* port 137 */
+       io_trap_in,             /* port 138 */
+       io_trap_in,             /* port 139 */
+       io_trap_in,             /* port 140 */
+       io_trap_in,             /* port 141 */
+       io_trap_in,             /* port 142 */
+       io_trap_in,             /* port 143 */
+       io_trap_in,             /* port 144 */
+       io_trap_in,             /* port 145 */
+       io_trap_in,             /* port 146 */
+       io_trap_in,             /* port 147 */
+       io_trap_in,             /* port 148 */
+       io_trap_in,             /* port 149 */
+       io_trap_in,             /* port 150 */
+       io_trap_in,             /* port 151 */
+       io_trap_in,             /* port 152 */
+       io_trap_in,             /* port 153 */
+       io_trap_in,             /* port 154 */
+       io_trap_in,             /* port 155 */
+       io_trap_in,             /* port 156 */
+       io_trap_in,             /* port 157 */
+       io_trap_in,             /* port 158 */
+       io_trap_in,             /* port 159 */
+       io_trap_in,             /* port 160 */
+       io_trap_in,             /* port 161 */
+       io_trap_in,             /* port 162 */
+       io_trap_in,             /* port 163 */
+       io_trap_in,             /* port 164 */
+       io_trap_in,             /* port 165 */
+       io_trap_in,             /* port 166 */
+       io_trap_in,             /* port 167 */
+       io_trap_in,             /* port 168 */
+       io_trap_in,             /* port 169 */
+       io_trap_in,             /* port 170 */
+       io_trap_in,             /* port 171 */
+       io_trap_in,             /* port 172 */
+       io_trap_in,             /* port 173 */
+       io_trap_in,             /* port 174 */
+       io_trap_in,             /* port 175 */
+       io_trap_in,             /* port 176 */
+       io_trap_in,             /* port 177 */
+       io_trap_in,             /* port 178 */
+       io_trap_in,             /* port 179 */
+       io_trap_in,             /* port 180 */
+       io_trap_in,             /* port 181 */
+       io_trap_in,             /* port 182 */
+       io_trap_in,             /* port 183 */
+       io_trap_in,             /* port 184 */
+       io_trap_in,             /* port 185 */
+       io_trap_in,             /* port 186 */
+       io_trap_in,             /* port 187 */
+       io_trap_in,             /* port 188 */
+       io_trap_in,             /* port 189 */
+       io_trap_in,             /* port 190 */
+       io_trap_in,             /* port 191 */
+       io_trap_in,             /* port 192 */
+       io_trap_in,             /* port 193 */
+       io_trap_in,             /* port 194 */
+       io_trap_in,             /* port 195 */
+       io_trap_in,             /* port 196 */
+       io_trap_in,             /* port 197 */
+       io_trap_in,             /* port 198 */
+       io_trap_in,             /* port 199 */
+       io_trap_in,             /* port 200 */
+       io_trap_in,             /* port 201 */
+       io_trap_in,             /* port 202 */
+       io_trap_in,             /* port 203 */
+       io_trap_in,             /* port 204 */
+       io_trap_in,             /* port 205 */
+       io_trap_in,             /* port 206 */
+       io_trap_in,             /* port 207 */
+       io_trap_in,             /* port 208 */
+       io_trap_in,             /* port 209 */
+       io_trap_in,             /* port 210 */
+       io_trap_in,             /* port 211 */
+       io_trap_in,             /* port 212 */
+       io_trap_in,             /* port 213 */
+       io_trap_in,             /* port 214 */
+       io_trap_in,             /* port 215 */
+       io_trap_in,             /* port 216 */
+       io_trap_in,             /* port 217 */
+       io_trap_in,             /* port 218 */
+       io_trap_in,             /* port 219 */
+       io_trap_in,             /* port 220 */
+       io_trap_in,             /* port 221 */
+       io_trap_in,             /* port 222 */
+       io_trap_in,             /* port 223 */
+       io_trap_in,             /* port 224 */
+       io_trap_in,             /* port 225 */
+       io_trap_in,             /* port 226 */
+       io_trap_in,             /* port 227 */
+       io_trap_in,             /* port 228 */
+       io_trap_in,             /* port 229 */
+       io_trap_in,             /* port 230 */
+       io_trap_in,             /* port 231 */
+       io_trap_in,             /* port 232 */
+       io_trap_in,             /* port 233 */
+       io_trap_in,             /* port 234 */
+       io_trap_in,             /* port 235 */
+       io_trap_in,             /* port 236 */
+       io_trap_in,             /* port 237 */
+       io_trap_in,             /* port 238 */
+       io_trap_in,             /* port 239 */
+       io_trap_in,             /* port 240 */
+       io_trap_in,             /* port 241 */
+       io_trap_in,             /* port 242 */
+       io_trap_in,             /* port 243 */
+       io_trap_in,             /* port 244 */
+       io_trap_in,             /* port 245 */
+       io_trap_in,             /* port 246 */
+       io_trap_in,             /* port 247 */
+       io_trap_in,             /* port 248 */
+       io_trap_in,             /* port 249 */
+       io_trap_in,             /* port 250 */
+       io_trap_in,             /* port 251 */
+       io_trap_in,             /* port 252 */
+       io_trap_in,             /* port 253 */
+       io_trap_in,             /* port 254 */
+       io_trap_in              /* port 255 */
+};
+
+/*
+ *     This array contains function pointers for every
+ *     output port.
+ */
+static void (*port_out[256]) (BYTE) = {
+       cons_out,               /* port 0 */
+       cond_out,               /* port 1 */
+       prts_out,               /* port 2 */
+       prtd_out,               /* port 3 */
+       auxs_out,               /* port 4 */
+       auxd_out,               /* port 5 */
+       io_trap_out,            /* port 6 */
+       io_trap_out,            /* port 7 */
+       io_trap_out,            /* port 8 */
+       io_trap_out,            /* port 9 */
+       fdcd_out,               /* port 10 */
+       fdct_out,               /* port 11 */
+       fdcs_out,               /* port 12 */
+       fdco_out,               /* port 13 */
+       fdcx_out,               /* port 14 */
+       dmal_out,               /* port 15 */
+       dmah_out,               /* port 16 */
+       fdcsh_out,              /* port 17 */
+       io_trap_out,            /* port 18 */
+       io_trap_out,            /* port 19 */
+       mmui_out,               /* port 20 */
+       mmus_out,               /* port 21 */
+       mmuc_out,               /* port 22 */
+       mmup_out,               /* port 23 */
+       io_trap_out,            /* port 24 */
+       clkc_out,               /* port 25 */
+       clkd_out,               /* port 26 */
+       time_out,               /* port 27 */
+       delay_out,              /* port 28 */
+       hwctl_out,              /* port 29 */
+       speedl_out,             /* port 30 */
+       speedh_out,             /* port 31 */
+       io_trap_out,            /* port 32 */
+       io_trap_out,            /* port 33 */
+       io_trap_out,            /* port 34 */
+       io_trap_out,            /* port 35 */
+       io_trap_out,            /* port 36 */
+       io_trap_out,            /* port 37 */
+       io_trap_out,            /* port 38 */
+       io_trap_out,            /* port 39 */
+       cons1_out,              /* port 40 */
+       cond1_out,              /* port 41 */
+       cons2_out,              /* port 42 */
+       cond2_out,              /* port 43 */
+       cons3_out,              /* port 44 */
+       cond3_out,              /* port 45 */
+       cons4_out,              /* port 46 */
+       cond4_out,              /* port 47 */
+       io_trap_out,            /* port 48 */
+       io_trap_out,            /* port 49 */
+       nets1_out,              /* port 50 */
+       netd1_out,              /* port 51 */
+       io_trap_out,            /* port 52 */
+       io_trap_out,            /* port 53 */
+       io_trap_out,            /* port 54 */
+       io_trap_out,            /* port 55 */
+       io_trap_out,            /* port 56 */
+       io_trap_out,            /* port 57 */
+       io_trap_out,            /* port 58 */
+       io_trap_out,            /* port 59 */
+       io_trap_out,            /* port 60 */
+       io_trap_out,            /* port 61 */
+       io_trap_out,            /* port 62 */
+       io_trap_out,            /* port 63 */
+       io_trap_out,            /* port 64 */
+       io_trap_out,            /* port 65 */
+       io_trap_out,            /* port 66 */
+       io_trap_out,            /* port 67 */
+       io_trap_out,            /* port 68 */
+       io_trap_out,            /* port 69 */
+       io_trap_out,            /* port 70 */
+       io_trap_out,            /* port 71 */
+       io_trap_out,            /* port 72 */
+       io_trap_out,            /* port 73 */
+       io_trap_out,            /* port 74 */
+       io_trap_out,            /* port 75 */
+       io_trap_out,            /* port 76 */
+       io_trap_out,            /* port 77 */
+       io_trap_out,            /* port 78 */
+       io_trap_out,            /* port 79 */
+       io_trap_out,            /* port 80 */
+       io_trap_out,            /* port 81 */
+       io_trap_out,            /* port 82 */
+       io_trap_out,            /* port 83 */
+       io_trap_out,            /* port 84 */
+       io_trap_out,            /* port 85 */
+       io_trap_out,            /* port 86 */
+       io_trap_out,            /* port 87 */
+       io_trap_out,            /* port 88 */
+       io_trap_out,            /* port 89 */
+       io_trap_out,            /* port 90 */
+       io_trap_out,            /* port 91 */
+       io_trap_out,            /* port 92 */
+       io_trap_out,            /* port 93 */
+       io_trap_out,            /* port 94 */
+       io_trap_out,            /* port 95 */
+       io_trap_out,            /* port 96 */
+       io_trap_out,            /* port 97 */
+       io_trap_out,            /* port 98 */
+       io_trap_out,            /* port 99 */
+       io_trap_out,            /* port 100 */
+       io_trap_out,            /* port 101 */
+       io_trap_out,            /* port 102 */
+       io_trap_out,            /* port 103 */
+       io_trap_out,            /* port 104 */
+       io_trap_out,            /* port 105 */
+       io_trap_out,            /* port 106 */
+       io_trap_out,            /* port 107 */
+       io_trap_out,            /* port 108 */
+       io_trap_out,            /* port 109 */
+       io_trap_out,            /* port 110 */
+       io_trap_out,            /* port 111 */
+       io_trap_out,            /* port 112 */
+       io_trap_out,            /* port 113 */
+       io_trap_out,            /* port 114 */
+       io_trap_out,            /* port 115 */
+       io_trap_out,            /* port 116 */
+       io_trap_out,            /* port 117 */
+       io_trap_out,            /* port 118 */
+       io_trap_out,            /* port 119 */
+       io_trap_out,            /* port 120 */
+       io_trap_out,            /* port 121 */
+       io_trap_out,            /* port 122 */
+       io_trap_out,            /* port 123 */
+       io_trap_out,            /* port 124 */
+       io_trap_out,            /* port 125 */
+       io_trap_out,            /* port 126 */
+       io_trap_out,            /* port 127 */
+       io_trap_out,            /* port 128 */
+       io_trap_out,            /* port 129 */
+       io_trap_out,            /* port 130 */
+       io_trap_out,            /* port 131 */
+       io_trap_out,            /* port 132 */
+       io_trap_out,            /* port 133 */
+       io_trap_out,            /* port 134 */
+       io_trap_out,            /* port 135 */
+       io_trap_out,            /* port 136 */
+       io_trap_out,            /* port 137 */
+       io_trap_out,            /* port 138 */
+       io_trap_out,            /* port 139 */
+       io_trap_out,            /* port 140 */
+       io_trap_out,            /* port 141 */
+       io_trap_out,            /* port 142 */
+       io_trap_out,            /* port 143 */
+       io_trap_out,            /* port 144 */
+       io_trap_out,            /* port 145 */
+       io_trap_out,            /* port 146 */
+       io_trap_out,            /* port 147 */
+       io_trap_out,            /* port 148 */
+       io_trap_out,            /* port 149 */
+       io_trap_out,            /* port 150 */
+       io_trap_out,            /* port 151 */
+       io_trap_out,            /* port 152 */
+       io_trap_out,            /* port 153 */
+       io_trap_out,            /* port 154 */
+       io_trap_out,            /* port 155 */
+       io_trap_out,            /* port 156 */
+       io_trap_out,            /* port 157 */
+       io_trap_out,            /* port 158 */
+       io_trap_out,            /* port 159 */
+       io_trap_out,            /* port 160 */
+       io_trap_out,            /* port 161 */
+       io_trap_out,            /* port 162 */
+       io_trap_out,            /* port 163 */
+       io_trap_out,            /* port 164 */
+       io_trap_out,            /* port 165 */
+       io_trap_out,            /* port 166 */
+       io_trap_out,            /* port 167 */
+       io_trap_out,            /* port 168 */
+       io_trap_out,            /* port 169 */
+       io_trap_out,            /* port 170 */
+       io_trap_out,            /* port 171 */
+       io_trap_out,            /* port 172 */
+       io_trap_out,            /* port 173 */
+       io_trap_out,            /* port 174 */
+       io_trap_out,            /* port 175 */
+       io_trap_out,            /* port 176 */
+       io_trap_out,            /* port 177 */
+       io_trap_out,            /* port 178 */
+       io_trap_out,            /* port 179 */
+       io_trap_out,            /* port 180 */
+       io_trap_out,            /* port 181 */
+       io_trap_out,            /* port 182 */
+       io_trap_out,            /* port 183 */
+       io_trap_out,            /* port 184 */
+       io_trap_out,            /* port 185 */
+       io_trap_out,            /* port 186 */
+       io_trap_out,            /* port 187 */
+       io_trap_out,            /* port 188 */
+       io_trap_out,            /* port 189 */
+       io_trap_out,            /* port 190 */
+       io_trap_out,            /* port 191 */
+       io_trap_out,            /* port 192 */
+       io_trap_out,            /* port 193 */
+       io_trap_out,            /* port 194 */
+       io_trap_out,            /* port 195 */
+       io_trap_out,            /* port 196 */
+       io_trap_out,            /* port 197 */
+       io_trap_out,            /* port 198 */
+       io_trap_out,            /* port 199 */
+       io_trap_out,            /* port 200 */
+       io_trap_out,            /* port 201 */
+       io_trap_out,            /* port 202 */
+       io_trap_out,            /* port 203 */
+       io_trap_out,            /* port 204 */
+       io_trap_out,            /* port 205 */
+       io_trap_out,            /* port 206 */
+       io_trap_out,            /* port 207 */
+       io_trap_out,            /* port 208 */
+       io_trap_out,            /* port 209 */
+       io_trap_out,            /* port 210 */
+       io_trap_out,            /* port 211 */
+       io_trap_out,            /* port 212 */
+       io_trap_out,            /* port 213 */
+       io_trap_out,            /* port 214 */
+       io_trap_out,            /* port 215 */
+       io_trap_out,            /* port 216 */
+       io_trap_out,            /* port 217 */
+       io_trap_out,            /* port 218 */
+       io_trap_out,            /* port 219 */
+       io_trap_out,            /* port 220 */
+       io_trap_out,            /* port 221 */
+       io_trap_out,            /* port 222 */
+       io_trap_out,            /* port 223 */
+       io_trap_out,            /* port 224 */
+       io_trap_out,            /* port 225 */
+       io_trap_out,            /* port 226 */
+       io_trap_out,            /* port 227 */
+       io_trap_out,            /* port 228 */
+       io_trap_out,            /* port 229 */
+       io_trap_out,            /* port 230 */
+       io_trap_out,            /* port 231 */
+       io_trap_out,            /* port 232 */
+       io_trap_out,            /* port 233 */
+       io_trap_out,            /* port 234 */
+       io_trap_out,            /* port 235 */
+       io_trap_out,            /* port 236 */
+       io_trap_out,            /* port 237 */
+       io_trap_out,            /* port 238 */
+       io_trap_out,            /* port 239 */
+       io_trap_out,            /* port 240 */
+       io_trap_out,            /* port 241 */
+       io_trap_out,            /* port 242 */
+       io_trap_out,            /* port 243 */
+       io_trap_out,            /* port 244 */
+       io_trap_out,            /* port 245 */
+       io_trap_out,            /* port 246 */
+       io_trap_out,            /* port 247 */
+       io_trap_out,            /* port 248 */
+       io_trap_out,            /* port 249 */
+       io_trap_out,            /* port 250 */
+       io_trap_out,            /* port 251 */
+       io_trap_out,            /* port 252 */
+       io_trap_out,            /* port 253 */
+       io_trap_out,            /* port 254 */
+       io_trap_out             /* port 255 */
+};
+
+/*
+ *     This function initialises the I/O handlers:
+ *     1. Open the files which emulate the disk drives.
+ *        Errors for opening one of the drives results
+ *        in a NULL pointer for fd in the dskdef structure,
+ *        so that this drive can't be used.
+ *     2. Creates the named pipes under /tmp/.z80pack, if they don't
+ *        exist.
+ *     3. Fork the process for receiving from the auxiliary serial port.
+ *     4. Open the named pipes "auxin" and "auxout" for simulation
+ *        of the auxiliary serial port.
+ *     5. Prepare TCP/IP sockets for serial port simulation
+ */
+void init_io(void)
+{
+       register int i;
+       struct stat sbuf;
+#if defined(NETWORKING) && defined(TCPASYNC)
+       static struct sigaction newact;
+#endif
+
+       for (i = 0; i <= 15; i++) {
+
+               /* if option -d is used disks are there */
+               if (diskdir != NULL) {
+                       strcpy(fn, diskd);
+               } else {
+                       /* if not first try ./disks */
+                       if ((stat("./disks", &sbuf) == 0) && 
+                           S_ISDIR(sbuf.st_mode)) {
+                               strcpy(fn, "./disks");
+                       /* nope, then DISKSDIR as set in Makefile */
+                       } else {
+                               strcpy(fn, DISKSDIR);
+                       }
+               }
+
+               strcat(fn, "/");
+               strcat(fn, disks[i].fn);
+
+               if ((*disks[i].fd = open(fn, O_RDWR)) == -1)
+                       if ((*disks[i].fd = open(fn, O_RDONLY)) == -1)
+                               disks[i].fd = NULL;
+       }
+
+#ifdef PIPES
+       /* check if /tmp/.z80pack exists */
+       if (stat("/tmp/.z80pack", &sbuf) != 0)
+               mkdir("/tmp/.z80pack", 0777);   /* no, create it */
+       /* and then the pipes */
+       if (stat("/tmp/.z80pack/cpmsim.auxin", &sbuf) != 0)
+               mknod("/tmp/.z80pack/cpmsim.auxin", 0666 | S_IFIFO, 0);
+       if (stat("/tmp/.z80pack/cpmsim.auxout", &sbuf) != 0)
+               mknod("/tmp/.z80pack/cpmsim.auxout", 0666 | S_IFIFO, 0);
+
+       pid_rec = fork();
+       switch (pid_rec) {
+       case -1:
+               puts("can't fork");
+               exit(1);
+       case 0:
+               /* . might not be in path, so check that first */
+               if (access("./receive", X_OK) == 0)
+                       execlp("./receive", "receive", "auxiliaryout.txt",
+                               (char *) NULL);
+               /* should be in path somewhere */
+               else
+                       execlp("receive", "receive", "auxiliaryout.txt",
+                               (char *) NULL);
+               /* if not cry and die */
+               puts("can't exec receive process, compile/install the tools dude");
+               kill(0, SIGQUIT);
+               exit(1);
+       }
+       if ((auxin = open("/tmp/.z80pack/cpmsim.auxin", O_RDONLY | O_NDELAY)) == -1) {
+               perror("pipe auxin");
+               exit(1);
+       }
+       if ((auxout = open("/tmp/.z80pack/cpmsim.auxout", O_WRONLY)) == -1) {
+               perror("pipe auxout");
+               exit(1);
+       }
+#endif
+
+#ifdef NETWORKING
+       net_server_config();
+       net_client_config();
+
+#ifdef TCPASYNC
+       newact.sa_handler = int_io;
+       memset((void *) &newact.sa_mask, 0, sizeof(newact.sa_mask));
+       newact.sa_flags = 0;
+       sigaction(SIGIO, &newact, NULL);
+#endif
+
+       for (i = 0; i < NUMSOC; i++)
+               init_server_socket(i);
+#endif
+}
+
+#ifdef NETWORKING
+/*
+ * initialise a server socket
+ */
+static void init_server_socket(int n)
+{
+       struct sockaddr_in sin;
+       int on = 1;
+#ifdef TCPASYNC
+       int i;
+#endif
+
+       if (ss_port[n] == 0)
+               return;
+       if ((ss[n] = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+               perror("create server socket");
+               exit(1);
+       }
+       if (setsockopt(ss[n], SOL_SOCKET, SO_REUSEADDR, (void *) &on,
+           sizeof(on)) == -1) {
+               perror("setsockopt SO_REUSEADDR on server socket");
+               exit(1);
+       }
+#ifdef TCPASYNC
+       fcntl(ss[n], F_SETOWN, getpid());
+       i = fcntl(ss[n], F_GETFL, 0);
+       if (fcntl(ss[n], F_SETFL, i | FASYNC) == -1) {
+               perror("fcntl FASYNC on server socket");
+               exit(1);
+       }
+#endif
+       memset((void *) &sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = INADDR_ANY;
+       sin.sin_port = htons(ss_port[n]);
+       if (bind(ss[n], (struct sockaddr *) &sin, sizeof(sin)) == -1) {
+               perror("bind server socket");
+               exit(1);
+       }
+       if (listen(ss[n], 0) == -1) {
+               perror("listen on server socket");
+               exit(1);
+       }
+}
+
+/*
+ * Read and process network server configuration file
+ */
+static void net_server_config(void)
+{
+       register int i;
+       FILE *fp;
+       char buf[BUFSIZE];
+       char *s;
+       char fn[4096];
+
+       strcpy(&fn[0], &confdir[0]);
+       strcat(&fn[0], "/net_server.conf");
+
+       if ((fp = fopen(fn, "r")) != NULL) {
+               printf("Server network configuration:\n");
+               s = &buf[0];
+               while (fgets(s, BUFSIZE, fp) != NULL) {
+                       if ((*s == '\n') || (*s == '#'))
+                               continue;
+                       i = atoi(s);
+                       if ((i < 1) || (i > 4)) {
+                               printf("console %d not supported\n", i);
+                               continue;
+                       }
+                       while((*s != ' ') && (*s != '\t'))
+                               s++;
+                       while((*s == ' ') || (*s == '\t'))
+                               s++;
+                       ss_telnet[i - 1] = atoi(s);
+                       while((*s != ' ') && (*s != '\t'))
+                               s++;
+                       while((*s == ' ') || (*s == '\t'))
+                               s++;
+                       ss_port[i - 1] = atoi(s);
+                       printf("console %d listening on port %d, telnet = %s\n",                               i, ss_port[i - 1],
+                              ((ss_telnet[i - 1] > 0) ? "on" : "off"));
+               }
+               fclose(fp);
+       }
+}
+
+/*
+ * Read and process network client configuration file
+ */
+static void net_client_config(void)
+{
+       FILE *fp;
+       char buf[BUFSIZE];
+       char *s, *d;
+       char fn[4096];
+
+       strcpy(&fn[0], &confdir[0]);
+       strcat(&fn[0], "/net_client.conf");
+
+       if ((fp = fopen(fn, "r")) != NULL) {
+               printf("Client network configuration:\n");
+               s = &buf[0];
+               while (fgets(s, BUFSIZE, fp) != NULL) {
+                       if ((*s == '\n') || (*s == '#'))
+                               continue;
+                       while((*s != ' ') && (*s != '\t'))
+                               s++;
+                       while((*s == ' ') || (*s == '\t'))
+                               s++;
+                       d = &cs_host[0];
+                       while ((*s != ' ') && (*s != '\t'))
+                               *d++ = *s++;
+                       *d = '\0';
+                       while((*s == ' ') || (*s == '\t'))
+                               s++;
+                       cs_port = atoi(s);
+                       printf("Connecting to %s at port %d\n", cs_host,
+                              cs_port);
+               }
+               fclose(fp);
+       }
+}
+#endif
+
+/*
+ *     This function stops the I/O handlers:
+ *
+ *     1. The files emulating the disk drives are closed.
+ *     2. The file "printer.txt" emulating a printer is closed.
+ *     3. The named pipes "auxin" and "auxout" are closed.
+ *     4. All connected sockets are closed
+ *     5. The receiving process for the aux serial port is stopped.
+ */
+void exit_io(void)
+{
+       register int i;
+
+       for (i = 0; i <= 15; i++)
+               if (disks[i].fd != NULL)
+                       close(*disks[i].fd);
+
+       if (printer != 0)
+               close(printer);
+
+#ifdef PIPES
+       close(auxin);
+       close(auxout);
+       kill(pid_rec, SIGHUP);
+#endif
+
+#ifdef NETWORKING
+       for (i = 0; i < NUMSOC; i++)
+               if (ssc[i])
+                       close(ssc[i]);
+       if (cs)
+               close(cs);
+#endif
+}
+
+/*
+ *     reset the CPU and I/O system
+ */
+void reset_system(void)
+{
+       extern BYTE *wrk_ram;
+       register int i;
+
+       /* reset hardware */
+       time_out(0);                    /* stop timer */
+
+       for (i = 1; i < MAXSEG; i++) {  /* reset MMU */
+               if (memory[i] != NULL) {
+                       free(memory[i]);
+                       memory[i] = NULL;
+               }
+       }
+       selbnk = 0;
+       segsize = SEGSIZ;
+
+       /* reset CPU */
+       reset_cpu();
+       wrk_ram = mem_base();
+
+       /* reboot */
+       boot();
+}
+
+/*
+ *     This function is called for every IN opcode from the
+ *     CPU emulation. It calls the handler for the port,
+ *     from which input is wanted.
+ */
+BYTE io_in(BYTE addrl, BYTE addrh)
+{
+       addrh = addrh;  /* to avoid compiler warning */
+
+       io_port = addrl;
+       io_data = (*port_in[addrl]) ();
+       //printf("input %02x from port %02x\r\n", io_data, io_port);
+       return(io_data);
+}
+
+/*
+ *     This function is called for every OUT opcode from the
+ *     CPU emulation. It calls the handler for the port,
+ *     to which output is wanted.
+ */
+void io_out(BYTE addrl, BYTE addrh, BYTE data)
+{
+       addrh = addrh;  /* to avoid compiler warning */
+
+       io_port = addrl;
+       io_data = data;
+
+       busy_loop_cnt[0] = 0;
+
+       (*port_out[addrl]) (data);
+       //printf("output %02x to port %02x\r\n", io_data, io_port)";
+}
+
+/*
+ *     I/O input trap handler
+ */
+static BYTE io_trap_in(void)
+{
+       if (i_flag) {
+               cpu_error = IOTRAPIN;
+               cpu_state = STOPPED;
+       }
+       return((BYTE) 0xff);
+}
+
+/*
+ *     I/O output trap handler
+ */
+static void io_trap_out(BYTE data)
+{
+       data = data;    /* to avoid compiler warning */
+
+       if (i_flag) {
+               cpu_error = IOTRAPOUT;
+               cpu_state = STOPPED;
+       }
+}
+
+/*
+ *     I/O handler for read console 0 status:
+ *     0xff : input available
+ *     0x00 : no input available
+ */
+static BYTE cons_in(void)
+{
+       struct pollfd p[1];
+       struct timespec timer;
+
+       if (++busy_loop_cnt[0] >= MAX_BUSY_COUNT) {
+               timer.tv_sec = 0;
+               timer.tv_nsec = 1000000L;
+               nanosleep(&timer, NULL);
+               busy_loop_cnt[0] = 0;
+               //putchar('~'); fflush(stdout);
+       }
+
+       p[0].fd = fileno(stdin);
+       p[0].events = POLLIN;
+       p[0].revents = 0;
+       poll(p, 1, 0);
+       if (p[0].revents & POLLIN)
+               return((BYTE) 0xff);
+       else
+               return((BYTE) 0x00);
+}
+
+/*
+ *     I/O handler for read console 1 status:
+ *     bit 0 = 1: input available
+ *     bit 1 = 1: output writable
+ */
+static BYTE cons1_in(void)
+{
+       BYTE status = 0;
+#ifdef NETWORKING
+       struct pollfd p[1];
+
+#ifndef TCPASYNC
+       socklen_t alen;
+       struct sockaddr_in fsin;
+       int go_away;
+       int on = 1;
+
+       if (ss[0] == 0)
+               return(status);
+
+       p[0].fd = ss[0];
+       p[0].events = POLLIN;
+       p[0].revents = 0;
+       poll(p, 1, 0);
+
+       if (p[0].revents) {
+
+               alen = sizeof(fsin);
+
+               if (ssc[0] != 0) {
+                       go_away = accept(ss[0],
+                                        (struct sockaddr *)&fsin, &alen);
+                       close(go_away);
+                       goto ss0_done;
+               }
+
+               if ((ssc[0] = accept(ss[0], (struct sockaddr *)&fsin,
+                   &alen)) == -1) {
+                       perror("accept server socket");
+                       ssc[0] = 0;
+               }
+
+               if (setsockopt(ssc[0], IPPROTO_TCP, TCP_NODELAY,
+                   (void *)&on, sizeof(on)) == -1) {
+                       perror("setsockopt TCP_NODELAY on server socket");
+               }
+
+               if (ss_telnet[0])
+                       telnet_negotiation(ssc[0]);
+       }
+ss0_done:
+#endif
+
+       if (ssc[0] != 0) {
+               p[0].fd = ssc[0];
+               p[0].events = POLLIN | POLLOUT;
+               p[0].revents = 0;
+               poll(p, 1, 0);
+               if (p[0].revents & POLLHUP) {
+                       close(ssc[0]);
+                       ssc[0] = 0;
+                       return(0);
+               }
+               if (p[0].revents & POLLIN)
+                       status |= 1;
+               if (p[0].revents & POLLOUT)
+                       status |= 2;
+       }
+#endif
+       return(status);
+}
+
+/*
+ *     I/O handler for read console 2 status:
+ *     bit 0 = 1: input available
+ *     bit 1 = 1: output writable
+ */
+static BYTE cons2_in(void)
+{
+       BYTE status = 0;
+#ifdef NETWORKING
+       struct pollfd p[1];
+
+#ifndef TCPASYNC
+       socklen_t alen;
+       struct sockaddr_in fsin;
+       int go_away;
+       int on = 1;
+
+       if (ss[1] == 0)
+               return(status);
+
+       p[0].fd = ss[1];
+       p[0].events = POLLIN;
+       p[0].revents = 0;
+       poll(p, 1, 0);
+
+       if (p[0].revents) {
+
+               alen = sizeof(fsin);
+
+               if (ssc[1] != 0) {
+                       go_away = accept(ss[1],
+                                        (struct sockaddr *)&fsin, &alen);
+                       close(go_away);
+                       goto ss1_done;
+               }
+
+               if ((ssc[1] = accept(ss[1], (struct sockaddr *)&fsin,
+                   &alen)) == -1) {
+                       perror("accept server socket");
+                       ssc[1] = 0;
+               }
+
+               if (setsockopt(ssc[1], IPPROTO_TCP, TCP_NODELAY,
+                   (void *)&on, sizeof(on)) == -1) {
+                       perror("setsockopt TCP_NODELAY on server socket");
+               }
+
+               if (ss_telnet[1])
+                       telnet_negotiation(ssc[1]);
+       }
+ss1_done:
+#endif
+
+       if (ssc[1] != 0) {
+               p[0].fd = ssc[1];
+               p[0].events = POLLIN | POLLOUT;
+               p[0].revents = 0;
+               poll(p, 1, 0);
+               if (p[0].revents & POLLHUP) {
+                       close(ssc[1]);
+                       ssc[1] = 0;
+                       return(0);
+               }
+               if (p[0].revents & POLLIN)
+                       status |= 1;
+               if (p[0].revents & POLLOUT)
+                       status |= 2;
+       }
+#endif
+       return(status);
+}
+
+/*
+ *     I/O handler for read console 3 status:
+ *     bit 0 = 1: input available
+ *     bit 1 = 1: output writable
+ */
+static BYTE cons3_in(void)
+{
+       BYTE status = 0;
+#ifdef NETWORKING
+       struct pollfd p[1];
+
+#ifndef TCPASYNC
+       socklen_t alen;
+       struct sockaddr_in fsin;
+       int go_away;
+       int on = 1;
+
+       if (ss[2] == 0)
+               return(status);
+
+       p[0].fd = ss[2];
+       p[0].events = POLLIN;
+       p[0].revents = 0;
+       poll(p, 1, 0);
+
+       if (p[0].revents) {
+
+               alen = sizeof(fsin);
+
+               if (ssc[2] != 0) {
+                       go_away = accept(ss[2],
+                                        (struct sockaddr *)&fsin, &alen);
+                       close(go_away);
+                       goto ss2_done;
+               }
+
+               if ((ssc[2] = accept(ss[2], (struct sockaddr *)&fsin,
+                   &alen)) == -1) {
+                       perror("accept server socket");
+                       ssc[2] = 0;
+               }
+
+               if (setsockopt(ssc[2], IPPROTO_TCP, TCP_NODELAY,
+                   (void *)&on, sizeof(on)) == -1) {
+                       perror("setsockopt TCP_NODELAY on server socket");
+               }
+
+               if (ss_telnet[2])
+                       telnet_negotiation(ssc[2]);
+       }
+ss2_done:
+#endif
+
+       if (ssc[2] != 0) {
+               p[0].fd = ssc[2];
+               p[0].events = POLLIN | POLLOUT;
+               p[0].revents = 0;
+               poll(p, 1, 0);
+               if (p[0].revents & POLLHUP) {
+                       close(ssc[2]);
+                       ssc[2] = 0;
+                       return(0);
+               }
+               if (p[0].revents & POLLIN)
+                       status |= 1;
+               if (p[0].revents & POLLOUT)
+                       status |= 2;
+       }
+#endif
+       return(status);
+}
+
+/*
+ *     I/O handler for read console 4 status:
+ *     bit 0 = 1: input available
+ *     bit 1 = 1: output writable
+ */
+static BYTE cons4_in(void)
+{
+       BYTE status = 0;
+#ifdef NETWORKING
+       struct pollfd p[1];
+
+#ifndef TCPASYNC
+       socklen_t alen;
+       struct sockaddr_in fsin;
+       int go_away;
+       int on = 1;
+
+       if (ss[3] == 0)
+               return(status);
+
+       p[0].fd = ss[3];
+       p[0].events = POLLIN;
+       p[0].revents = 0;
+       poll(p, 1, 0);
+
+       if (p[0].revents) {
+
+               alen = sizeof(fsin);
+
+               if (ssc[3] != 0) {
+                       go_away = accept(ss[3],
+                                        (struct sockaddr *)&fsin, &alen);
+                       close(go_away);
+                       goto ss3_done;
+               }
+
+               if ((ssc[3] = accept(ss[3], (struct sockaddr *)&fsin,
+                   &alen)) == -1) {
+                       perror("accept server socket");
+                       ssc[3] = 0;
+               }
+
+               if (setsockopt(ssc[3], IPPROTO_TCP, TCP_NODELAY,
+                   (void *)&on, sizeof(on)) == -1) {
+                       perror("setsockopt TCP_NODELAY on server socket");
+               }
+
+               if (ss_telnet[3])
+                       telnet_negotiation(ssc[3]);
+       }
+ss3_done:
+#endif
+
+       if (ssc[3] != 0) {
+               p[0].fd = ssc[3];
+               p[0].events = POLLIN | POLLOUT;
+               p[0].revents = 0;
+               poll(p, 1, 0);
+               if (p[0].revents & POLLHUP) {
+                       close(ssc[3]);
+                       ssc[3] = 0;
+                       return(0);
+               }
+               if (p[0].revents & POLLIN)
+                       status |= 1;
+               if (p[0].revents & POLLOUT)
+                       status |= 2;
+       }
+#endif
+       return(status);
+}
+
+/*
+ *     I/O handler for read client socket 1 status:
+ *     bit 0 = 1: input available
+ *     bit 1 = 1: output writable
+ */
+static BYTE nets1_in(void)
+{
+       BYTE status = 0;
+#ifdef NETWORKING
+       struct sockaddr_in sin;
+       struct hostent *host;
+       struct pollfd p[1];
+       int on = 1;
+
+       if ((cs == 0) && (cs_port != 0)) {
+               host = gethostbyname(&cs_host[0]);
+               if ((cs = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+                       perror("create client socket");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+               memset((void *) &sin, 0, sizeof(sin));
+               memcpy((void *) &sin.sin_addr, (void *) host->h_addr, host->h_length);
+               sin.sin_family = AF_INET;
+               sin.sin_port = htons(cs_port);
+               if (connect(cs, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
+                       perror("connect client socket");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+               if (setsockopt(cs, IPPROTO_TCP, TCP_NODELAY,
+                   (void *)&on, sizeof(on)) == -1) {
+                       perror("setsockopt TCP_NODELAY on client socket");
+               }
+       }
+
+       if (cs != 0) {
+               p[0].fd = cs;
+               p[0].events = POLLIN | POLLOUT;
+               p[0].revents = 0;
+               poll(p, 1, 0);
+               if (p[0].revents & POLLHUP) {
+                       close(cs);
+                       cs = 0;
+                       return((BYTE) 0);
+               }
+               if (p[0].revents & POLLIN)
+                       status |= 1;
+               if (p[0].revents & POLLOUT)
+                       status |= 2;
+       }
+#endif
+       return(status);
+}
+
+/*
+ *     I/O handler for write console 0 status:
+ *     no function
+ */
+static void cons_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for write console 1 status:
+ *     no function
+ */
+static void cons1_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for write console 2 status:
+ *     no function
+ */
+static void cons2_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for write console 3 status:
+ *     no function
+ */
+static void cons3_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for write console 4 status:
+ *     no function
+ */
+static void cons4_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for write client socket 1 status:
+ *     no function
+ */
+static void nets1_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for read console 0 data
+ */
+static BYTE cond_in(void)
+{
+       char c;
+
+       busy_loop_cnt[0] = 0;
+       read(0, &c, 1);
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for read console 1 data
+ */
+static BYTE cond1_in(void)
+{
+       char c;
+#ifdef NETWORKING
+       char x;
+
+       if (read(ssc[0], &c, 1) != 1) {
+               if ((errno == EAGAIN) || (errno == EINTR)) {
+                       close(ssc[0]);
+                       ssc[0] = 0;
+                       return((BYTE) 0);
+               } else {
+                       perror("read console 1");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+       }
+       if (ss_telnet[0] && (c == '\r'))
+               read(ssc[0], &x, 1);
+#ifdef SNETDEBUG
+       if (sdirection != 1) {
+               printf("\n<- ");
+               sdirection = 1;
+       }
+       printf("%02x ", (BYTE) c);
+#endif
+#else
+       c = 0;
+#endif
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for read console 2 data
+ */
+static BYTE cond2_in(void)
+{
+       char c;
+#ifdef NETWORKING
+       char x;
+
+       if (read(ssc[1], &c, 1) != 1) {
+               if ((errno == EAGAIN) || (errno == EINTR)) {
+                       close(ssc[1]);
+                       ssc[1] = 0;
+                       return((BYTE) 0);
+               } else {
+                       perror("read console 2");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+       }
+       if (ss_telnet[1] && (c == '\r'))
+               read(ssc[1], &x, 1);
+#ifdef SNETDEBUG
+       if (sdirection != 1) {
+               printf("\n<- ");
+               sdirection = 1;
+       }
+       printf("%02x ", (BYTE) c);
+#endif
+#else
+       c = 0;
+#endif
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for read console 3 data
+ */
+static BYTE cond3_in(void)
+{
+       char c;
+#ifdef NETWORKING
+       char x;
+
+       if (read(ssc[2], &c, 1) != 1) {
+               if ((errno == EAGAIN) || (errno == EINTR)) {
+                       close(ssc[2]);
+                       ssc[2] = 0;
+                       return((BYTE) 0);
+               } else {
+                       perror("read console 3");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+       }
+       if (ss_telnet[2] && (c == '\r'))
+               read(ssc[2], &x, 1);
+#ifdef SNETDEBUG
+       if (sdirection != 1) {
+               printf("\n<- ");
+               sdirection = 1;
+       }
+       printf("%02x ", (BYTE) c);
+#endif
+#else
+       c = 0;
+#endif
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for read console 4 data
+ */
+static BYTE cond4_in(void)
+{
+       char c;
+#ifdef NETWORKING
+       char x;
+
+       if (read(ssc[3], &c, 1) != 1) {
+               if ((errno == EAGAIN) || (errno == EINTR)) {
+                       close(ssc[3]);
+                       ssc[3] = 0;
+                       return((BYTE) 0);
+               } else {
+                       perror("read console 4");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+       }
+       if (ss_telnet[3] && (c == '\r'))
+               read(ssc[3], &x, 1);
+#ifdef SNETDEBUG
+       if (sdirection != 1) {
+               printf("\n<- ");
+               sdirection = 1;
+       }
+       printf("%02x ", (BYTE) c);
+#endif
+#else
+       c = 0;
+#endif
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for read client socket 1 data
+ */
+static BYTE netd1_in(void)
+{
+       char c;
+
+#ifdef NETWORKING
+       if (read(cs, &c, 1) != 1) {
+               perror("read client socket");
+               cpu_error = IOERROR;
+               cpu_state = STOPPED;
+               return((BYTE) 0);
+       }
+#ifdef CNETDEBUG
+       if (cdirection != 1) {
+               printf("\n<- ");
+               cdirection = 1;
+       }
+       printf("%02x ", (BYTE) c);
+#endif
+#else
+       c = 0;
+#endif
+       return((BYTE) c);
+}
+
+/*
+ *     I/O handler for write console 0 data:
+ *     the output is written to the terminal
+ */
+static void cond_out(BYTE data)
+{
+again:
+       if (write(fileno(stdout), (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write console 0");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+}
+
+/*
+ *     I/O handler for write console 1 data:
+ *     the output is written to the socket
+ */
+static void cond1_out(BYTE data)
+{
+#ifdef NETWORKING
+#ifdef SNETDEBUG
+       if (sdirection != 0) {
+               printf("\n-> ");
+               sdirection = 0;
+       }
+       printf("%02x ", (BYTE) data);
+#endif
+again:
+       if (write(ssc[0], (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write console 1");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+#endif
+}
+
+/*
+ *     I/O handler for write console 2 data:
+ *     the output is written to the socket
+ */
+static void cond2_out(BYTE data)
+{
+#ifdef NETWORKING
+#ifdef SNETDEBUG
+       if (sdirection != 0) {
+               printf("\n-> ");
+               sdirection = 0;
+       }
+       printf("%02x ", (BYTE) data);
+#endif
+again:
+       if (write(ssc[1], (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write console 2");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+#endif
+}
+
+/*
+ *     I/O handler for write console 3 data:
+ *     the output is written to the socket
+ */
+static void cond3_out(BYTE data)
+{
+#ifdef NETWORKING
+#ifdef SNETDEBUG
+       if (sdirection != 0) {
+               printf("\n-> ");
+               sdirection = 0;
+       }
+       printf("%02x ", (BYTE) data);
+#endif
+again:
+       if (write(ssc[2], (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write console 3");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+#endif
+}
+
+/*
+ *     I/O handler for write console 4 data:
+ *     the output is written to the socket
+ */
+static void cond4_out(BYTE data)
+{
+#ifdef NETWORKING
+#ifdef SNETDEBUG
+       if (sdirection != 0) {
+               printf("\n-> ");
+               sdirection = 0;
+       }
+       printf("%02x ", (BYTE) data);
+#endif
+again:
+       if (write(ssc[3], (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write console 4");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+#endif
+}
+
+/*
+ *     I/O handler for write client socket 1 data:
+ *     the output is written to the socket
+ */
+static void netd1_out(BYTE data)
+{
+#ifdef NETWORKING
+#ifdef CNETDEBUG
+       if (cdirection != 0) {
+               printf("\n-> ");
+               cdirection = 0;
+       }
+       printf("%02x ", (BYTE) data);
+#endif
+again:
+       if (write(cs, (char *) &data, 1) != 1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       perror("write client socket");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+               }
+       }
+#endif
+}
+
+/*
+ *     I/O handler for read printer status:
+ *     the printer is ready all the time
+ */
+static BYTE prts_in(void)
+{
+       return((BYTE) 0xff);
+}
+
+/*
+ *     I/O handler for write printer status:
+ *     no function
+ */
+static void prts_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for read printer data:
+ *     always read an EOF from the printer
+ */
+static BYTE prtd_in(void)
+{
+       return((BYTE) 0x1a);    /* CP/M EOF */
+}
+
+/*
+ *     I/O handler for write printer data:
+ *     the output is written to file "printer.txt"
+ */
+static void prtd_out(BYTE data)
+{
+       if (printer == 0)
+               printer = creat("printer.txt", 0664);
+
+       if (data != '\r') {
+again:
+               if (write(printer, (char *) &data, 1) != 1) {
+                       if (errno == EINTR) {
+                               goto again;
+                       } else {
+                               perror("write printer");
+                               cpu_error = IOERROR;
+                               cpu_state = STOPPED;
+                       }
+               }
+       }
+}
+
+/*
+ *     I/O handler for read aux status:
+ *     return EOF status of the aux device
+ */
+static BYTE auxs_in(void)
+{
+#ifdef PIPES
+       return((BYTE) aux_in_eof);
+#else
+       return((BYTE) 0xff);
+#endif
+}
+
+/*
+ *     I/O handler for write aux status:
+ *     change EOF status of the aux device
+ */
+static void auxs_out(BYTE data)
+{
+#ifdef PIPES
+       aux_in_eof = data;
+#else
+       data = data; /* to avoid compiler warning */
+#endif
+}
+
+/*
+ *     I/O handler for read aux data:
+ *     read next byte from pipe "auxin" or from file "auxiliaryin.txt"
+ */
+static BYTE auxd_in(void)
+{
+       char c;
+
+#ifdef PIPES
+       if (read(auxin, &c, 1) == 1)
+               return((BYTE) c);
+       else {
+               aux_in_eof = 0xff;
+               return((BYTE) 0x1a);    /* CP/M EOF */
+       }
+#else
+       if (aux_in == 0) {
+               if ((aux_in = open("auxiliaryin.txt", O_RDONLY)) == -1){
+                       perror("open auxiliaryin.txt");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return((BYTE) 0);
+               }
+       }
+
+       if (aux_in_lf) {
+               aux_in_lf = 0;
+               return((BYTE) '\n');
+       }
+
+       if (read(aux_in, &c, 1) != 1) {
+               close(aux_in);
+               aux_in = 0;
+               return((BYTE) 0x1a);
+       }
+
+       if (c == '\n') {
+               aux_in_lf = 1;
+               return((BYTE) '\r');
+       }
+
+       return((BYTE) c);
+#endif
+}
+
+/*
+ *     I/O handler for write aux data:
+ *     write output to pipe "auxout" or to file "auxiliaryout.txt"
+ */
+static void auxd_out(BYTE data)
+{
+#ifdef PIPES
+       if ((data == 0) || (data == 0x1a))
+               return;
+
+       if (data != '\r')
+               write(auxout, (char *) &data, 1);
+#else
+       if (data == 0)
+               return;
+
+       if (aux_out == 0) {
+               if ((aux_out = creat("auxiliaryout.txt", 0644)) == -1) {
+                       perror("open auxiliaryout.txt");
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return;
+               }
+       }
+
+       if (data == 0x1a) {
+               close(aux_out);
+               aux_out = 0;
+               return;
+       }
+
+       if (data != '\r')
+               write(aux_out, (char *) &data, 1);
+#endif
+}
+
+/*
+ *     I/O handler for read FDC drive:
+ *     return the current drive
+ */
+static BYTE fdcd_in(void)
+{
+       return((BYTE) drive);
+}
+
+/*
+ *     I/O handler for write FDC drive:
+ *     set the current drive
+ */
+static void fdcd_out(BYTE data)
+{
+       drive = data;
+}
+
+/*
+ *     I/O handler for read FDC track:
+ *     return the current track
+ */
+static BYTE fdct_in(void)
+{
+       return((BYTE) track);
+}
+
+/*
+ *     I/O handler for write FDC track:
+ *     set the current track
+ */
+static void fdct_out(BYTE data)
+{
+       track = data;
+}
+
+/*
+ *     I/O handler for read FDC sector low
+ *     return low byte of the current sector
+ */
+static BYTE fdcs_in(void)
+{
+       return((BYTE) sector & 0xff);
+}
+
+/*
+ *     I/O handler for write FDC sector low
+ *     set low byte of the current sector
+ */
+static void fdcs_out(BYTE data)
+{
+       sector = (sector & 0xff00) + data;
+}
+
+/*
+ *     I/O handler for read FDC sector high
+ *     return high byte of the current sector
+ */
+static BYTE fdcsh_in(void)
+{
+       return((BYTE) (sector >> 8));
+}
+
+/*
+ *     I/O handler for write FDC sector high
+ *     set high byte of the current sector
+ */
+static void fdcsh_out(BYTE data)
+{
+       sector = (sector & 0xff) + (data << 8);
+}
+
+/*
+ *     I/O handler for read FDC command:
+ *     always returns 0
+ */
+static BYTE fdco_in(void)
+{
+       return((BYTE) 0);
+}
+
+/*
+ *     I/O handler for write FDC command:
+ *     transfer one sector in the wanted direction,
+ *     0 = read, 1 = write
+ *
+ *     The status byte of the FDC is set as follows:
+ *       0 - ok
+ *       1 - illegal drive
+ *       2 - illegal track
+ *       3 - illegal sector
+ *       4 - seek error
+ *       5 - read error
+ *       6 - write error
+ *       7 - illegal command to FDC
+ */
+static void fdco_out(BYTE data)
+{
+       register int i;
+       unsigned long pos;
+       static char buf[128];
+
+       if (disks[drive].fd == NULL) {
+               status = 1;
+               return;
+       }
+       if (track > disks[drive].tracks) {
+               status = 2;
+               return;
+       }
+       if (sector > disks[drive].sectors) {
+               status = 3;
+               return;
+       }
+       pos = (((long)track) * ((long)disks[drive].sectors) + sector - 1) << 7;
+       if (lseek(*disks[drive].fd, pos, SEEK_SET) == -1L) {
+               status = 4;
+               return;
+       }
+       switch (data) {
+       case 0: /* read */
+               if (read(*disks[drive].fd, buf, 128) != 128)
+                       status = 5;
+               else {
+                       for (i = 0; i < 128; i++)
+                               dma_write((dmadh << 8) + dmadl + i, buf[i]);
+                       status = 0;
+               }
+               break;
+       case 1: /* write */
+               for (i = 0; i < 128; i++)
+                       buf[i] = dma_read((dmadh << 8) + dmadl + i);
+               if (write(*disks[drive].fd, buf, 128) != 128)
+                       status = 6;
+               else
+                       status = 0;
+               break;
+       default:                /* illegal command */
+               status = 7;
+               break;
+       }
+}
+
+/*
+ *     I/O handler for read FDC status:
+ *     returns status of last FDC operation,
+ *     0 = ok, else some error
+ */
+static BYTE fdcx_in(void)
+{
+       return((BYTE) status);
+}
+
+/*
+ *     I/O handler for write FDC status:
+ *     no function
+ */
+static void fdcx_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     I/O handler for read lower byte of DMA address:
+ *     return lower byte of current DMA address
+ */
+static BYTE dmal_in(void)
+{
+       return((BYTE) dmadl);
+}
+
+/*
+ *     I/O handler for write lower byte of DMA address:
+ *     set lower byte of DMA address
+ */
+static void dmal_out(BYTE data)
+{
+       dmadl = data;
+}
+
+/*
+ *     I/O handler for read higher byte of DMA address:
+ *     return higher byte of current DMA address
+ */
+static BYTE dmah_in(void)
+{
+       return((BYTE) dmadh);
+}
+
+/*
+ *     I/O handler for write higher byte of DMA address:
+ *     set higher byte of the DMA address
+ */
+static void dmah_out(BYTE data)
+{
+       dmadh = data;
+}
+
+/*
+ *     I/O handler for read MMU initialisation:
+ *     return number of initialised MMU banks
+ */
+static BYTE mmui_in(void)
+{
+       return((BYTE) maxbnk);
+}
+
+/*
+ *     I/O handler for write MMU initialisation:
+ *     for the FIRST call the memory for the wanted number of banks
+ *     is allocated and pointers to the memory is stored in the MMU array
+ *
+ *     The number of banks is the total, including bank 0 which already
+ *     is allocated
+ */
+static void mmui_out(BYTE data)
+{
+       register int i;
+
+       /* do nothing if MMU initialised already */
+       if (memory[1] != NULL)
+               return;
+
+       if (data > MAXSEG) {
+               printf("Try to init %d banks, available %d banks\r\n",
+                      data, MAXSEG);
+               cpu_error = IOERROR;
+               cpu_state = STOPPED;
+               return;
+       }
+
+       for (i = 1; i < data; i++) {
+               if ((memory[i] = malloc(segsize)) == NULL) {
+                       printf("can't allocate memory for bank %d\r\n", i);
+                       cpu_error = IOERROR;
+                       cpu_state = STOPPED;
+                       return;
+               }
+       }
+
+       maxbnk = data;
+}
+
+/*
+ *     I/O handler for read MMU bank select:
+ *     return current selected MMU bank
+ */
+static BYTE mmus_in(void)
+{
+       return((BYTE) selbnk);
+}
+
+/*
+ *     I/O handler for write MMU bank select:
+ *     make the new bank the current one
+ */
+static void mmus_out(BYTE data)
+{
+       if (data > maxbnk - 1) {
+               printf("%04x: try to select unallocated bank %d\r\n", PC, data);
+               cpu_error = IOERROR;
+               cpu_state = STOPPED;
+               return;
+       }
+       selbnk = data;
+}
+
+/*
+ *     I/O handler for read MMU segment size configuration:
+ *     returns size of the bank segments in pages a 256 bytes
+ */
+static BYTE mmuc_in(void)
+{
+       return((BYTE) (segsize >> 8));
+}
+
+/*
+ *     I/O handler for write MMU segment size configuration:
+ *     set the size of the bank segments in pages a 256 bytes
+ *     must be done before any banks are allocated
+ */
+static void mmuc_out(BYTE data)
+{
+       if (memory[1] != NULL) {
+               printf("Not possible to resize already allocated segments\r\n");
+               cpu_error = IOERROR;
+               cpu_state = STOPPED;
+               return;
+       }
+       segsize = data << 8;
+}
+
+/*
+ *     I/O handler to read status of MMU protect/unprotect common segment
+ */
+static BYTE mmup_in(void)
+{
+       return(wp_common);
+}
+
+/*
+ *     I/O handler for MMU protect/unprotect common segment
+ */
+static void mmup_out(BYTE data)
+{
+       wp_common = data;
+}
+
+/*
+ *     I/O handler for read clock command:
+ *     return last clock command
+ */
+static BYTE clkc_in(void)
+{
+       return(clkcmd);
+}
+
+/*
+ *     I/O handler for write clock command:
+ *     set the wanted clock command
+ *     toggle BCD/decimal format if toggle command (255)
+ */
+static void clkc_out(BYTE data)
+{
+       clkcmd = data;
+       if (data == 255)
+               clkfmt = clkfmt ^ 1;
+}
+
+/*
+ *     I/O handler for read clock data:
+ *     dependent on the last clock command the following
+ *     informations are returned from the system clock:
+ *             0 - seconds in BCD or decimal
+ *             1 - minutes in BCD or decimal
+ *             2 - hours in BCD or decimal
+ *             3 - low byte number of days since 1.1.1978
+ *             4 - high byte number of days since 1.1.1978
+ *             5 - day of month in BCD or decimal
+ *             6 - month in BCD or decimal
+ *             7 - year in BCD or decimal
+ *     for every other clock command a 0 is returned
+ */
+static BYTE clkd_in(void)
+{
+       register struct tm *t;
+       register int val;
+       time_t Time;
+
+       time(&Time);
+       t = localtime(&Time);
+       switch(clkcmd) {
+       case 0:                 /* seconds */
+               if (clkfmt)
+                       val = t->tm_sec;
+               else
+                       val = to_bcd(t->tm_sec);
+               break;
+       case 1:                 /* minutes */
+               if (clkfmt)
+                       val = t->tm_min;
+               else
+                       val = to_bcd(t->tm_min);
+               break;
+       case 2:                 /* hours */
+               if (clkfmt)
+                       val = t->tm_hour;
+               else
+                       val = to_bcd(t->tm_hour);
+               break;
+       case 3:                 /* low byte days */
+               val = get_date(t) & 255;
+               break;
+       case 4:                 /* high byte days */
+               val = get_date(t) >> 8;
+               break;
+       case 5:                 /* day of month */
+               if (clkfmt)
+                       val = t->tm_mday;
+               else
+                       val = to_bcd(t->tm_mday);
+               break;
+       case 6:                 /* month */
+               if (clkfmt)
+                       val = t->tm_mon;
+               else
+                       val = to_bcd(t->tm_mon);
+               break;
+       case 7:                 /* year */
+               if (clkfmt)
+                       val = t->tm_year;
+               else
+                       val = to_bcd(t->tm_year);
+               break;
+       default:
+               val = 0;
+               break;
+       }
+       return((BYTE) val);
+}
+
+/*
+ *     I/O handler for write clock data:
+ *     under UNIX the system clock only can be set by the
+ *     super user, so we do nothing here
+ */
+static void clkd_out(BYTE data)
+{
+       data = data; /* to avoid compiler warning */
+}
+
+/*
+ *     Convert an integer to BCD
+ */
+static int to_bcd(int val)
+{
+       register int i = 0;
+
+       while (val >= 10) {
+               i += val / 10;
+               i <<= 4;
+               val %= 10;
+       }
+       i += val;
+       return (i);
+}
+
+/*
+ *     Calculate number of days since 1.1.1978
+ *     CP/M 3 and MP/M 2 are Y2K bug fixed and can handle the date,
+ *     so the Y2K bug here is intentional.
+ */
+static int get_date(struct tm *t)
+{
+       register int i;
+       register int val = 0;
+
+       for (i = 1978; i < 1900 + t->tm_year; i++) {
+               val += 365;
+               if (i % 4 == 0)
+                       val++;
+       }
+       val += t->tm_yday + 1;
+       return(val);
+}
+
+/*
+ *     I/O handler for write timer
+ *     start or stop the 10ms interrupt timer
+ */
+static void time_out(BYTE data)
+{
+       static struct itimerval tim;
+       static struct sigaction newact;
+
+       if (data == 1) {
+               timer = 1;
+               newact.sa_handler = int_timer;
+               memset((void *) &newact.sa_mask, 0, sizeof(newact.sa_mask));
+               newact.sa_flags = 0;
+               sigaction(SIGALRM, &newact, NULL);
+               tim.it_value.tv_sec = 0;
+               tim.it_value.tv_usec = 10000;
+               tim.it_interval.tv_sec = 0;
+               tim.it_interval.tv_usec = 10000;
+               setitimer(ITIMER_REAL, &tim, NULL);
+       } else {
+               timer = 0;
+               newact.sa_handler = SIG_IGN;
+               memset((void *) &newact.sa_mask, 0, sizeof(newact.sa_mask));
+               newact.sa_flags = 0;
+               sigaction(SIGALRM, &newact, NULL);
+               tim.it_value.tv_sec = 0;
+               tim.it_value.tv_usec = 0;
+               setitimer(ITIMER_REAL, &tim, NULL);
+       }
+}
+
+/*
+ *     I/O handler for read timer
+ *     return current status of 10ms interrupt timer,
+ *     1 = enabled, 0 = disabled
+ */
+static BYTE time_in(void)
+{
+       return(timer);
+}
+
+/*
+ *     I/O handler for write delay
+ *     delay CPU for data * 10ms
+ */
+static void delay_out(BYTE data)
+{
+       struct timespec timer;
+
+       timer.tv_sec = 0;
+       timer.tv_nsec = (long) (10000000L * data);
+       nanosleep(&timer, NULL);
+
+#ifdef CNETDEBUG
+       printf(". ");
+#endif
+}
+
+/*
+ *     I/O handler for read delay
+ *     returns 0
+ */
+static BYTE delay_in(void)
+{
+       return((BYTE) 0);
+}
+
+/*
+ *     I/O handler for write hardware control:
+ *     bit 0 = 1       reset CPU, MMU and reboot
+ *     bit 7 = 1       halt emulation via I/O
+ */
+static void hwctl_out(BYTE data)
+{
+       if (data & 128) {
+               cpu_error = IOHALT;
+               cpu_state = STOPPED;
+               return;
+       }
+
+       if (data & 1) {
+               reset_system();
+               return;
+       }
+}
+
+/*
+ *     I/O handler for read hardware control
+ *     returns 0
+ */
+static BYTE hwctl_in(void)
+{
+       return((BYTE) 0);
+}
+
+/*
+ *     I/O handler for write CPU speed low
+ */
+static void speedl_out(BYTE data)
+{
+       speed = data;
+}
+
+/*
+ *     I/O handler for read CPU speed low
+ */
+static BYTE speedl_in(void)
+{
+       return(f_flag & 0xff);
+}
+
+/*
+ *     I/O handler for write CPU speed high
+ */
+static void speedh_out(BYTE data)
+{
+       speed += data << 8;
+       tmax = speed * 10000;
+       f_flag = speed;
+}
+
+/*
+ *     I/O handler for read CPU speed high
+ */
+static BYTE speedh_in(void)
+{
+       return(f_flag  >> 8);
+}
+
+/*
+ *     timer interrupt causes maskable CPU interrupt
+ */
+static void int_timer(int sig)
+{
+       sig = sig;      /* to avoid compiler warning */
+
+       int_int = 1;
+       int_data = 0xff;        /* RST 38H for IM 0, 0FFH for IM 2 */
+}
+
+#if defined(NETWORKING) && defined(TCPASYNC)
+/*
+ *     SIGIO interrupt handler
+ */
+static void int_io(int sig)
+{
+       register int i;
+       struct sockaddr_in fsin;
+       socklen_t alen;
+       struct pollfd p[NUMSOC];
+       int go_away;
+       int on = 1;
+
+       sig = sig;      /* to avoid compiler warning */
+
+       for (i = 0; i < NUMSOC; i++) {
+               p[i].fd = ss[i];
+               p[i].events = POLLIN;
+               p[i].revents = 0;
+       }
+
+       poll(p, NUMSOC, 0);
+
+       for (i = 0; i < NUMSOC; i++) {
+               if ((ss[i] != 0) && (p[i].revents)) {
+                       alen = sizeof(fsin);
+
+                       if (ssc[i] != 0) {
+                               go_away = accept(ss[i],
+                                                (struct sockaddr *) &fsin,
+                                                &alen);
+                               close(go_away);
+                               return;
+                       }
+
+                       if ((ssc[i] = accept(ss[i], (struct sockaddr *) &fsin,
+                           &alen)) == -1) {
+                               perror("accept on server socket");
+                               ssc[i] = 0;
+                       }
+
+                       if (setsockopt(ssc[i], IPPROTO_TCP, TCP_NODELAY,
+                           (void *) &on, sizeof(on)) == -1) {
+                               perror("setsockopt TCP_NODELAY on server socket");
+                       }
+
+                       if (ss_telnet[i])
+                               telnet_negotiation(ssc[i]);
+               }
+       }
+}
+#endif
+
+#ifdef NETWORKING
+/*
+ *     do the telnet option negotiation
+ */
+void telnet_negotiation(int fd)
+{
+       static char will_echo[3] = {255, 251, 1};
+       static char char_mode[3] = {255, 251, 3};
+       struct pollfd p[1];
+       BYTE c[3];
+
+       /* send the telnet options we need */
+       write(fd, &char_mode, 3);
+       write(fd, &will_echo, 3);
+
+       /* and reject all others offered */
+       p[0].fd = fd;
+       p[0].events = POLLIN;
+       while (1) {
+               /* wait for input */
+               p[0].revents = 0;
+               poll(p, 1, TELNET_TIMEOUT);
+
+               /* done if no more input */
+               if (! p[0].revents)
+                       break;
+
+               /* else read the option */
+               read(fd, &c, 3);
+               //printf("telnet: %d %d %d\r\n", c[0], c[1], c[2]);
+               if (c[2] == 1 || c[2] == 3)
+                       continue;       /* ignore answers to our requests */
+               if (c[1] == 251)        /* and reject other options */
+                       c[1] = 254;
+               else if (c[1] == 253)
+                       c[1] = 252;
+               write(fd, &c, 3);
+       }
+}
+#endif
diff --git a/sim/lnsrc b/sim/lnsrc
new file mode 100755 (executable)
index 0000000..740b4e1
--- /dev/null
+++ b/sim/lnsrc
@@ -0,0 +1,15 @@
+# use this to link the common parts of Z80 simulation
+
+ln ../../z80sim/srcsim/sim0.c sim0.c
+ln ../../z80sim/srcsim/sim1.c sim1.c
+ln ../../z80sim/srcsim/sim1a.c sim1a.c
+ln ../../z80sim/srcsim/sim2.c sim2.c
+ln ../../z80sim/srcsim/sim3.c sim3.c
+ln ../../z80sim/srcsim/sim4.c sim4.c
+ln ../../z80sim/srcsim/sim5.c sim5.c
+ln ../../z80sim/srcsim/sim6.c sim6.c
+ln ../../z80sim/srcsim/sim7.c sim7.c
+ln ../../z80sim/srcsim/simfun.c simfun.c
+ln ../../z80sim/srcsim/simint.c simint.c
+ln ../../z80sim/srcsim/simglb.c simglb.c
+ln ../../z80sim/srcsim/simglb.h simglb.h
diff --git a/sim/memory.c b/sim/memory.c
new file mode 100644 (file)
index 0000000..f9e6717
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * This module implements banked memory management for cpmsim
+ *
+ *      MMU:
+ *      ===
+ *
+ *      +--------+
+ * 16KB | common |
+ *      +--------+
+ *      +--------+  +--------+  ..........  +--------+
+ *      |        |  |        |              |        |
+ * 48KB |        |  |        |  ..........  |        |
+ *      | bank 0 |  | bank 1 |              | bank n |
+ *      +--------+  +--------+  ..........  +--------+
+ *
+ * This is an example for 48KB segments as it was implemented originally.
+ * The segment size now can be configured via port 22.
+ * If the segment size isn't configured the default is 48 KB as it was
+ * before, to maintain compatibility.
+ *
+ * History:
+ * 21-DEC-16 moved banked memory implementation to here
+ * 03-FEB-17 added ROM initialisation
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "sim.h"
+#include "simglb.h"
+#include "memory.h"
+
+BYTE *memory[MAXSEG];          /* MMU with pointers to the banks */
+int selbnk;                    /* current selected bank */
+int maxbnk;                    /* number of allocated banks */
+int segsize = SEGSIZ;          /* segment size of banks, default 48KB */
+int wp_common;                 /* write protect/unprotect common segment */
+
+void init_memory(void)
+{
+       /* allocate the first 64KB bank, so that we have some memory */
+       if ((memory[0] = malloc(65536)) == NULL) {
+               printf("can't allocate memory for bank 0\r\n");
+               cpu_error = IOERROR;
+               cpu_state = STOPPED;
+               return;
+       }
+       maxbnk = 1;
+}
+
+void init_rom(void)
+{
+}
diff --git a/sim/memory.h b/sim/memory.h
new file mode 100644 (file)
index 0000000..4b70040
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * This module implements banked memory management for cpmsim
+ *
+ *      MMU:
+ *      ===
+ *
+ *      +--------+
+ * 16KB | common |
+ *      +--------+
+ *      +--------+  +--------+  ..........  +--------+
+ *      |        |  |        |              |        |
+ * 48KB |        |  |        |  ..........  |        |
+ *      | bank 0 |  | bank 1 |              | bank n |
+ *      +--------+  +--------+  ..........  +--------+
+ *
+ * This is an example for 48KB segments as it was implemented originally.
+ * The segment size now can be configured via port 22.
+ * If the segment size isn't configured the default is 48 KB as it was
+ * before, to maintain compatibility.
+ *
+ * History:
+ * 22-NOV-16 stuff moved to here for further improvements
+ * 03-FEB-17 added ROM initialisation
+ */
+
+#define MAXSEG 16              /* max. number of memory banks */
+#define SEGSIZ 49152           /* default size of one bank = 48 KBytes */
+
+extern void init_memory(void), init_rom(void);
+
+extern BYTE *memory[];
+extern int selbnk, maxbnk, segsize, wp_common;
+
+/*
+ * memory access for the CPU cores
+ */
+static inline void memwrt(WORD addr, BYTE data)
+{
+       if ((addr >= segsize) && (wp_common != 0))
+               return;
+
+       if (selbnk == 0) {
+               *(memory[0] + addr) = data;
+       } else {
+               if (addr >= segsize)
+                       *(memory[0] + addr) = data;
+               else
+                       *(memory[selbnk] + addr) = data;
+       }
+}
+
+static inline BYTE memrdr(WORD addr)
+{
+       if (selbnk == 0)
+               return(*(memory[0] + addr));
+
+       if (addr >= segsize)
+               return(*(memory[0] + addr));
+       else
+               return(*(memory[selbnk] + addr));
+}
+
+/*
+ * memory access for DMA devices
+ */
+static inline void dma_write(WORD addr, BYTE data)
+{
+       if ((addr >= segsize) && (wp_common != 0))
+               return;
+
+       if (selbnk == 0) {
+               *(memory[0] + addr) = data;
+       } else {
+               if (addr >= segsize)
+                       *(memory[0] + addr) = data;
+               else
+                       *(memory[selbnk] + addr) = data;
+       }
+}
+
+static inline BYTE dma_read(WORD addr)
+{
+       if (selbnk == 0)
+               return(*(memory[0] + addr));
+
+       if (addr >= segsize)
+               return(*(memory[0] + addr));
+       else
+               return(*(memory[selbnk] + addr));
+}
+
+/*
+ * return memory base pointer for the simulation frame
+ */
+static inline BYTE *mem_base(void)
+{
+       return(memory[0]);
+}
diff --git a/sim/sim.h b/sim/sim.h
new file mode 100644 (file)
index 0000000..76fe7f4
--- /dev/null
+++ b/sim/sim.h
@@ -0,0 +1,167 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 some improvements here and there
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 20-JUL-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ */
+
+/*
+ *     The following defines may be activated, commented or modified
+ *     by user for her/his own purpose.
+ */
+#define CPU_SPEED 0    /* default CPU speed 0=unlimited */
+#define Z80_UNDOC      /* compile undocumented Z80 instructions */
+#define WANT_FASTM     /* much faster but not accurate Z80 block moves */
+/*#define WANT_TIM*/   /* don't count t-states */
+/*#define HISIZE  1000*//* no history */
+/*#define SBSIZE  10*/ /* no breakpoints */
+/*#define FRONTPANEL*/ /* no frontpanel emulation */
+/*#define BUS_8080*/   /* no emulation of 8080 bus status */
+
+#define HAS_DISKS      /* uses disk images */
+#define HAS_CONFIG     /* has configuration files somewhere */
+
+#define PIPES          /* use named pipes for auxiliary device */
+#define NETWORKING     /* TCP/IP networked serial ports */
+#define NUMSOC 4       /* number of server sockets */
+#define TCPASYNC       /* tcp/ip server can use async I/O */
+/*#define CNETDEBUG*/  /* client network protocol debugger */
+/*#define SNETDEBUG*/  /* server network protocol debugger */
+
+/*
+ * forking and pipes are working now with Cygwin in 2014,
+ * but SIGIO on BSD sockets is not
+ */
+#ifdef __CYGWIN__
+//#undef PIPES         /* forking and pipes was not working correct */
+#undef TCPASYNC                /* SIGIO on BSD sockets not working */
+#endif
+
+/*
+ *     Default CPU
+ */
+#define Z80            1
+#define I8080          2
+#define DEFAULT_CPU    Z80
+
+/*
+ *     The following lines of this file should not be modified by user
+ */
+#define COPYR  "Copyright (C) 1987-2017 by Udo Munk"
+#define RELEASE        "1.36"
+
+#define LENCMD         80              /* length of command buffers etc */
+
+#define S_FLAG         128             /* bit definitions of CPU flags */
+#define Z_FLAG         64
+#define N2_FLAG                32
+#define H_FLAG         16
+#define N1_FLAG                8
+#define P_FLAG         4
+#define N_FLAG         2
+#define C_FLAG         1
+
+#define CPU_MEMR       128             /* bit definitions for CPU bus status */
+#define CPU_INP                64
+#define CPU_M1         32
+#define CPU_OUT                16
+#define CPU_HLTA       8
+#define CPU_STACK      4
+#define CPU_WO         2
+#define CPU_INTA       1
+
+                                       /* operation of simulated CPU */
+#define STOPPED                0               /* stopped */
+#define CONTIN_RUN     1               /* continual run */
+#define SINGLE_STEP    2               /* single step */
+#define RESET          4               /* reset */
+
+                                       /* error codes */
+#define NONE           0               /* no error */
+#define OPHALT         1               /* HALT op-code trap */
+#define IOTRAPIN       2               /* I/O trap input */
+#define IOTRAPOUT      3               /* I/O trap output */
+#define IOHALT         4               /* halt system via I/O register */
+#define IOERROR                5               /* fatal I/O error */
+#define OPTRAP1                6               /* illegal 1 byte op-code trap */
+#define OPTRAP2                7               /* illegal 2 byte op-code trap */
+#define OPTRAP4                8               /* illegal 4 byte op-code trap */
+#define USERINT                9               /* user interrupt */
+#define POWEROFF       255             /* CPU off, no error */
+
+typedef unsigned short WORD;           /* 16 bit unsigned */
+typedef signed short   SWORD;          /* 16 bit signed */
+typedef unsigned char  BYTE;           /* 8 bit unsigned */
+
+#ifdef HISIZE
+struct history {                       /* structure of a history entry */
+       WORD    h_adr;                  /* address of execution */
+       WORD    h_af;                   /* register AF */
+       WORD    h_bc;                   /* register BC */
+       WORD    h_de;                   /* register DE */
+       WORD    h_hl;                   /* register HL */
+       WORD    h_ix;                   /* register IX */
+       WORD    h_iy;                   /* register IY */
+       WORD    h_sp;                   /* register SP */
+};
+#endif
+
+#ifdef SBSIZE
+struct softbreak {                     /* structure of a breakpoint */
+       WORD    sb_adr;                 /* address of breakpoint */
+       BYTE    sb_oldopc;              /* op-code at address of breakpoint */
+       int     sb_passcount;           /* pass counter of breakpoint */
+       int     sb_pass;                /* no. of pass to break */
+};
+#endif
+
+#ifndef isxdigit
+#define isxdigit(c) ((c<='f'&&c>='a')||(c<='F'&&c>='A')||(c<='9'&&c>='0'))
+#endif
+
+/*
+ *     Structure for the disk images
+ */
+struct dskdef {
+       char *fn;                       /* filename */
+       int *fd;                        /* file descriptor */
+       unsigned int tracks;            /* number of tracks */
+       unsigned int sectors;           /* number of sectors */
+};
diff --git a/sim/sim0.c b/sim/sim0.c
new file mode 100644 (file)
index 0000000..6fd4710
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     This module contains the 'main()' function of the simulator,
+ *     where the options are checked and variables are initialised.
+ *     After initialisation of the UNIX interrupts ( int_on() )
+ *     and initialisation of the I/O simulation ( init_io() )
+ *     the user interface ( mon() ) is called.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libgen.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#include "../../frontpanel/frontpanel.h"
+#include "memory.h"
+
+#define BUFSIZE        256             /* buffer size for file I/O */
+
+static void init_cpu(void);
+int load_core(void);
+static void save_core(void);
+static int load_mos(int, char *), load_hex(char *), checksum(char *);
+extern void int_on(void), int_off(void), mon(void);
+extern void init_io(void), exit_io(void);
+extern int exatoi(char *);
+
+BYTE *wrk_ram;                 /* work pointer for the memory */
+
+int main(int argc, char *argv[])
+{
+       register char *s, *p;
+       register int i;
+       char *pn = basename(argv[0]);
+       struct timeval tv;
+#ifdef HAS_CONFIG
+       struct stat sbuf;
+#endif
+#ifdef BOOTROM
+       char *rom = "-r ";
+#else
+       char *rom = "";
+#endif
+#ifdef CPU_SPEED
+       f_flag = CPU_SPEED;
+       tmax = CPU_SPEED * 10000;
+#endif
+
+       while (--argc > 0 && (*++argv)[0] == '-')
+               for (s = argv[0] + 1; *s != '\0'; s++)
+
+                       switch (*s) {
+                       case 's':       /* save core and CPU on exit */
+                               s_flag = 1;
+                               break;
+
+                       case 'l':       /* load core and CPU from file */
+                               l_flag = 1;
+                               break;
+
+                       case 'u':       /* trap undocumented ops */
+                               u_flag = 1;
+                               break;
+
+                       case 'i':       /* trap I/O on unused ports */
+                               i_flag = 1;
+                               break;
+
+                       case 'm':       /* initialise Z80 memory */
+                               if (*(s+1) != '\0') {
+                                       m_flag = exatoi(s+1);
+                                       s += strlen(s+1);
+                               } else {
+                                       if (argc <= 1)
+                                               goto usage;
+                                       argc--;
+                                       argv++;
+                                       m_flag = exatoi(argv[0]);
+                               }
+                               break;
+
+                       case 'f':       /* set emulation speed */
+                               if (*(s+1) != '\0') {
+                                       f_flag = atoi(s+1);
+                                       s += strlen(s+1);
+                               } else {
+                                       if (argc <= 1)
+                                               goto usage;
+                                       argc--;
+                                       argv++;
+                                       f_flag = atoi(argv[0]);
+                               }
+                               tmax = f_flag * 10000;
+                               break;
+
+                       case 'x':       /* get filename with Z80 executable */
+                               x_flag = 1;
+                               s++;
+                               if (*s == '\0') {
+                                       if (argc <= 1)
+                                               goto usage;
+                                       argc--;
+                                       argv++;
+                                       s = argv[0];
+                               }
+                               p = xfn;
+                               while (*s)
+                                       *p++ = *s++;
+                               *p = '\0';
+                               s--;
+                               break;
+
+#ifdef BOOTROM
+                       case 'r':       /* load default boot ROM */
+                               x_flag = 1;
+                               strcpy(xfn, BOOTROM);
+                               break;
+#endif
+
+#ifdef HAS_DISKS
+                       case 'd':       /* get path for disk images */
+                               s++;
+                               if (*s == '\0') {
+                                       if (argc <= 1)
+                                               goto usage;
+                                       argc--;
+                                       argv++;
+                                       s = argv[0];
+                               }
+                               p = diskdir = diskd;
+                               while (*s)
+                                       *p++ = *s++;
+                               *p = '\0';
+                               s--;
+                               break;
+#endif
+
+                       case '8':
+                               cpu = I8080;
+                               break;
+
+                       case 'z':
+                               cpu = Z80;
+                               break;
+
+                       case '?':
+                       case 'h':
+                               goto usage;
+
+                       default:
+                               printf("illegal option %c\n", *s);
+
+usage:
+
+#ifdef HAS_DISKS
+                               printf("usage:\t%s -z -8 -s -l -i -u %s-m val -f freq -x filename -d diskpath\n", pn, rom);
+#else
+                               printf("usage:\t%s -z -8 -s -l -i -u %s-m val -f freq -x filename\n", pn, rom);
+#endif
+                               puts("\t-z = emulate Zilog Z80");
+                               puts("\t-8 = emulate Intel 8080");
+                               puts("\t-s = save core and CPU");
+                               puts("\t-l = load core and CPU");
+                               puts("\t-i = trap on I/O to unused ports");
+                               puts("\t-u = trap on undocumented instructions");
+#ifdef BOOTROM
+                               puts("\t-r = load and execute default ROM");
+                               printf("\t     %s\n", BOOTROM);
+#endif
+                               puts("\t-m = init memory with val (00-FF)");
+                               puts("\t-f = CPU clock frequency freq in MHz");
+                               puts("\t-x = load and execute filename");
+#ifdef HAS_DISKS
+                               puts("\t-d = use disks images at diskpath");
+                               puts("\t     default path for disk images:");
+                               puts("\t     ./disks");
+                               printf("\t     %s\n", DISKSDIR);
+#endif
+                               exit(1);
+                       }
+
+       putchar('\n');
+
+       if (cpu == Z80) {
+puts("#######  #####    ###            #####    ###   #     #");
+puts("     #  #     #  #   #          #     #    #    ##   ##");
+puts("    #   #     # #     #         #          #    # # # #");
+puts("   #     #####  #     #  #####   #####     #    #  #  #");
+puts("  #     #     # #     #               #    #    #     #");
+puts(" #      #     #  #   #          #     #    #    #     #");
+puts("#######  #####    ###            #####    ###   #     #");
+
+       } else {
+
+puts(" #####    ###     #####    ###            #####    ###   #     #");
+puts("#     #  #   #   #     #  #   #          #     #    #    ##   ##");
+puts("#     # #     #  #     # #     #         #          #    # # # #");
+puts(" #####  #     #   #####  #     #  #####   #####     #    #  #  #");
+puts("#     # #     #  #     # #     #               #    #    #     #");
+puts("#     #  #   #   #     #  #   #          #     #    #    #     #");
+puts(" #####    ###     #####    ###            #####    ###   #     #");
+       }
+
+       printf("\nRelease %s, %s\n", RELEASE, COPYR);
+
+#ifdef USR_COM
+       printf("%s Release %s, %s\n\n", USR_COM, USR_REL, USR_CPR);
+#else
+       putchar('\n');
+#endif
+       if (f_flag > 0)
+               printf("CPU speed is %d MHz\n", f_flag);
+       else
+               printf("CPU speed is unlimited\n");
+
+       fflush(stdout);
+
+       /* if the machine has configuration files try to find them */
+#ifdef HAS_CONFIG
+       /* first try ./conf */
+       if ((stat("./conf", &sbuf) == 0) && S_ISDIR(sbuf.st_mode)) {
+               strcpy(&confdir[0], "./conf");
+       /* then CONFDIR as set in Makefile */
+       } else {
+               strcpy(&confdir[0], CONFDIR);
+       }
+
+       //printf("config = %s\n", &confdir[0]);
+#endif
+
+       /* seed random generator */
+       gettimeofday(&tv, NULL);
+       srand(tv.tv_sec);
+
+       config();               /* read system configuration */
+       init_memory();          /* initialise memory configuration */
+       init_cpu();             /* initialise CPU */
+       wrk_ram = mem_base();   /* set work pointer for memory */
+
+       /* fill memory content with some initial value */
+       if (m_flag >= 0) {
+               memset((char *) wrk_ram, m_flag, 65536);
+       } else {
+               for (i = 0; i < 65536; i++)
+                       *(wrk_ram + i) = (BYTE) (rand() % 256);
+       }
+
+       init_rom();             /* initialise ROM's */
+
+       if (l_flag)             /* load core */
+               if (load_core())
+                       return(1);
+
+       int_on();               /* initialize UNIX interrupts */
+       init_io();              /* initialize I/O devices */
+
+       mon();                  /* run system */
+
+       if (s_flag)             /* save core */
+               save_core();
+
+       exit_io();              /* stop I/O devices */
+       int_off();              /* stop UNIX interrupts */
+
+       return(0);
+}
+
+/*
+ *     Initialize the CPU
+ */
+static void init_cpu(void)
+{
+       /* same for i8080 and Z80 */
+       PC = 0;
+       SP = rand() % 65536;
+       A = rand() % 256;
+       B = rand() % 256;
+       C = rand() % 256;
+       D = rand() % 256;
+       E = rand() % 256;
+       H = rand() % 256;
+       L = rand() % 256;
+       F = rand() % 256;
+
+       if (cpu == I8080) {     /* i8080 specific */
+               F &= ~(N2_FLAG | N1_FLAG);
+               F |= N_FLAG;
+       } else {                /* Z80 specific */
+               I = 0;
+               A_ = rand() % 256;
+               B_ = rand() % 256;
+               C_ = rand() % 256;
+               D_ = rand() % 256;
+               E_ = rand() % 256;
+               H_ = rand() % 256;
+               L_ = rand() % 256;
+               F_ = rand() % 256;
+               IX = rand() % 65536;
+               IY = rand() % 65536;
+       }
+}
+
+/*
+ *     Reset the CPU
+ */
+void reset_cpu(void)
+{
+       IFF = int_int = int_nmi = int_protection = int_mode = 0;
+       int_data = -1;
+
+       PC = 0;
+
+       if (cpu == Z80) {
+               I = 0;
+               R = 0L;
+       }
+}
+
+/*
+ *     This function saves the CPU and the memory into the file core.z80
+ */
+static void save_core(void)
+{
+       int fd;
+
+       if ((fd = open("core.z80", O_WRONLY | O_CREAT, 0600)) == -1) {
+               puts("can't open file core.z80");
+               return;
+       }
+       write(fd, (char *) &A, sizeof(A));
+       write(fd, (char *) &F, sizeof(F));
+       write(fd, (char *) &B, sizeof(B));
+       write(fd, (char *) &C, sizeof(C));
+       write(fd, (char *) &D, sizeof(D));
+       write(fd, (char *) &E, sizeof(E));
+       write(fd, (char *) &H, sizeof(H));
+       write(fd, (char *) &L, sizeof(L));
+       write(fd, (char *) &A_, sizeof(A_));
+       write(fd, (char *) &F_, sizeof(F_));
+       write(fd, (char *) &B_, sizeof(B_));
+       write(fd, (char *) &C_, sizeof(C_));
+       write(fd, (char *) &D_, sizeof(D_));
+       write(fd, (char *) &E_, sizeof(E_));
+       write(fd, (char *) &H_, sizeof(H_));
+       write(fd, (char *) &L_, sizeof(L_));
+       write(fd, (char *) &I, sizeof(I));
+       write(fd, (char *) &IFF, sizeof(IFF));
+       write(fd, (char *) &R, sizeof(R));
+       write(fd, (char *) &PC, sizeof(PC));
+       write(fd, (char *) &SP, sizeof(SP));
+       write(fd, (char *) &IX, sizeof(IX));
+       write(fd, (char *) &IY, sizeof(IY));
+       write(fd, (char *) mem_base(), 65536);
+       close(fd);
+}
+
+/*
+ *     This function loads the CPU and memory from the file core.z80
+ */
+int load_core(void)
+{
+       int fd;
+
+       if ((fd = open("core.z80", O_RDONLY)) == -1) {
+               puts("can't open file core.z80");
+               return(1);
+       }
+       read(fd, (char *) &A, sizeof(A));
+       read(fd, (char *) &F, sizeof(F));
+       read(fd, (char *) &B, sizeof(B));
+       read(fd, (char *) &C, sizeof(C));
+       read(fd, (char *) &D, sizeof(D));
+       read(fd, (char *) &E, sizeof(E));
+       read(fd, (char *) &H, sizeof(H));
+       read(fd, (char *) &L, sizeof(L));
+       read(fd, (char *) &A_, sizeof(A_));
+       read(fd, (char *) &F_, sizeof(F_));
+       read(fd, (char *) &B_, sizeof(B_));
+       read(fd, (char *) &C_, sizeof(C_));
+       read(fd, (char *) &D_, sizeof(D_));
+       read(fd, (char *) &E_, sizeof(E_));
+       read(fd, (char *) &H_, sizeof(H_));
+       read(fd, (char *) &L_, sizeof(L_));
+       read(fd, (char *) &I, sizeof(I));
+       read(fd, (char *) &IFF, sizeof(IFF));
+       read(fd, (char *) &R, sizeof(R));
+       read(fd, (char *) &PC, sizeof(PC));
+       read(fd, (char *) &SP, sizeof(SP));
+       read(fd, (char *) &IX, sizeof(IX));
+       read(fd, (char *) &IY, sizeof(IY));
+       read(fd, (char *) mem_base(), 65536);
+       close(fd);
+
+       return(0);
+}
+
+/*
+ *     Read a file into the memory of the emulated CPU.
+ *     The following file formats are supported:
+ *
+ *             binary images with Mostek header
+ *             Intel hex
+ */
+int load_file(char *s)
+{
+       char fn[LENCMD];
+       BYTE fileb[5];
+       register char *pfn = fn;
+       int fd;
+
+       while (isspace((int)*s))
+               s++;
+       while (*s != ',' && *s != '\n' && *s != '\0')
+               *pfn++ = *s++;
+       *pfn = '\0';
+       if (strlen(fn) == 0) {
+               puts("no input file given");
+               return(1);
+       }
+       if ((fd = open(fn, O_RDONLY)) == -1) {
+               printf("can't open file %s\n", fn);
+               return(1);
+       }
+       if (*s == ',')
+               wrk_ram = mem_base() + exatoi(++s);
+       else
+               wrk_ram = NULL;
+       read(fd, (char *) fileb, 5); /* read first 5 bytes of file */
+       if (*fileb == (BYTE) 0xff) {    /* Mostek header ? */
+               lseek(fd, 0l, SEEK_SET);
+               return (load_mos(fd, fn));
+       }
+       else {
+               close(fd);
+               return (load_hex(fn));
+       }
+}
+
+/*
+ *     Loader for binary images with Mostek header.
+ *     Format of the first 3 bytes:
+ *
+ *     0xff ll lh
+ *
+ *     ll = load address low
+ *     lh = load address high
+ */
+static int load_mos(int fd, char *fn)
+{
+       BYTE fileb[3];
+       unsigned count, readn;
+       int rc = 0;
+
+       read(fd, (char *) fileb, 3);    /* read load address */
+       if (wrk_ram == NULL)            /* and set if not given */
+               wrk_ram = mem_base() + (fileb[2] << 8) + fileb[1];
+       count = mem_base() + 65535 - wrk_ram;
+       if ((readn = read(fd, (char *) wrk_ram, count)) == count) {
+               puts("Too much to load, stopped at 0xffff");
+               rc = 1;
+       }
+       close(fd);
+       printf("Loader statistics for file %s:\n", fn);
+       printf("START : %04x\n", (unsigned int)(wrk_ram - mem_base()));
+       printf("END   : %04x\n", (unsigned int)(wrk_ram - mem_base()
+                                + readn - 1));
+       printf("LOADED: %04x\n\n", readn);
+       PC = wrk_ram - mem_base();
+       return(rc);
+}
+
+/*
+ *     Loader for Intel hex
+ */
+static int load_hex(char *fn)
+{
+       register int i;
+       FILE *fd;
+       char buf[BUFSIZE];
+       char *s;
+       int count = 0;
+       int addr = 0;
+       int saddr = 0xffff;
+       int eaddr = 0;
+       int data;
+
+       if ((fd = fopen(fn, "r")) == NULL) {
+               printf("can't open file %s\n", fn);
+               return(1);
+       }
+
+       while (fgets(&buf[0], BUFSIZE, fd) != NULL) {
+               s = &buf[0];
+               while (isspace((int)*s))
+                       s++;
+               if (*s != ':')
+                       continue;
+               if (checksum(s + 1) != 0) {
+                       printf("invalid checksum in hex record: %s\n", s);
+                       return(1);
+               }
+               s++;
+               count = (*s <= '9') ? (*s - '0') << 4 :
+                                     (*s - 'A' + 10) << 4;
+               s++;
+               count += (*s <= '9') ? (*s - '0') :
+                                      (*s - 'A' + 10);
+               s++;
+               if (count == 0)
+                       break;
+               addr = (*s <= '9') ? (*s - '0') << 4 :
+                                    (*s - 'A' + 10) << 4;
+               s++;
+               addr += (*s <= '9') ? (*s - '0') :
+                                     (*s - 'A' + 10);
+               s++;
+               addr *= 256;
+               addr += (*s <= '9') ? (*s - '0') << 4 :
+                                     (*s - 'A' + 10) << 4;
+               s++;
+               addr += (*s <= '9') ? (*s - '0') :
+                                     (*s - 'A' + 10);
+               s++;
+               if (addr < saddr)
+                       saddr = addr;
+               if (addr >= eaddr)
+                       eaddr = addr + count - 1;
+               s += 2;
+               for (i = 0; i < count; i++) {
+                       data = (*s <= '9') ? (*s - '0') << 4 :
+                                            (*s - 'A' + 10) << 4;
+                       s++;
+                       data += (*s <= '9') ? (*s - '0') :
+                                             (*s - 'A' + 10);
+                       s++;
+                       *(mem_base() + addr + i) = data;
+               }
+       }
+
+       fclose(fd);
+       count = eaddr - saddr + 1;
+       printf("Loader statistics for file %s:\n", fn);
+       printf("START : %04xH\n", saddr);
+       printf("END   : %04xH\n", eaddr);
+       printf("LOADED: %04xH (%d)\n\n", count, count);
+       PC = saddr;
+       wrk_ram = mem_base() + saddr;
+
+       return(0);
+}
+
+/*
+ *     Verify checksum of Intel hex records
+ */
+static int checksum(char *s)
+{
+       int chk = 0;
+
+       while ((*s != '\r') && (*s != '\n')) {
+               chk += (*s <= '9') ?
+                       (*s - '0') << 4 :
+                       (*s - 'A' + 10) << 4;
+               s++;
+               chk += (*s <= '9') ?
+                       (*s - '0') :
+                       (*s - 'A' + 10);
+               s++;
+       }
+
+       if ((chk & 255) == 0)
+               return(0);
+       else
+               return(1);
+}
diff --git a/sim/sim1.c b/sim/sim1.c
new file mode 100644 (file)
index 0000000..b090384
--- /dev/null
@@ -0,0 +1,3263 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+#ifdef WANT_GUI
+void check_gui_break(void);
+#endif
+
+static int op_nop(void), op_halt(void), op_scf(void);
+static int op_ccf(void), op_cpl(void), op_daa(void);
+static int op_ei(void), op_di(void);
+static int op_in(void), op_out(void);
+static int op_ldan(void), op_ldbn(void), op_ldcn(void);
+static int op_lddn(void), op_lden(void);
+static int op_ldhn(void), op_ldln(void);
+static int op_ldabc(void), op_ldade(void), op_ldann(void);
+static int op_ldbca(void), op_lddea(void), op_ldnna(void);
+static int op_ldhla(void), op_ldhlb(void), op_ldhlc(void), op_ldhld(void);
+static int op_ldhle(void), op_ldhlh(void), op_ldhll(void), op_ldhl1(void);
+static int op_ldaa(void), op_ldab(void), op_ldac(void);
+static int op_ldad(void), op_ldae(void);
+static int op_ldah(void), op_ldal(void), op_ldahl(void);
+static int op_ldba(void), op_ldbb(void), op_ldbc(void);
+static int op_ldbd(void), op_ldbe(void);
+static int op_ldbh(void), op_ldbl(void), op_ldbhl(void);
+static int op_ldca(void), op_ldcb(void), op_ldcc(void);
+static int op_ldcd(void), op_ldce(void);
+static int op_ldch(void), op_ldcl(void), op_ldchl(void);
+static int op_ldda(void), op_lddb(void), op_lddc(void);
+static int op_lddd(void), op_ldde(void);
+static int op_lddh(void), op_lddl(void), op_lddhl(void);
+static int op_ldea(void), op_ldeb(void), op_ldec(void);
+static int op_lded(void), op_ldee(void);
+static int op_ldeh(void), op_ldel(void), op_ldehl(void);
+static int op_ldha(void), op_ldhb(void), op_ldhc(void);
+static int op_ldhd(void), op_ldhe(void);
+static int op_ldhh(void), op_ldhl(void), op_ldhhl(void);
+static int op_ldla(void), op_ldlb(void), op_ldlc(void);
+static int op_ldld(void), op_ldle(void);
+static int op_ldlh(void), op_ldll(void), op_ldlhl(void);
+static int op_ldbcnn(void), op_lddenn(void), op_ldhlnn(void);
+static int op_ldspnn(void), op_ldsphl(void);
+static int op_ldhlin(void), op_ldinhl(void);
+static int op_incbc(void), op_incde(void), op_inchl(void), op_incsp(void);
+static int op_decbc(void), op_decde(void), op_dechl(void), op_decsp(void);
+static int op_adhlbc(void), op_adhlde(void), op_adhlhl(void), op_adhlsp(void);
+static int op_anda(void), op_andb(void), op_andc(void), op_andd(void), op_ande(void);
+static int op_andh(void), op_andl(void), op_andhl(void), op_andn(void);
+static int op_ora(void), op_orb(void), op_orc(void), op_ord(void), op_ore(void);
+static int op_orh(void), op_orl(void), op_orhl(void), op_orn(void);
+static int op_xora(void), op_xorb(void), op_xorc(void), op_xord(void), op_xore(void);
+static int op_xorh(void), op_xorl(void), op_xorhl(void), op_xorn(void);
+static int op_adda(void), op_addb(void), op_addc(void), op_addd(void), op_adde(void);
+static int op_addh(void), op_addl(void), op_addhl(void), op_addn(void);
+static int op_adca(void), op_adcb(void), op_adcc(void), op_adcd(void), op_adce(void);
+static int op_adch(void), op_adcl(void), op_adchl(void), op_adcn(void);
+static int op_suba(void), op_subb(void), op_subc(void), op_subd(void), op_sube(void);
+static int op_subh(void), op_subl(void), op_subhl(void), op_subn(void);
+static int op_sbca(void), op_sbcb(void), op_sbcc(void), op_sbcd(void), op_sbce(void);
+static int op_sbch(void), op_sbcl(void), op_sbchl(void), op_sbcn(void);
+static int op_cpa(void), op_cpb(void), op_cpc(void), op_cpd(void), op_cpe(void);
+static int op_cph(void), op_cplr(void), op_cphl(void), op_cpn(void);
+static int op_inca(void), op_incb(void), op_incc(void), op_incd(void), op_ince(void);
+static int op_inch(void), op_incl(void), op_incihl(void);
+static int op_deca(void), op_decb(void), op_decc(void), op_decd(void), op_dece(void);
+static int op_dech(void), op_decl(void), op_decihl(void);
+static int op_rlca(void), op_rrca(void),op_rla(void),op_rra(void);
+static int op_exdehl(void), op_exafaf(void), op_exx(void), op_exsphl(void);
+static int op_pushaf(void), op_pushbc(void), op_pushde(void), op_pushhl(void);
+static int op_popaf(void), op_popbc(void), op_popde(void), op_pophl(void);
+static int op_jp(void), op_jphl(void), op_jr(void), op_djnz(void), op_call(void), op_ret(void);
+static int op_jpz(void), op_jpnz(void), op_jpc(void), op_jpnc(void);
+static int op_jppe(void), op_jppo(void), op_jpm(void), op_jpp(void);
+static int op_calz(void), op_calnz(void), op_calc(void), op_calnc(void);
+static int op_calpe(void), op_calpo(void), op_calm(void), op_calp(void);
+static int op_retz(void), op_retnz(void), op_retc(void), op_retnc(void);
+static int op_retpe(void), op_retpo(void), op_retm(void), op_retp(void);
+static int op_jrz(void), op_jrnz(void), op_jrc(void), op_jrnc(void);
+static int op_rst00(void), op_rst08(void), op_rst10(void), op_rst18(void);
+static int op_rst20(void), op_rst28(void), op_rst30(void), op_rst38(void);
+extern int op_cb_handel(void), op_dd_handel(void);
+extern int op_ed_handel(void), op_fd_handel(void);
+
+/*
+ *     This function builds the Z80 central processing unit.
+ *     The opcode where PC points to is fetched from the memory
+ *     and PC incremented by one. The opcode is used as an
+ *     index to an array with function pointers, to execute a
+ *     function which emulates this Z80 opcode.
+ */
+void cpu_z80(void)
+{
+       static int (*op_sim[256]) (void) = {
+               op_nop,                         /* 0x00 */
+               op_ldbcnn,                      /* 0x01 */
+               op_ldbca,                       /* 0x02 */
+               op_incbc,                       /* 0x03 */
+               op_incb,                        /* 0x04 */
+               op_decb,                        /* 0x05 */
+               op_ldbn,                        /* 0x06 */
+               op_rlca,                        /* 0x07 */
+               op_exafaf,                      /* 0x08 */
+               op_adhlbc,                      /* 0x09 */
+               op_ldabc,                       /* 0x0a */
+               op_decbc,                       /* 0x0b */
+               op_incc,                        /* 0x0c */
+               op_decc,                        /* 0x0d */
+               op_ldcn,                        /* 0x0e */
+               op_rrca,                        /* 0x0f */
+               op_djnz,                        /* 0x10 */
+               op_lddenn,                      /* 0x11 */
+               op_lddea,                       /* 0x12 */
+               op_incde,                       /* 0x13 */
+               op_incd,                        /* 0x14 */
+               op_decd,                        /* 0x15 */
+               op_lddn,                        /* 0x16 */
+               op_rla,                         /* 0x17 */
+               op_jr,                          /* 0x18 */
+               op_adhlde,                      /* 0x19 */
+               op_ldade,                       /* 0x1a */
+               op_decde,                       /* 0x1b */
+               op_ince,                        /* 0x1c */
+               op_dece,                        /* 0x1d */
+               op_lden,                        /* 0x1e */
+               op_rra,                         /* 0x1f */
+               op_jrnz,                        /* 0x20 */
+               op_ldhlnn,                      /* 0x21 */
+               op_ldinhl,                      /* 0x22 */
+               op_inchl,                       /* 0x23 */
+               op_inch,                        /* 0x24 */
+               op_dech,                        /* 0x25 */
+               op_ldhn,                        /* 0x26 */
+               op_daa,                         /* 0x27 */
+               op_jrz,                         /* 0x28 */
+               op_adhlhl,                      /* 0x29 */
+               op_ldhlin,                      /* 0x2a */
+               op_dechl,                       /* 0x2b */
+               op_incl,                        /* 0x2c */
+               op_decl,                        /* 0x2d */
+               op_ldln,                        /* 0x2e */
+               op_cpl,                         /* 0x2f */
+               op_jrnc,                        /* 0x30 */
+               op_ldspnn,                      /* 0x31 */
+               op_ldnna,                       /* 0x32 */
+               op_incsp,                       /* 0x33 */
+               op_incihl,                      /* 0x34 */
+               op_decihl,                      /* 0x35 */
+               op_ldhl1,                       /* 0x36 */
+               op_scf,                         /* 0x37 */
+               op_jrc,                         /* 0x38 */
+               op_adhlsp,                      /* 0x39 */
+               op_ldann,                       /* 0x3a */
+               op_decsp,                       /* 0x3b */
+               op_inca,                        /* 0x3c */
+               op_deca,                        /* 0x3d */
+               op_ldan,                        /* 0x3e */
+               op_ccf,                         /* 0x3f */
+               op_ldbb,                        /* 0x40 */
+               op_ldbc,                        /* 0x41 */
+               op_ldbd,                        /* 0x42 */
+               op_ldbe,                        /* 0x43 */
+               op_ldbh,                        /* 0x44 */
+               op_ldbl,                        /* 0x45 */
+               op_ldbhl,                       /* 0x46 */
+               op_ldba,                        /* 0x47 */
+               op_ldcb,                        /* 0x48 */
+               op_ldcc,                        /* 0x49 */
+               op_ldcd,                        /* 0x4a */
+               op_ldce,                        /* 0x4b */
+               op_ldch,                        /* 0x4c */
+               op_ldcl,                        /* 0x4d */
+               op_ldchl,                       /* 0x4e */
+               op_ldca,                        /* 0x4f */
+               op_lddb,                        /* 0x50 */
+               op_lddc,                        /* 0x51 */
+               op_lddd,                        /* 0x52 */
+               op_ldde,                        /* 0x53 */
+               op_lddh,                        /* 0x54 */
+               op_lddl,                        /* 0x55 */
+               op_lddhl,                       /* 0x56 */
+               op_ldda,                        /* 0x57 */
+               op_ldeb,                        /* 0x58 */
+               op_ldec,                        /* 0x59 */
+               op_lded,                        /* 0x5a */
+               op_ldee,                        /* 0x5b */
+               op_ldeh,                        /* 0x5c */
+               op_ldel,                        /* 0x5d */
+               op_ldehl,                       /* 0x5e */
+               op_ldea,                        /* 0x5f */
+               op_ldhb,                        /* 0x60 */
+               op_ldhc,                        /* 0x61 */
+               op_ldhd,                        /* 0x62 */
+               op_ldhe,                        /* 0x63 */
+               op_ldhh,                        /* 0x64 */
+               op_ldhl,                        /* 0x65 */
+               op_ldhhl,                       /* 0x66 */
+               op_ldha,                        /* 0x67 */
+               op_ldlb,                        /* 0x68 */
+               op_ldlc,                        /* 0x69 */
+               op_ldld,                        /* 0x6a */
+               op_ldle,                        /* 0x6b */
+               op_ldlh,                        /* 0x6c */
+               op_ldll,                        /* 0x6d */
+               op_ldlhl,                       /* 0x6e */
+               op_ldla,                        /* 0x6f */
+               op_ldhlb,                       /* 0x70 */
+               op_ldhlc,                       /* 0x71 */
+               op_ldhld,                       /* 0x72 */
+               op_ldhle,                       /* 0x73 */
+               op_ldhlh,                       /* 0x74 */
+               op_ldhll,                       /* 0x75 */
+               op_halt,                        /* 0x76 */
+               op_ldhla,                       /* 0x77 */
+               op_ldab,                        /* 0x78 */
+               op_ldac,                        /* 0x79 */
+               op_ldad,                        /* 0x7a */
+               op_ldae,                        /* 0x7b */
+               op_ldah,                        /* 0x7c */
+               op_ldal,                        /* 0x7d */
+               op_ldahl,                       /* 0x7e */
+               op_ldaa,                        /* 0x7f */
+               op_addb,                        /* 0x80 */
+               op_addc,                        /* 0x81 */
+               op_addd,                        /* 0x82 */
+               op_adde,                        /* 0x83 */
+               op_addh,                        /* 0x84 */
+               op_addl,                        /* 0x85 */
+               op_addhl,                       /* 0x86 */
+               op_adda,                        /* 0x87 */
+               op_adcb,                        /* 0x88 */
+               op_adcc,                        /* 0x89 */
+               op_adcd,                        /* 0x8a */
+               op_adce,                        /* 0x8b */
+               op_adch,                        /* 0x8c */
+               op_adcl,                        /* 0x8d */
+               op_adchl,                       /* 0x8e */
+               op_adca,                        /* 0x8f */
+               op_subb,                        /* 0x90 */
+               op_subc,                        /* 0x91 */
+               op_subd,                        /* 0x92 */
+               op_sube,                        /* 0x93 */
+               op_subh,                        /* 0x94 */
+               op_subl,                        /* 0x95 */
+               op_subhl,                       /* 0x96 */
+               op_suba,                        /* 0x97 */
+               op_sbcb,                        /* 0x98 */
+               op_sbcc,                        /* 0x99 */
+               op_sbcd,                        /* 0x9a */
+               op_sbce,                        /* 0x9b */
+               op_sbch,                        /* 0x9c */
+               op_sbcl,                        /* 0x9d */
+               op_sbchl,                       /* 0x9e */
+               op_sbca,                        /* 0x9f */
+               op_andb,                        /* 0xa0 */
+               op_andc,                        /* 0xa1 */
+               op_andd,                        /* 0xa2 */
+               op_ande,                        /* 0xa3 */
+               op_andh,                        /* 0xa4 */
+               op_andl,                        /* 0xa5 */
+               op_andhl,                       /* 0xa6 */
+               op_anda,                        /* 0xa7 */
+               op_xorb,                        /* 0xa8 */
+               op_xorc,                        /* 0xa9 */
+               op_xord,                        /* 0xaa */
+               op_xore,                        /* 0xab */
+               op_xorh,                        /* 0xac */
+               op_xorl,                        /* 0xad */
+               op_xorhl,                       /* 0xae */
+               op_xora,                        /* 0xaf */
+               op_orb,                         /* 0xb0 */
+               op_orc,                         /* 0xb1 */
+               op_ord,                         /* 0xb2 */
+               op_ore,                         /* 0xb3 */
+               op_orh,                         /* 0xb4 */
+               op_orl,                         /* 0xb5 */
+               op_orhl,                        /* 0xb6 */
+               op_ora,                         /* 0xb7 */
+               op_cpb,                         /* 0xb8 */
+               op_cpc,                         /* 0xb9 */
+               op_cpd,                         /* 0xba */
+               op_cpe,                         /* 0xbb */
+               op_cph,                         /* 0xbc */
+               op_cplr,                        /* 0xbd */
+               op_cphl,                        /* 0xbe */
+               op_cpa,                         /* 0xbf */
+               op_retnz,                       /* 0xc0 */
+               op_popbc,                       /* 0xc1 */
+               op_jpnz,                        /* 0xc2 */
+               op_jp,                          /* 0xc3 */
+               op_calnz,                       /* 0xc4 */
+               op_pushbc,                      /* 0xc5 */
+               op_addn,                        /* 0xc6 */
+               op_rst00,                       /* 0xc7 */
+               op_retz,                        /* 0xc8 */
+               op_ret,                         /* 0xc9 */
+               op_jpz,                         /* 0xca */
+               op_cb_handel,                   /* 0xcb */
+               op_calz,                        /* 0xcc */
+               op_call,                        /* 0xcd */
+               op_adcn,                        /* 0xce */
+               op_rst08,                       /* 0xcf */
+               op_retnc,                       /* 0xd0 */
+               op_popde,                       /* 0xd1 */
+               op_jpnc,                        /* 0xd2 */
+               op_out,                         /* 0xd3 */
+               op_calnc,                       /* 0xd4 */
+               op_pushde,                      /* 0xd5 */
+               op_subn,                        /* 0xd6 */
+               op_rst10,                       /* 0xd7 */
+               op_retc,                        /* 0xd8 */
+               op_exx,                         /* 0xd9 */
+               op_jpc,                         /* 0xda */
+               op_in,                          /* 0xdb */
+               op_calc,                        /* 0xdc */
+               op_dd_handel,                   /* 0xdd */
+               op_sbcn,                        /* 0xde */
+               op_rst18,                       /* 0xdf */
+               op_retpo,                       /* 0xe0 */
+               op_pophl,                       /* 0xe1 */
+               op_jppo,                        /* 0xe2 */
+               op_exsphl,                      /* 0xe3 */
+               op_calpo,                       /* 0xe4 */
+               op_pushhl,                      /* 0xe5 */
+               op_andn,                        /* 0xe6 */
+               op_rst20,                       /* 0xe7 */
+               op_retpe,                       /* 0xe8 */
+               op_jphl,                        /* 0xe9 */
+               op_jppe,                        /* 0xea */
+               op_exdehl,                      /* 0xeb */
+               op_calpe,                       /* 0xec */
+               op_ed_handel,                   /* 0xed */
+               op_xorn,                        /* 0xee */
+               op_rst28,                       /* 0xef */
+               op_retp,                        /* 0xf0 */
+               op_popaf,                       /* 0xf1 */
+               op_jpp,                         /* 0xf2 */
+               op_di,                          /* 0xf3 */
+               op_calp,                        /* 0xf4 */
+               op_pushaf,                      /* 0xf5 */
+               op_orn,                         /* 0xf6 */
+               op_rst30,                       /* 0xf7 */
+               op_retm,                        /* 0xf8 */
+               op_ldsphl,                      /* 0xf9 */
+               op_jpm,                         /* 0xfa */
+               op_ei,                          /* 0xfb */
+               op_calm,                        /* 0xfc */
+               op_fd_handel,                   /* 0xfd */
+               op_cpn,                         /* 0xfe */
+               op_rst38                        /* 0xff */
+       };
+
+       register int t = 0;
+       register int states;
+       struct timespec timer;
+       struct timeval t1, t2, tdiff;
+       WORD p;
+
+       gettimeofday(&t1, NULL);
+
+       do {
+
+#ifdef HISIZE
+               /* write history */
+               his[h_next].h_adr = PC;
+               his[h_next].h_af = (A << 8) + F;
+               his[h_next].h_bc = (B << 8) + C;
+               his[h_next].h_de = (D << 8) + E;
+               his[h_next].h_hl = (H << 8) + L;
+               his[h_next].h_ix = IX;
+               his[h_next].h_iy = IY;
+               his[h_next].h_sp = SP;
+               h_next++;
+               if (h_next == HISIZE) {
+                       h_flag = 1;
+                       h_next = 0;
+               }
+#endif
+
+#ifdef WANT_TIM
+               /* check for start address of runtime measurement */
+               if (PC == t_start && !t_flag) {
+                       t_flag = 1;     /* switch measurement on */
+                       t_states = 0L;  /* initialise counted T-states */
+               }
+#endif
+
+               /* CPU interrupt handling */
+               if (int_nmi) {          /* non maskable interrupt */
+                       IFF <<= 1 & 3;
+                       memwrt(--SP, PC >> 8);
+                       memwrt(--SP, PC);
+                       PC = 0x66;
+                       int_nmi = 0;
+               }
+
+               if (int_int) {          /* maskable interrupt */
+                       if (IFF != 3)
+                               goto leave;
+                       if (int_protection)     /* protect first instr */
+                               goto leave;
+
+                       IFF = 0;
+
+#ifdef BUS_8080
+                       if (!(cpu_bus & CPU_HLTA)) {
+                               cpu_bus = CPU_WO | CPU_M1 | CPU_INTA;
+#endif
+#ifdef FRONTPANEL
+                               fp_clock += 1000;
+                               fp_led_data = (int_data != -1) ?
+                                               (BYTE) int_data : 0xff;
+                               fp_sampleData();
+                               wait_int_step();
+                               if (cpu_state & RESET)
+                                       goto leave;
+#endif
+#ifdef BUS_8080
+                       }
+                       cpu_bus = 0;
+#endif
+
+                       switch (int_mode) {
+                       case 0:         /* IM 0 */
+                               memwrt(--SP, PC >> 8);
+                               memwrt(--SP, PC);
+#ifdef FRONTPANEL
+                               if (cpu_state & RESET)
+                                       goto leave;
+#endif
+                               switch (int_data) {
+                               case 0xc7: /* RST 00H */
+                                       PC = 0;
+                                       break;
+                               case 0xcf: /* RST 08H */
+                                       PC = 8;
+                                       break;
+                               case 0xd7: /* RST 10H */
+                                       PC = 0x10;
+                                       break;
+                               case 0xdf: /* RST 18H */
+                                       PC = 0x18;
+                                       break;
+                               case 0xe7: /* RST 20H */
+                                       PC = 0x20;
+                                       break;
+                               case 0xef: /* RST 28H */
+                                       PC = 0x28;
+                                       break;
+                               case 0xf7: /* RST 30H */
+                                       PC = 0x30;
+                                       break;
+                               case 0xff: /* RST 38H */
+                                       PC = 0x38;
+                                       break;
+                               default:
+                                       PC = 0x38;
+                                       break;
+                               }
+                               break;
+                       case 1:         /* IM 1 */
+                               memwrt(--SP, PC >> 8);
+                               memwrt(--SP, PC);
+#ifdef FRONTPANEL
+                               if (cpu_state & RESET)
+                                       goto leave;
+#endif
+                               PC = 0x38;
+                               break;
+                       case 2:         /* IM 2 */
+                               memwrt(--SP, PC >> 8);
+                               memwrt(--SP, PC);
+#ifdef FRONTPANEL
+                               if (cpu_state & RESET)
+                                       goto leave;
+#endif
+                               p = (I << 8) + (int_data & 0xff);
+                               PC = memrdr(p++);
+                               PC += memrdr(p) << 8;
+                               break;
+                       }
+                       int_int = 0;
+                       int_data = -1;
+#ifdef FRONTPANEL
+                       m1_step = 1;
+#endif
+               }
+leave:
+
+#ifdef BUS_8080
+               /* M1 opcode fetch */
+               cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+#endif
+
+#ifdef FRONTPANEL
+               /* update frontpanel */
+               fp_clock++;
+               fp_led_address = PC;
+               fp_led_data = dma_read(PC);
+               fp_sampleData();
+#endif
+
+               int_protection = 0;
+               states = (*op_sim[memrdr(PC++)]) (); /* execute next opcode */
+               t += states;
+
+               if (f_flag) {                   /* adjust CPU speed */
+                       if (t >= tmax) {
+                               gettimeofday(&t2, NULL);
+                               tdiff.tv_sec = t2.tv_sec - t1.tv_sec;
+                               tdiff.tv_usec = t2.tv_usec - t1.tv_usec;
+                               if (tdiff.tv_usec < 0) {
+                                       --tdiff.tv_sec;
+                                       tdiff.tv_usec += 1000000;
+                               }
+                               if ((tdiff.tv_sec == 0) && (tdiff.tv_usec
+                                                           < 10000)) {
+                                       timer.tv_sec = 0;
+                                       timer.tv_nsec = (long) ((10000
+                                                               - tdiff.tv_usec)
+                                                               * 1000);
+                                       nanosleep(&timer, NULL);
+                               }
+                               t = 0;
+                               gettimeofday(&t1, NULL);
+                       }
+               }
+
+               R++;                    /* increment refresh register */
+
+                                       /* do runtime measurement */
+#ifdef WANT_TIM
+               if (t_flag) {
+                       t_states += states; /* add T-states for this opcode */
+                       if (PC == t_end)        /* check for end address */
+                               t_flag = 0;     /* if reached, switch off */
+               }
+#endif
+
+#ifdef WANT_GUI
+                check_gui_break();
+#endif
+
+       } while (cpu_state == CONTIN_RUN);
+
+#ifdef BUS_8080
+       if (!(cpu_bus & CPU_INTA))
+               cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+#endif
+#ifdef FRONTPANEL
+       fp_led_address = PC;
+       fp_led_data = dma_read(PC);
+       fp_clock++;
+       fp_sampleData();
+#endif
+}
+
+static int op_nop(void)                        /* NOP */
+{
+       return(4);
+}
+
+static int op_halt(void)               /* HALT */
+{
+       struct timespec timer;
+
+#ifdef BUS_8080
+       cpu_bus = CPU_WO | CPU_HLTA | CPU_MEMR;
+#endif
+
+#ifndef FRONTPANEL
+       /* without a frontpanel DI + HALT stops the machine */
+       if (IFF == 0)   {
+               cpu_error = OPHALT;
+               cpu_state = STOPPED;
+       } else {
+       /* else wait for INT, NMI or user interrupt */
+               while ((int_int == 0) && (int_nmi == 0) &&
+                      (cpu_state == CONTIN_RUN)) {
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+               }
+       }
+#ifdef BUS_8080
+       if (int_int)
+               cpu_bus = CPU_INTA | CPU_WO | CPU_HLTA | CPU_M1;
+#endif
+
+       busy_loop_cnt[0] = 0;
+
+#else
+
+       fp_led_address = 0xffff;
+       fp_led_data = 0xff;
+
+       /* INT disabled, wait for NMI, frontpanel reset or user interrupt */
+       if (IFF == 0)   {
+               while ((int_nmi == 0) && !(cpu_state & RESET)) {
+                       fp_clock++;
+                       fp_sampleData();
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+                       if (cpu_error != NONE)
+                               break;
+               }
+       } else {
+       /* else wait for INT, NMI, frontpanel reset or user interrupt */
+               while ((int_int == 0) && (int_nmi == 0) &&
+                      !(cpu_state & RESET)) {
+                       fp_clock++;
+                       fp_sampleData();
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+                       if (cpu_error != NONE)
+                               break;
+               }
+               if (int_int) {
+                       cpu_bus = CPU_INTA | CPU_WO | CPU_HLTA | CPU_M1;
+                       fp_clock++;
+                       fp_sampleLightGroup(0, 0);
+               }
+       }
+#endif
+
+       return(4);
+}
+
+static int op_scf(void)                        /* SCF */
+{
+       F |= C_FLAG;
+       F &= ~(N_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_ccf(void)                        /* CCF */
+{
+       if (F & C_FLAG) {
+               F |= H_FLAG;
+               F &= ~C_FLAG;
+       } else {
+               F &= ~H_FLAG;
+               F |= C_FLAG;
+       }
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_cpl(void)                        /* CPL */
+{
+       A = ~A;
+       F |= H_FLAG | N_FLAG;
+       return(4);
+}
+
+/*
+ * This is my original implementation of the DAA instruction.
+ * It implements the instruction as described in Z80 data sheets
+ * and books, but it won't pass the ex.com instruction exerciser.
+ * Below is a contributed implementation active, that also passes
+ * the tests done by ex.com.
+ */
+#if 0
+static int op_daa(void)                        /* DAA */
+{
+       if (F & N_FLAG) {               /* subtractions */
+               if (((A & 0x0f) > 9) || (F & H_FLAG)) {
+                       (((A & 0x0f) - 6) < 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+                       A -= 6;
+               }
+               if (((A & 0xf0) > 0x90) || (F & C_FLAG)) {
+                       if (((A & 0xf0) - 0x60) < 0)
+                               F |= C_FLAG;
+                       A -= 0x60;
+               }
+       } else {                        /* additions */
+               if (((A & 0x0f) > 9) || (F & H_FLAG)) {
+                       (((A & 0x0f) + 6) > 0x0f) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+                       A += 6;
+               }
+               if (((A & 0xf0) > 0x90) || (F & C_FLAG)) {
+                       if (((A & 0xf0) + 0x60) > 0xf0)
+                               F |= C_FLAG;
+                       A += 0x60;
+               }
+       }
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(4);
+}
+#endif
+
+/*
+ * This implementation was contributed by Mark Garlanger,
+ * see http://heathkit.garlanger.com/
+ * It passes the instruction exerciser test from ex.com
+ * and is correct.
+ */
+static int op_daa(void)                        /* DAA */
+{
+       int tmp_a = A;
+       int low_nibble = A & 0x0f;
+       int carry = (F & C_FLAG);
+
+       if (F & N_FLAG) {               /* subtraction */
+               int adjustment = (carry || (tmp_a > 0x99)) ? 0x160 : 0x00;
+
+               if ((F & H_FLAG) || (low_nibble > 9)) {
+                       if (low_nibble > 5) {
+                               F &= ~H_FLAG;
+                       }
+                       tmp_a = (tmp_a - 6) & 0xff;
+               }
+               tmp_a -= adjustment;
+        } else {                       /* addition */
+               if ((low_nibble > 9) || (F & H_FLAG)) {
+                       (low_nibble > 9) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+                       tmp_a += 6;
+               }
+               if (((tmp_a & 0x1f0) > 0x90) || carry) {
+                       tmp_a += 0x60;
+               }
+       }
+
+       (carry || (tmp_a & 0x100)) ?  (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = (tmp_a & 0xff);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(4);
+}
+
+static int op_ei(void)                 /* EI */
+{
+       IFF = 3;
+       int_protection = 1;             /* protect next instruction */
+       return(4);
+}
+
+static int op_di(void)                 /* DI */
+{
+       IFF = 0;
+       return(4);
+}
+
+static int op_in(void)                 /* IN A,(n) */
+{
+       BYTE io_in(BYTE, BYTE);
+       BYTE addr;
+
+       addr = memrdr(PC++);
+       A = io_in(addr, A);
+       return(11);
+}
+
+static int op_out(void)                        /* OUT (n),A */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       BYTE addr;
+
+       addr = memrdr(PC++);
+       io_out(addr, A, A);
+       return(11);
+}
+
+static int op_ldan(void)               /* LD A,n */
+{
+       A = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldbn(void)               /* LD B,n */
+{
+       B = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldcn(void)               /* LD C,n */
+{
+       C = memrdr(PC++);
+       return(7);
+}
+
+static int op_lddn(void)               /* LD D,n */
+{
+       D = memrdr(PC++);
+       return(7);
+}
+
+static int op_lden(void)               /* LD E,n */
+{
+       E = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldhn(void)               /* LD H,n */
+{
+       H = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldln(void)               /* LD L,n */
+{
+       L = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldabc(void)              /* LD A,(BC) */
+{
+       A = memrdr((B << 8) + C);
+       return(7);
+}
+
+static int op_ldade(void)              /* LD A,(DE) */
+{
+       A = memrdr((D << 8) + E);
+       return(7);
+}
+
+static int op_ldann(void)              /* LD A,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       A = memrdr(i);
+       return(13);
+}
+
+static int op_ldbca(void)              /* LD (BC),A */
+{
+       memwrt((B << 8) + C, A);
+       return(7);
+}
+
+static int op_lddea(void)              /* LD (DE),A */
+{
+       memwrt((D << 8) + E, A);
+       return(7);
+}
+
+static int op_ldnna(void)              /* LD (nn),A */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i, A);
+       return(13);
+}
+
+static int op_ldhla(void)              /* LD (HL),A */
+{
+       memwrt((H << 8) + L, A);
+       return(7);
+}
+
+static int op_ldhlb(void)              /* LD (HL),B */
+{
+       memwrt((H << 8) + L, B);
+       return(7);
+}
+
+static int op_ldhlc(void)              /* LD (HL),C */
+{
+       memwrt((H << 8) + L, C);
+       return(7);
+}
+
+static int op_ldhld(void)              /* LD (HL),D */
+{
+       memwrt((H << 8) + L, D);
+       return(7);
+}
+
+static int op_ldhle(void)              /* LD (HL),E */
+{
+       memwrt((H << 8) + L, E);
+       return(7);
+}
+
+static int op_ldhlh(void)              /* LD (HL),H */
+{
+       memwrt((H << 8) + L, H);
+       return(7);
+}
+
+static int op_ldhll(void)              /* LD (HL),L */
+{
+       memwrt((H << 8) + L, L);
+       return(7);
+}
+
+static int op_ldhl1(void)              /* LD (HL),n */
+{
+       memwrt((H << 8) + L, memrdr(PC++));
+       return(10);
+}
+
+static int op_ldaa(void)               /* LD A,A */
+{
+       return(4);
+}
+
+static int op_ldab(void)               /* LD A,B */
+{
+       A = B;
+       return(4);
+}
+
+static int op_ldac(void)               /* LD A,C */
+{
+       A = C;
+       return(4);
+}
+
+static int op_ldad(void)               /* LD A,D */
+{
+       A = D;
+       return(4);
+}
+
+static int op_ldae(void)               /* LD A,E */
+{
+       A = E;
+       return(4);
+}
+
+static int op_ldah(void)               /* LD A,H */
+{
+       A = H;
+       return(4);
+}
+
+static int op_ldal(void)               /* LD A,L */
+{
+       A = L;
+       return(4);
+}
+
+static int op_ldahl(void)              /* LD A,(HL) */
+{
+       A = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldba(void)               /* LD B,A */
+{
+       B = A;
+       return(4);
+}
+
+static int op_ldbb(void)               /* LD B,B */
+{
+       return(4);
+}
+
+static int op_ldbc(void)               /* LD B,C */
+{
+       B = C;
+       return(4);
+}
+
+static int op_ldbd(void)               /* LD B,D */
+{
+       B = D;
+       return(4);
+}
+
+static int op_ldbe(void)               /* LD B,E */
+{
+       B = E;
+       return(4);
+}
+
+static int op_ldbh(void)               /* LD B,H */
+{
+       B = H;
+       return(4);
+}
+
+static int op_ldbl(void)               /* LD B,L */
+{
+       B = L;
+       return(4);
+}
+
+static int op_ldbhl(void)              /* LD B,(HL) */
+{
+       B = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldca(void)               /* LD C,A */
+{
+       C = A;
+       return(4);
+}
+
+static int op_ldcb(void)               /* LD C,B */
+{
+       C = B;
+       return(4);
+}
+
+static int op_ldcc(void)               /* LD C,C */
+{
+       return(4);
+}
+
+static int op_ldcd(void)               /* LD C,D */
+{
+       C = D;
+       return(4);
+}
+
+static int op_ldce(void)               /* LD C,E */
+{
+       C = E;
+       return(4);
+}
+
+static int op_ldch(void)               /* LD C,H */
+{
+       C = H;
+       return(4);
+}
+
+static int op_ldcl(void)               /* LD C,L */
+{
+       C = L;
+       return(4);
+}
+
+static int op_ldchl(void)              /* LD C,(HL) */
+{
+       C = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldda(void)               /* LD D,A */
+{
+       D = A;
+       return(4);
+}
+
+static int op_lddb(void)               /* LD D,B */
+{
+       D = B;
+       return(4);
+}
+
+static int op_lddc(void)               /* LD D,C */
+{
+       D = C;
+       return(4);
+}
+
+static int op_lddd(void)               /* LD D,D */
+{
+       return(4);
+}
+
+static int op_ldde(void)               /* LD D,E */
+{
+       D = E;
+       return(4);
+}
+
+static int op_lddh(void)               /* LD D,H */
+{
+       D = H;
+       return(4);
+}
+
+static int op_lddl(void)               /* LD D,L */
+{
+       D = L;
+       return(4);
+}
+
+static int op_lddhl(void)              /* LD D,(HL) */
+{
+       D = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldea(void)               /* LD E,A */
+{
+       E = A;
+       return(4);
+}
+
+static int op_ldeb(void)               /* LD E,B */
+{
+       E = B;
+       return(4);
+}
+
+static int op_ldec(void)               /* LD E,C */
+{
+       E = C;
+       return(4);
+}
+
+static int op_lded(void)               /* LD E,D */
+{
+       E = D;
+       return(4);
+}
+
+static int op_ldee(void)               /* LD E,E */
+{
+       return(4);
+}
+
+static int op_ldeh(void)               /* LD E,H */
+{
+       E = H;
+       return(4);
+}
+
+static int op_ldel(void)               /* LD E,L */
+{
+       E = L;
+       return(4);
+}
+
+static int op_ldehl(void)              /* LD E,(HL) */
+{
+       E = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldha(void)               /* LD H,A */
+{
+       H = A;
+       return(4);
+}
+
+static int op_ldhb(void)               /* LD H,B */
+{
+       H = B;
+       return(4);
+}
+
+static int op_ldhc(void)               /* LD H,C */
+{
+       H = C;
+       return(4);
+}
+
+static int op_ldhd(void)               /* LD H,D */
+{
+       H = D;
+       return(4);
+}
+
+static int op_ldhe(void)               /* LD H,E */
+{
+       H = E;
+       return(4);
+}
+
+static int op_ldhh(void)               /* LD H,H */
+{
+       return(4);
+}
+
+static int op_ldhl(void)               /* LD H,L */
+{
+       H = L;
+       return(4);
+}
+
+static int op_ldhhl(void)              /* LD H,(HL) */
+{
+       H = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldla(void)               /* LD L,A */
+{
+       L = A;
+       return(4);
+}
+
+static int op_ldlb(void)               /* LD L,B */
+{
+       L = B;
+       return(4);
+}
+
+static int op_ldlc(void)               /* LD L,C */
+{
+       L = C;
+       return(4);
+}
+
+static int op_ldld(void)               /* LD L,D */
+{
+       L = D;
+       return(4);
+}
+
+static int op_ldle(void)               /* LD L,E */
+{
+       L = E;
+       return(4);
+}
+
+static int op_ldlh(void)               /* LD L,H */
+{
+       L = H;
+       return(4);
+}
+
+static int op_ldll(void)               /* LD L,L */
+{
+       return(4);
+}
+
+static int op_ldlhl(void)              /* LD L,(HL) */
+{
+       L = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_ldbcnn(void)             /* LD BC,nn */
+{
+       C = memrdr(PC++);
+       B = memrdr(PC++);
+       return(10);
+}
+
+static int op_lddenn(void)             /* LD DE,nn */
+{
+       E = memrdr(PC++);
+       D = memrdr(PC++);
+       return(10);
+}
+
+static int op_ldhlnn(void)             /* LD HL,nn */
+{
+       L = memrdr(PC++);
+       H = memrdr(PC++);
+       return(10);
+}
+
+static int op_ldspnn(void)             /* LD SP,nn */
+{
+       SP = memrdr(PC++);
+       SP += memrdr(PC++) << 8;
+       return(10);
+}
+
+static int op_ldsphl(void)             /* LD SP,HL */
+{
+       SP = (H << 8) + L;
+       return(6);
+}
+
+static int op_ldhlin(void)             /* LD HL,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       L = memrdr(i++);
+       H = memrdr(i);
+       return(16);
+}
+
+static int op_ldinhl(void)             /* LD (nn),HL */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i++, L);
+       memwrt(i, H);
+       return(16);
+}
+
+static int op_incbc(void)              /* INC BC */
+{
+       C++;
+       if (!C)
+               B++;
+       return(6);
+}
+
+static int op_incde(void)              /* INC DE */
+{
+       E++;
+       if (!E)
+               D++;
+       return(6);
+}
+
+static int op_inchl(void)              /* INC HL */
+{
+       L++;
+       if (!L)
+               H++;
+       return(6);
+}
+
+static int op_incsp(void)              /* INC SP */
+{
+       SP++;
+       return(6);
+}
+
+static int op_decbc(void)              /* DEC BC */
+{
+       C--;
+       if (C == 0xff)
+               B--;
+       return(6);
+}
+
+static int op_decde(void)              /* DEC DE */
+{
+       E--;
+       if (E == 0xff)
+               D--;
+       return(6);
+}
+
+static int op_dechl(void)              /* DEC HL */
+{
+       L--;
+       if (L == 0xff)
+               H--;
+       return(6);
+}
+
+static int op_decsp(void)              /* DEC SP */
+{
+       SP--;
+       return(6);
+}
+
+static int op_adhlbc(void)             /* ADD HL,BC */
+{
+       register int carry;
+
+       carry = (L + C > 255) ? 1 : 0;
+       L += C;
+       ((H & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += B + carry;
+       F &= ~N_FLAG;
+       return(11);
+}
+
+static int op_adhlde(void)             /* ADD HL,DE */
+{
+       register int carry;
+
+       carry = (L + E > 255) ? 1 : 0;
+       L += E;
+       ((H & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += D + carry;
+       F &= ~N_FLAG;
+       return(11);
+}
+
+static int op_adhlhl(void)             /* ADD HL,HL */
+{
+       register int carry;
+
+       carry = (L << 1 > 255) ? 1 : 0;
+       L <<= 1;
+       ((H & 0xf) + (H & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += H + carry;
+       F &= ~N_FLAG;
+       return(11);
+}
+
+static int op_adhlsp(void)             /* ADD HL,SP */
+{
+       register int carry;
+
+       BYTE spl = SP & 0xff;
+       BYTE sph = SP >> 8;
+       
+       carry = (L + spl > 255) ? 1 : 0;
+       L += spl;
+       ((H & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                               : (F &= ~H_FLAG);
+       (H + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += sph + carry;
+       F &= ~N_FLAG;
+       return(11);
+}
+
+static int op_anda(void)               /* AND A */
+{
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andb(void)               /* AND B */
+{
+       A &= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andc(void)               /* AND C */
+{
+       A &= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andd(void)               /* AND D */
+{
+       A &= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_ande(void)               /* AND E */
+{
+       A &= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andh(void)               /* AND H */
+{
+       A &= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andl(void)               /* AND L */
+{
+       A &= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_andhl(void)              /* AND (HL) */
+{
+       A &= memrdr((H << 8) + L);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_andn(void)               /* AND n */
+{
+       A &= memrdr(PC++);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_ora(void)                        /* OR A */
+{
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_orb(void)                        /* OR B */
+{
+       A |= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_orc(void)                        /* OR C */
+{
+       A |= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_ord(void)                        /* OR D */
+{
+       A |= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_ore(void)                        /* OR E */
+{
+       A |= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_orh(void)                        /* OR H */
+{
+       A |= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_orl(void)                        /* OR L */
+{
+       A |= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_orhl(void)               /* OR (HL) */
+{
+       A |= memrdr((H << 8) + L);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_orn(void)                        /* OR n */
+{
+       A |= memrdr(PC++);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_xora(void)               /* XOR A */
+{
+       A = 0;
+       F &= ~(S_FLAG | H_FLAG | N_FLAG | C_FLAG);
+       F |= Z_FLAG | P_FLAG;
+       return(4);
+}
+
+static int op_xorb(void)               /* XOR B */
+{
+       A ^= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xorc(void)               /* XOR C */
+{
+       A ^= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xord(void)               /* XOR D */
+{
+       A ^= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xore(void)               /* XOR E */
+{
+       A ^= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xorh(void)               /* XOR H */
+{
+       A ^= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xorl(void)               /* XOR L */
+{
+       A ^= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xorhl(void)              /* XOR (HL) */
+{
+       A ^= memrdr((H << 8) + L);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_xorn(void)               /* XOR n */
+{
+       A ^= memrdr(PC++);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_adda(void)               /* ADD A,A */
+{
+       register int i;
+
+       ((A & 0xf) + (A & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       ((A << 1) > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = ((signed char) A) << 1;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addb(void)               /* ADD A,B */
+{
+       register int i;
+
+       ((A & 0xf) + (B & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + B > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) B;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addc(void)               /* ADD A,C */
+{
+       register int i;
+
+       ((A & 0xf) + (C & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + C > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) C;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addd(void)               /* ADD A,D */
+{
+       register int i;
+
+       ((A & 0xf) + (D & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + D > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) D;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adde(void)               /* ADD A,E */
+{
+       register int i;
+
+       ((A & 0xf) + (E & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + E > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) E;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addh(void)               /* ADD A,H */
+{
+       register int i;
+
+       ((A & 0xf) + (H & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + H > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) H;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addl(void)               /* ADD A,L */
+{
+       register int i;
+
+       ((A & 0xf) + (L & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + L > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) L;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_addhl(void)              /* ADD A,(HL) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(7);
+}
+
+static int op_addn(void)               /* ADD A,n */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(7);
+}
+
+static int op_adca(void)               /* ADC A,A */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (A & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       ((A << 1) + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (((signed char) A) << 1) + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adcb(void)               /* ADC A,B */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) B + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adcc(void)               /* ADC A,C */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (C & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + C + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) C + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adcd(void)               /* ADC A,D */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) D + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adce(void)               /* ADC A,E */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (E & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + E + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) E + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adch(void)               /* ADC A,H */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (H & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) H + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adcl(void)               /* ADC A,L */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (L & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + L + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) L + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_adchl(void)              /* ADC A,(HL) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(7);
+}
+
+static int op_adcn(void)               /* ADC A,n */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(PC++);
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(7);
+}
+
+static int op_suba(void)               /* SUB A,A */
+{
+       A = 0;
+       F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG);
+       F |= Z_FLAG | N_FLAG;
+       return(4);
+}
+
+static int op_subb(void)               /* SUB A,B */
+{
+       register int i;
+
+       ((B & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) B;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_subc(void)               /* SUB A,C */
+{
+       register int i;
+
+       ((C & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) C;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_subd(void)               /* SUB A,D */
+{
+       register int i;
+
+       ((D & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) D;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sube(void)               /* SUB A,E */
+{
+       register int i;
+
+       ((E & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) E;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_subh(void)               /* SUB A,H */
+{
+       register int i;
+
+       ((H & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) H;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_subl(void)               /* SUB A,L */
+{
+       register int i;
+
+       ((L & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) L;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_subhl(void)              /* SUB A,(HL) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_subn(void)               /* SUB A,n */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_sbca(void)               /* SBC A,A */
+{
+       if (F & C_FLAG) {
+               F |= S_FLAG | H_FLAG | N_FLAG | C_FLAG;
+               F &= ~(Z_FLAG | P_FLAG);
+               A = 255;
+       } else {
+               F |= Z_FLAG | N_FLAG;
+               F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG);
+               A = 0;
+       }
+       return(4);
+}
+
+static int op_sbcb(void)               /* SBC A,B */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((B & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (B + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) B - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbcc(void)               /* SBC A,C */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((C & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (C + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) C - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbcd(void)               /* SBC A,D */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((D & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (D + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) D - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbce(void)               /* SBC A,E */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((E & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (E + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) E - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbch(void)               /* SBC A,H */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((H & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) H - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbcl(void)               /* SBC A,L */
+{
+       register int i, carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((L & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (L + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) L - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_sbchl(void)              /* SBC A,(HL) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_sbcn(void)               /* SBC A,n */
+{
+       register int i, carry;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_cpa(void)                        /* CP A */
+{
+       F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG);
+       F |= Z_FLAG | N_FLAG;
+       return(4);
+}
+
+static int op_cpb(void)                        /* CP B */
+{
+       register int i;
+
+       ((B & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) B;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cpc(void)                        /* CP C */
+{
+       register int i;
+
+       ((C & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) C;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cpd(void)                        /* CP D */
+{
+       register int i;
+
+       ((D & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) D;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cpe(void)                        /* CP E */
+{
+       register int i;
+
+       ((E & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) E;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cph(void)                        /* CP H */
+{
+       register int i;
+
+       ((H & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) H;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cplr(void)               /* CP L */
+{
+       register int i;
+
+       ((L & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) L;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_cphl(void)               /* CP (HL) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_cpn(void)                        /* CP n */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(7);
+}
+
+static int op_inca(void)               /* INC A */
+{
+       A++;
+       ((A & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_incb(void)               /* INC B */
+{
+       B++;
+       ((B & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (B == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_incc(void)               /* INC C */
+{
+       C++;
+       ((C & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (C == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_incd(void)               /* INC D */
+{
+       D++;
+       ((D & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (D == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_ince(void)               /* INC E */
+{
+       E++;
+       ((E & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (E == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_inch(void)               /* INC H */
+{
+       H++;
+       ((H & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_incl(void)               /* INC L */
+{
+       L++;
+       ((L & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (L == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(4);
+}
+
+static int op_incihl(void)             /* INC (HL) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       P++;
+       memwrt(addr, P);
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(11);
+}
+
+static int op_deca(void)               /* DEC A */
+{
+       A--;
+       ((A & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_decb(void)               /* DEC B */
+{
+       B--;
+       ((B & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (B == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_decc(void)               /* DEC C */
+{
+       C--;
+       ((C & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (C == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_decd(void)               /* DEC D */
+{
+       D--;
+       ((D & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (D == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_dece(void)               /* DEC E */
+{
+       E--;
+       ((E & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (E == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_dech(void)               /* DEC H */
+{
+       H--;
+       ((H & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (H == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_decl(void)               /* DEC L */
+{
+       L--;
+       ((L & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (L == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(4);
+}
+
+static int op_decihl(void)             /* DEC (HL) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       P--;
+       memwrt(addr, P);
+       ((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(11);
+}
+
+static int op_rlca(void)               /* RLCA */
+{
+       register int i;
+
+       i = (A & 128) ? 1 : 0;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A <<= 1;
+       A |= i;
+       return(4);
+}
+
+static int op_rrca(void)               /* RRCA */
+{
+       register int i;
+
+       i = A & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A >>= 1;
+       if (i) A |= 128;
+       return(4);
+}
+
+static int op_rla(void)                        /* RLA */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A <<= 1;
+       if (old_c_flag) A |= 1;
+       return(4);
+}
+
+static int op_rra(void)                        /* RRA */
+{
+       register int i, old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       i = A & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A >>= 1;
+       if (old_c_flag) A |= 128;
+       return(4);
+}
+
+static int op_exdehl(void)             /* EX DE,HL */
+{
+       register BYTE i;
+
+       i = D;
+       D = H;
+       H = i;
+       i = E;
+       E = L;
+       L = i;
+       return(4);
+}
+
+static int op_exafaf(void)             /* EX AF,AF' */
+{
+       register BYTE i;
+
+       i = A;
+       A = A_;
+       A_ = i;
+       i = F;
+       F = F_;
+       F_ = i;
+       return(4);
+}
+
+static int op_exx(void)                        /* EXX */
+{
+       register BYTE i;
+
+       i = B;
+       B = B_;
+       B_ = i;
+       i = C;
+       C = C_;
+       C_ = i;
+       i = D;
+       D = D_;
+       D_ = i;
+       i = E;
+       E = E_;
+       E_ = i;
+       i = H;
+       H = H_;
+       H_ = i;
+       i = L;
+       L = L_;
+       L_ = i;
+       return(4);
+}
+
+static int op_exsphl(void)             /* EX (SP),HL */
+{
+       register BYTE i;
+
+       i = memrdr(SP);
+       memwrt(SP, L);
+       L = i;
+       i = memrdr(SP + 1);
+       memwrt(SP + 1, H);
+       H = i;
+       return(19);
+}
+
+static int op_pushaf(void)             /* PUSH AF */
+{
+       memwrt(--SP, A);
+       memwrt(--SP, F);
+       return(11);
+}
+
+static int op_pushbc(void)             /* PUSH BC */
+{
+       memwrt(--SP, B);
+       memwrt(--SP, C);
+       return(11);
+}
+
+static int op_pushde(void)             /* PUSH DE */
+{
+       memwrt(--SP, D);
+       memwrt(--SP, E);
+       return(11);
+}
+
+static int op_pushhl(void)             /* PUSH HL */
+{
+       memwrt(--SP, H);
+       memwrt(--SP, L);
+       return(11);
+}
+
+static int op_popaf(void)              /* POP AF */
+{
+       F = memrdr(SP++);
+       A = memrdr(SP++);
+       return(10);
+}
+
+static int op_popbc(void)              /* POP BC */
+{
+       C = memrdr(SP++);
+       B = memrdr(SP++);
+       return(10);
+}
+
+static int op_popde(void)              /* POP DE */
+{
+       E = memrdr(SP++);
+       D = memrdr(SP++);
+       return(10);
+}
+
+static int op_pophl(void)              /* POP HL */
+{
+       L = memrdr(SP++);
+       H = memrdr(SP++);
+       return(10);
+}
+
+static int op_jp(void)                 /* JP */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC) << 8;
+       PC = i;
+       return(10);
+}
+
+static int op_jphl(void)               /* JP (HL) */
+{
+       PC = (H << 8) + L;
+       return(4);
+}
+
+static int op_jr(void)                 /* JR */
+{
+       PC += (signed char) memrdr(PC) + 1;
+       return(12);
+}
+
+static int op_djnz(void)               /* DJNZ */
+{
+       if (--B) {
+               PC += (signed char) memrdr(PC) + 1;
+               return(13);
+       } else {
+               PC++;
+               return(8);
+       }
+}
+
+static int op_call(void)               /* CALL */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = i;
+       return(17);
+}
+
+static int op_ret(void)                        /* RET */
+{
+       register WORD i;
+
+       i = memrdr(SP++);
+       i += memrdr(SP++) << 8;
+       PC = i;
+       return(10);
+}
+
+static int op_jpz(void)                        /* JP Z,nn */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpnz(void)               /* JP NZ,nn */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpc(void)                        /* JP C,nn */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpnc(void)               /* JP NC,nn */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jppe(void)               /* JP PE,nn */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jppo(void)               /* JP PO,nn */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpm(void)                        /* JP M,nn */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpp(void)                        /* JP P,nn */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_calz(void)               /* CALL Z,nn */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calnz(void)              /* CALL NZ,nn */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calc(void)               /* CALL C,nn */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_WO | CPU_MEMR;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calnc(void)              /* CALL NC,nn */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calpe(void)              /* CALL PE,nn */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calpo(void)              /* CALL PO,nn */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calm(void)               /* CALL M,nn */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_calp(void)               /* CALL P,nn */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(10);
+       }
+}
+
+static int op_retz(void)               /* RET Z */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retnz(void)              /* RET NZ */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retc(void)               /* RET C */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retnc(void)              /* RET NC */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retpe(void)              /* RET PE */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retpo(void)              /* RET PO */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retm(void)               /* RET M */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_retp(void)               /* RET P */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_jrz(void)                        /* JR Z,n */
+{
+       if (F & Z_FLAG) {
+               PC += (signed char) memrdr(PC) + 1;
+               return(12);
+       } else {
+               PC++;
+               return(7);
+       }
+}
+
+static int op_jrnz(void)               /* JR NZ,n */
+{
+       if (!(F & Z_FLAG)) {
+               PC += (signed char) memrdr(PC) + 1;
+               return(12);
+       } else {
+               PC++;
+               return(7);
+       }
+}
+
+static int op_jrc(void)                        /* JR C,n */
+{
+       if (F & C_FLAG) {
+               PC += (signed char) memrdr(PC) + 1;
+               return(12);
+       } else {
+               PC++;
+               return(7);
+       }
+}
+
+static int op_jrnc(void)               /* JR NC,n */
+{
+       if (!(F & C_FLAG)) {
+               PC += (signed char) memrdr(PC) + 1;
+               return(12);
+       } else {
+               PC++;
+               return(7);
+       }
+}
+
+static int op_rst00(void)              /* RST 00 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0;
+       return(11);
+}
+
+static int op_rst08(void)              /* RST 08 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x08;
+       return(11);
+}
+
+static int op_rst10(void)              /* RST 10 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x10;
+       return(11);
+}
+
+static int op_rst18(void)              /* RST 18 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x18;
+       return(11);
+}
+
+static int op_rst20(void)              /* RST 20 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x20;
+       return(11);
+}
+
+static int op_rst28(void)              /* RST 28 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x28;
+       return(11);
+}
+
+static int op_rst30(void)              /* RST 30 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x30;
+       return(11);
+}
+
+static int op_rst38(void)              /* RST 38 */
+{
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x38;
+       return(11);
+}
diff --git a/sim/sim1a.c b/sim/sim1a.c
new file mode 100644 (file)
index 0000000..eeb96b2
--- /dev/null
@@ -0,0 +1,3120 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+#ifdef WANT_GUI
+void check_gui_break(void);
+#endif
+
+static int op_nop(void), op_hlt(void), op_stc(void);
+static int op_cmc(void), op_cma(void), op_daa(void), op_ei(void), op_di(void);
+static int op_out(void), op_in(void);
+static int op_mvian(void), op_mvibn(void), op_mvicn(void), op_mvidn(void);
+static int op_mvien(void), op_mvihn(void), op_mviln(void);
+static int op_ldaxb(void), op_ldaxd(void), op_ldann(void);
+static int op_staxb(void), op_staxd(void), op_stann(void);
+static int op_movma(void), op_movmb(void), op_movmc(void);
+static int op_movmd(void), op_movme(void), op_movmh(void), op_movml(void);
+static int op_mvimn(void);
+static int op_movaa(void), op_movab(void), op_movac(void), op_movad(void);
+static int op_movae(void), op_movah(void), op_moval(void), op_movam(void);
+static int op_movba(void), op_movbb(void), op_movbc(void), op_movbd(void);
+static int op_movbe(void), op_movbh(void), op_movbl(void), op_movbm(void);
+static int op_movca(void), op_movcb(void), op_movcc(void), op_movcd(void);
+static int op_movce(void), op_movch(void), op_movcl(void), op_movcm(void);
+static int op_movda(void), op_movdb(void), op_movdc(void), op_movdd(void);
+static int op_movde(void), op_movdh(void), op_movdl(void), op_movdm(void);
+static int op_movea(void), op_moveb(void), op_movec(void), op_moved(void);
+static int op_movee(void), op_moveh(void), op_movel(void), op_movem(void);
+static int op_movha(void), op_movhb(void), op_movhc(void), op_movhd(void);
+static int op_movhe(void), op_movhh(void), op_movhl(void), op_movhm(void);
+static int op_movla(void), op_movlb(void), op_movlc(void), op_movld(void);
+static int op_movle(void), op_movlh(void), op_movll(void), op_movlm(void);
+static int op_lxibnn(void), op_lxidnn(void), op_lxihnn(void);
+static int op_lxispnn(void), op_sphl(void), op_lhldnn(void), op_shldnn(void);
+static int op_inxb(void), op_inxd(void), op_inxh(void), op_inxsp(void);
+static int op_dcxb(void), op_dcxd(void), op_dcxh(void), op_dcxsp(void);
+static int op_dadb(void), op_dadd(void), op_dadh(void), op_dadsp(void);
+static int op_anaa(void), op_anab(void), op_anac(void), op_anad(void);
+static int op_anae(void), op_anah(void), op_anal(void), op_anam(void);
+static int op_anin(void);
+static int op_oraa(void), op_orab(void), op_orac(void), op_orad(void);
+static int op_orae(void), op_orah(void), op_oral(void), op_oram(void);
+static int op_orin(void);
+static int op_xraa(void), op_xrab(void), op_xrac(void), op_xrad(void);
+static int op_xrae(void), op_xrah(void), op_xral(void), op_xram(void);
+static int op_xrin(void);
+static int op_adda(void), op_addb(void), op_addc(void), op_addd(void);
+static int op_adde(void), op_addh(void), op_addl(void), op_addm(void);
+static int op_adin(void);
+static int op_adca(void), op_adcb(void), op_adcc(void), op_adcd(void);
+static int op_adce(void), op_adch(void), op_adcl(void), op_adcm(void);
+static int op_acin(void);
+static int op_suba(void), op_subb(void), op_subc(void), op_subd(void);
+static int op_sube(void), op_subh(void), op_subl(void), op_subm(void);
+static int op_suin(void);
+static int op_sbba(void), op_sbbb(void), op_sbbc(void), op_sbbd(void);
+static int op_sbbe(void), op_sbbh(void), op_sbbl(void), op_sbbm(void);
+static int op_sbin(void);
+static int op_cmpa(void), op_cmpb(void), op_cmpc(void), op_cmpd(void);
+static int op_cmpe(void), op_cmph(void), op_cmpl(void), op_cmpm(void);
+static int op_cpin(void);
+static int op_inra(void), op_inrb(void), op_inrc(void), op_inrd(void);
+static int op_inre(void), op_inrh(void), op_inrl(void), op_inrm(void);
+static int op_dcra(void), op_dcrb(void), op_dcrc(void), op_dcrd(void);
+static int op_dcre(void), op_dcrh(void), op_dcrl(void), op_dcrm(void);
+static int op_rlc(void), op_rrc(void), op_ral(void), op_rar(void);
+static int op_xchg(void), op_xthl(void);
+static int op_pushpsw(void), op_pushb(void), op_pushd(void), op_pushh(void);
+static int op_poppsw(void), op_popb(void), op_popd(void), op_poph(void);
+static int op_jmp(void), op_pchl(void), op_call(void), op_ret(void);
+static int op_jz(void), op_jnz(void), op_jc(void), op_jnc(void);
+static int op_jpe(void), op_jpo(void), op_jm(void), op_jp(void);
+static int op_cz(void), op_cnz(void), op_cc(void), op_cnc(void);
+static int op_cpe(void), op_cpo(void), op_cm(void), op_cp(void);
+static int op_rz(void), op_rnz(void), op_rc(void), op_rnc(void);
+static int op_rpe(void), op_rpo(void), op_rm(void), op_rp(void);
+static int op_rst0(void), op_rst1(void), op_rst2(void), op_rst3(void);
+static int op_rst4(void), op_rst5(void), op_rst6(void), op_rst7(void);
+static int op_undoc_nop(void), op_undoc_jmp(void);
+static int op_undoc_ret(void), op_undoc_call(void);
+
+/*
+ *     This function builds the 8080 central processing unit.
+ *     The opcode where PC points to is fetched from the memory
+ *     and PC incremented by one. The opcode is used as an
+ *     index to an array with function pointers, to execute a
+ *     function which emulates this 8080 opcode.
+ *
+ */
+void cpu_8080(void)
+{
+       static int (*op_sim[256]) (void) = {
+               op_nop,                         /* 0x00 */
+               op_lxibnn,                      /* 0x01 */
+               op_staxb,                       /* 0x02 */
+               op_inxb,                        /* 0x03 */
+               op_inrb,                        /* 0x04 */
+               op_dcrb,                        /* 0x05 */
+               op_mvibn,                       /* 0x06 */
+               op_rlc,                         /* 0x07 */
+               op_undoc_nop,                   /* 0x08 */
+               op_dadb,                        /* 0x09 */
+               op_ldaxb,                       /* 0x0a */
+               op_dcxb,                        /* 0x0b */
+               op_inrc,                        /* 0x0c */
+               op_dcrc,                        /* 0x0d */
+               op_mvicn,                       /* 0x0e */
+               op_rrc,                         /* 0x0f */
+               op_undoc_nop,                   /* 0x10 */
+               op_lxidnn,                      /* 0x11 */
+               op_staxd,                       /* 0x12 */
+               op_inxd,                        /* 0x13 */
+               op_inrd,                        /* 0x14 */
+               op_dcrd,                        /* 0x15 */
+               op_mvidn,                       /* 0x16 */
+               op_ral,                         /* 0x17 */
+               op_undoc_nop,                   /* 0x18 */
+               op_dadd,                        /* 0x19 */
+               op_ldaxd,                       /* 0x1a */
+               op_dcxd,                        /* 0x1b */
+               op_inre,                        /* 0x1c */
+               op_dcre,                        /* 0x1d */
+               op_mvien,                       /* 0x1e */
+               op_rar,                         /* 0x1f */
+               op_undoc_nop,                   /* 0x20 */
+               op_lxihnn,                      /* 0x21 */
+               op_shldnn,                      /* 0x22 */
+               op_inxh,                        /* 0x23 */
+               op_inrh,                        /* 0x24 */
+               op_dcrh,                        /* 0x25 */
+               op_mvihn,                       /* 0x26 */
+               op_daa,                         /* 0x27 */
+               op_undoc_nop,                   /* 0x28 */
+               op_dadh,                        /* 0x29 */
+               op_lhldnn,                      /* 0x2a */
+               op_dcxh,                        /* 0x2b */
+               op_inrl,                        /* 0x2c */
+               op_dcrl,                        /* 0x2d */
+               op_mviln,                       /* 0x2e */
+               op_cma,                         /* 0x2f */
+               op_undoc_nop,                   /* 0x30 */
+               op_lxispnn,                     /* 0x31 */
+               op_stann,                       /* 0x32 */
+               op_inxsp,                       /* 0x33 */
+               op_inrm,                        /* 0x34 */
+               op_dcrm,                        /* 0x35 */
+               op_mvimn,                       /* 0x36 */
+               op_stc,                         /* 0x37 */
+               op_undoc_nop,                   /* 0x38 */
+               op_dadsp,                       /* 0x39 */
+               op_ldann,                       /* 0x3a */
+               op_dcxsp,                       /* 0x3b */
+               op_inra,                        /* 0x3c */
+               op_dcra,                        /* 0x3d */
+               op_mvian,                       /* 0x3e */
+               op_cmc,                         /* 0x3f */
+               op_movbb,                       /* 0x40 */
+               op_movbc,                       /* 0x41 */
+               op_movbd,                       /* 0x42 */
+               op_movbe,                       /* 0x43 */
+               op_movbh,                       /* 0x44 */
+               op_movbl,                       /* 0x45 */
+               op_movbm,                       /* 0x46 */
+               op_movba,                       /* 0x47 */
+               op_movcb,                       /* 0x48 */
+               op_movcc,                       /* 0x49 */
+               op_movcd,                       /* 0x4a */
+               op_movce,                       /* 0x4b */
+               op_movch,                       /* 0x4c */
+               op_movcl,                       /* 0x4d */
+               op_movcm,                       /* 0x4e */
+               op_movca,                       /* 0x4f */
+               op_movdb,                       /* 0x50 */
+               op_movdc,                       /* 0x51 */
+               op_movdd,                       /* 0x52 */
+               op_movde,                       /* 0x53 */
+               op_movdh,                       /* 0x54 */
+               op_movdl,                       /* 0x55 */
+               op_movdm,                       /* 0x56 */
+               op_movda,                       /* 0x57 */
+               op_moveb,                       /* 0x58 */
+               op_movec,                       /* 0x59 */
+               op_moved,                       /* 0x5a */
+               op_movee,                       /* 0x5b */
+               op_moveh,                       /* 0x5c */
+               op_movel,                       /* 0x5d */
+               op_movem,                       /* 0x5e */
+               op_movea,                       /* 0x5f */
+               op_movhb,                       /* 0x60 */
+               op_movhc,                       /* 0x61 */
+               op_movhd,                       /* 0x62 */
+               op_movhe,                       /* 0x63 */
+               op_movhh,                       /* 0x64 */
+               op_movhl,                       /* 0x65 */
+               op_movhm,                       /* 0x66 */
+               op_movha,                       /* 0x67 */
+               op_movlb,                       /* 0x68 */
+               op_movlc,                       /* 0x69 */
+               op_movld,                       /* 0x6a */
+               op_movle,                       /* 0x6b */
+               op_movlh,                       /* 0x6c */
+               op_movll,                       /* 0x6d */
+               op_movlm,                       /* 0x6e */
+               op_movla,                       /* 0x6f */
+               op_movmb,                       /* 0x70 */
+               op_movmc,                       /* 0x71 */
+               op_movmd,                       /* 0x72 */
+               op_movme,                       /* 0x73 */
+               op_movmh,                       /* 0x74 */
+               op_movml,                       /* 0x75 */
+               op_hlt,                         /* 0x76 */
+               op_movma,                       /* 0x77 */
+               op_movab,                       /* 0x78 */
+               op_movac,                       /* 0x79 */
+               op_movad,                       /* 0x7a */
+               op_movae,                       /* 0x7b */
+               op_movah,                       /* 0x7c */
+               op_moval,                       /* 0x7d */
+               op_movam,                       /* 0x7e */
+               op_movaa,                       /* 0x7f */
+               op_addb,                        /* 0x80 */
+               op_addc,                        /* 0x81 */
+               op_addd,                        /* 0x82 */
+               op_adde,                        /* 0x83 */
+               op_addh,                        /* 0x84 */
+               op_addl,                        /* 0x85 */
+               op_addm,                        /* 0x86 */
+               op_adda,                        /* 0x87 */
+               op_adcb,                        /* 0x88 */
+               op_adcc,                        /* 0x89 */
+               op_adcd,                        /* 0x8a */
+               op_adce,                        /* 0x8b */
+               op_adch,                        /* 0x8c */
+               op_adcl,                        /* 0x8d */
+               op_adcm,                        /* 0x8e */
+               op_adca,                        /* 0x8f */
+               op_subb,                        /* 0x90 */
+               op_subc,                        /* 0x91 */
+               op_subd,                        /* 0x92 */
+               op_sube,                        /* 0x93 */
+               op_subh,                        /* 0x94 */
+               op_subl,                        /* 0x95 */
+               op_subm,                        /* 0x96 */
+               op_suba,                        /* 0x97 */
+               op_sbbb,                        /* 0x98 */
+               op_sbbc,                        /* 0x99 */
+               op_sbbd,                        /* 0x9a */
+               op_sbbe,                        /* 0x9b */
+               op_sbbh,                        /* 0x9c */
+               op_sbbl,                        /* 0x9d */
+               op_sbbm,                        /* 0x9e */
+               op_sbba,                        /* 0x9f */
+               op_anab,                        /* 0xa0 */
+               op_anac,                        /* 0xa1 */
+               op_anad,                        /* 0xa2 */
+               op_anae,                        /* 0xa3 */
+               op_anah,                        /* 0xa4 */
+               op_anal,                        /* 0xa5 */
+               op_anam,                        /* 0xa6 */
+               op_anaa,                        /* 0xa7 */
+               op_xrab,                        /* 0xa8 */
+               op_xrac,                        /* 0xa9 */
+               op_xrad,                        /* 0xaa */
+               op_xrae,                        /* 0xab */
+               op_xrah,                        /* 0xac */
+               op_xral,                        /* 0xad */
+               op_xram,                        /* 0xae */
+               op_xraa,                        /* 0xaf */
+               op_orab,                        /* 0xb0 */
+               op_orac,                        /* 0xb1 */
+               op_orad,                        /* 0xb2 */
+               op_orae,                        /* 0xb3 */
+               op_orah,                        /* 0xb4 */
+               op_oral,                        /* 0xb5 */
+               op_oram,                        /* 0xb6 */
+               op_oraa,                        /* 0xb7 */
+               op_cmpb,                        /* 0xb8 */
+               op_cmpc,                        /* 0xb9 */
+               op_cmpd,                        /* 0xba */
+               op_cmpe,                        /* 0xbb */
+               op_cmph,                        /* 0xbc */
+               op_cmpl,                        /* 0xbd */
+               op_cmpm,                        /* 0xbe */
+               op_cmpa,                        /* 0xbf */
+               op_rnz,                         /* 0xc0 */
+               op_popb,                        /* 0xc1 */
+               op_jnz,                         /* 0xc2 */
+               op_jmp,                         /* 0xc3 */
+               op_cnz,                         /* 0xc4 */
+               op_pushb,                       /* 0xc5 */
+               op_adin,                        /* 0xc6 */
+               op_rst0,                        /* 0xc7 */
+               op_rz,                          /* 0xc8 */
+               op_ret,                         /* 0xc9 */
+               op_jz,                          /* 0xca */
+               op_undoc_jmp,                   /* 0xcb */
+               op_cz,                          /* 0xcc */
+               op_call,                        /* 0xcd */
+               op_acin,                        /* 0xce */
+               op_rst1,                        /* 0xcf */
+               op_rnc,                         /* 0xd0 */
+               op_popd,                        /* 0xd1 */
+               op_jnc,                         /* 0xd2 */
+               op_out,                         /* 0xd3 */
+               op_cnc,                         /* 0xd4 */
+               op_pushd,                       /* 0xd5 */
+               op_suin,                        /* 0xd6 */
+               op_rst2,                        /* 0xd7 */
+               op_rc,                          /* 0xd8 */
+               op_undoc_ret,                   /* 0xd9 */
+               op_jc,                          /* 0xda */
+               op_in,                          /* 0xdb */
+               op_cc,                          /* 0xdc */
+               op_undoc_call,                  /* 0xdd */
+               op_sbin,                        /* 0xde */
+               op_rst3,                        /* 0xdf */
+               op_rpo,                         /* 0xe0 */
+               op_poph,                        /* 0xe1 */
+               op_jpo,                         /* 0xe2 */
+               op_xthl,                        /* 0xe3 */
+               op_cpo,                         /* 0xe4 */
+               op_pushh,                       /* 0xe5 */
+               op_anin,                        /* 0xe6 */
+               op_rst4,                        /* 0xe7 */
+               op_rpe,                         /* 0xe8 */
+               op_pchl,                        /* 0xe9 */
+               op_jpe,                         /* 0xea */
+               op_xchg,                        /* 0xeb */
+               op_cpe,                         /* 0xec */
+               op_undoc_call,                  /* 0xed */
+               op_xrin,                        /* 0xee */
+               op_rst5,                        /* 0xef */
+               op_rp,                          /* 0xf0 */
+               op_poppsw,                      /* 0xf1 */
+               op_jp,                          /* 0xf2 */
+               op_di,                          /* 0xf3 */
+               op_cp,                          /* 0xf4 */
+               op_pushpsw,                     /* 0xf5 */
+               op_orin,                        /* 0xf6 */
+               op_rst6,                        /* 0xf7 */
+               op_rm,                          /* 0xf8 */
+               op_sphl,                        /* 0xf9 */
+               op_jm,                          /* 0xfa */
+               op_ei,                          /* 0xfb */
+               op_cm,                          /* 0xfc */
+               op_undoc_call,                  /* 0xfd */
+               op_cpin,                        /* 0xfe */
+               op_rst7                         /* 0xff */
+       };
+
+       register int t = 0;
+       register int states;
+       struct timespec timer;
+       struct timeval t1, t2, tdiff;
+
+       gettimeofday(&t1, NULL);
+
+       do {
+
+#ifdef HISIZE
+               /* write history */
+               his[h_next].h_adr = PC;
+               his[h_next].h_af = (A << 8) + F;
+               his[h_next].h_bc = (B << 8) + C;
+               his[h_next].h_de = (D << 8) + E;
+               his[h_next].h_hl = (H << 8) + L;
+               his[h_next].h_sp = SP;
+               h_next++;
+               if (h_next == HISIZE) {
+                       h_flag = 1;
+                       h_next = 0;
+               }
+#endif
+
+#ifdef WANT_TIM
+               /* check for start address of runtime measurement */
+               if (PC == t_start && !t_flag) {
+                       t_flag = 1;     /* switch measurement on */
+                       t_states = 0L;  /* initialise counted T-states */
+               }
+#endif
+
+               /* CPU interrupt handling */
+               if (int_int) {
+                       if (IFF != 3)
+                               goto leave;
+                       if (int_protection)     /* protect first instr */
+                               goto leave;     /* after EI */
+
+                       IFF = 0;
+
+#ifdef BUS_8080
+                       if (!(cpu_bus & CPU_HLTA)) {
+                               cpu_bus = CPU_WO | CPU_M1 | CPU_INTA;
+#endif
+#ifdef FRONTPANEL
+                               fp_clock += 1000;
+                               fp_led_data = (int_data != -1) ?
+                                               (BYTE) int_data : 0xff;
+                               fp_sampleData();
+                               wait_int_step();
+                               if (cpu_state & RESET)
+                                       goto leave;
+#endif
+#ifdef BUS_8080
+                       }
+                       cpu_bus = CPU_STACK;
+#endif
+#ifdef FRONTPANEL
+                       fp_clock++;
+                       fp_sampleLightGroup(0, 0);
+#endif
+
+                       memwrt(--SP, PC >> 8);
+                       memwrt(--SP, PC);
+
+#ifdef FRONTPANEL
+                       if (cpu_state & RESET)
+                               goto leave;
+#endif
+
+                       switch (int_data) {
+                       case 0xc7: /* RST 00H */
+                               PC = 0;
+                               break;
+                       case 0xcf: /* RST 08H */
+                               PC = 8;
+                               break;
+                       case 0xd7: /* RST 10H */
+                               PC = 0x10;
+                               break;
+                       case 0xdf: /* RST 18H */
+                               PC = 0x18;
+                               break;
+                       case 0xe7: /* RST 20H */
+                               PC = 0x20;
+                               break;
+                       case 0xef: /* RST 28H */
+                               PC = 0x28;
+                               break;
+                       case 0xf7: /* RST 30H */
+                               PC = 0x30;
+                               break;
+                       case 0xff: /* RST 38H */
+                               PC = 0x38;
+                               break;
+                       default:
+                               PC = 0x38;
+                               break;
+                       }
+                       int_int = 0;
+                       int_data = -1;
+#ifdef FRONTPANEL
+                       m1_step = 1;
+#endif
+               }
+leave:
+
+#ifdef BUS_8080
+               /* M1 opcode fetch */
+               cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+#endif
+
+#ifdef FRONTPANEL
+               /* update frontpanel */
+               fp_clock++;
+               fp_led_address = PC;
+               fp_led_data = dma_read(PC);
+               fp_sampleData();
+#endif
+
+               int_protection = 0;
+               states = (*op_sim[memrdr(PC++)]) (); /* execute next opcode */
+               t += states;
+
+               if (f_flag) {                   /* adjust CPU speed */
+                       if (t >= tmax) {
+                               gettimeofday(&t2, NULL);
+                                tdiff.tv_sec = t2.tv_sec - t1.tv_sec;
+                                tdiff.tv_usec = t2.tv_usec - t1.tv_usec;
+                                if (tdiff.tv_usec < 0) {
+                                        --tdiff.tv_sec;
+                                        tdiff.tv_usec += 1000000;
+                                }
+                               if ((tdiff.tv_sec == 0) &&
+                                   (tdiff.tv_usec < 10000)) {
+                                       timer.tv_sec = 0;
+                                       timer.tv_nsec = (long) ((10000
+                                                               - tdiff.tv_usec)
+                                                               * 1000);
+                                       nanosleep(&timer, NULL);
+                               }
+                               t = 0;
+                               gettimeofday(&t1, NULL);
+                       }
+               }
+
+               R++;                    /* increment refresh register */
+
+                                       /* do runtime measurement */
+#ifdef WANT_TIM
+               if (t_flag) {
+                       t_states += states; /* add T-states for this opcode */
+                       if (PC == t_end)        /* check for end address */
+                               t_flag = 0;     /* if reached, switch off */
+               }
+#endif
+
+#ifdef WANT_GUI
+                check_gui_break();
+#endif
+
+       } while (cpu_state == CONTIN_RUN);
+
+#ifdef BUS_8080
+       if (!(cpu_bus & CPU_INTA))
+               cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+#endif
+#ifdef FRONTPANEL
+       fp_led_address = PC;
+       fp_led_data = dma_read(PC);
+       fp_clock++;
+       fp_sampleData();
+#endif
+}
+
+static int op_nop(void)                 /* NOP */
+{
+       return(4);
+}
+
+static int op_undoc_nop(void)          /* Undocumented NOP */
+{
+       if (u_flag) {   /* trap with option -u */
+               cpu_error = OPTRAP1;
+               cpu_state = STOPPED;
+               return(0);
+       } else {        /* else NOP */
+               return(4);
+       }
+}
+
+static int op_hlt(void)                        /* HLT */
+{
+       struct timespec timer;
+
+#ifdef BUS_8080
+       cpu_bus = CPU_WO | CPU_HLTA | CPU_MEMR;
+#endif
+
+#ifndef FRONTPANEL
+       /* without a frontpanel DI + HALT stops the machine */
+       if (IFF == 0)   {
+               cpu_error = OPHALT;
+               cpu_state = STOPPED;
+       } else {
+       /* else wait for INT or user interrupt */
+               while ((int_int == 0) && (cpu_state == CONTIN_RUN)) {
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+               }
+       }
+#ifdef BUS_8080
+       if (int_int)
+               cpu_bus = CPU_INTA | CPU_WO | CPU_HLTA | CPU_M1;
+#endif
+
+       busy_loop_cnt[0] = 0;
+
+#else
+
+       fp_led_address = 0xffff;
+       fp_led_data = 0xff;
+
+       /* INT disabled, wait for frontpanel reset or user interrupt */
+       if (IFF == 0)   {
+               while (!(cpu_state & RESET)) {
+                       fp_clock++;
+                       fp_sampleData();
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+                       if (cpu_error != NONE)
+                               break;
+               }
+       } else {
+       /* else wait for INT, frontpanel reset or user interrupt */
+               while ((int_int == 0) && !(cpu_state & RESET)) {
+                       fp_clock++;
+                       fp_sampleData();
+                       timer.tv_sec = 0;
+                       timer.tv_nsec = 1000000L;
+                       nanosleep(&timer, NULL);
+                       R += 9999;
+                       if (cpu_error != NONE)
+                               break;
+               }
+               if (int_int) {
+                       cpu_bus = CPU_INTA | CPU_WO | CPU_HLTA | CPU_M1;
+                       fp_clock++;
+                       fp_sampleLightGroup(0, 0);
+               }
+       }
+#endif
+
+       return(7);
+}
+
+static int op_stc(void)                        /* STC */
+{
+       F |= C_FLAG;
+       return(4);
+}
+
+static int op_cmc(void)                        /* CMC */
+{
+       if (F & C_FLAG)
+               F &= ~C_FLAG;
+       else
+               F |= C_FLAG;
+       return(4);
+}
+
+static int op_cma(void)                        /* CMA */
+{
+       A = ~A;
+       return(4);
+}
+
+static int op_daa(void)                        /* DAA */
+{
+       register int tmp_a = A;
+
+       if (((A & 0xf) > 9) ||  (F & H_FLAG)) {
+               ((A & 0xf) > 9) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+               tmp_a += 6;
+       }
+       if (((tmp_a & 0x1f0) > 0x90) || (F & C_FLAG)) {
+               tmp_a += 0x60;
+       }
+        if (tmp_a & 0x100)
+               (F |= C_FLAG);
+        A = tmp_a & 0xff;
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(4);
+}
+
+static int op_ei(void)                 /* EI */
+{
+       IFF = 3;
+       int_protection = 1;             /* protect next instruction */
+       return(4);
+}
+
+static int op_di(void)                 /* DI */
+{
+       IFF = 0;
+       return(4);
+}
+
+static int op_in(void)                 /* IN n */
+{
+       BYTE io_in(BYTE, BYTE);
+       BYTE addr;
+
+       addr = memrdr(PC++);
+       A = io_in(addr, addr);
+       return(10);
+}
+
+static int op_out(void)                        /* OUT n */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       BYTE addr;
+
+       addr = memrdr(PC++);
+       io_out(addr, addr, A);
+       return(10);
+}
+
+static int op_mvian(void)              /* MVI A,n */
+{
+       A = memrdr(PC++);
+       return(7);
+}
+
+static int op_mvibn(void)              /* MVI B,n */
+{
+       B = memrdr(PC++);
+       return(7);
+}
+
+static int op_mvicn(void)              /* MVI C,n */
+{
+       C = memrdr(PC++);
+       return(7);
+}
+
+static int op_mvidn(void)              /* MVI D,n */
+{
+       D = memrdr(PC++);
+       return(7);
+}
+
+static int op_mvien(void)              /* MVI E,n */
+{
+       E = memrdr(PC++);
+       return(7);
+}
+
+static int op_mvihn(void)              /* MVI H,n */
+{
+       H = memrdr(PC++);
+       return(7);
+}
+
+static int op_mviln(void)              /* MVI L,n */
+{
+       L = memrdr(PC++);
+       return(7);
+}
+
+static int op_ldaxb(void)              /* LDAX B */
+{
+       A = memrdr((B << 8) + C);
+       return(7);
+}
+
+static int op_ldaxd(void)              /* LDAX D */
+{
+       A = memrdr((D << 8) + E);
+       return(7);
+}
+
+static int op_ldann(void)              /* LDA nn */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       A = memrdr(i);
+       return(13);
+}
+
+static int op_staxb(void)              /* STAX B */
+{
+       memwrt((B << 8) + C, A);
+       return(7);
+}
+
+static int op_staxd(void)              /* STAX D */
+{
+       memwrt((D << 8) + E, A);
+       return(7);
+}
+
+static int op_stann(void)              /* STA nn */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i, A);
+       return(13);
+}
+
+static int op_movma(void)              /* MOV M,A */
+{
+       memwrt((H << 8) + L, A);
+       return(7);
+}
+
+static int op_movmb(void)              /* MOV M,B */
+{
+       memwrt((H << 8) + L, B);
+       return(7);
+}
+
+static int op_movmc(void)              /* MOV M,C */
+{
+       memwrt((H << 8) + L, C);
+       return(7);
+}
+
+static int op_movmd(void)              /* MOV M,D */
+{
+       memwrt((H << 8) + L, D);
+       return(7);
+}
+
+static int op_movme(void)              /* MOV M,E */
+{
+       memwrt((H << 8) + L, E);
+       return(7);
+}
+
+static int op_movmh(void)              /* MOV M,H */
+{
+       memwrt((H << 8) + L, H);
+       return(7);
+}
+
+static int op_movml(void)              /* MOV M,L */
+{
+       memwrt((H << 8) + L, L);
+       return(7);
+}
+
+static int op_mvimn(void)              /* MVI M,n */
+{
+       memwrt((H << 8) + L, memrdr(PC++));
+       return(10);
+}
+
+static int op_movaa(void)              /* MOV A,A */
+{
+       return(5);
+}
+
+static int op_movab(void)              /* MOV A,B */
+{
+       A = B;
+       return(5);
+}
+
+static int op_movac(void)              /* MOV A,C */
+{
+       A = C;
+       return(5);
+}
+
+static int op_movad(void)              /* MOV A,D */
+{
+       A = D;
+       return(5);
+}
+
+static int op_movae(void)              /* MOV A,E */
+{
+       A = E;
+       return(5);
+}
+
+static int op_movah(void)              /* MOV A,H */
+{
+       A = H;
+       return(5);
+}
+
+static int op_moval(void)              /* MOV A,L */
+{
+       A = L;
+       return(5);
+}
+
+static int op_movam(void)              /* MOV A,M */
+{
+       A = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movba(void)              /* MOV B,A */
+{
+       B = A;
+       return(5);
+}
+
+static int op_movbb(void)              /* MOV B,B */
+{
+       return(5);
+}
+
+static int op_movbc(void)              /* MOV B,C */
+{
+       B = C;
+       return(5);
+}
+
+static int op_movbd(void)              /* MOV B,D */
+{
+       B = D;
+       return(5);
+}
+
+static int op_movbe(void)              /* MOV B,E */
+{
+       B = E;
+       return(5);
+}
+
+static int op_movbh(void)              /* MOV B,H */
+{
+       B = H;
+       return(5);
+}
+
+static int op_movbl(void)              /* MOV B,L */
+{
+       B = L;
+       return(5);
+}
+
+static int op_movbm(void)              /* MOV B,M */
+{
+       B = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movca(void)              /* MOV C,A */
+{
+       C = A;
+       return(5);
+}
+
+static int op_movcb(void)              /* MOV C,B */
+{
+       C = B;
+       return(5);
+}
+
+static int op_movcc(void)              /* MOV C,C */
+{
+       return(5);
+}
+
+static int op_movcd(void)              /* MOV C,D */
+{
+       C = D;
+       return(5);
+}
+
+static int op_movce(void)              /* MOV C,E */
+{
+       C = E;
+       return(5);
+}
+
+static int op_movch(void)              /* MOV C,H */
+{
+       C = H;
+       return(5);
+}
+
+static int op_movcl(void)              /* MOV C,L */
+{
+       C = L;
+       return(5);
+}
+
+static int op_movcm(void)              /* MOV C,M */
+{
+       C = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movda(void)              /* MOV D,A */
+{
+       D = A;
+       return(5);
+}
+
+static int op_movdb(void)              /* MOV D,B */
+{
+       D = B;
+       return(5);
+}
+
+static int op_movdc(void)              /* MOV D,C */
+{
+       D = C;
+       return(5);
+}
+
+static int op_movdd(void)              /* MOV D,D */
+{
+       return(5);
+}
+
+static int op_movde(void)              /* MOV D,E */
+{
+       D = E;
+       return(5);
+}
+
+static int op_movdh(void)              /* MOV D,H */
+{
+       D = H;
+       return(5);
+}
+
+static int op_movdl(void)              /* MOV D,L */
+{
+       D = L;
+       return(5);
+}
+
+static int op_movdm(void)              /* MOV D,M */
+{
+       D = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movea(void)              /* MOV E,A */
+{
+       E = A;
+       return(5);
+}
+
+static int op_moveb(void)              /* MOV E,B */
+{
+       E = B;
+       return(5);
+}
+
+static int op_movec(void)              /* MOV E,C */
+{
+       E = C;
+       return(5);
+}
+
+static int op_moved(void)              /* MOV E,D */
+{
+       E = D;
+       return(5);
+}
+
+static int op_movee(void)              /* MOV E,E */
+{
+       return(5);
+}
+
+static int op_moveh(void)              /* MOV E,H */
+{
+       E = H;
+       return(5);
+}
+
+static int op_movel(void)              /* MOV E,L */
+{
+       E = L;
+       return(5);
+}
+
+static int op_movem(void)              /* MOV E,M */
+{
+       E = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movha(void)              /* MOV H,A */
+{
+       H = A;
+       return(5);
+}
+
+static int op_movhb(void)              /* MOV H,B */
+{
+       H = B;
+       return(5);
+}
+
+static int op_movhc(void)              /* MOV H,C */
+{
+       H = C;
+       return(5);
+}
+
+static int op_movhd(void)              /* MOV H,D */
+{
+       H = D;
+       return(5);
+}
+
+static int op_movhe(void)              /* MOV H,E */
+{
+       H = E;
+       return(5);
+}
+
+static int op_movhh(void)              /* MOV H,H */
+{
+       return(5);
+}
+
+static int op_movhl(void)              /* MOV H,L */
+{
+       H = L;
+       return(5);
+}
+
+static int op_movhm(void)              /* MOV H,M */
+{
+       H = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_movla(void)              /* MOV L,A */
+{
+       L = A;
+       return(5);
+}
+
+static int op_movlb(void)              /* MOV L,B */
+{
+       L = B;
+       return(5);
+}
+
+static int op_movlc(void)              /* MOV L,C */
+{
+       L = C;
+       return(5);
+}
+
+static int op_movld(void)              /* MOV L,D */
+{
+       L = D;
+       return(5);
+}
+
+static int op_movle(void)              /* MOV L,E */
+{
+       L = E;
+       return(5);
+}
+
+static int op_movlh(void)              /* MOV L,H */
+{
+       L = H;
+       return(5);
+}
+
+static int op_movll(void)              /* MOV L,L */
+{
+       return(5);
+}
+
+static int op_movlm(void)              /* MOV L,M */
+{
+       L = memrdr((H << 8) + L);
+       return(7);
+}
+
+static int op_lxibnn(void)             /* LXI B,nn */
+{
+       C = memrdr(PC++);
+       B = memrdr(PC++);
+       return(10);
+}
+
+static int op_lxidnn(void)             /* LXI D,nn */
+{
+       E = memrdr(PC++);
+       D = memrdr(PC++);
+       return(10);
+}
+
+static int op_lxihnn(void)             /* LXI H,nn */
+{
+       L = memrdr(PC++);
+       H = memrdr(PC++);
+       return(10);
+}
+
+static int op_lxispnn(void)            /* LXI SP,nn */
+{
+       SP = memrdr(PC++);
+       SP += memrdr(PC++) << 8;
+       return(10);
+}
+
+static int op_sphl(void)               /* SPHL */
+{
+       SP = (H << 8) + L;
+       return(5);
+}
+
+static int op_lhldnn(void)             /* LHLD nn */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       L = memrdr(i);
+       H = memrdr(i + 1);
+       return(16);
+}
+
+static int op_shldnn(void)             /* SHLD nn */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i, L);
+       memwrt(i + 1, H);
+       return(16);
+}
+
+static int op_inxb(void)               /* INX B */
+{
+       C++;
+       if (!C)
+               B++;
+       return(5);
+}
+
+static int op_inxd(void)               /* INX D */
+{
+       E++;
+       if (!E)
+               D++;
+       return(5);
+}
+
+static int op_inxh(void)               /* INX H */
+{
+       L++;
+       if (!L)
+               H++;
+       return(5);
+}
+
+static int op_inxsp(void)              /* INX SP */
+{
+       SP++;
+       return(5);
+}
+
+static int op_dcxb(void)               /* DCX B */
+{
+       C--;
+       if (C == 0xff)
+               B--;
+       return(5);
+}
+
+static int op_dcxd(void)               /* DCX D */
+{
+       E--;
+       if (E == 0xff)
+               D--;
+       return(5);
+}
+
+static int op_dcxh(void)               /* DCX H */
+{
+       L--;
+       if (L == 0xff)
+               H--;
+       return(5);
+}
+
+static int op_dcxsp(void)              /* DCX SP */
+{
+       SP--;
+       return(5);
+}
+
+static int op_dadb(void)               /* DAD B */
+{
+       register int carry;
+
+       carry = (L + C > 255) ? 1 : 0;
+       L += C;
+       (H + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += B + carry;
+       return(10);
+}
+
+static int op_dadd(void)               /* DAD D */
+{
+       register int carry;
+
+       carry = (L + E > 255) ? 1 : 0;
+       L += E;
+       (H + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += D + carry;
+       return(10);
+}
+
+static int op_dadh(void)               /* DAD H */
+{
+       register int carry;
+
+       carry = (L << 1 > 255) ? 1 : 0;
+       L <<= 1;
+       (H + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += H + carry;
+       return(10);
+}
+
+static int op_dadsp(void)              /* DAD SP */
+{
+       register int carry;
+
+       BYTE spl = SP & 0xff;
+       BYTE sph = SP >> 8;
+       
+       carry = (L + spl > 255) ? 1 : 0;
+       L += spl;
+       (H + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H += sph + carry;
+       return(10);
+}
+
+static int op_anaa(void)               /* ANA A */
+{
+       (A & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anab(void)               /* ANA B */
+{
+       ((A | B) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anac(void)               /* ANA C */
+{
+       ((A | C) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anad(void)               /* ANA D */
+{
+       ((A | D) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anae(void)               /* ANA E */
+{
+       ((A | E) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anah(void)               /* ANA H */
+{
+       ((A | H) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anal(void)               /* ANA L */
+{
+       ((A | L) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(4);
+}
+
+static int op_anam(void)               /* ANA M */
+{
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((A | P) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= P;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(7);
+}
+
+static int op_anin(void)               /* ANI n */
+{
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((A | P) & 8) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A &= P;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~C_FLAG;
+       return(7);
+}
+
+static int op_oraa(void)               /* ORA A */
+{
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_orab(void)               /* ORA B */
+{
+       A |= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_orac(void)               /* ORA C */
+{
+       A |= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_orad(void)               /* ORA D */
+{
+       A |= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_orae(void)               /* ORA E */
+{
+       A |= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_orah(void)               /* ORA H */
+{
+       A |= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_oral(void)               /* ORA L */
+{
+       A |= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(4);
+}
+
+static int op_oram(void)               /* ORA M */
+{
+       A |= memrdr((H << 8) + L);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(7);
+}
+
+static int op_orin(void)               /* ORI n */
+{
+       A |= memrdr(PC++);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(C_FLAG | H_FLAG);
+       return(7);
+}
+
+static int op_xraa(void)               /* XRA A */
+{
+       A = 0;
+       F &= ~(S_FLAG | H_FLAG | C_FLAG);
+       F |= Z_FLAG | P_FLAG;
+       return(4);
+}
+
+static int op_xrab(void)               /* XRA B */
+{
+       A ^= B;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xrac(void)               /* XRA C */
+{
+       A ^= C;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xrad(void)               /* XRA D */
+{
+       A ^= D;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xrae(void)               /* XRA E */
+{
+       A ^= E;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xrah(void)               /* XRA H */
+{
+       A ^= H;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xral(void)               /* XRA L */
+{
+       A ^= L;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(4);
+}
+
+static int op_xram(void)               /* XRA M */
+{
+       A ^= memrdr((H << 8) + L);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_xrin(void)               /* XRI n */
+{
+       A ^= memrdr(PC++);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | C_FLAG);
+       return(7);
+}
+
+static int op_adda(void)               /* ADD A */
+{
+       ((A & 0xf) + (A & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       ((A << 1) > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A << 1;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addb(void)               /* ADD B */
+{
+       ((A & 0xf) + (B & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + B > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + B;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addc(void)               /* ADD C */
+{
+       ((A & 0xf) + (C & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + C > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A =  A + C;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addd(void)               /* ADD D */
+{
+       ((A & 0xf) + (D & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + D > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + D;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adde(void)               /* ADD E */
+{
+       ((A & 0xf) + (E & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + E > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + E;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addh(void)               /* ADD H */
+{
+       ((A & 0xf) + (H & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + H > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + H;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addl(void)               /* ADD L */
+{
+       ((A & 0xf) + (L & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + L > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + L;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_addm(void)               /* ADD M */
+{
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + P;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_adin(void)               /* ADI n */
+{
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + P;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_adca(void)               /* ADC A */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (A & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       ((A << 1) + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = (A << 1) + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adcb(void)               /* ADC B */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + B + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adcc(void)               /* ADC C */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (C & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + C + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + C + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adcd(void)               /* ADC D */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + D + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adce(void)               /* ADC E */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (E & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + E + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + E + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adch(void)               /* ADC H */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (H & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + H + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adcl(void)               /* ADC L */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (L & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + L + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + L + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_adcm(void)               /* ADC M */
+{
+       register int carry;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + P + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_acin(void)               /* ACI n */
+{
+       register int carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(PC++);
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A + P + carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_suba(void)               /* SUB A */
+{
+       A = 0;
+       F &= ~(S_FLAG | C_FLAG);
+       F |= Z_FLAG | H_FLAG | P_FLAG;
+       return(4);
+}
+
+static int op_subb(void)               /* SUB B */
+{
+       ((B & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - B;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_subc(void)               /* SUB C */
+{
+       ((C & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - C;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_subd(void)               /* SUB D */
+{
+       ((D & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - D;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sube(void)               /* SUB E */
+{
+       ((E & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - E;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_subh(void)               /* SUB H */
+{
+       ((H & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - H;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_subl(void)               /* SUB L */
+{
+       ((L & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - L;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_subm(void)               /* SUB M */
+{
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((P & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - P;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_suin(void)               /* SUI n */
+{
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((P & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - P;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_sbba(void)               /* SBB A */
+{
+       if (F & C_FLAG) {
+               F |= S_FLAG | C_FLAG | P_FLAG;
+               F &= ~(Z_FLAG | H_FLAG);
+               A = 255;
+       } else {
+               F |= Z_FLAG | H_FLAG | P_FLAG;
+               F &= ~(S_FLAG | C_FLAG);
+               A = 0;
+       }
+       return(4);
+}
+
+static int op_sbbb(void)               /* SBB B */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((B & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (B + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - B - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbc(void)               /* SBB C */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((C & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (C + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - C - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbd(void)               /* SBB D */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((D & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (D + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - D - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbe(void)               /* SBB E */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((E & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (E + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A =  A - E - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbh(void)               /* SBB H */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((H & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (H + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - H - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbl(void)               /* SBB L */
+{
+       register int carry;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((L & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (L + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - L - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_sbbm(void)               /* SBB M */
+{
+       register int carry;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - P - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_sbin(void)               /* SBI n */
+{
+       register int carry;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       carry = (F & C_FLAG) ? 1 : 0;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A - P - carry;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_cmpa(void)               /* CMP A */
+{
+       F &= ~(S_FLAG | C_FLAG);
+       F |= Z_FLAG | H_FLAG | P_FLAG;
+       return(4);
+}
+
+static int op_cmpb(void)               /* CMP B */
+{
+       register BYTE i;
+
+       ((B & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - B;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmpc(void)               /* CMP C */
+{
+       register BYTE i;
+
+       ((C & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - C;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmpd(void)               /* CMP D */
+{
+       register BYTE i;
+
+       ((D & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - D;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmpe(void)               /* CMP E */
+{
+       register BYTE i;
+
+       ((E & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - E;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmph(void)               /* CMP H */
+{
+       register BYTE i;
+
+       ((H & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - H;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmpl(void)               /* CMP L */
+{
+       register BYTE i;
+
+       ((L & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - L;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(4);
+}
+
+static int op_cmpm(void)               /* CMP M */
+{
+       register BYTE i;
+       register BYTE P;
+
+       P = memrdr((H << 8) + L);
+       ((P & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - P;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_cpin(void)               /* CPI n */
+{
+       register BYTE i;
+       register BYTE P;
+
+       P = memrdr(PC++);
+       ((P & 0xf) > (A & 0xf)) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = A - P;
+       (parity[i]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(7);
+}
+
+static int op_inra(void)               /* INR A */
+{
+       A++;
+       ((A & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrb(void)               /* INR B */
+{
+       B++;
+       ((B & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrc(void)               /* INR C */
+{
+       C++;
+       ((C & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrd(void)               /* INR D */
+{
+       D++;
+       ((D & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inre(void)               /* INR E */
+{
+       E++;
+       ((E & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrh(void)               /* INR H */
+{
+       H++;
+       ((H & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrl(void)               /* INR L */
+{
+       L++;
+       ((L & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_inrm(void)               /* INR M */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+        P++;
+        memwrt(addr, P);
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(10);
+}
+
+static int op_dcra(void)               /* DCR A */
+{
+       A--;
+       ((A & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrb(void)               /* DCR B */
+{
+       B--;
+       ((B & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrc(void)               /* DCR C */
+{
+       C--;
+       ((C & 0xf) == 0xf) ? (F &= ~H_FLAG): (F |= H_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrd(void)               /* DCR D */
+{
+       D--;
+       ((D & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcre(void)               /* DCR E */
+{
+       E--;
+       ((E & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrh(void)               /* DCR H */
+{
+       H--;
+       ((H & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrl(void)               /* DCR L */
+{
+       L--;
+       ((L & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(5);
+}
+
+static int op_dcrm(void)               /* DCR M */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       P--;
+       memwrt(addr, P);
+       ((P & 0xf) == 0xf) ? (F &= ~H_FLAG) : (F |= H_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(10);
+}
+
+static int op_rlc(void)                        /* RLC */
+{
+       register int i;
+
+       i = (A & 128) ? 1 : 0;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A <<= 1;
+       A |= i;
+       return(4);
+}
+
+static int op_rrc(void)                        /* RRC */
+{
+       register int i;
+
+       i = A & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A >>= 1;
+       if (i) A |= 128;
+       return(4);
+}
+
+static int op_ral(void)                        /* RAL */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A <<= 1;
+       if (old_c_flag) A |= 1;
+       return(4);
+}
+
+static int op_rar(void)                        /* RAR */
+{
+       register int i, old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       i = A & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A >>= 1;
+       if (old_c_flag) A |= 128;
+       return(4);
+}
+
+static int op_xchg(void)               /* XCHG */
+{
+       register BYTE i;
+
+       i = D;
+       D = H;
+       H = i;
+       i = E;
+       E = L;
+       L = i;
+       return(4);
+}
+
+static int op_xthl(void)               /* XTHL */
+{
+       register BYTE i;
+
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       i = memrdr(SP);
+       memwrt(SP, L);
+       L = i;
+       i = memrdr(SP + 1);
+       memwrt(SP + 1, H);
+       H = i;
+       return(18);
+}
+
+static int op_pushpsw(void)            /* PUSH PSW */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, A);
+       memwrt(--SP, F);
+       return(11);
+}
+
+static int op_pushb(void)              /* PUSH B */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, B);
+       memwrt(--SP, C);
+       return(11);
+}
+
+static int op_pushd(void)              /* PUSH D */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, D);
+       memwrt(--SP, E);
+       return(11);
+}
+
+static int op_pushh(void)              /* PUSH H */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, H);
+       memwrt(--SP, L);
+       return(11);
+}
+
+static int op_poppsw(void)             /* POP PSW */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       F = memrdr(SP++);
+       F &= ~(N2_FLAG | N1_FLAG);
+       F |= N_FLAG;
+       A = memrdr(SP++);
+       return(10);
+}
+
+static int op_popb(void)               /* POP B */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       C = memrdr(SP++);
+       B = memrdr(SP++);
+       return(10);
+}
+
+static int op_popd(void)               /* POP D */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       E = memrdr(SP++);
+       D = memrdr(SP++);
+       return(10);
+}
+
+static int op_poph(void)               /* POP H */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       L = memrdr(SP++);
+       H = memrdr(SP++);
+       return(10);
+}
+
+static int op_jmp(void)                        /* JMP */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC) << 8;
+       PC = i;
+       return(10);
+}
+
+static int op_undoc_jmp(void)          /* Undocumented JMP */
+{
+       if (u_flag) {   /* trap with option -u */
+               cpu_error = OPTRAP1;
+               cpu_state = STOPPED;
+               return(0);
+       } else {        /* else JMP */
+               return(op_jmp());
+       }
+}
+
+static int op_pchl(void)               /* PCHL */
+{
+       PC = (H << 8) + L;
+       return(5);
+}
+
+static int op_call(void)               /* CALL */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = i;
+       return(17);
+}
+
+static int op_undoc_call(void)         /* Undocumented CALL */
+{
+       if (u_flag) {   /* trap with option -u */
+               cpu_error = OPTRAP1;
+               cpu_state = STOPPED;
+               return(0);
+       } else {
+               return(op_call());
+       }
+}
+
+static int op_ret(void)                        /* RET */
+{
+       register WORD i;
+
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       i = memrdr(SP++);
+       i += memrdr(SP++) << 8;
+       PC = i;
+       return(10);
+}
+
+static int op_undoc_ret(void)          /* Undocumented RET */
+{
+       if (u_flag) {   /* trap with option -u */
+               cpu_error = OPTRAP1;
+               cpu_state = STOPPED;
+               return(0);
+       } else {        /* else RET */
+               return(op_ret());
+       }
+}
+
+static int op_jz(void)                 /* JZ nn */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jnz(void)                        /* JNZ nn */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jc(void)                 /* JC nn */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jnc(void)                        /* JNC nn */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpe(void)                        /* JPE nn */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jpo(void)                        /* JPO nn */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jm(void)                 /* JM nn */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_jp(void)                 /* JP nn */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+               PC = i;
+       } else
+               PC += 2;
+       return(10);
+}
+
+static int op_cz(void)                 /* CZ nn */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cnz(void)                        /* CNZ nn */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cc(void)                 /* CC nn */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cnc(void)                        /* CNC nn */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cpe(void)                        /* CPE nn */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cpo(void)                        /* CPO nn */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cm(void)                 /* CM nn */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_cp(void)                 /* CP nn */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+               i = memrdr(PC++);
+               i += memrdr(PC++) << 8;
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               memwrt(--SP, PC >> 8);
+               memwrt(--SP, PC);
+               PC = i;
+               return(17);
+       } else {
+               PC += 2;
+               return(11);
+       }
+}
+
+static int op_rz(void)                 /* RZ */
+{
+       register WORD i;
+
+       if (F & Z_FLAG) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rnz(void)                        /* RNZ */
+{
+       register WORD i;
+
+       if (!(F & Z_FLAG)) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rc(void)                 /* RC */
+{
+       register WORD i;
+
+       if (F & C_FLAG) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rnc(void)                        /* RNC */
+{
+       register WORD i;
+
+       if (!(F & C_FLAG)) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rpe(void)                        /* RPE */
+{
+       register WORD i;
+
+       if (F & P_FLAG) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rpo(void)                        /* RPO */
+{
+       register WORD i;
+
+       if (!(F & P_FLAG)) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rm(void)                 /* RM */
+{
+       register WORD i;
+
+       if (F & S_FLAG) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rp(void)                 /* RP */
+{
+       register WORD i;
+
+       if (!(F & S_FLAG)) {
+#ifdef BUS_8080
+               cpu_bus = CPU_STACK;
+#endif
+               i = memrdr(SP++);
+               i += memrdr(SP++) << 8;
+               PC = i;
+               return(11);
+       } else {
+               return(5);
+       }
+}
+
+static int op_rst0(void)               /* RST 0 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0;
+       return(11);
+}
+
+static int op_rst1(void)               /* RST 1 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x08;
+       return(11);
+}
+
+static int op_rst2(void)               /* RST 2 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x10;
+       return(11);
+}
+
+static int op_rst3(void)               /* RST 3 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x18;
+       return(11);
+}
+
+static int op_rst4(void)               /* RST 4 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x20;
+       return(11);
+}
+
+static int op_rst5(void)               /* RST 5 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x28;
+       return(11);
+}
+
+static int op_rst6(void)               /* RST 6 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x30;
+       return(11);
+}
+
+static int op_rst7(void)               /* RST 7 */
+{
+#ifdef BUS_8080
+       cpu_bus = CPU_STACK;
+#endif
+       memwrt(--SP, PC >> 8);
+       memwrt(--SP, PC);
+       PC = 0x38;
+       return(11);
+}
diff --git a/sim/sim2.c b/sim/sim2.c
new file mode 100644 (file)
index 0000000..a8ef698
--- /dev/null
@@ -0,0 +1,2711 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates multi byte opcodes
+ *     starting with 0xcb
+ */
+
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_cb(void);
+static int op_srla(void), op_srlb(void), op_srlc(void);
+static int op_srld(void), op_srle(void);
+static int op_srlh(void), op_srll(void), op_srlhl(void);
+static int op_slaa(void), op_slab(void), op_slac(void);
+static int op_slad(void), op_slae(void);
+static int op_slah(void), op_slal(void), op_slahl(void);
+static int op_rlra(void), op_rlb(void), op_rlc(void);
+static int op_rld(void), op_rle(void);
+static int op_rlh(void), op_rll(void), op_rlhl(void);
+static int op_rrra(void), op_rrb(void), op_rrc(void);
+static int op_rrd(void), op_rre(void);
+static int op_rrh(void), op_rrl(void), op_rrhl(void);
+static int op_rrcra(void), op_rrcb(void), op_rrcc(void);
+static int op_rrcd(void), op_rrce(void);
+static int op_rrch(void), op_rrcl(void), op_rrchl(void);
+static int op_rlcra(void), op_rlcb(void), op_rlcc(void);
+static int op_rlcd(void), op_rlce(void);
+static int op_rlch(void), op_rlcl(void), op_rlchl(void);
+static int op_sraa(void), op_srab(void), op_srac(void);
+static int op_srad(void), op_srae(void);
+static int op_srah(void), op_sral(void), op_srahl(void);
+static int op_sb0a(void), op_sb1a(void), op_sb2a(void), op_sb3a(void);
+static int op_sb4a(void), op_sb5a(void), op_sb6a(void), op_sb7a(void);
+static int op_sb0b(void), op_sb1b(void), op_sb2b(void), op_sb3b(void);
+static int op_sb4b(void), op_sb5b(void), op_sb6b(void), op_sb7b(void);
+static int op_sb0c(void), op_sb1c(void), op_sb2c(void), op_sb3c(void);
+static int op_sb4c(void), op_sb5c(void), op_sb6c(void), op_sb7c(void);
+static int op_sb0d(void), op_sb1d(void), op_sb2d(void), op_sb3d(void);
+static int op_sb4d(void), op_sb5d(void), op_sb6d(void), op_sb7d(void);
+static int op_sb0e(void), op_sb1e(void), op_sb2e(void), op_sb3e(void);
+static int op_sb4e(void), op_sb5e(void), op_sb6e(void), op_sb7e(void);
+static int op_sb0h(void), op_sb1h(void), op_sb2h(void), op_sb3h(void);
+static int op_sb4h(void), op_sb5h(void), op_sb6h(void), op_sb7h(void);
+static int op_sb0l(void), op_sb1l(void), op_sb2l(void), op_sb3l(void);
+static int op_sb4l(void), op_sb5l(void), op_sb6l(void), op_sb7l(void);
+static int op_sb0hl(void), op_sb1hl(void), op_sb2hl(void), op_sb3hl(void);
+static int op_sb4hl(void), op_sb5hl(void), op_sb6hl(void), op_sb7hl(void);
+static int op_rb0a(void), op_rb1a(void), op_rb2a(void), op_rb3a(void);
+static int op_rb4a(void), op_rb5a(void), op_rb6a(void), op_rb7a(void);
+static int op_rb0b(void), op_rb1b(void), op_rb2b(void), op_rb3b(void);
+static int op_rb4b(void), op_rb5b(void), op_rb6b(void), op_rb7b(void);
+static int op_rb0c(void), op_rb1c(void), op_rb2c(void), op_rb3c(void);
+static int op_rb4c(void), op_rb5c(void), op_rb6c(void), op_rb7c(void);
+static int op_rb0d(void), op_rb1d(void), op_rb2d(void), op_rb3d(void);
+static int op_rb4d(void), op_rb5d(void), op_rb6d(void), op_rb7d(void);
+static int op_rb0e(void), op_rb1e(void), op_rb2e(void), op_rb3e(void);
+static int op_rb4e(void), op_rb5e(void), op_rb6e(void), op_rb7e(void);
+static int op_rb0h(void), op_rb1h(void), op_rb2h(void), op_rb3h(void);
+static int op_rb4h(void), op_rb5h(void), op_rb6h(void), op_rb7h(void);
+static int op_rb0l(void), op_rb1l(void), op_rb2l(void), op_rb3l(void);
+static int op_rb4l(void), op_rb5l(void), op_rb6l(void), op_rb7l(void);
+static int op_rb0hl(void), op_rb1hl(void), op_rb2hl(void), op_rb3hl(void);
+static int op_rb4hl(void), op_rb5hl(void), op_rb6hl(void), op_rb7hl(void);
+static int op_tb0a(void), op_tb1a(void), op_tb2a(void), op_tb3a(void);
+static int op_tb4a(void), op_tb5a(void), op_tb6a(void), op_tb7a(void);
+static int op_tb0b(void), op_tb1b(void), op_tb2b(void), op_tb3b(void);
+static int op_tb4b(void), op_tb5b(void), op_tb6b(void), op_tb7b(void);
+static int op_tb0c(void), op_tb1c(void), op_tb2c(void), op_tb3c(void);
+static int op_tb4c(void), op_tb5c(void), op_tb6c(void), op_tb7c(void);
+static int op_tb0d(void), op_tb1d(void), op_tb2d(void), op_tb3d(void);
+static int op_tb4d(void), op_tb5d(void), op_tb6d(void), op_tb7d(void);
+static int op_tb0e(void), op_tb1e(void), op_tb2e(void), op_tb3e(void);
+static int op_tb4e(void), op_tb5e(void), op_tb6e(void), op_tb7e(void);
+static int op_tb0h(void), op_tb1h(void), op_tb2h(void), op_tb3h(void);
+static int op_tb4h(void), op_tb5h(void), op_tb6h(void), op_tb7h(void);
+static int op_tb0l(void), op_tb1l(void), op_tb2l(void), op_tb3l(void);
+static int op_tb4l(void), op_tb5l(void), op_tb6l(void), op_tb7l(void);
+static int op_tb0hl(void), op_tb1hl(void), op_tb2hl(void), op_tb3hl(void);
+static int op_tb4hl(void), op_tb5hl(void), op_tb6hl(void), op_tb7hl(void);
+
+#ifdef Z80_UNDOC
+static int op_undoc_slla(void), op_undoc_sllb(void), op_undoc_sllc(void);
+static int op_undoc_slld(void), op_undoc_slle(void);
+static int op_undoc_sllh(void), op_undoc_slll(void), op_undoc_sllhl(void);
+#endif
+
+int op_cb_handel(void)
+{
+       register int t;
+
+       static int (*op_cb[256]) (void) = {
+               op_rlcb,                        /* 0x00 */
+               op_rlcc,                        /* 0x01 */
+               op_rlcd,                        /* 0x02 */
+               op_rlce,                        /* 0x03 */
+               op_rlch,                        /* 0x04 */
+               op_rlcl,                        /* 0x05 */
+               op_rlchl,                       /* 0x06 */
+               op_rlcra,                       /* 0x07 */
+               op_rrcb,                        /* 0x08 */
+               op_rrcc,                        /* 0x09 */
+               op_rrcd,                        /* 0x0a */
+               op_rrce,                        /* 0x0b */
+               op_rrch,                        /* 0x0c */
+               op_rrcl,                        /* 0x0d */
+               op_rrchl,                       /* 0x0e */
+               op_rrcra,                       /* 0x0f */
+               op_rlb,                         /* 0x10 */
+               op_rlc,                         /* 0x11 */
+               op_rld,                         /* 0x12 */
+               op_rle,                         /* 0x13 */
+               op_rlh,                         /* 0x14 */
+               op_rll,                         /* 0x15 */
+               op_rlhl,                        /* 0x16 */
+               op_rlra,                        /* 0x17 */
+               op_rrb,                         /* 0x18 */
+               op_rrc,                         /* 0x19 */
+               op_rrd,                         /* 0x1a */
+               op_rre,                         /* 0x1b */
+               op_rrh,                         /* 0x1c */
+               op_rrl,                         /* 0x1d */
+               op_rrhl,                        /* 0x1e */
+               op_rrra,                        /* 0x1f */
+               op_slab,                        /* 0x20 */
+               op_slac,                        /* 0x21 */
+               op_slad,                        /* 0x22 */
+               op_slae,                        /* 0x23 */
+               op_slah,                        /* 0x24 */
+               op_slal,                        /* 0x25 */
+               op_slahl,                       /* 0x26 */
+               op_slaa,                        /* 0x27 */
+               op_srab,                        /* 0x28 */
+               op_srac,                        /* 0x29 */
+               op_srad,                        /* 0x2a */
+               op_srae,                        /* 0x2b */
+               op_srah,                        /* 0x2c */
+               op_sral,                        /* 0x2d */
+               op_srahl,                       /* 0x2e */
+               op_sraa,                        /* 0x2f */
+#ifndef Z80_UNDOC
+               trap_cb,                        /* 0x30 */
+               trap_cb,                        /* 0x31 */
+               trap_cb,                        /* 0x32 */
+               trap_cb,                        /* 0x33 */
+               trap_cb,                        /* 0x34 */
+               trap_cb,                        /* 0x35 */
+               trap_cb,                        /* 0x36 */
+               trap_cb,                        /* 0x37 */
+#else
+               op_undoc_sllb,
+               op_undoc_sllc,
+               op_undoc_slld,
+               op_undoc_slle,
+               op_undoc_sllh,
+               op_undoc_slll,
+               op_undoc_sllhl,
+               op_undoc_slla,
+#endif
+               op_srlb,                        /* 0x38 */
+               op_srlc,                        /* 0x39 */
+               op_srld,                        /* 0x3a */
+               op_srle,                        /* 0x3b */
+               op_srlh,                        /* 0x3c */
+               op_srll,                        /* 0x3d */
+               op_srlhl,                       /* 0x3e */
+               op_srla,                        /* 0x3f */
+               op_tb0b,                        /* 0x40 */
+               op_tb0c,                        /* 0x41 */
+               op_tb0d,                        /* 0x42 */
+               op_tb0e,                        /* 0x43 */
+               op_tb0h,                        /* 0x44 */
+               op_tb0l,                        /* 0x45 */
+               op_tb0hl,                       /* 0x46 */
+               op_tb0a,                        /* 0x47 */
+               op_tb1b,                        /* 0x48 */
+               op_tb1c,                        /* 0x49 */
+               op_tb1d,                        /* 0x4a */
+               op_tb1e,                        /* 0x4b */
+               op_tb1h,                        /* 0x4c */
+               op_tb1l,                        /* 0x4d */
+               op_tb1hl,                       /* 0x4e */
+               op_tb1a,                        /* 0x4f */
+               op_tb2b,                        /* 0x50 */
+               op_tb2c,                        /* 0x51 */
+               op_tb2d,                        /* 0x52 */
+               op_tb2e,                        /* 0x53 */
+               op_tb2h,                        /* 0x54 */
+               op_tb2l,                        /* 0x55 */
+               op_tb2hl,                       /* 0x56 */
+               op_tb2a,                        /* 0x57 */
+               op_tb3b,                        /* 0x58 */
+               op_tb3c,                        /* 0x59 */
+               op_tb3d,                        /* 0x5a */
+               op_tb3e,                        /* 0x5b */
+               op_tb3h,                        /* 0x5c */
+               op_tb3l,                        /* 0x5d */
+               op_tb3hl,                       /* 0x5e */
+               op_tb3a,                        /* 0x5f */
+               op_tb4b,                        /* 0x60 */
+               op_tb4c,                        /* 0x61 */
+               op_tb4d,                        /* 0x62 */
+               op_tb4e,                        /* 0x63 */
+               op_tb4h,                        /* 0x64 */
+               op_tb4l,                        /* 0x65 */
+               op_tb4hl,                       /* 0x66 */
+               op_tb4a,                        /* 0x67 */
+               op_tb5b,                        /* 0x68 */
+               op_tb5c,                        /* 0x69 */
+               op_tb5d,                        /* 0x6a */
+               op_tb5e,                        /* 0x6b */
+               op_tb5h,                        /* 0x6c */
+               op_tb5l,                        /* 0x6d */
+               op_tb5hl,                       /* 0x6e */
+               op_tb5a,                        /* 0x6f */
+               op_tb6b,                        /* 0x70 */
+               op_tb6c,                        /* 0x71 */
+               op_tb6d,                        /* 0x72 */
+               op_tb6e,                        /* 0x73 */
+               op_tb6h,                        /* 0x74 */
+               op_tb6l,                        /* 0x75 */
+               op_tb6hl,                       /* 0x76 */
+               op_tb6a,                        /* 0x77 */
+               op_tb7b,                        /* 0x78 */
+               op_tb7c,                        /* 0x79 */
+               op_tb7d,                        /* 0x7a */
+               op_tb7e,                        /* 0x7b */
+               op_tb7h,                        /* 0x7c */
+               op_tb7l,                        /* 0x7d */
+               op_tb7hl,                       /* 0x7e */
+               op_tb7a,                        /* 0x7f */
+               op_rb0b,                        /* 0x80 */
+               op_rb0c,                        /* 0x81 */
+               op_rb0d,                        /* 0x82 */
+               op_rb0e,                        /* 0x83 */
+               op_rb0h,                        /* 0x84 */
+               op_rb0l,                        /* 0x85 */
+               op_rb0hl,                       /* 0x86 */
+               op_rb0a,                        /* 0x87 */
+               op_rb1b,                        /* 0x88 */
+               op_rb1c,                        /* 0x89 */
+               op_rb1d,                        /* 0x8a */
+               op_rb1e,                        /* 0x8b */
+               op_rb1h,                        /* 0x8c */
+               op_rb1l,                        /* 0x8d */
+               op_rb1hl,                       /* 0x8e */
+               op_rb1a,                        /* 0x8f */
+               op_rb2b,                        /* 0x90 */
+               op_rb2c,                        /* 0x91 */
+               op_rb2d,                        /* 0x92 */
+               op_rb2e,                        /* 0x93 */
+               op_rb2h,                        /* 0x94 */
+               op_rb2l,                        /* 0x95 */
+               op_rb2hl,                       /* 0x96 */
+               op_rb2a,                        /* 0x97 */
+               op_rb3b,                        /* 0x98 */
+               op_rb3c,                        /* 0x99 */
+               op_rb3d,                        /* 0x9a */
+               op_rb3e,                        /* 0x9b */
+               op_rb3h,                        /* 0x9c */
+               op_rb3l,                        /* 0x9d */
+               op_rb3hl,                       /* 0x9e */
+               op_rb3a,                        /* 0x9f */
+               op_rb4b,                        /* 0xa0 */
+               op_rb4c,                        /* 0xa1 */
+               op_rb4d,                        /* 0xa2 */
+               op_rb4e,                        /* 0xa3 */
+               op_rb4h,                        /* 0xa4 */
+               op_rb4l,                        /* 0xa5 */
+               op_rb4hl,                       /* 0xa6 */
+               op_rb4a,                        /* 0xa7 */
+               op_rb5b,                        /* 0xa8 */
+               op_rb5c,                        /* 0xa9 */
+               op_rb5d,                        /* 0xaa */
+               op_rb5e,                        /* 0xab */
+               op_rb5h,                        /* 0xac */
+               op_rb5l,                        /* 0xad */
+               op_rb5hl,                       /* 0xae */
+               op_rb5a,                        /* 0xaf */
+               op_rb6b,                        /* 0xb0 */
+               op_rb6c,                        /* 0xb1 */
+               op_rb6d,                        /* 0xb2 */
+               op_rb6e,                        /* 0xb3 */
+               op_rb6h,                        /* 0xb4 */
+               op_rb6l,                        /* 0xb5 */
+               op_rb6hl,                       /* 0xb6 */
+               op_rb6a,                        /* 0xb7 */
+               op_rb7b,                        /* 0xb8 */
+               op_rb7c,                        /* 0xb9 */
+               op_rb7d,                        /* 0xba */
+               op_rb7e,                        /* 0xbb */
+               op_rb7h,                        /* 0xbc */
+               op_rb7l,                        /* 0xbd */
+               op_rb7hl,                       /* 0xbe */
+               op_rb7a,                        /* 0xbf */
+               op_sb0b,                        /* 0xc0 */
+               op_sb0c,                        /* 0xc1 */
+               op_sb0d,                        /* 0xc2 */
+               op_sb0e,                        /* 0xc3 */
+               op_sb0h,                        /* 0xc4 */
+               op_sb0l,                        /* 0xc5 */
+               op_sb0hl,                       /* 0xc6 */
+               op_sb0a,                        /* 0xc7 */
+               op_sb1b,                        /* 0xc8 */
+               op_sb1c,                        /* 0xc9 */
+               op_sb1d,                        /* 0xca */
+               op_sb1e,                        /* 0xcb */
+               op_sb1h,                        /* 0xcc */
+               op_sb1l,                        /* 0xcd */
+               op_sb1hl,                       /* 0xce */
+               op_sb1a,                        /* 0xcf */
+               op_sb2b,                        /* 0xd0 */
+               op_sb2c,                        /* 0xd1 */
+               op_sb2d,                        /* 0xd2 */
+               op_sb2e,                        /* 0xd3 */
+               op_sb2h,                        /* 0xd4 */
+               op_sb2l,                        /* 0xd5 */
+               op_sb2hl,                       /* 0xd6 */
+               op_sb2a,                        /* 0xd7 */
+               op_sb3b,                        /* 0xd8 */
+               op_sb3c,                        /* 0xd9 */
+               op_sb3d,                        /* 0xda */
+               op_sb3e,                        /* 0xdb */
+               op_sb3h,                        /* 0xdc */
+               op_sb3l,                        /* 0xdd */
+               op_sb3hl,                       /* 0xde */
+               op_sb3a,                        /* 0xdf */
+               op_sb4b,                        /* 0xe0 */
+               op_sb4c,                        /* 0xe1 */
+               op_sb4d,                        /* 0xe2 */
+               op_sb4e,                        /* 0xe3 */
+               op_sb4h,                        /* 0xe4 */
+               op_sb4l,                        /* 0xe5 */
+               op_sb4hl,                       /* 0xe6 */
+               op_sb4a,                        /* 0xe7 */
+               op_sb5b,                        /* 0xe8 */
+               op_sb5c,                        /* 0xe9 */
+               op_sb5d,                        /* 0xea */
+               op_sb5e,                        /* 0xeb */
+               op_sb5h,                        /* 0xec */
+               op_sb5l,                        /* 0xed */
+               op_sb5hl,                       /* 0xee */
+               op_sb5a,                        /* 0xef */
+               op_sb6b,                        /* 0xf0 */
+               op_sb6c,                        /* 0xf1 */
+               op_sb6d,                        /* 0xf2 */
+               op_sb6e,                        /* 0xf3 */
+               op_sb6h,                        /* 0xf4 */
+               op_sb6l,                        /* 0xf5 */
+               op_sb6hl,                       /* 0xf6 */
+               op_sb6a,                        /* 0xf7 */
+               op_sb7b,                        /* 0xf8 */
+               op_sb7c,                        /* 0xf9 */
+               op_sb7d,                        /* 0xfa */
+               op_sb7e,                        /* 0xfb */
+               op_sb7h,                        /* 0xfc */
+               op_sb7l,                        /* 0xfd */
+               op_sb7hl,                       /* 0xfe */
+               op_sb7a                         /* 0xff */
+       };
+
+#ifdef BUS_8080
+       /* M1 opcode fetch */
+       cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+       m1_step = 1;
+#endif
+#ifdef FRONTPANEL
+       /* update frontpanel */
+       fp_clock++;
+       fp_sampleLightGroup(0, 0);
+#endif
+
+       t = (*op_cb[memrdr(PC++)]) ();          /* execute next opcode */
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xcb of a multi byte opcode.
+ */
+static int trap_cb(void)
+{
+       cpu_error = OPTRAP2;
+       cpu_state = STOPPED;
+       return(0);
+}
+
+static int op_srla(void)               /* SRL A */
+{
+       (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srlb(void)               /* SRL B */
+{
+       (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srlc(void)               /* SRL C */
+{
+       (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srld(void)               /* SRL D */
+{
+       (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srle(void)               /* SRL E */
+{
+       (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) :(F |= P_FLAG);
+       return(8);
+}
+
+static int op_srlh(void)               /* SRL H */
+{
+       (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srll(void)               /* SRL L */
+{
+       (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L >>= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srlhl(void)              /* SRL (HL) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_slaa(void)               /* SLA A */
+{
+       (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slab(void)               /* SLA B */
+{
+       (B & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slac(void)               /* SLA C */
+{
+       (C & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slad(void)               /* SLA D */
+{
+       (D & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slae(void)               /* SLA E */
+{
+       (E & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slah(void)               /* SLA H */
+{
+       (H & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slal(void)               /* SLA L */
+{
+       (L & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L <<= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_slahl(void)              /* SLA (HL) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_rlra(void)               /* RL A */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A <<= 1;
+       if (old_c_flag) A |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlb(void)                        /* RL B */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (B & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B <<= 1;
+       if (old_c_flag) B |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlc(void)                        /* RL C */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (C & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C <<= 1;
+       if (old_c_flag) C |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rld(void)                        /* RL D */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (D & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D <<= 1;
+       if (old_c_flag) D |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rle(void)                        /* RL E */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (E & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E <<= 1;
+       if (old_c_flag) E |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlh(void)                        /* RL H */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (H & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H <<= 1;
+       if (old_c_flag) H |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) :(F |= P_FLAG);
+       return(8);
+}
+
+static int op_rll(void)                        /* RL L */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (L & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L <<= 1;
+       if (old_c_flag) L |= 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlhl(void)               /* RL (HL) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (old_c_flag) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_rrra(void)               /* RR A */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A >>= 1;
+       if (old_c_flag) A |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrb(void)                        /* RR B */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B >>= 1;
+       if (old_c_flag) B |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrc(void)                        /* RR C */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C >>= 1;
+       if (old_c_flag) C |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrd(void)                        /* RR D */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D >>= 1;
+       if (old_c_flag) D |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rre(void)                        /* RR E */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E >>= 1;
+       if (old_c_flag) E |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrh(void)                        /* RR H */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H >>= 1;
+       if (old_c_flag) H |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrl(void)                        /* RR L */
+{
+       register int old_c_flag;
+
+       old_c_flag = F & C_FLAG;
+       (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L >>= 1;
+       if (old_c_flag) L |= 128;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrhl(void)               /* RR (HL) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (old_c_flag) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_rrcra(void)              /* RRC A */
+{
+       register int i;
+
+       i = A & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A >>= 1;
+       if (i) A |= 128;
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrcb(void)               /* RRC B */
+{
+       register int i;
+
+       i = B & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       B >>= 1;
+       if (i) B |= 128;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrcc(void)               /* RRC C */
+{
+       register int i;
+
+       i = C & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       C >>= 1;
+       if (i) C |= 128;
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrcd(void)               /* RRC D */
+{
+       register int i;
+
+       i = D & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       D >>= 1;
+       if (i) D |= 128;
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrce(void)               /* RRC E */
+{
+       register int i;
+
+       i = E & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       E >>= 1;
+       if (i) E |= 128;
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrch(void)               /* RRC H */
+{
+       register int i;
+
+       i = H & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       H >>= 1;
+       if (i) H |= 128;
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrcl(void)               /* RRC L */
+{
+       register int i;
+
+       i = L & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       L >>= 1;
+       if (i) L |= 128;
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rrchl(void)              /* RRC (HL) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       i = P & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (i) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_rlcra(void)              /* RLC A */
+{
+       register int i;
+
+       i = A & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       A <<= 1;
+       if (i) A |= 1;
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlcb(void)               /* RLC B */
+{
+       register int i;
+
+       i = B & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       B <<= 1;
+       if (i) B |= 1;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlcc(void)               /* RLC C */
+{
+       register int i;
+
+       i = C & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       C <<= 1;
+       if (i) C |= 1;
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlcd(void)               /* RLC D */
+{
+       register int i;
+
+       i = D & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       D <<= 1;
+       if (i) D |= 1;
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlce(void)               /* RLC E */
+{
+       register int i;
+
+       i = E & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       E <<= 1;
+       if (i) E |= 1;
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlch(void)               /* RLC H */
+{
+       register int i;
+
+       i = H & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       H <<= 1;
+       if (i) H |= 1;
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlcl(void)               /* RLC L */
+{
+       register int i;
+
+       i = L & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       F &= ~(H_FLAG | N_FLAG);
+       L <<= 1;
+       if (i) L |= 1;
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_rlchl(void)              /* RLC (HL) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       i = P & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (i) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_sraa(void)               /* SRA A */
+{
+       register int i;
+
+       i = A & 128;
+       (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A >>= 1;
+       A |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srab(void)               /* SRA B */
+{
+       register int i;
+
+       i = B & 128;
+       (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B >>= 1;
+       B |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srac(void)               /* SRA C */
+{
+       register int i;
+
+       i = C & 128;
+       (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C >>= 1;
+       C |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srad(void)               /* SRA D */
+{
+       register int i;
+
+       i = D & 128;
+       (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D >>= 1;
+       D |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srae(void)               /* SRA E */
+{
+       register int i;
+
+       i = E & 128;
+       (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E >>= 1;
+       E |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srah(void)               /* SRA H */
+{
+       register int i;
+
+       i = H & 128;
+       (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H >>= 1;
+       H |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_sral(void)               /* SRA L */
+{
+       register int i;
+
+       i = L & 128;
+       (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L >>= 1;
+       L |= i;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_srahl(void)              /* SRA (HL) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       i = P & 128;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P = (P >> 1) | i;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+static int op_sb0a(void)               /* SET 0,A */
+{
+       A |= 1;
+       return(8);
+}
+
+static int op_sb1a(void)               /* SET 1,A */
+{
+       A |= 2;
+       return(8);
+}
+
+static int op_sb2a(void)               /* SET 2,A */
+{
+       A |= 4;
+       return(8);
+}
+
+static int op_sb3a(void)               /* SET 3,A */
+{
+       A |= 8;
+       return(8);
+}
+
+static int op_sb4a(void)               /* SET 4,A */
+{
+       A |= 16;
+       return(8);
+}
+
+static int op_sb5a(void)               /* SET 5,A */
+{
+       A |= 32;
+       return(8);
+}
+
+static int op_sb6a(void)               /* SET 6,A */
+{
+       A |= 64;
+       return(8);
+}
+
+static int op_sb7a(void)               /* SET 7,A */
+{
+       A |= 128;
+       return(8);
+}
+
+static int op_sb0b(void)               /* SET 0,B */
+{
+       B |= 1;
+       return(8);
+}
+
+static int op_sb1b(void)               /* SET 1,B */
+{
+       B |= 2;
+       return(8);
+}
+
+static int op_sb2b(void)               /* SET 2,B */
+{
+       B |= 4;
+       return(8);
+}
+
+static int op_sb3b(void)               /* SET 3,B */
+{
+       B |= 8;
+       return(8);
+}
+
+static int op_sb4b(void)               /* SET 4,B */
+{
+       B |= 16;
+       return(8);
+}
+
+static int op_sb5b(void)               /* SET 5,B */
+{
+       B |= 32;
+       return(8);
+}
+
+static int op_sb6b(void)               /* SET 6,B */
+{
+       B |= 64;
+       return(8);
+}
+
+static int op_sb7b(void)               /* SET 7,B */
+{
+       B |= 128;
+       return(8);
+}
+
+static int op_sb0c(void)               /* SET 0,C */
+{
+       C |= 1;
+       return(8);
+}
+
+static int op_sb1c(void)               /* SET 1,C */
+{
+       C |= 2;
+       return(8);
+}
+
+static int op_sb2c(void)               /* SET 2,C */
+{
+       C |= 4;
+       return(8);
+}
+
+static int op_sb3c(void)               /* SET 3,C */
+{
+       C |= 8;
+       return(8);
+}
+
+static int op_sb4c(void)               /* SET 4,C */
+{
+       C |= 16;
+       return(8);
+}
+
+static int op_sb5c(void)               /* SET 5,C */
+{
+       C |= 32;
+       return(8);
+}
+
+static int op_sb6c(void)               /* SET 6,C */
+{
+       C |= 64;
+       return(8);
+}
+
+static int op_sb7c(void)               /* SET 7,C */
+{
+       C |= 128;
+       return(8);
+}
+
+static int op_sb0d(void)               /* SET 0,D */
+{
+       D |= 1;
+       return(8);
+}
+
+static int op_sb1d(void)               /* SET 1,D */
+{
+       D |= 2;
+       return(8);
+}
+
+static int op_sb2d(void)               /* SET 2,D */
+{
+       D |= 4;
+       return(8);
+}
+
+static int op_sb3d(void)               /* SET 3,D */
+{
+       D |= 8;
+       return(8);
+}
+
+static int op_sb4d(void)               /* SET 4,D */
+{
+       D |= 16;
+       return(8);
+}
+
+static int op_sb5d(void)               /* SET 5,D */
+{
+       D |= 32;
+       return(8);
+}
+
+static int op_sb6d(void)               /* SET 6,D */
+{
+       D |= 64;
+       return(8);
+}
+
+static int op_sb7d(void)               /* SET 7,D */
+{
+       D |= 128;
+       return(8);
+}
+
+static int op_sb0e(void)               /* SET 0,E */
+{
+       E |= 1;
+       return(8);
+}
+
+static int op_sb1e(void)               /* SET 1,E */
+{
+       E |= 2;
+       return(8);
+}
+
+static int op_sb2e(void)               /* SET 2,E */
+{
+       E |= 4;
+       return(8);
+}
+
+static int op_sb3e(void)               /* SET 3,E */
+{
+       E |= 8;
+       return(8);
+}
+
+static int op_sb4e(void)               /* SET 4,E */
+{
+       E |= 16;
+       return(8);
+}
+
+static int op_sb5e(void)               /* SET 5,E */
+{
+       E |= 32;
+       return(8);
+}
+
+static int op_sb6e(void)               /* SET 6,E */
+{
+       E |= 64;
+       return(8);
+}
+
+static int op_sb7e(void)               /* SET 7,E */
+{
+       E |= 128;
+       return(8);
+}
+
+static int op_sb0h(void)               /* SET 0,H */
+{
+       H |= 1;
+       return(8);
+}
+
+static int op_sb1h(void)               /* SET 1,H */
+{
+       H |= 2;
+       return(8);
+}
+
+static int op_sb2h(void)               /* SET 2,H */
+{
+       H |= 4;
+       return(8);
+}
+
+static int op_sb3h(void)               /* SET 3,H */
+{
+       H |= 8;
+       return(8);
+}
+
+static int op_sb4h(void)               /* SET 4,H */
+{
+       H |= 16;
+       return(8);
+}
+
+static int op_sb5h(void)               /* SET 5,H */
+{
+       H |= 32;
+       return(8);
+}
+
+static int op_sb6h(void)               /* SET 6,H */
+{
+       H |= 64;
+       return(8);
+}
+
+static int op_sb7h(void)               /* SET 7,H */
+{
+       H |= 128;
+       return(8);
+}
+
+static int op_sb0l(void)               /* SET 0,L */
+{
+       L |= 1;
+       return(8);
+}
+
+static int op_sb1l(void)               /* SET 1,L */
+{
+       L |= 2;
+       return(8);
+}
+
+static int op_sb2l(void)               /* SET 2,L */
+{
+       L |= 4;
+       return(8);
+}
+
+static int op_sb3l(void)               /* SET 3,L */
+{
+       L |= 8;
+       return(8);
+}
+
+static int op_sb4l(void)               /* SET 4,L */
+{
+       L |= 16;
+       return(8);
+}
+
+static int op_sb5l(void)               /* SET 5,L */
+{
+       L |= 32;
+       return(8);
+}
+
+static int op_sb6l(void)               /* SET 6,L */
+{
+       L |= 64;
+       return(8);
+}
+
+static int op_sb7l(void)               /* SET 7,L */
+{
+       L |= 128;
+       return(8);
+}
+
+static int op_sb0hl(void)              /* SET 0,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 1);
+       return(15);
+}
+
+static int op_sb1hl(void)              /* SET 1,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 2);
+       return(15);
+}
+
+static int op_sb2hl(void)              /* SET 2,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 4);
+       return(15);
+}
+
+static int op_sb3hl(void)              /* SET 3,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 8);
+       return(15);
+}
+
+static int op_sb4hl(void)              /* SET 4,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 16);
+       return(15);
+}
+
+static int op_sb5hl(void)              /* SET 5,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 32);
+       return(15);
+}
+
+static int op_sb6hl(void)              /* SET 6,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 64);
+       return(15);
+}
+
+static int op_sb7hl(void)              /* SET 7,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) | 128);
+       return(15);
+}
+
+static int op_rb0a(void)               /* RES 0,A */
+{
+       A &= ~1;
+       return(8);
+}
+
+static int op_rb1a(void)               /* RES 1,A */
+{
+       A &= ~2;
+       return(8);
+}
+
+static int op_rb2a(void)               /* RES 2,A */
+{
+       A &= ~4;
+       return(8);
+}
+
+static int op_rb3a(void)               /* RES 3,A */
+{
+       A &= ~8;
+       return(8);
+}
+
+static int op_rb4a(void)               /* RES 4,A */
+{
+       A &= ~16;
+       return(8);
+}
+
+static int op_rb5a(void)               /* RES 5,A */
+{
+       A &= ~32;
+       return(8);
+}
+
+static int op_rb6a(void)               /* RES 6,A */
+{
+       A &= ~64;
+       return(8);
+}
+
+static int op_rb7a(void)               /* RES 7,A */
+{
+       A &= ~128;
+       return(8);
+}
+
+static int op_rb0b(void)               /* RES 0,B */
+{
+       B &= ~1;
+       return(8);
+}
+
+static int op_rb1b(void)               /* RES 1,B */
+{
+       B &= ~2;
+       return(8);
+}
+
+static int op_rb2b(void)               /* RES 2,B */
+{
+       B &= ~4;
+       return(8);
+}
+
+static int op_rb3b(void)               /* RES 3,B */
+{
+       B &= ~8;
+       return(8);
+}
+
+static int op_rb4b(void)               /* RES 4,B */
+{
+       B &= ~16;
+       return(8);
+}
+
+static int op_rb5b(void)               /* RES 5,B */
+{
+       B &= ~32;
+       return(8);
+}
+
+static int op_rb6b(void)               /* RES 6,B */
+{
+       B &= ~64;
+       return(8);
+}
+
+static int op_rb7b(void)               /* RES 7,B */
+{
+       B &= ~128;
+       return(8);
+}
+
+static int op_rb0c(void)               /* RES 0,C */
+{
+       C &= ~1;
+       return(8);
+}
+
+static int op_rb1c(void)               /* RES 1,C */
+{
+       C &= ~2;
+       return(8);
+}
+
+static int op_rb2c(void)               /* RES 2,C */
+{
+       C &= ~4;
+       return(8);
+}
+
+static int op_rb3c(void)               /* RES 3,C */
+{
+       C &= ~8;
+       return(8);
+}
+
+static int op_rb4c(void)               /* RES 4,C */
+{
+       C &= ~16;
+       return(8);
+}
+
+static int op_rb5c(void)               /* RES 5,C */
+{
+       C &= ~32;
+       return(8);
+}
+
+static int op_rb6c(void)               /* RES 6,C */
+{
+       C &= ~64;
+       return(8);
+}
+
+static int op_rb7c(void)               /* RES 7,C */
+{
+       C &= ~128;
+       return(8);
+}
+
+static int op_rb0d(void)               /* RES 0,D */
+{
+       D &= ~1;
+       return(8);
+}
+
+static int op_rb1d(void)               /* RES 1,D */
+{
+       D &= ~2;
+       return(8);
+}
+
+static int op_rb2d(void)               /* RES 2,D */
+{
+       D &= ~4;
+       return(8);
+}
+
+static int op_rb3d(void)               /* RES 3,D */
+{
+       D &= ~8;
+       return(8);
+}
+
+static int op_rb4d(void)               /* RES 4,D */
+{
+       D &= ~16;
+       return(8);
+}
+
+static int op_rb5d(void)               /* RES 5,D */
+{
+       D &= ~32;
+       return(8);
+}
+
+static int op_rb6d(void)               /* RES 6,D */
+{
+       D &= ~64;
+       return(8);
+}
+
+static int op_rb7d(void)               /* RES 7,D */
+{
+       D &= ~128;
+       return(8);
+}
+
+static int op_rb0e(void)               /* RES 0,E */
+{
+       E &= ~1;
+       return(8);
+}
+
+static int op_rb1e(void)               /* RES 1,E */
+{
+       E &= ~2;
+       return(8);
+}
+
+static int op_rb2e(void)               /* RES 2,E */
+{
+       E &= ~4;
+       return(8);
+}
+
+static int op_rb3e(void)               /* RES 3,E */
+{
+       E &= ~8;
+       return(8);
+}
+
+static int op_rb4e(void)               /* RES 4,E */
+{
+       E &= ~16;
+       return(8);
+}
+
+static int op_rb5e(void)               /* RES 5,E */
+{
+       E &= ~32;
+       return(8);
+}
+
+static int op_rb6e(void)               /* RES 6,E */
+{
+       E &= ~64;
+       return(8);
+}
+
+static int op_rb7e(void)               /* RES 7,E */
+{
+       E &= ~128;
+       return(8);
+}
+
+static int op_rb0h(void)               /* RES 0,H */
+{
+       H &= ~1;
+       return(8);
+}
+
+static int op_rb1h(void)               /* RES 1,H */
+{
+       H &= ~2;
+       return(8);
+}
+
+static int op_rb2h(void)               /* RES 2,H */
+{
+       H &= ~4;
+       return(8);
+}
+
+static int op_rb3h(void)               /* RES 3,H */
+{
+       H &= ~8;
+       return(8);
+}
+
+static int op_rb4h(void)               /* RES 4,H */
+{
+       H &= ~16;
+       return(8);
+}
+
+static int op_rb5h(void)               /* RES 5,H */
+{
+       H &= ~32;
+       return(8);
+}
+
+static int op_rb6h(void)               /* RES 6,H */
+{
+       H &= ~64;
+       return(8);
+}
+
+static int op_rb7h(void)               /* RES 7,H */
+{
+       H &= ~128;
+       return(8);
+}
+
+static int op_rb0l(void)               /* RES 0,L */
+{
+       L &= ~1;
+       return(8);
+}
+
+static int op_rb1l(void)               /* RES 1,L */
+{
+       L &= ~2;
+       return(8);
+}
+
+static int op_rb2l(void)               /* RES 2,L */
+{
+       L &= ~4;
+       return(8);
+}
+
+static int op_rb3l(void)               /* RES 3,L */
+{
+       L &= ~8;
+       return(8);
+}
+
+static int op_rb4l(void)               /* RES 4,L */
+{
+       L &= ~16;
+       return(8);
+}
+
+static int op_rb5l(void)               /* RES 5,L */
+{
+       L &= ~32;
+       return(8);
+}
+
+static int op_rb6l(void)               /* RES 6,L */
+{
+       L &= ~64;
+       return(8);
+}
+
+static int op_rb7l(void)               /* RES 7,L */
+{
+       L &= ~128;
+       return(8);
+}
+
+static int op_rb0hl(void)              /* RES 0,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~1);
+       return(15);
+}
+
+static int op_rb1hl(void)              /* RES 1,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~2);
+       return(15);
+}
+
+static int op_rb2hl(void)              /* RES 2,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~4);
+       return(15);
+}
+
+static int op_rb3hl(void)              /* RES 3,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~8);
+       return(15);
+}
+
+static int op_rb4hl(void)              /* RES 4,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~16);
+       return(15);
+}
+
+static int op_rb5hl(void)              /* RES 5,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~32);
+       return(15);
+}
+
+static int op_rb6hl(void)              /* RES 6,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~64);
+       return(15);
+}
+
+static int op_rb7hl(void)              /* RES 7,(HL) */
+{
+       memwrt((H << 8) + L, memrdr((H << 8) + L) & ~128);
+       return(15);
+}
+
+static int op_tb0a(void)               /* BIT 0,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1a(void)               /* BIT 1,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2a(void)               /* BIT 2,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3a(void)               /* BIT 3,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4a(void)               /* BIT 4,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5a(void)               /* BIT 5,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6a(void)               /* BIT 6,A */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (A & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7a(void)               /* BIT 7,A */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (A & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0b(void)               /* BIT 0,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1b(void)               /* BIT 1,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2b(void)               /* BIT 2,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3b(void)               /* BIT 3,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4b(void)               /* BIT 4,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5b(void)               /* BIT 5,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6b(void)               /* BIT 6,B */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (B & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7b(void)               /* BIT 7,B */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (B & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0c(void)               /* BIT 0,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1c(void)               /* BIT 1,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2c(void)               /* BIT 2,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3c(void)               /* BIT 3,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4c(void)               /* BIT 4,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5c(void)               /* BIT 5,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6c(void)               /* BIT 6,C */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (C & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7c(void)               /* BIT 7,C */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (C & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0d(void)               /* BIT 0,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1d(void)               /* BIT 1,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2d(void)               /* BIT 2,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3d(void)               /* BIT 3,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4d(void)               /* BIT 4,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5d(void)               /* BIT 5,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6d(void)               /* BIT 6,D */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (D & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7d(void)               /* BIT 7,D */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (D & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0e(void)               /* BIT 0,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1e(void)               /* BIT 1,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2e(void)               /* BIT 2,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3e(void)               /* BIT 3,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4e(void)               /* BIT 4,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5e(void)               /* BIT 5,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6e(void)               /* BIT 6,E */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (E & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7e(void)               /* BIT 7,E */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (E & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0h(void)               /* BIT 0,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1h(void)               /* BIT 1,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2h(void)               /* BIT 2,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3h(void)               /* BIT 3,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4h(void)               /* BIT 4,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5h(void)               /* BIT 5,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6h(void)               /* BIT 6,H */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (H & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7h(void)               /* BIT 7,H */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (H & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0l(void)               /* BIT 0,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb1l(void)               /* BIT 1,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb2l(void)               /* BIT 2,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb3l(void)               /* BIT 3,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb4l(void)               /* BIT 4,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb5l(void)               /* BIT 5,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb6l(void)               /* BIT 6,L */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (L & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG));
+       return(8);
+}
+
+static int op_tb7l(void)               /* BIT 7,L */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (L & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(8);
+}
+
+static int op_tb0hl(void)              /* BIT 0,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 1) ? (F &= ~(Z_FLAG | P_FLAG))
+                                  : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb1hl(void)              /* BIT 1,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 2) ? (F &= ~(Z_FLAG | P_FLAG))
+                                  : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb2hl(void)              /* BIT 2,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 4) ? (F &= ~(Z_FLAG | P_FLAG))
+                                  : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb3hl(void)              /* BIT 3,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 8) ? (F &= ~(Z_FLAG | P_FLAG))
+                                  : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb4hl(void)              /* BIT 4,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 16) ? (F &= ~(Z_FLAG | P_FLAG))
+                                   : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb5hl(void)              /* BIT 5,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 32) ? (F &= ~(Z_FLAG | P_FLAG))
+                                   : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb6hl(void)              /* BIT 6,(HL) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr((H << 8) + L) & 64) ? (F &= ~(Z_FLAG | P_FLAG))
+                                   : (F |= (Z_FLAG | P_FLAG));
+       return(12);
+}
+
+static int op_tb7hl(void)              /* BIT 7,(HL) */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (memrdr((H << 8) + L) & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(12);
+}
+
+/**********************************************************************/
+/**********************************************************************/
+/*********       UNDOCUMENTED Z80 INSTRUCTIONS, BEWARE!      **********/
+/**********************************************************************/
+/**********************************************************************/
+
+#ifdef Z80_UNDOC
+
+static int op_undoc_slla(void)         /* SLL A */
+{
+       if (u_flag)
+               trap_cb();
+
+       (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = A << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_sllb(void)         /* SLL B */
+{
+       if (u_flag)
+               trap_cb();
+
+       (B & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       B = B << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_sllc(void)         /* SLL C */
+{
+       if (u_flag)
+               trap_cb();
+
+       (C & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       C = C << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_slld(void)         /* SLL D */
+{
+       if (u_flag)
+               trap_cb();
+
+       (D & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       D = D << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_slle(void)         /* SLL E */
+{
+       if (u_flag)
+               trap_cb();
+
+       (E & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       E = E << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_sllh(void)         /* SLL H */
+{
+       if (u_flag)
+               trap_cb();
+
+       (H & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       H = H << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_slll(void)         /* SLL L */
+{
+       if (u_flag)
+               trap_cb();
+
+       (L & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       L = L << 1 | 1;
+       F &= ~(H_FLAG | N_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(8);
+}
+
+static int op_undoc_sllhl(void)                /* SLL (HL) */
+{
+       register BYTE P;
+       WORD addr;
+
+       if (u_flag)
+               trap_cb();
+
+       addr = (H << 8) + L;
+       P = memrdr(addr);
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P = (P << 1) | 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(15);
+}
+
+#endif
diff --git a/sim/sim3.c b/sim/sim3.c
new file mode 100644 (file)
index 0000000..65af0c3
--- /dev/null
@@ -0,0 +1,1100 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates multi byte opcodes
+ *     starting with 0xdd
+ */
+
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_dd(void);
+static int op_popix(void), op_pusix(void);
+static int op_jpix(void);
+static int op_exspx(void);
+static int op_ldspx(void);
+static int op_ldixnn(void), op_ldixinn(void), op_ldinx(void);
+static int op_adaxd(void), op_acaxd(void), op_suaxd(void), op_scaxd(void);
+static int op_andxd(void), op_xorxd(void), op_orxd(void), op_cpxd(void);
+static int op_decxd(void), op_incxd(void);
+static int op_addxb(void), op_addxd(void), op_addxs(void), op_addxx(void);
+static int op_incix(void), op_decix(void);
+static int op_ldaxd(void), op_ldbxd(void), op_ldcxd(void);
+static int op_lddxd(void), op_ldexd(void);
+static int op_ldhxd(void), op_ldlxd(void);
+static int op_ldxda(void), op_ldxdb(void), op_ldxdc(void);
+static int op_ldxdd(void), op_ldxde(void);
+static int op_ldxdh(void), op_ldxdl(void), op_ldxdn(void);
+extern int op_ddcb_handel(void);
+
+#ifdef Z80_UNDOC
+static int op_undoc_ldcixh(void);
+static int op_undoc_lddixl(void);
+static int op_undoc_ldixlc(void), op_undoc_ldixld(void);
+static int op_undoc_ldixha(void), op_undoc_ldixla(void);
+static int op_undoc_ldixhc(void);
+static int op_undoc_ldaixl(void), op_undoc_ldaixh(void);
+static int op_undoc_cpixl(void);
+static int op_undoc_acaixl(void), op_undoc_acaixh(void);
+static int op_undoc_scaixl(void), op_undoc_scaixh(void);
+static int op_undoc_oraixl(void), op_undoc_oraixh(void);
+static int op_undoc_andixl(void), op_undoc_andixh(void);
+static int op_undoc_incixl(void), op_undoc_incixh(void);
+#endif
+
+long op_dd_handel(void)
+{
+       register int t;
+
+       static int (*op_dd[256]) (void) = {
+               trap_dd,                        /* 0x00 */
+               trap_dd,                        /* 0x01 */
+               trap_dd,                        /* 0x02 */
+               trap_dd,                        /* 0x03 */
+               trap_dd,                        /* 0x04 */
+               trap_dd,                        /* 0x05 */
+               trap_dd,                        /* 0x06 */
+               trap_dd,                        /* 0x07 */
+               trap_dd,                        /* 0x08 */
+               op_addxb,                       /* 0x09 */
+               trap_dd,                        /* 0x0a */
+               trap_dd,                        /* 0x0b */
+               trap_dd,                        /* 0x0c */
+               trap_dd,                        /* 0x0d */
+               trap_dd,                        /* 0x0e */
+               trap_dd,                        /* 0x0f */
+               trap_dd,                        /* 0x10 */
+               trap_dd,                        /* 0x11 */
+               trap_dd,                        /* 0x12 */
+               trap_dd,                        /* 0x13 */
+               trap_dd,                        /* 0x14 */
+               trap_dd,                        /* 0x15 */
+               trap_dd,                        /* 0x16 */
+               trap_dd,                        /* 0x17 */
+               trap_dd,                        /* 0x18 */
+               op_addxd,                       /* 0x19 */
+               trap_dd,                        /* 0x1a */
+               trap_dd,                        /* 0x1b */
+               trap_dd,                        /* 0x1c */
+               trap_dd,                        /* 0x1d */
+               trap_dd,                        /* 0x1e */
+               trap_dd,                        /* 0x1f */
+               trap_dd,                        /* 0x20 */
+               op_ldixnn,                      /* 0x21 */
+               op_ldinx,                       /* 0x22 */
+               op_incix,                       /* 0x23 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x24 */
+#else
+               op_undoc_incixh,
+#endif
+               trap_dd,                        /* 0x25 */
+               trap_dd,                        /* 0x26 */
+               trap_dd,                        /* 0x27 */
+               trap_dd,                        /* 0x28 */
+               op_addxx,                       /* 0x29 */
+               op_ldixinn,                     /* 0x2a */
+               op_decix,                       /* 0x2b */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x2c */
+#else
+               op_undoc_incixl,
+#endif
+               trap_dd,                        /* 0x2d */
+               trap_dd,                        /* 0x2e */
+               trap_dd,                        /* 0x2f */
+               trap_dd,                        /* 0x30 */
+               trap_dd,                        /* 0x31 */
+               trap_dd,                        /* 0x32 */
+               trap_dd,                        /* 0x33 */
+               op_incxd,                       /* 0x34 */
+               op_decxd,                       /* 0x35 */
+               op_ldxdn,                       /* 0x36 */
+               trap_dd,                        /* 0x37 */
+               trap_dd,                        /* 0x38 */
+               op_addxs,                       /* 0x39 */
+               trap_dd,                        /* 0x3a */
+               trap_dd,                        /* 0x3b */
+               trap_dd,                        /* 0x3c */
+               trap_dd,                        /* 0x3d */
+               trap_dd,                        /* 0x3e */
+               trap_dd,                        /* 0x3f */
+               trap_dd,                        /* 0x40 */
+               trap_dd,                        /* 0x41 */
+               trap_dd,                        /* 0x42 */
+               trap_dd,                        /* 0x43 */
+               trap_dd,                        /* 0x44 */
+               trap_dd,                        /* 0x45 */
+               op_ldbxd,                       /* 0x46 */
+               trap_dd,                        /* 0x47 */
+               trap_dd,                        /* 0x48 */
+               trap_dd,                        /* 0x49 */
+               trap_dd,                        /* 0x4a */
+               trap_dd,                        /* 0x4b */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x4c */
+#else
+               op_undoc_ldcixh,
+#endif
+               trap_dd,                        /* 0x4d */
+               op_ldcxd,                       /* 0x4e */
+               trap_dd,                        /* 0x4f */
+               trap_dd,                        /* 0x50 */
+               trap_dd,                        /* 0x51 */
+               trap_dd,                        /* 0x52 */
+               trap_dd,                        /* 0x53 */
+               trap_dd,                        /* 0x54 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x55 */
+#else
+               op_undoc_lddixl,
+#endif
+               op_lddxd,                       /* 0x56 */
+               trap_dd,                        /* 0x57 */
+               trap_dd,                        /* 0x58 */
+               trap_dd,                        /* 0x59 */
+               trap_dd,                        /* 0x5a */
+               trap_dd,                        /* 0x5b */
+               trap_dd,                        /* 0x5c */
+               trap_dd,                        /* 0x5d */
+               op_ldexd,                       /* 0x5e */
+               trap_dd,                        /* 0x5f */
+               trap_dd,                        /* 0x60 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x61 */
+#else
+               op_undoc_ldixhc,
+#endif
+               trap_dd,                        /* 0x62 */
+               trap_dd,                        /* 0x63 */
+               trap_dd,                        /* 0x64 */
+               trap_dd,                        /* 0x65 */
+               op_ldhxd,                       /* 0x66 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x67 */
+#else
+               op_undoc_ldixha,
+#endif
+               trap_dd,                        /* 0x68 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x69 */
+#else
+               op_undoc_ldixlc,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x6a */
+#else
+               op_undoc_ldixld,
+#endif
+               trap_dd,                        /* 0x6b */
+               trap_dd,                        /* 0x6c */
+               trap_dd,                        /* 0x6d */
+               op_ldlxd,                       /* 0x6e */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x6f */
+#else
+               op_undoc_ldixla,
+#endif
+               op_ldxdb,                       /* 0x70 */
+               op_ldxdc,                       /* 0x71 */
+               op_ldxdd,                       /* 0x72 */
+               op_ldxde,                       /* 0x73 */
+               op_ldxdh,                       /* 0x74 */
+               op_ldxdl,                       /* 0x75 */
+               trap_dd,                        /* 0x76 */
+               op_ldxda,                       /* 0x77 */
+               trap_dd,                        /* 0x78 */
+               trap_dd,                        /* 0x79 */
+               trap_dd,                        /* 0x7a */
+               trap_dd,                        /* 0x7b */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x7c */
+#else
+               op_undoc_ldaixh,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x7d */
+#else
+               op_undoc_ldaixl,
+#endif
+               op_ldaxd,                       /* 0x7e */
+               trap_dd,                        /* 0x7f */
+               trap_dd,                        /* 0x80 */
+               trap_dd,                        /* 0x81 */
+               trap_dd,                        /* 0x82 */
+               trap_dd,                        /* 0x83 */
+               trap_dd,                        /* 0x84 */
+               trap_dd,                        /* 0x85 */
+               op_adaxd,                       /* 0x86 */
+               trap_dd,                        /* 0x87 */
+               trap_dd,                        /* 0x88 */
+               trap_dd,                        /* 0x89 */
+               trap_dd,                        /* 0x8a */
+               trap_dd,                        /* 0x8b */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x8c */
+#else
+               op_undoc_acaixh,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x8d */
+#else
+               op_undoc_acaixl,
+#endif
+               op_acaxd,                       /* 0x8e */
+               trap_dd,                        /* 0x8f */
+               trap_dd,                        /* 0x90 */
+               trap_dd,                        /* 0x91 */
+               trap_dd,                        /* 0x92 */
+               trap_dd,                        /* 0x93 */
+               trap_dd,                        /* 0x94 */
+               trap_dd,                        /* 0x95 */
+               op_suaxd,                       /* 0x96 */
+               trap_dd,                        /* 0x97 */
+               trap_dd,                        /* 0x98 */
+               trap_dd,                        /* 0x99 */
+               trap_dd,                        /* 0x9a */
+               trap_dd,                        /* 0x9b */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x9c */
+#else
+               op_undoc_scaixh,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0x9d */
+#else
+               op_undoc_scaixl,
+#endif
+               op_scaxd,                       /* 0x9e */
+               trap_dd,                        /* 0x9f */
+               trap_dd,                        /* 0xa0 */
+               trap_dd,                        /* 0xa1 */
+               trap_dd,                        /* 0xa2 */
+               trap_dd,                        /* 0xa3 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0xa4 */
+#else
+               op_undoc_andixh,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0xa5 */
+#else
+               op_undoc_andixl,
+#endif
+               op_andxd,                       /* 0xa6 */
+               trap_dd,                        /* 0xa7 */
+               trap_dd,                        /* 0xa8 */
+               trap_dd,                        /* 0xa9 */
+               trap_dd,                        /* 0xaa */
+               trap_dd,                        /* 0xab */
+               trap_dd,                        /* 0xac */
+               trap_dd,                        /* 0xad */
+               op_xorxd,                       /* 0xae */
+               trap_dd,                        /* 0xaf */
+               trap_dd,                        /* 0xb0 */
+               trap_dd,                        /* 0xb1 */
+               trap_dd,                        /* 0xb2 */
+               trap_dd,                        /* 0xb3 */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0xb4 */
+#else
+               op_undoc_oraixh,
+#endif
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0xb5 */
+#else
+               op_undoc_oraixl,
+#endif
+               op_orxd,                        /* 0xb6 */
+               trap_dd,                        /* 0xb7 */
+               trap_dd,                        /* 0xb8 */
+               trap_dd,                        /* 0xb9 */
+               trap_dd,                        /* 0xba */
+               trap_dd,                        /* 0xbb */
+               trap_dd,                        /* 0xbc */
+#ifndef Z80_UNDOC
+               trap_dd,                        /* 0xbd */
+#else
+               op_undoc_cpixl,
+#endif
+               op_cpxd,                        /* 0xbe */
+               trap_dd,                        /* 0xbf */
+               trap_dd,                        /* 0xc0 */
+               trap_dd,                        /* 0xc1 */
+               trap_dd,                        /* 0xc2 */
+               trap_dd,                        /* 0xc3 */
+               trap_dd,                        /* 0xc4 */
+               trap_dd,                        /* 0xc5 */
+               trap_dd,                        /* 0xc6 */
+               trap_dd,                        /* 0xc7 */
+               trap_dd,                        /* 0xc8 */
+               trap_dd,                        /* 0xc9 */
+               trap_dd,                        /* 0xca */
+               op_ddcb_handel,                 /* 0xcb */
+               trap_dd,                        /* 0xcc */
+               trap_dd,                        /* 0xcd */
+               trap_dd,                        /* 0xce */
+               trap_dd,                        /* 0xcf */
+               trap_dd,                        /* 0xd0 */
+               trap_dd,                        /* 0xd1 */
+               trap_dd,                        /* 0xd2 */
+               trap_dd,                        /* 0xd3 */
+               trap_dd,                        /* 0xd4 */
+               trap_dd,                        /* 0xd5 */
+               trap_dd,                        /* 0xd6 */
+               trap_dd,                        /* 0xd7 */
+               trap_dd,                        /* 0xd8 */
+               trap_dd,                        /* 0xd9 */
+               trap_dd,                        /* 0xda */
+               trap_dd,                        /* 0xdb */
+               trap_dd,                        /* 0xdc */
+               trap_dd,                        /* 0xdd */
+               trap_dd,                        /* 0xde */
+               trap_dd,                        /* 0xdf */
+               trap_dd,                        /* 0xe0 */
+               op_popix,                       /* 0xe1 */
+               trap_dd,                        /* 0xe2 */
+               op_exspx,                       /* 0xe3 */
+               trap_dd,                        /* 0xe4 */
+               op_pusix,                       /* 0xe5 */
+               trap_dd,                        /* 0xe6 */
+               trap_dd,                        /* 0xe7 */
+               trap_dd,                        /* 0xe8 */
+               op_jpix,                        /* 0xe9 */
+               trap_dd,                        /* 0xea */
+               trap_dd,                        /* 0xeb */
+               trap_dd,                        /* 0xec */
+               trap_dd,                        /* 0xed */
+               trap_dd,                        /* 0xee */
+               trap_dd,                        /* 0xef */
+               trap_dd,                        /* 0xf0 */
+               trap_dd,                        /* 0xf1 */
+               trap_dd,                        /* 0xf2 */
+               trap_dd,                        /* 0xf3 */
+               trap_dd,                        /* 0xf4 */
+               trap_dd,                        /* 0xf5 */
+               trap_dd,                        /* 0xf6 */
+               trap_dd,                        /* 0xf7 */
+               trap_dd,                        /* 0xf8 */
+               op_ldspx,                       /* 0xf9 */
+               trap_dd,                        /* 0xfa */
+               trap_dd,                        /* 0xfb */
+               trap_dd,                        /* 0xfc */
+               trap_dd,                        /* 0xfd */
+               trap_dd,                        /* 0xfe */
+               trap_dd                         /* 0xff */
+       };
+
+#ifdef BUS_8080
+       /* M1 opcode fetch */
+       cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+       m1_step = 1;
+#endif
+#ifdef FRONTPANEL
+       /* update frontpanel */
+       fp_clock++;
+       fp_sampleLightGroup(0, 0);
+#endif
+
+       t = (*op_dd[memrdr(PC++)]) ();  /* execute next opcode */
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xdd of a multi byte opcode.
+ */
+static int trap_dd(void)
+{
+       cpu_error = OPTRAP2;
+       cpu_state = STOPPED;
+       return(0);
+}
+
+static int op_popix(void)              /* POP IX */
+{
+       IX = memrdr(SP++);
+       IX += memrdr(SP++) << 8;
+       return(14);
+}
+
+static int op_pusix(void)              /* PUSH IX */
+{
+       memwrt(--SP, IX >> 8);
+       memwrt(--SP, IX);
+       return(15);
+}
+
+static int op_jpix(void)               /* JP (IX) */
+{
+       PC = IX;
+       return(8);
+}
+
+static int op_exspx(void)              /* EX (SP),IX */
+{
+       register WORD i;
+
+       i = memrdr(SP) + (memrdr(SP + 1) << 8);
+       memwrt(SP, IX);
+       memwrt(SP + 1, IX >> 8);
+       IX = i;
+       return(23);
+}
+
+static int op_ldspx(void)              /* LD SP,IX */
+{
+       SP = IX;
+       return(10);
+}
+
+static int op_ldixnn(void)             /* LD IX,nn */
+{
+       IX = memrdr(PC++);
+       IX += memrdr(PC++) << 8;
+       return(14);
+}
+
+static int op_ldixinn(void)            /* LD IX,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       IX = memrdr(i);
+       IX += memrdr(i + 1) << 8;
+       return(20);
+}
+
+static int op_ldinx(void)              /* LD (nn),IX */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i, IX);
+       memwrt(i + 1, IX >> 8);
+       return(20);
+}
+
+static int op_adaxd(void)              /* ADD A,(IX+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IX + (signed char) memrdr(PC++));
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(19);
+}
+
+static int op_acaxd(void)              /* ADC A,(IX+d) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(IX + (signed char) memrdr(PC++));
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(19);
+}
+
+static int op_suaxd(void)              /* SUB A,(IX+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IX + (signed char) memrdr(PC++));
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_scaxd(void)              /* SBC A,(IX+d) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(IX + (signed char) memrdr(PC++));
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_andxd(void)              /* AND (IX+d) */
+{
+       A &= memrdr(IX + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_xorxd(void)              /* XOR (IX+d) */
+{
+       A ^= memrdr(IX + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_orxd(void)               /* OR (IX+d) */
+{
+       A |= memrdr(IX + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_cpxd(void)               /* CP (IX+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IX + (signed char) memrdr(PC++));
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_incxd(void)              /* INC (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IX + (signed char) memrdr(PC++);
+       P = memrdr(addr);
+       P++;
+       memwrt(addr, P);
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F  |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(23);
+}
+
+static int op_decxd(void)              /* DEC (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IX + (signed char) memrdr(PC++);
+       P = memrdr(addr);
+       P--;
+       memwrt(addr, P);
+       ((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F  &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(23);
+}
+
+static int op_addxb(void)              /* ADD IX,BC */
+{
+       register int carry;
+       BYTE ixl = IX & 0xff;
+       BYTE ixh = IX >> 8;
+       
+       carry = (ixl + C > 255) ? 1 : 0;
+       ixl += C;
+       ((ixh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                               : (F &= ~H_FLAG);
+       (ixh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       ixh += B + carry;
+       IX = (ixh << 8) + ixl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addxd(void)              /* ADD IX,DE */
+{
+       register int carry;
+       BYTE ixl = IX & 0xff;
+       BYTE ixh = IX >> 8;
+       
+       carry = (ixl + E > 255) ? 1 : 0;
+       ixl += E;
+       ((ixh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                               : (F &= ~H_FLAG);
+       (ixh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       ixh += D + carry;
+       IX = (ixh << 8) + ixl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addxs(void)              /* ADD IX,SP */
+{
+       register int carry;
+       BYTE ixl = IX & 0xff;
+       BYTE ixh = IX >> 8;
+       BYTE spl = SP & 0xff;
+       BYTE sph = SP >> 8;
+       
+       carry = (ixl + spl > 255) ? 1 : 0;
+       ixl += spl;
+       ((ixh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       (ixh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       ixh += sph + carry;
+       IX = (ixh << 8) + ixl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addxx(void)              /* ADD IX,IX */
+{
+       register int carry;
+       BYTE ixl = IX & 0xff;
+       BYTE ixh = IX >> 8;
+       
+       carry = (ixl << 1 > 255) ? 1 : 0;
+       ixl <<= 1;
+       ((ixh & 0xf) + (ixh & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       (ixh + ixh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       ixh += ixh + carry;
+       IX = (ixh << 8) + ixl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_incix(void)              /* INC IX */
+{
+       IX++;
+       return(10);
+}
+
+static int op_decix(void)              /* DEC IX */
+{
+       IX--;
+       return(10);
+}
+
+static int op_ldaxd(void)              /* LD A,(IX+d) */
+{
+       A = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldbxd(void)              /* LD B,(IX+d) */
+{
+       B = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldcxd(void)              /* LD C,(IX+d) */
+{
+       C = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_lddxd(void)              /* LD D,(IX+d) */
+{
+       D = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldexd(void)              /* LD E,(IX+d) */
+{
+       E = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldhxd(void)              /* LD H,(IX+d) */
+{
+       H = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldlxd(void)              /* LD L,(IX+d) */
+{
+       L = memrdr(IX + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldxda(void)              /* LD (IX+d),A */
+{
+       memwrt(IX + (signed char) memrdr(PC++), A);
+       return(19);
+}
+
+static int op_ldxdb(void)              /* LD (IX+d),B */
+{
+       memwrt(IX + (signed char) memrdr(PC++), B);
+       return(19);
+}
+
+static int op_ldxdc(void)              /* LD (IX+d),C */
+{
+       memwrt(IX + (signed char) memrdr(PC++), C);
+       return(19);
+}
+
+static int op_ldxdd(void)              /* LD (IX+d),D */
+{
+       memwrt(IX + (signed char) memrdr(PC++), D);
+       return(19);
+}
+
+static int op_ldxde(void)              /* LD (IX+d),E */
+{
+       memwrt(IX + (signed char) memrdr(PC++), E);
+       return(19);
+}
+
+static int op_ldxdh(void)              /* LD (IX+d),H */
+{
+       memwrt(IX + (signed char) memrdr(PC++), H);
+       return(19);
+}
+
+static int op_ldxdl(void)              /* LD (IX+d),L */
+{
+       memwrt(IX + (signed char) memrdr(PC++), L);
+       return(19);
+}
+
+static int op_ldxdn(void)              /* LD (IX+d),n */
+{
+       register signed char d;
+
+       d = memrdr(PC++);
+       memwrt(IX + d, memrdr(PC++));
+       return(19);
+}
+
+/**********************************************************************/
+/**********************************************************************/
+/*********       UNDOCUMENTED Z80 INSTRUCTIONS, BEWARE!      **********/
+/**********************************************************************/
+/**********************************************************************/
+
+#ifdef Z80_UNDOC
+
+static int op_undoc_ldaixl(void)       /* LD A,IXL */
+{
+       if (u_flag)
+               trap_dd();
+
+       A = IX & 0xff;
+       return(8);
+}
+
+static int op_undoc_ldaixh(void)       /* LD A,IXH */
+{
+       if (u_flag)
+               trap_dd();
+
+       A = IX >> 8;
+       return(8);
+}
+
+static int op_undoc_ldcixh(void)       /* LD C,IXH */
+{
+       if (u_flag)
+               trap_dd();
+
+       C = IX >> 8;
+       return(8);
+}
+
+static int op_undoc_lddixl(void)       /* LD D,IXL */
+{
+       if (u_flag)
+               trap_dd();
+
+       D = IX & 0xff;
+       return(8);
+}
+
+static int op_undoc_ldixha(void)       /* LD IXH,A */
+{
+       if (u_flag)
+               trap_dd();
+
+       IX = (IX & 0x00ff) | (A << 8);
+       return(8);
+}
+
+static int op_undoc_ldixhc(void)       /* LD IXH,C */
+{
+       if (u_flag)
+               trap_dd();
+
+       IX = (IX & 0x00ff) | (C << 8);
+       return(8);
+}
+
+static int op_undoc_ldixla(void)       /* LD IXL,A */
+{
+       if (u_flag)
+               trap_dd();
+
+       IX = (IX & 0xff00) | A;
+       return(8);
+}
+
+static int op_undoc_ldixlc(void)       /* LD IXL,C */
+{
+       if (u_flag)
+               trap_dd();
+
+       IX = (IX & 0xff00) | C;
+       return(8);
+}
+
+static int op_undoc_ldixld(void)       /* LD IXL,D */
+{
+       if (u_flag)
+               trap_dd();
+
+       IX = (IX & 0xff00) | D;
+       return(8);
+}
+
+static int op_undoc_cpixl(void)                /* CP IXL */
+{
+       register int i;
+       register BYTE P;
+
+       if (u_flag)
+               trap_dd();
+
+       P = IX & 0xff;
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(8);
+}
+
+static int op_undoc_acaixl(void)       /* ADC A,IXL */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = IX & 0xff;
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(8);
+}
+
+static int op_undoc_acaixh(void)       /* ADC A,IXH */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = IX >> 8;
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(8);
+}
+
+static int op_undoc_scaixl(void)       /* SBC A,IXL */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = IX & 0xff;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(8);
+}
+
+static int op_undoc_scaixh(void)       /* SBC A,IXH */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = IX >> 8;
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(8);
+}
+
+static int op_undoc_oraixl(void)       /* OR IXL */
+{
+       A |= IX & 0xff;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(8);
+}
+
+static int op_undoc_oraixh(void)       /* OR IXH */
+{
+       A |= IX >> 8;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(8);
+}
+
+static int op_undoc_andixl(void)       /* AND IXL */
+{
+       A &= IX & 0xff;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(8);
+}
+
+static int op_undoc_andixh(void)       /* AND IXH */
+{
+       A &= IX >> 8;
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(8);
+}
+
+static int op_undoc_incixl(void)       /* INC IXL */
+{
+       register BYTE P;
+
+       P = IX & 0xff;
+       P++;
+       IX = (IX & 0xff00) | P;
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(8);
+}
+
+static int op_undoc_incixh(void)       /* INC IXH */
+{
+       register BYTE P;
+
+       P = IX >> 8;
+       P++;
+       IX = (IX & 0x00ff) | (P << 8);
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(8);
+}
+
+#endif
diff --git a/sim/sim4.c b/sim/sim4.c
new file mode 100644 (file)
index 0000000..4b32657
--- /dev/null
@@ -0,0 +1,1259 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates multi byte opcodes
+ *     starting with 0xed
+ */
+
+#include <stdio.h>
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_ed(void);
+static int op_im0(void), op_im1(void), op_im2(void);
+static int op_reti(void), op_retn(void);
+static int op_neg(void);
+static int op_inaic(void), op_inbic(void), op_incic(void);
+static int op_indic(void), op_ineic(void);
+static int op_inhic(void), op_inlic(void);
+static int op_outca(void), op_outcb(void), op_outcc(void);
+static int op_outcd(void), op_outce(void);
+static int op_outch(void), op_outcl(void);
+static int op_ini(void), op_inir(void), op_ind(void), op_indr(void);
+static int op_outi(void), op_otir(void), op_outd(void), op_otdr(void);
+static int op_ldai(void), op_ldar(void), op_ldia(void), op_ldra(void);
+static int op_ldbcinn(void), op_lddeinn(void);
+static int op_ldhlinn(void), op_ldspinn(void);
+static int op_ldinbc(void), op_ldinde(void), op_ldinhl(void), op_ldinsp(void);
+static int op_adchb(void), op_adchd(void), op_adchh(void), op_adchs(void);
+static int op_sbchb(void), op_sbchd(void), op_sbchh(void), op_sbchs(void);
+static int op_ldi(void), op_ldir(void), op_ldd(void), op_lddr(void);
+static int op_cpi(void), op_cpir(void), op_cpdop(void), op_cpdr(void);
+static int op_oprld(void), op_oprrd(void);
+
+int op_ed_handel(void)
+{
+       register int t;
+
+       static int (*op_ed[256]) (void) = {
+               trap_ed,                        /* 0x00 */
+               trap_ed,                        /* 0x01 */
+               trap_ed,                        /* 0x02 */
+               trap_ed,                        /* 0x03 */
+               trap_ed,                        /* 0x04 */
+               trap_ed,                        /* 0x05 */
+               trap_ed,                        /* 0x06 */
+               trap_ed,                        /* 0x07 */
+               trap_ed,                        /* 0x08 */
+               trap_ed,                        /* 0x09 */
+               trap_ed,                        /* 0x0a */
+               trap_ed,                        /* 0x0b */
+               trap_ed,                        /* 0x0c */
+               trap_ed,                        /* 0x0d */
+               trap_ed,                        /* 0x0e */
+               trap_ed,                        /* 0x0f */
+               trap_ed,                        /* 0x10 */
+               trap_ed,                        /* 0x11 */
+               trap_ed,                        /* 0x12 */
+               trap_ed,                        /* 0x13 */
+               trap_ed,                        /* 0x14 */
+               trap_ed,                        /* 0x15 */
+               trap_ed,                        /* 0x16 */
+               trap_ed,                        /* 0x17 */
+               trap_ed,                        /* 0x18 */
+               trap_ed,                        /* 0x19 */
+               trap_ed,                        /* 0x1a */
+               trap_ed,                        /* 0x1b */
+               trap_ed,                        /* 0x1c */
+               trap_ed,                        /* 0x1d */
+               trap_ed,                        /* 0x1e */
+               trap_ed,                        /* 0x1f */
+               trap_ed,                        /* 0x20 */
+               trap_ed,                        /* 0x21 */
+               trap_ed,                        /* 0x22 */
+               trap_ed,                        /* 0x23 */
+               trap_ed,                        /* 0x24 */
+               trap_ed,                        /* 0x25 */
+               trap_ed,                        /* 0x26 */
+               trap_ed,                        /* 0x27 */
+               trap_ed,                        /* 0x28 */
+               trap_ed,                        /* 0x29 */
+               trap_ed,                        /* 0x2a */
+               trap_ed,                        /* 0x2b */
+               trap_ed,                        /* 0x2c */
+               trap_ed,                        /* 0x2d */
+               trap_ed,                        /* 0x2e */
+               trap_ed,                        /* 0x2f */
+               trap_ed,                        /* 0x30 */
+               trap_ed,                        /* 0x31 */
+               trap_ed,                        /* 0x32 */
+               trap_ed,                        /* 0x33 */
+               trap_ed,                        /* 0x34 */
+               trap_ed,                        /* 0x35 */
+               trap_ed,                        /* 0x36 */
+               trap_ed,                        /* 0x37 */
+               trap_ed,                        /* 0x38 */
+               trap_ed,                        /* 0x39 */
+               trap_ed,                        /* 0x3a */
+               trap_ed,                        /* 0x3b */
+               trap_ed,                        /* 0x3c */
+               trap_ed,                        /* 0x3d */
+               trap_ed,                        /* 0x3e */
+               trap_ed,                        /* 0x3f */
+               op_inbic,                       /* 0x40 */
+               op_outcb,                       /* 0x41 */
+               op_sbchb,                       /* 0x42 */
+               op_ldinbc,                      /* 0x43 */
+               op_neg,                         /* 0x44 */
+               op_retn,                        /* 0x45 */
+               op_im0,                         /* 0x46 */
+               op_ldia,                        /* 0x47 */
+               op_incic,                       /* 0x48 */
+               op_outcc,                       /* 0x49 */
+               op_adchb,                       /* 0x4a */
+               op_ldbcinn,                     /* 0x4b */
+               trap_ed,                        /* 0x4c */
+               op_reti,                        /* 0x4d */
+               trap_ed,                        /* 0x4e */
+               op_ldra,                        /* 0x4f */
+               op_indic,                       /* 0x50 */
+               op_outcd,                       /* 0x51 */
+               op_sbchd,                       /* 0x52 */
+               op_ldinde,                      /* 0x53 */
+               trap_ed,                        /* 0x54 */
+               trap_ed,                        /* 0x55 */
+               op_im1,                         /* 0x56 */
+               op_ldai,                        /* 0x57 */
+               op_ineic,                       /* 0x58 */
+               op_outce,                       /* 0x59 */
+               op_adchd,                       /* 0x5a */
+               op_lddeinn,                     /* 0x5b */
+               trap_ed,                        /* 0x5c */
+               trap_ed,                        /* 0x5d */
+               op_im2,                         /* 0x5e */
+               op_ldar,                        /* 0x5f */
+               op_inhic,                       /* 0x60 */
+               op_outch,                       /* 0x61 */
+               op_sbchh,                       /* 0x62 */
+               op_ldinhl,                      /* 0x63 */
+               trap_ed,                        /* 0x64 */
+               trap_ed,                        /* 0x65 */
+               trap_ed,                        /* 0x66 */
+               op_oprrd,                       /* 0x67 */
+               op_inlic,                       /* 0x68 */
+               op_outcl,                       /* 0x69 */
+               op_adchh,                       /* 0x6a */
+               op_ldhlinn,                     /* 0x6b */
+               trap_ed,                        /* 0x6c */
+               trap_ed,                        /* 0x6d */
+               trap_ed,                        /* 0x6e */
+               op_oprld,                       /* 0x6f */
+               trap_ed,                        /* 0x70 */
+               trap_ed,                        /* 0x71 */
+               op_sbchs,                       /* 0x72 */
+               op_ldinsp,                      /* 0x73 */
+               trap_ed,                        /* 0x74 */
+               trap_ed,                        /* 0x75 */
+               trap_ed,                        /* 0x76 */
+               trap_ed,                        /* 0x77 */
+               op_inaic,                       /* 0x78 */
+               op_outca,                       /* 0x79 */
+               op_adchs,                       /* 0x7a */
+               op_ldspinn,                     /* 0x7b */
+               trap_ed,                        /* 0x7c */
+               trap_ed,                        /* 0x7d */
+               trap_ed,                        /* 0x7e */
+               trap_ed,                        /* 0x7f */
+               trap_ed,                        /* 0x80 */
+               trap_ed,                        /* 0x81 */
+               trap_ed,                        /* 0x82 */
+               trap_ed,                        /* 0x83 */
+               trap_ed,                        /* 0x84 */
+               trap_ed,                        /* 0x85 */
+               trap_ed,                        /* 0x86 */
+               trap_ed,                        /* 0x87 */
+               trap_ed,                        /* 0x88 */
+               trap_ed,                        /* 0x89 */
+               trap_ed,                        /* 0x8a */
+               trap_ed,                        /* 0x8b */
+               trap_ed,                        /* 0x8c */
+               trap_ed,                        /* 0x8d */
+               trap_ed,                        /* 0x8e */
+               trap_ed,                        /* 0x8f */
+               trap_ed,                        /* 0x90 */
+               trap_ed,                        /* 0x91 */
+               trap_ed,                        /* 0x92 */
+               trap_ed,                        /* 0x93 */
+               trap_ed,                        /* 0x94 */
+               trap_ed,                        /* 0x95 */
+               trap_ed,                        /* 0x96 */
+               trap_ed,                        /* 0x97 */
+               trap_ed,                        /* 0x98 */
+               trap_ed,                        /* 0x99 */
+               trap_ed,                        /* 0x9a */
+               trap_ed,                        /* 0x9b */
+               trap_ed,                        /* 0x9c */
+               trap_ed,                        /* 0x9d */
+               trap_ed,                        /* 0x9e */
+               trap_ed,                        /* 0x9f */
+               op_ldi,                         /* 0xa0 */
+               op_cpi,                         /* 0xa1 */
+               op_ini,                         /* 0xa2 */
+               op_outi,                        /* 0xa3 */
+               trap_ed,                        /* 0xa4 */
+               trap_ed,                        /* 0xa5 */
+               trap_ed,                        /* 0xa6 */
+               trap_ed,                        /* 0xa7 */
+               op_ldd,                         /* 0xa8 */
+               op_cpdop,                       /* 0xa9 */
+               op_ind,                         /* 0xaa */
+               op_outd,                        /* 0xab */
+               trap_ed,                        /* 0xac */
+               trap_ed,                        /* 0xad */
+               trap_ed,                        /* 0xae */
+               trap_ed,                        /* 0xaf */
+               op_ldir,                        /* 0xb0 */
+               op_cpir,                        /* 0xb1 */
+               op_inir,                        /* 0xb2 */
+               op_otir,                        /* 0xb3 */
+               trap_ed,                        /* 0xb4 */
+               trap_ed,                        /* 0xb5 */
+               trap_ed,                        /* 0xb6 */
+               trap_ed,                        /* 0xb7 */
+               op_lddr,                        /* 0xb8 */
+               op_cpdr,                        /* 0xb9 */
+               op_indr,                        /* 0xba */
+               op_otdr,                        /* 0xbb */
+               trap_ed,                        /* 0xbc */
+               trap_ed,                        /* 0xbd */
+               trap_ed,                        /* 0xbe */
+               trap_ed,                        /* 0xbf */
+               trap_ed,                        /* 0xc0 */
+               trap_ed,                        /* 0xc1 */
+               trap_ed,                        /* 0xc2 */
+               trap_ed,                        /* 0xc3 */
+               trap_ed,                        /* 0xc4 */
+               trap_ed,                        /* 0xc5 */
+               trap_ed,                        /* 0xc6 */
+               trap_ed,                        /* 0xc7 */
+               trap_ed,                        /* 0xc8 */
+               trap_ed,                        /* 0xc9 */
+               trap_ed,                        /* 0xca */
+               trap_ed,                        /* 0xcb */
+               trap_ed,                        /* 0xcc */
+               trap_ed,                        /* 0xcd */
+               trap_ed,                        /* 0xce */
+               trap_ed,                        /* 0xcf */
+               trap_ed,                        /* 0xd0 */
+               trap_ed,                        /* 0xd1 */
+               trap_ed,                        /* 0xd2 */
+               trap_ed,                        /* 0xd3 */
+               trap_ed,                        /* 0xd4 */
+               trap_ed,                        /* 0xd5 */
+               trap_ed,                        /* 0xd6 */
+               trap_ed,                        /* 0xd7 */
+               trap_ed,                        /* 0xd8 */
+               trap_ed,                        /* 0xd9 */
+               trap_ed,                        /* 0xda */
+               trap_ed,                        /* 0xdb */
+               trap_ed,                        /* 0xdc */
+               trap_ed,                        /* 0xdd */
+               trap_ed,                        /* 0xde */
+               trap_ed,                        /* 0xdf */
+               trap_ed,                        /* 0xe0 */
+               trap_ed,                        /* 0xe1 */
+               trap_ed,                        /* 0xe2 */
+               trap_ed,                        /* 0xe3 */
+               trap_ed,                        /* 0xe4 */
+               trap_ed,                        /* 0xe5 */
+               trap_ed,                        /* 0xe6 */
+               trap_ed,                        /* 0xe7 */
+               trap_ed,                        /* 0xe8 */
+               trap_ed,                        /* 0xe9 */
+               trap_ed,                        /* 0xea */
+               trap_ed,                        /* 0xeb */
+               trap_ed,                        /* 0xec */
+               trap_ed,                        /* 0xed */
+               trap_ed,                        /* 0xee */
+               trap_ed,                        /* 0xef */
+               trap_ed,                        /* 0xf0 */
+               trap_ed,                        /* 0xf1 */
+               trap_ed,                        /* 0xf2 */
+               trap_ed,                        /* 0xf3 */
+               trap_ed,                        /* 0xf4 */
+               trap_ed,                        /* 0xf5 */
+               trap_ed,                        /* 0xf6 */
+               trap_ed,                        /* 0xf7 */
+               trap_ed,                        /* 0xf8 */
+               trap_ed,                        /* 0xf9 */
+               trap_ed,                        /* 0xfa */
+               trap_ed,                        /* 0xfb */
+               trap_ed,                        /* 0xfc */
+               trap_ed,                        /* 0xfd */
+               trap_ed,                        /* 0xfe */
+               trap_ed                         /* 0xff */
+       };
+
+#ifdef BUS_8080
+       /* M1 opcode fetch */
+       cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+       m1_step = 1;
+#endif
+#ifdef FRONTPANEL
+       /* update frontpanel */
+       fp_clock++;
+       fp_sampleLightGroup(0, 0);
+#endif
+
+       t = (*op_ed[memrdr(PC++)]) ();  /* execute next opcode */
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xed of a multi byte opcode.
+ */
+static int trap_ed(void)
+{
+       cpu_error = OPTRAP2;
+       cpu_state = STOPPED;
+       return(0);
+}
+
+static int op_im0(void)                        /* IM 0 */
+{
+       int_mode = 0;
+       return(8);
+}
+
+static int op_im1(void)                        /* IM 1 */
+{
+       int_mode = 1;
+       return(8);
+}
+
+static int op_im2(void)                        /* IM 2 */
+{
+       int_mode = 2;
+       return(8);
+}
+
+static int op_reti(void)               /* RETI */
+{
+       register WORD i;
+
+       i = memrdr(SP++);
+       i += memrdr(SP++) << 8;
+       PC = i;
+       return(14);
+}
+
+static int op_retn(void)               /* RETN */
+{
+       register WORD i;
+
+       i = memrdr(SP++);
+       i += memrdr(SP++) << 8;
+       PC = i;
+       if (IFF & 2)
+               IFF |= 1;
+       return(14);
+}
+
+static int op_neg(void)                        /* NEG */
+{
+       (A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       (A == 0x80) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (0 - ((signed char) A & 0xf) <  0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       A = 0 - A;
+       F |= N_FLAG;
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(8);
+}
+
+static int op_inaic(void)              /* IN A,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       A = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_inbic(void)              /* IN B,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       B = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_incic(void)              /* IN C,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       C = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_indic(void)              /* IN D,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       D = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_ineic(void)              /* IN E,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       E = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_inhic(void)              /* IN H,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       H = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_inlic(void)              /* IN L,(C) */
+{
+       BYTE io_in(BYTE, BYTE);
+
+       L = io_in(C, B);
+       F &= ~(N_FLAG | H_FLAG);
+       (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(12);
+}
+
+static int op_outca(void)              /* OUT (C),A */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, A);
+       return(12);
+}
+
+static int op_outcb(void)              /* OUT (C),B */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, B);
+       return(12);
+}
+
+static int op_outcc(void)              /* OUT (C),C */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, C);
+       return(12);
+}
+
+static int op_outcd(void)              /* OUT (C),D */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, D);
+       return(12);
+}
+
+static int op_outce(void)              /* OUT (C),E */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, E);
+       return(12);
+}
+
+static int op_outch(void)              /* OUT (C),H */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, H);
+       return(12);
+}
+
+static int op_outcl(void)              /* OUT (C),L */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+
+       io_out(C, B, L);
+       return(12);
+}
+
+static int op_ini(void)                        /* INI */
+{
+       BYTE io_in(BYTE, BYTE);
+       BYTE data;
+
+       data = io_in(C, B);
+       memwrt((H << 8) + L, data);
+       L++;
+       if (!L)
+               H++;
+       B--;
+       F |= N_FLAG;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(16);
+}
+
+static int op_inir(void)               /* INIR */
+{
+       BYTE io_in(BYTE ,BYTE);
+       WORD addr;
+       BYTE data;
+       register int t  = -21;
+
+       addr = (H << 8) + L;
+       do {
+               data = io_in(C, B);
+               memwrt(addr++, data);
+               B--;
+               t += 21;
+       } while (B);
+       H = addr >> 8;
+       L = addr;
+       F |= N_FLAG | Z_FLAG;
+       return(t + 16);
+}
+
+static int op_ind(void)                        /* IND */
+{
+       BYTE io_in(BYTE, BYTE);
+       BYTE data;
+
+       data = io_in(C, B);
+       memwrt((H << 8) + L, data);
+       L--;
+       if (L == 0xff)
+               H--;
+       B--;
+       F |= N_FLAG;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(16);
+}
+
+static int op_indr(void)               /* INDR */
+{
+       BYTE io_in(BYTE, BYTE);
+       WORD addr;
+       BYTE data;
+       register int t  = -21;
+
+       addr = (H << 8) + L;
+       do {
+               data = io_in(C, B);
+               memwrt(addr--, data);
+               B--;
+               t += 21;
+       } while (B);
+       H = addr >> 8;
+       L = addr;
+       F |= N_FLAG | Z_FLAG;
+       return(t + 16);
+}
+
+static int op_outi(void)               /* OUTI */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       BYTE data;
+
+       data = memrdr((H << 8) + L);
+       io_out(C, B, data);
+       L++;
+       if (!L)
+               H++;
+       B--;
+       F |= N_FLAG;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(16);
+}
+
+static int op_otir(void)               /* OTIR */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       WORD addr;
+       BYTE data;
+       register int t  = -21;
+
+       addr = (H << 8) + L;
+       do {
+               data = memrdr(addr++);
+               io_out(C, B, data);
+               B--;
+               t += 21;
+       } while (B);
+       H = addr >> 8;
+       L = addr;
+       F |= N_FLAG | Z_FLAG;
+       return(t + 16);
+}
+
+static int op_outd(void)               /* OUTD */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       BYTE data;
+
+       data = memrdr((H << 8) + L);
+       io_out(C, B, data);
+       L--;
+       if (L == 0xff)
+               H--;
+       B--;
+       F |= N_FLAG;
+       (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       return(16);
+}
+
+static int op_otdr(void)               /* OTDR */
+{
+       BYTE io_out(BYTE, BYTE, BYTE);
+       WORD addr;
+       BYTE data;
+       register int t  = -21;
+
+       addr = (H << 8) + L;
+       do {
+               data = memrdr(addr--);
+               io_out(C, B, data);
+               B--;
+               t += 21;
+       } while (B);
+       H = addr >> 8;
+       L = addr;
+       F |= N_FLAG | Z_FLAG;
+       return(t + 16);
+}
+
+static int op_ldai(void)               /* LD A,I */
+{
+       A = I;
+       F &= ~(N_FLAG | H_FLAG);
+       (IFF & 2) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(9);
+}
+
+static int op_ldar(void)               /* LD A,R */
+{
+       A = (BYTE) R;
+       F &= ~(N_FLAG | H_FLAG);
+       (IFF & 2) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(9);
+}
+
+static int op_ldia(void)               /* LD I,A */
+{
+       I = A;
+       return(9);
+}
+
+static int op_ldra(void)               /* LD R,A */
+{
+       R = A;
+       return(9);
+}
+
+static int op_ldbcinn(void)            /* LD BC,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       C = memrdr(i++);
+       B = memrdr(i);
+       return(20);
+}
+
+static int op_lddeinn(void)            /* LD DE,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       E = memrdr(i++);
+       D = memrdr(i);
+       return(20);
+}
+
+static int op_ldhlinn(void)            /* LD HL,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       L = memrdr(i++);
+       H = memrdr(i);
+       return(20);
+}
+
+static int op_ldspinn(void)            /* LD SP,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       SP = memrdr(i++);
+       SP += memrdr(i) << 8;
+       return(20);
+}
+
+static int op_ldinbc(void)             /* LD (nn),BC */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i++, C);
+       memwrt(i, B);
+       return(20);
+}
+
+static int op_ldinde(void)             /* LD (nn),DE */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i++, E);
+       memwrt(i, D);
+       return(20);
+}
+
+static int op_ldinhl(void)             /* LD (nn),HL */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i++, L);
+       memwrt(i, H);
+       return(20);
+}
+
+static int op_ldinsp(void)             /* LD (nn),SP */
+{
+       register WORD addr;
+       WORD i;
+
+       addr = memrdr(PC++);
+       addr += memrdr(PC++) << 8;
+       i = SP;
+       memwrt(addr++, i);
+       memwrt(addr, i >> 8);
+       return(20);
+}
+
+static int op_adchb(void)              /* ADC HL,BC */
+{
+       int carry, i;
+       WORD hl, bc;
+       SWORD shl, sbc;
+
+       hl = (H << 8) + L;
+       bc = (B << 8) + C;
+       shl = hl;
+       sbc = bc;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((hl & 0x0fff) + (bc & 0x0fff) + carry) > 0x0fff) ? (F |= H_FLAG)
+                                                          : (F &= ~H_FLAG);
+       i = shl + sbc + carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (hl + bc + carry > 0xffff) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_adchd(void)              /* ADC HL,DE */
+{
+       int carry, i;
+       WORD hl, de;
+       SWORD shl, sde;
+
+       hl = (H << 8) + L;
+       de = (D << 8) + E;
+       shl = hl;
+       sde = de;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((hl & 0x0fff) + (de & 0x0fff) + carry) > 0x0fff) ? (F |= H_FLAG)
+                                                          : (F &= ~H_FLAG);
+       i = shl + sde + carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (hl + de + carry > 0xffff) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_adchh(void)              /* ADC HL,HL */
+{
+       int carry, i;
+       WORD hl;
+       SWORD shl;
+
+       hl = (H << 8) + L;
+       shl = hl;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((hl & 0x0fff) + (hl & 0x0fff) + carry) > 0x0fff) ? (F |= H_FLAG)
+                                                          : (F &= ~H_FLAG);
+       i = shl + shl + carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (hl + hl + carry > 0xffff) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_adchs(void)              /* ADC HL,SP */
+{
+       int carry, i;
+       WORD hl, sp;
+       SWORD shl, ssp;
+
+       hl = (H << 8) + L;
+       sp = SP;
+       shl = hl;
+       ssp = sp;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((hl & 0x0fff) + (sp & 0x0fff) + carry) > 0x0fff) ? (F |= H_FLAG)
+                                                          : (F &= ~H_FLAG);
+       i = shl + ssp + carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (hl + sp + carry > 0xffff) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_sbchb(void)              /* SBC HL,BC */
+{
+       int carry, i;
+       WORD hl, bc;
+       SWORD shl, sbc;
+
+       hl = (H << 8) + L;
+       bc = (B << 8) + C;
+       shl = hl;
+       sbc = bc;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((bc & 0x0fff) + carry) > (hl & 0x0fff)) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       i = shl - sbc - carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (bc + carry > hl) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F |= N_FLAG;
+       return(15);
+}
+
+static int op_sbchd(void)              /* SBC HL,DE */
+{
+       int carry, i;
+       WORD hl, de;
+       SWORD shl, sde;
+
+       hl = (H << 8) + L;
+       de = (D << 8) + E;
+       shl = hl;
+       sde = de;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((de & 0x0fff) + carry) > (hl & 0x0fff)) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       i = shl - sde - carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (de + carry > hl) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F |= N_FLAG;
+       return(15);
+}
+
+static int op_sbchh(void)              /* SBC HL,HL */
+{
+       int carry, i;
+       WORD hl;
+       SWORD shl;
+
+       hl = (H << 8) + L;
+       shl = hl;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((hl & 0x0fff) + carry) > (hl & 0x0fff)) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       i = shl - shl - carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (hl + carry > hl) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F |= N_FLAG;
+       return(15);
+}
+
+static int op_sbchs(void)              /* SBC HL,SP */
+{
+       int carry, i;
+       WORD hl, sp;
+       SWORD shl, ssp;
+
+       hl = (H << 8) + L;
+       sp = SP;
+       shl = hl;
+       ssp = sp;
+       carry = (F & C_FLAG) ? 1 : 0;
+       (((sp & 0x0fff) + carry) > (hl & 0x0fff)) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       i = shl - ssp - carry;
+       ((i > 32767) || (i < -32768)) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (sp + carry > hl) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i &= 0xffff;
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 0x8000) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       H = i >> 8;
+       L = i;
+       F |= N_FLAG;
+       return(15);
+}
+
+static int op_ldi(void)                        /* LDI */
+{
+       memwrt((D << 8) + E, memrdr((H << 8) + L));
+       E++;
+       if (!E)
+               D++;
+       L++;
+       if (!L)
+               H++;
+       C--;
+       if (C == 0xff)
+               B--;
+       (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       F &= ~(N_FLAG | H_FLAG);
+       return(16);
+}
+
+#ifdef WANT_FASTM
+static int op_ldir(void)               /* LDIR */
+{
+       register int t  = -21;
+       register WORD i;
+       register WORD s, d;
+
+       i = (B << 8) + C;
+       d = (D << 8) + E;
+       s = (H << 8) + L;
+       do {
+               memwrt(d++, memrdr(s++));
+               t += 21;
+       } while (--i);
+       B = C = 0;
+       D = d >> 8;
+       E = d;
+       H = s >> 8;
+       L = s;
+       F &= ~(N_FLAG | P_FLAG | H_FLAG);
+       return(t + 16);
+}
+#else
+static int op_ldir(void)               /* LDIR */
+{
+       register int t;
+
+       op_ldi();
+       if (F & P_FLAG) {
+               t = 21;
+               PC -= 2;
+       } else
+               t = 16;
+       return(t);
+}
+#endif
+
+static int op_ldd(void)                        /* LDD */
+{
+       memwrt((D << 8) + E, memrdr((H << 8) + L));
+       E--;
+       if (E == 0xff)
+               D--;
+       L--;
+       if (L == 0xff)
+               H--;
+       C--;
+       if (C == 0xff)
+               B--;
+       (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       F &= ~(N_FLAG | H_FLAG);
+       return(16);
+}
+
+#ifdef WANT_FASTM
+static int op_lddr(void)               /* LDDR */
+{
+       register int t  = -21;
+       register WORD i;
+       register WORD s, d;
+
+       i = (B << 8) + C;
+       d = (D << 8) + E;
+       s = (H << 8) + L;
+       do {
+               memwrt(d--, memrdr(s--));
+               t += 21;
+       } while (--i);
+       B = C = 0;
+       D = d  >> 8;
+       E = d;
+       H = s >> 8;
+       L = s;
+       F &= ~(N_FLAG | P_FLAG | H_FLAG);
+       return(t + 16);
+}
+#else
+static int op_lddr(void)               /* LDDR */
+{
+       register int t;
+
+       op_ldd();
+       if (F & P_FLAG) {
+               t = 21;
+               PC -= 2;
+       } else
+               t = 16;
+       return(t);
+}
+#endif
+
+static int op_cpi(void)                /* CPI */
+{
+       register BYTE i;
+
+       i = memrdr(((H << 8) + L));
+       ((i & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       i = A - i;
+       L++;
+       if (!L)
+               H++;
+       C--;
+       if (C == 0xff)
+               B--;
+       F |= N_FLAG;
+       (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(16);
+}
+
+static int op_cpir(void)       /* CPIR */
+{
+       register int t  = -21;
+       register WORD s;
+       register BYTE d;
+       register WORD i;
+       register BYTE tmp;
+
+       i = (B << 8) + C;
+       s = (H << 8) + L;
+       do {
+               tmp = memrdr(s++);
+               ((tmp & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+               d = A - tmp;
+               t += 21;
+       } while (--i && d);
+       F |= N_FLAG;
+       B = i >> 8;
+       C = i;
+       H = s >> 8;
+       L = s;
+       (i) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (d) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (d & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(t + 16);
+}
+
+static int op_cpdop(void)      /* CPD */
+{
+       register BYTE i;
+
+       i = memrdr(((H << 8) + L));
+       ((i & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       i = A - i;
+       L--;
+       if (L == 0xff)
+               H--;
+       C--;
+       if (C == 0xff)
+               B--;
+       F |= N_FLAG;
+       (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(16);
+}
+
+static int op_cpdr(void)       /* CPDR */
+{
+       register int t  = -21;
+       register WORD s;
+       register BYTE d;
+       register WORD i;
+       register BYTE tmp;
+
+       i = (B << 8) + C;
+       s = (H << 8) + L;
+       do {
+               tmp = memrdr(s--);
+               ((tmp & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+               d = A - tmp;
+               t += 21;
+       } while (--i && d);
+       F |= N_FLAG;
+       B = i >> 8;
+       C = i;
+       H = s >> 8;
+       L = s;
+       (i) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (d) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (d & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       return(t + 16);
+}
+
+static int op_oprld(void)      /* RLD (HL) */
+{
+       register BYTE i, j;
+
+       i = memrdr((H << 8) + L);
+       j = A & 0x0f;
+       A = (A & 0xf0) | (i >> 4);
+       i = (i << 4) | j;
+       memwrt((H << 8) + L, i);
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(18);
+}
+
+static int op_oprrd(void)      /* RRD (HL) */
+{
+       register BYTE i, j;
+
+       i = memrdr((H << 8) + L);
+       j = A & 0x0f;
+       A = (A & 0xf0) | (i & 0x0f);
+       i = (i >> 4) | (j << 4);
+       memwrt((H << 8) + L, i);
+       F &= ~(H_FLAG | N_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(18);
+}
diff --git a/sim/sim5.c b/sim/sim5.c
new file mode 100644 (file)
index 0000000..4ea78e7
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates multi byte opcodes
+ *     starting with 0xfd
+ */
+
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_fd(void);
+static int op_popiy(void), op_pusiy(void);
+static int op_jpiy(void);
+static int op_exspy(void);
+static int op_ldspy(void);
+static int op_ldiynn(void), op_ldiyinn(void), op_ldiny(void);
+static int op_adayd(void), op_acayd(void), op_suayd(void), op_scayd(void);
+static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void);
+static int op_decyd(void), op_incyd(void);
+static int op_addyb(void), op_addyd(void), op_addys(void), op_addyy(void);
+static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void);
+static int op_decyd(void), op_incyd(void);
+static int op_inciy(void), op_deciy(void);
+static int op_ldayd(void), op_ldbyd(void), op_ldcyd(void);
+static int op_lddyd(void), op_ldeyd(void);
+static int op_ldhyd(void), op_ldlyd(void);
+static int op_ldyda(void), op_ldydb(void), op_ldydc(void);
+static int op_ldydd(void), op_ldyde(void);
+static int op_ldydh(void), op_ldydl(void), op_ldydn(void);
+extern int op_fdcb_handel(void);
+
+int op_fd_handel(void)
+{
+       register int t;
+
+       static int (*op_fd[256]) () = {
+               trap_fd,                        /* 0x00 */
+               trap_fd,                        /* 0x01 */
+               trap_fd,                        /* 0x02 */
+               trap_fd,                        /* 0x03 */
+               trap_fd,                        /* 0x04 */
+               trap_fd,                        /* 0x05 */
+               trap_fd,                        /* 0x06 */
+               trap_fd,                        /* 0x07 */
+               trap_fd,                        /* 0x08 */
+               op_addyb,                       /* 0x09 */
+               trap_fd,                        /* 0x0a */
+               trap_fd,                        /* 0x0b */
+               trap_fd,                        /* 0x0c */
+               trap_fd,                        /* 0x0d */
+               trap_fd,                        /* 0x0e */
+               trap_fd,                        /* 0x0f */
+               trap_fd,                        /* 0x10 */
+               trap_fd,                        /* 0x11 */
+               trap_fd,                        /* 0x12 */
+               trap_fd,                        /* 0x13 */
+               trap_fd,                        /* 0x14 */
+               trap_fd,                        /* 0x15 */
+               trap_fd,                        /* 0x16 */
+               trap_fd,                        /* 0x17 */
+               trap_fd,                        /* 0x18 */
+               op_addyd,                       /* 0x19 */
+               trap_fd,                        /* 0x1a */
+               trap_fd,                        /* 0x1b */
+               trap_fd,                        /* 0x1c */
+               trap_fd,                        /* 0x1d */
+               trap_fd,                        /* 0x1e */
+               trap_fd,                        /* 0x1f */
+               trap_fd,                        /* 0x20 */
+               op_ldiynn,                      /* 0x21 */
+               op_ldiny,                       /* 0x22 */
+               op_inciy,                       /* 0x23 */
+               trap_fd,                        /* 0x24 */
+               trap_fd,                        /* 0x25 */
+               trap_fd,                        /* 0x26 */
+               trap_fd,                        /* 0x27 */
+               trap_fd,                        /* 0x28 */
+               op_addyy,                       /* 0x29 */
+               op_ldiyinn,                     /* 0x2a */
+               op_deciy,                       /* 0x2b */
+               trap_fd,                        /* 0x2c */
+               trap_fd,                        /* 0x2d */
+               trap_fd,                        /* 0x2e */
+               trap_fd,                        /* 0x2f */
+               trap_fd,                        /* 0x30 */
+               trap_fd,                        /* 0x31 */
+               trap_fd,                        /* 0x32 */
+               trap_fd,                        /* 0x33 */
+               op_incyd,                       /* 0x34 */
+               op_decyd,                       /* 0x35 */
+               op_ldydn,                       /* 0x36 */
+               trap_fd,                        /* 0x37 */
+               trap_fd,                        /* 0x38 */
+               op_addys,                       /* 0x39 */
+               trap_fd,                        /* 0x3a */
+               trap_fd,                        /* 0x3b */
+               trap_fd,                        /* 0x3c */
+               trap_fd,                        /* 0x3d */
+               trap_fd,                        /* 0x3e */
+               trap_fd,                        /* 0x3f */
+               trap_fd,                        /* 0x40 */
+               trap_fd,                        /* 0x41 */
+               trap_fd,                        /* 0x42 */
+               trap_fd,                        /* 0x43 */
+               trap_fd,                        /* 0x44 */
+               trap_fd,                        /* 0x45 */
+               op_ldbyd,                       /* 0x46 */
+               trap_fd,                        /* 0x47 */
+               trap_fd,                        /* 0x48 */
+               trap_fd,                        /* 0x49 */
+               trap_fd,                        /* 0x4a */
+               trap_fd,                        /* 0x4b */
+               trap_fd,                        /* 0x4c */
+               trap_fd,                        /* 0x4d */
+               op_ldcyd,                       /* 0x4e */
+               trap_fd,                        /* 0x4f */
+               trap_fd,                        /* 0x50 */
+               trap_fd,                        /* 0x51 */
+               trap_fd,                        /* 0x52 */
+               trap_fd,                        /* 0x53 */
+               trap_fd,                        /* 0x54 */
+               trap_fd,                        /* 0x55 */
+               op_lddyd,                       /* 0x56 */
+               trap_fd,                        /* 0x57 */
+               trap_fd,                        /* 0x58 */
+               trap_fd,                        /* 0x59 */
+               trap_fd,                        /* 0x5a */
+               trap_fd,                        /* 0x5b */
+               trap_fd,                        /* 0x5c */
+               trap_fd,                        /* 0x5d */
+               op_ldeyd,                       /* 0x5e */
+               trap_fd,                        /* 0x5f */
+               trap_fd,                        /* 0x60 */
+               trap_fd,                        /* 0x61 */
+               trap_fd,                        /* 0x62 */
+               trap_fd,                        /* 0x63 */
+               trap_fd,                        /* 0x64 */
+               trap_fd,                        /* 0x65 */
+               op_ldhyd,                       /* 0x66 */
+               trap_fd,                        /* 0x67 */
+               trap_fd,                        /* 0x68 */
+               trap_fd,                        /* 0x69 */
+               trap_fd,                        /* 0x6a */
+               trap_fd,                        /* 0x6b */
+               trap_fd,                        /* 0x6c */
+               trap_fd,                        /* 0x6d */
+               op_ldlyd,                       /* 0x6e */
+               trap_fd,                        /* 0x6f */
+               op_ldydb,                       /* 0x70 */
+               op_ldydc,                       /* 0x71 */
+               op_ldydd,                       /* 0x72 */
+               op_ldyde,                       /* 0x73 */
+               op_ldydh,                       /* 0x74 */
+               op_ldydl,                       /* 0x75 */
+               trap_fd,                        /* 0x76 */
+               op_ldyda,                       /* 0x77 */
+               trap_fd,                        /* 0x78 */
+               trap_fd,                        /* 0x79 */
+               trap_fd,                        /* 0x7a */
+               trap_fd,                        /* 0x7b */
+               trap_fd,                        /* 0x7c */
+               trap_fd,                        /* 0x7d */
+               op_ldayd,                       /* 0x7e */
+               trap_fd,                        /* 0x7f */
+               trap_fd,                        /* 0x80 */
+               trap_fd,                        /* 0x81 */
+               trap_fd,                        /* 0x82 */
+               trap_fd,                        /* 0x83 */
+               trap_fd,                        /* 0x84 */
+               trap_fd,                        /* 0x85 */
+               op_adayd,                       /* 0x86 */
+               trap_fd,                        /* 0x87 */
+               trap_fd,                        /* 0x88 */
+               trap_fd,                        /* 0x89 */
+               trap_fd,                        /* 0x8a */
+               trap_fd,                        /* 0x8b */
+               trap_fd,                        /* 0x8c */
+               trap_fd,                        /* 0x8d */
+               op_acayd,                       /* 0x8e */
+               trap_fd,                        /* 0x8f */
+               trap_fd,                        /* 0x90 */
+               trap_fd,                        /* 0x91 */
+               trap_fd,                        /* 0x92 */
+               trap_fd,                        /* 0x93 */
+               trap_fd,                        /* 0x94 */
+               trap_fd,                        /* 0x95 */
+               op_suayd,                       /* 0x96 */
+               trap_fd,                        /* 0x97 */
+               trap_fd,                        /* 0x98 */
+               trap_fd,                        /* 0x99 */
+               trap_fd,                        /* 0x9a */
+               trap_fd,                        /* 0x9b */
+               trap_fd,                        /* 0x9c */
+               trap_fd,                        /* 0x9d */
+               op_scayd,                       /* 0x9e */
+               trap_fd,                        /* 0x9f */
+               trap_fd,                        /* 0xa0 */
+               trap_fd,                        /* 0xa1 */
+               trap_fd,                        /* 0xa2 */
+               trap_fd,                        /* 0xa3 */
+               trap_fd,                        /* 0xa4 */
+               trap_fd,                        /* 0xa5 */
+               op_andyd,                       /* 0xa6 */
+               trap_fd,                        /* 0xa7 */
+               trap_fd,                        /* 0xa8 */
+               trap_fd,                        /* 0xa9 */
+               trap_fd,                        /* 0xaa */
+               trap_fd,                        /* 0xab */
+               trap_fd,                        /* 0xac */
+               trap_fd,                        /* 0xad */
+               op_xoryd,                       /* 0xae */
+               trap_fd,                        /* 0xaf */
+               trap_fd,                        /* 0xb0 */
+               trap_fd,                        /* 0xb1 */
+               trap_fd,                        /* 0xb2 */
+               trap_fd,                        /* 0xb3 */
+               trap_fd,                        /* 0xb4 */
+               trap_fd,                        /* 0xb5 */
+               op_oryd,                        /* 0xb6 */
+               trap_fd,                        /* 0xb7 */
+               trap_fd,                        /* 0xb8 */
+               trap_fd,                        /* 0xb9 */
+               trap_fd,                        /* 0xba */
+               trap_fd,                        /* 0xbb */
+               trap_fd,                        /* 0xbc */
+               trap_fd,                        /* 0xbd */
+               op_cpyd,                        /* 0xbe */
+               trap_fd,                        /* 0xbf */
+               trap_fd,                        /* 0xc0 */
+               trap_fd,                        /* 0xc1 */
+               trap_fd,                        /* 0xc2 */
+               trap_fd,                        /* 0xc3 */
+               trap_fd,                        /* 0xc4 */
+               trap_fd,                        /* 0xc5 */
+               trap_fd,                        /* 0xc6 */
+               trap_fd,                        /* 0xc7 */
+               trap_fd,                        /* 0xc8 */
+               trap_fd,                        /* 0xc9 */
+               trap_fd,                        /* 0xca */
+               op_fdcb_handel,                 /* 0xcb */
+               trap_fd,                        /* 0xcc */
+               trap_fd,                        /* 0xcd */
+               trap_fd,                        /* 0xce */
+               trap_fd,                        /* 0xcf */
+               trap_fd,                        /* 0xd0 */
+               trap_fd,                        /* 0xd1 */
+               trap_fd,                        /* 0xd2 */
+               trap_fd,                        /* 0xd3 */
+               trap_fd,                        /* 0xd4 */
+               trap_fd,                        /* 0xd5 */
+               trap_fd,                        /* 0xd6 */
+               trap_fd,                        /* 0xd7 */
+               trap_fd,                        /* 0xd8 */
+               trap_fd,                        /* 0xd9 */
+               trap_fd,                        /* 0xda */
+               trap_fd,                        /* 0xdb */
+               trap_fd,                        /* 0xdc */
+               trap_fd,                        /* 0xdd */
+               trap_fd,                        /* 0xde */
+               trap_fd,                        /* 0xdf */
+               trap_fd,                        /* 0xe0 */
+               op_popiy,                       /* 0xe1 */
+               trap_fd,                        /* 0xe2 */
+               op_exspy,                       /* 0xe3 */
+               trap_fd,                        /* 0xe4 */
+               op_pusiy,                       /* 0xe5 */
+               trap_fd,                        /* 0xe6 */
+               trap_fd,                        /* 0xe7 */
+               trap_fd,                        /* 0xe8 */
+               op_jpiy,                        /* 0xe9 */
+               trap_fd,                        /* 0xea */
+               trap_fd,                        /* 0xeb */
+               trap_fd,                        /* 0xec */
+               trap_fd,                        /* 0xed */
+               trap_fd,                        /* 0xee */
+               trap_fd,                        /* 0xef */
+               trap_fd,                        /* 0xf0 */
+               trap_fd,                        /* 0xf1 */
+               trap_fd,                        /* 0xf2 */
+               trap_fd,                        /* 0xf3 */
+               trap_fd,                        /* 0xf4 */
+               trap_fd,                        /* 0xf5 */
+               trap_fd,                        /* 0xf6 */
+               trap_fd,                        /* 0xf7 */
+               trap_fd,                        /* 0xf8 */
+               op_ldspy,                       /* 0xf9 */
+               trap_fd,                        /* 0xfa */
+               trap_fd,                        /* 0xfb */
+               trap_fd,                        /* 0xfc */
+               trap_fd,                        /* 0xfd */
+               trap_fd,                        /* 0xfe */
+               trap_fd                         /* 0xff */
+       };
+
+#ifdef BUS_8080
+       /* M1 opcode fetch */
+       cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
+       m1_step = 1;
+#endif
+#ifdef FRONTPANEL
+       /* update frontpanel */
+       fp_clock++;
+       fp_sampleLightGroup(0, 0);
+#endif
+
+       t = (*op_fd[memrdr(PC++)]) ();  /* execute next opcode */
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xfd of a multi byte opcode.
+ */
+static int trap_fd(void)
+{
+       cpu_error = OPTRAP2;
+       cpu_state = STOPPED;
+       return(0);
+}
+
+static int op_popiy(void)              /* POP IY */
+{
+       IY = memrdr(SP++);
+       IY += memrdr(SP++) << 8;
+       return(14);
+}
+
+static int op_pusiy(void)              /* PUSH IY */
+{
+       memwrt(--SP, IY >> 8);
+       memwrt(--SP, IY);
+       return(15);
+}
+
+static int op_jpiy(void)               /* JP (IY) */
+{
+       PC = IY;
+       return(8);
+}
+
+static int op_exspy(void)              /* EX (SP),IY */
+{
+       register WORD i;
+
+       i = memrdr(SP) + (memrdr(SP + 1) << 8);
+       memwrt(SP, IY);
+       memwrt(SP + 1, IY >> 8);
+       IY = i;
+       return(23);
+}
+
+static int op_ldspy(void)              /* LD SP,IY */
+{
+       SP = IY;
+       return(10);
+}
+
+static int op_ldiynn(void)             /* LD IY,nn */
+{
+       IY = memrdr(PC++);
+       IY += memrdr(PC++) << 8;
+       return(14);
+}
+
+static int op_ldiyinn(void)            /* LD IY,(nn) */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       IY = memrdr(i);
+       IY += memrdr(i + 1) << 8;
+       return(20);
+}
+
+static int op_ldiny(void)              /* LD (nn),IY */
+{
+       register WORD i;
+
+       i = memrdr(PC++);
+       i += memrdr(PC++) << 8;
+       memwrt(i, IY);
+       memwrt(i + 1, IY >> 8);
+       return(20);
+}
+
+static int op_adayd(void)              /* ADD A,(IY+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IY + (signed char) memrdr(PC++));
+       ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(19);
+}
+
+static int op_acayd(void)              /* ADC A,(IY+d) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(IY + (signed char) memrdr(PC++));
+       ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A + (signed char) P + carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(19);
+}
+
+static int op_suayd(void)              /* SUB A,(IY+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IY + (signed char) memrdr(PC++));
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_scayd(void)              /* SBC A,(IY+d) */
+{
+       register int i, carry;
+       register BYTE P;
+
+       carry = (F & C_FLAG) ? 1 : 0;
+       P = memrdr(IY + (signed char) memrdr(PC++));
+       ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       A = i = (signed char) A - (signed char) P - carry;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_andyd(void)              /* AND (IY+d) */
+{
+       A &= memrdr(IY + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= H_FLAG;
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_xoryd(void)              /* XOR (IY+d) */
+{
+       A ^= memrdr(IY + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_oryd(void)               /* OR (IY+d) */
+{
+       A |= memrdr(IY + (signed char) memrdr(PC++));
+       (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       F &= ~(H_FLAG | N_FLAG | C_FLAG);
+       return(19);
+}
+
+static int op_cpyd(void)               /* CP (IY+d) */
+{
+       register int i;
+       register BYTE P;
+
+       P = memrdr(IY + (signed char) memrdr(PC++));
+       ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       i = (signed char) A - (signed char) P;
+       (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(19);
+}
+
+static int op_incyd(void)              /* INC (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IY + (signed char) memrdr(PC++);
+       P = memrdr(addr);
+       P++;
+       memwrt(addr, P);
+       ((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F  |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F &= ~N_FLAG;
+       return(23);
+}
+
+static int op_decyd(void)              /* DEC (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IY + (signed char) memrdr(PC++);
+       P = memrdr(addr);
+       P--;
+       memwrt(addr, P);
+       ((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
+       (P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
+       (P & 128) ? (F  |= S_FLAG) : (F &= ~S_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       F |= N_FLAG;
+       return(23);
+}
+
+static int op_addyb(void)              /* ADD IY,BC */
+{
+       register int carry;
+       BYTE iyl = IY & 0xff;
+       BYTE iyh = IY >> 8;
+       
+       carry = (iyl + C > 255) ? 1 : 0;
+       iyl += C;
+       ((iyh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                               : (F &= ~H_FLAG);
+       (iyh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       iyh += B + carry;
+       IY = (iyh << 8) + iyl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addyd(void)              /* ADD IY,DE */
+{
+       register int carry;
+       BYTE iyl = IY & 0xff;
+       BYTE iyh = IY >> 8;
+       
+       carry = (iyl + E > 255) ? 1 : 0;
+       iyl += E;
+       ((iyh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                               : (F &= ~H_FLAG);
+       (iyh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       iyh += D + carry;
+       IY = (iyh << 8) + iyl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addys(void)              /* ADD IY,SP */
+{
+       register int carry;
+       BYTE iyl = IY & 0xff;
+       BYTE iyh = IY >> 8;
+       BYTE spl = SP & 0xff;
+       BYTE sph = SP >> 8;
+       
+       carry = (iyl + spl > 255) ? 1 : 0;
+       iyl += spl;
+       ((iyh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       (iyh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       iyh += sph + carry;
+       IY = (iyh << 8) + iyl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_addyy(void)              /* ADD IY,IY */
+{
+       register int carry;
+       BYTE iyl = IY & 0xff;
+       BYTE iyh = IY >> 8;
+       
+       carry = (iyl << 1 > 255) ? 1 : 0;
+       iyl <<= 1;
+       ((iyh & 0xf) + (iyh & 0xf) + carry > 0xf) ? (F |= H_FLAG)
+                                                 : (F &= ~H_FLAG);
+       (iyh + iyh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       iyh += iyh + carry;
+       IY = (iyh << 8) + iyl;
+       F &= ~N_FLAG;
+       return(15);
+}
+
+static int op_inciy(void)              /* INC IY */
+{
+       IY++;
+       return(10);
+}
+
+static int op_deciy(void)              /* DEC IY */
+{
+       IY--;
+       return(10);
+}
+
+static int op_ldayd(void)              /* LD A,(IY+d) */
+{
+       A = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldbyd(void)              /* LD B,(IY+d) */
+{
+       B = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldcyd(void)              /* LD C,(IY+d) */
+{
+       C = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_lddyd(void)              /* LD D,(IY+d) */
+{
+       D = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldeyd(void)              /* LD E,(IY+d) */
+{
+       E = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldhyd(void)              /* LD H,(IY+d) */
+{
+       H = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldlyd(void)              /* LD L,(IY+d) */
+{
+       L = memrdr(IY + (signed char) memrdr(PC++));
+       return(19);
+}
+
+static int op_ldyda(void)              /* LD (IY+d),A */
+{
+       memwrt(IY + (signed char) memrdr(PC++), A);
+       return(19);
+}
+
+static int op_ldydb(void)              /* LD (IY+d),B */
+{
+       memwrt(IY + (signed char) memrdr(PC++), B);
+       return(19);
+}
+
+static int op_ldydc(void)              /* LD (IY+d),C */
+{
+       memwrt(IY + (signed char) memrdr(PC++), C);
+       return(19);
+}
+
+static int op_ldydd(void)              /* LD (IY+d),D */
+{
+       memwrt(IY + (signed char) memrdr(PC++), D);
+       return(19);
+}
+
+static int op_ldyde(void)              /* LD (IY+d),E */
+{
+       memwrt(IY + (signed char) memrdr(PC++), E);
+       return(19);
+}
+
+static int op_ldydh(void)              /* LD (IY+d),H */
+{
+       memwrt(IY + (signed char) memrdr(PC++), H);
+       return(19);
+}
+
+static int op_ldydl(void)              /* LD (IY+d),L */
+{
+       memwrt(IY + (signed char) memrdr(PC++), L);
+       return(19);
+}
+
+static int op_ldydn(void)              /* LD (IY+d),n */
+{
+       register signed char d;
+
+       d = memrdr(PC++);
+       memwrt(IY + d, memrdr(PC++));
+       return(19);
+}
diff --git a/sim/sim6.c b/sim/sim6.c
new file mode 100644 (file)
index 0000000..d42f3f2
--- /dev/null
@@ -0,0 +1,656 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates 4 byte opcodes
+ *     starting with 0xdd 0xcb
+ */
+
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_ddcb(void);
+static int op_tb0ixd(int), op_tb1ixd(int), op_tb2ixd(int), op_tb3ixd(int);
+static int op_tb4ixd(int), op_tb5ixd(int), op_tb6ixd(int), op_tb7ixd(int);
+static int op_rb0ixd(int), op_rb1ixd(int), op_rb2ixd(int), op_rb3ixd(int);
+static int op_rb4ixd(int), op_rb5ixd(int), op_rb6ixd(int), op_rb7ixd(int);
+static int op_sb0ixd(int), op_sb1ixd(int), op_sb2ixd(int), op_sb3ixd(int);
+static int op_sb4ixd(int), op_sb5ixd(int), op_sb6ixd(int), op_sb7ixd(int);
+static int op_rlcixd(int), op_rrcixd(int), op_rlixd(int), op_rrixd(int);
+static int op_slaixd(int), op_sraixd(int), op_srlixd(int);
+
+int op_ddcb_handel(void)
+{
+       static int (*op_ddcb[256]) () = {
+               trap_ddcb,                      /* 0x00 */
+               trap_ddcb,                      /* 0x01 */
+               trap_ddcb,                      /* 0x02 */
+               trap_ddcb,                      /* 0x03 */
+               trap_ddcb,                      /* 0x04 */
+               trap_ddcb,                      /* 0x05 */
+               op_rlcixd,                      /* 0x06 */
+               trap_ddcb,                      /* 0x07 */
+               trap_ddcb,                      /* 0x08 */
+               trap_ddcb,                      /* 0x09 */
+               trap_ddcb,                      /* 0x0a */
+               trap_ddcb,                      /* 0x0b */
+               trap_ddcb,                      /* 0x0c */
+               trap_ddcb,                      /* 0x0d */
+               op_rrcixd,                      /* 0x0e */
+               trap_ddcb,                      /* 0x0f */
+               trap_ddcb,                      /* 0x10 */
+               trap_ddcb,                      /* 0x11 */
+               trap_ddcb,                      /* 0x12 */
+               trap_ddcb,                      /* 0x13 */
+               trap_ddcb,                      /* 0x14 */
+               trap_ddcb,                      /* 0x15 */
+               op_rlixd,                       /* 0x16 */
+               trap_ddcb,                      /* 0x17 */
+               trap_ddcb,                      /* 0x18 */
+               trap_ddcb,                      /* 0x19 */
+               trap_ddcb,                      /* 0x1a */
+               trap_ddcb,                      /* 0x1b */
+               trap_ddcb,                      /* 0x1c */
+               trap_ddcb,                      /* 0x1d */
+               op_rrixd,                       /* 0x1e */
+               trap_ddcb,                      /* 0x1f */
+               trap_ddcb,                      /* 0x20 */
+               trap_ddcb,                      /* 0x21 */
+               trap_ddcb,                      /* 0x22 */
+               trap_ddcb,                      /* 0x23 */
+               trap_ddcb,                      /* 0x24 */
+               trap_ddcb,                      /* 0x25 */
+               op_slaixd,                      /* 0x26 */
+               trap_ddcb,                      /* 0x27 */
+               trap_ddcb,                      /* 0x28 */
+               trap_ddcb,                      /* 0x29 */
+               trap_ddcb,                      /* 0x2a */
+               trap_ddcb,                      /* 0x2b */
+               trap_ddcb,                      /* 0x2c */
+               trap_ddcb,                      /* 0x2d */
+               op_sraixd,                      /* 0x2e */
+               trap_ddcb,                      /* 0x2f */
+               trap_ddcb,                      /* 0x30 */
+               trap_ddcb,                      /* 0x31 */
+               trap_ddcb,                      /* 0x32 */
+               trap_ddcb,                      /* 0x33 */
+               trap_ddcb,                      /* 0x34 */
+               trap_ddcb,                      /* 0x35 */
+               trap_ddcb,                      /* 0x36 */
+               trap_ddcb,                      /* 0x37 */
+               trap_ddcb,                      /* 0x38 */
+               trap_ddcb,                      /* 0x39 */
+               trap_ddcb,                      /* 0x3a */
+               trap_ddcb,                      /* 0x3b */
+               trap_ddcb,                      /* 0x3c */
+               trap_ddcb,                      /* 0x3d */
+               op_srlixd,                      /* 0x3e */
+               trap_ddcb,                      /* 0x3f */
+               trap_ddcb,                      /* 0x40 */
+               trap_ddcb,                      /* 0x41 */
+               trap_ddcb,                      /* 0x42 */
+               trap_ddcb,                      /* 0x43 */
+               trap_ddcb,                      /* 0x44 */
+               trap_ddcb,                      /* 0x45 */
+               op_tb0ixd,                      /* 0x46 */
+               trap_ddcb,                      /* 0x47 */
+               trap_ddcb,                      /* 0x48 */
+               trap_ddcb,                      /* 0x49 */
+               trap_ddcb,                      /* 0x4a */
+               trap_ddcb,                      /* 0x4b */
+               trap_ddcb,                      /* 0x4c */
+               trap_ddcb,                      /* 0x4d */
+               op_tb1ixd,                      /* 0x4e */
+               trap_ddcb,                      /* 0x4f */
+               trap_ddcb,                      /* 0x50 */
+               trap_ddcb,                      /* 0x51 */
+               trap_ddcb,                      /* 0x52 */
+               trap_ddcb,                      /* 0x53 */
+               trap_ddcb,                      /* 0x54 */
+               trap_ddcb,                      /* 0x55 */
+               op_tb2ixd,                      /* 0x56 */
+               trap_ddcb,                      /* 0x57 */
+               trap_ddcb,                      /* 0x58 */
+               trap_ddcb,                      /* 0x59 */
+               trap_ddcb,                      /* 0x5a */
+               trap_ddcb,                      /* 0x5b */
+               trap_ddcb,                      /* 0x5c */
+               trap_ddcb,                      /* 0x5d */
+               op_tb3ixd,                      /* 0x5e */
+               trap_ddcb,                      /* 0x5f */
+               trap_ddcb,                      /* 0x60 */
+               trap_ddcb,                      /* 0x61 */
+               trap_ddcb,                      /* 0x62 */
+               trap_ddcb,                      /* 0x63 */
+               trap_ddcb,                      /* 0x64 */
+               trap_ddcb,                      /* 0x65 */
+               op_tb4ixd,                      /* 0x66 */
+               trap_ddcb,                      /* 0x67 */
+               trap_ddcb,                      /* 0x68 */
+               trap_ddcb,                      /* 0x69 */
+               trap_ddcb,                      /* 0x6a */
+               trap_ddcb,                      /* 0x6b */
+               trap_ddcb,                      /* 0x6c */
+               trap_ddcb,                      /* 0x6d */
+               op_tb5ixd,                      /* 0x6e */
+               trap_ddcb,                      /* 0x6f */
+               trap_ddcb,                      /* 0x70 */
+               trap_ddcb,                      /* 0x71 */
+               trap_ddcb,                      /* 0x72 */
+               trap_ddcb,                      /* 0x73 */
+               trap_ddcb,                      /* 0x74 */
+               trap_ddcb,                      /* 0x75 */
+               op_tb6ixd,                      /* 0x76 */
+               trap_ddcb,                      /* 0x77 */
+               trap_ddcb,                      /* 0x78 */
+               trap_ddcb,                      /* 0x79 */
+               trap_ddcb,                      /* 0x7a */
+               trap_ddcb,                      /* 0x7b */
+               trap_ddcb,                      /* 0x7c */
+               trap_ddcb,                      /* 0x7d */
+               op_tb7ixd,                      /* 0x7e */
+               trap_ddcb,                      /* 0x7f */
+               trap_ddcb,                      /* 0x80 */
+               trap_ddcb,                      /* 0x81 */
+               trap_ddcb,                      /* 0x82 */
+               trap_ddcb,                      /* 0x83 */
+               trap_ddcb,                      /* 0x84 */
+               trap_ddcb,                      /* 0x85 */
+               op_rb0ixd,                      /* 0x86 */
+               trap_ddcb,                      /* 0x87 */
+               trap_ddcb,                      /* 0x88 */
+               trap_ddcb,                      /* 0x89 */
+               trap_ddcb,                      /* 0x8a */
+               trap_ddcb,                      /* 0x8b */
+               trap_ddcb,                      /* 0x8c */
+               trap_ddcb,                      /* 0x8d */
+               op_rb1ixd,                      /* 0x8e */
+               trap_ddcb,                      /* 0x8f */
+               trap_ddcb,                      /* 0x90 */
+               trap_ddcb,                      /* 0x91 */
+               trap_ddcb,                      /* 0x92 */
+               trap_ddcb,                      /* 0x93 */
+               trap_ddcb,                      /* 0x94 */
+               trap_ddcb,                      /* 0x95 */
+               op_rb2ixd,                      /* 0x96 */
+               trap_ddcb,                      /* 0x97 */
+               trap_ddcb,                      /* 0x98 */
+               trap_ddcb,                      /* 0x99 */
+               trap_ddcb,                      /* 0x9a */
+               trap_ddcb,                      /* 0x9b */
+               trap_ddcb,                      /* 0x9c */
+               trap_ddcb,                      /* 0x9d */
+               op_rb3ixd,                      /* 0x9e */
+               trap_ddcb,                      /* 0x9f */
+               trap_ddcb,                      /* 0xa0 */
+               trap_ddcb,                      /* 0xa1 */
+               trap_ddcb,                      /* 0xa2 */
+               trap_ddcb,                      /* 0xa3 */
+               trap_ddcb,                      /* 0xa4 */
+               trap_ddcb,                      /* 0xa5 */
+               op_rb4ixd,                      /* 0xa6 */
+               trap_ddcb,                      /* 0xa7 */
+               trap_ddcb,                      /* 0xa8 */
+               trap_ddcb,                      /* 0xa9 */
+               trap_ddcb,                      /* 0xaa */
+               trap_ddcb,                      /* 0xab */
+               trap_ddcb,                      /* 0xac */
+               trap_ddcb,                      /* 0xad */
+               op_rb5ixd,                      /* 0xae */
+               trap_ddcb,                      /* 0xaf */
+               trap_ddcb,                      /* 0xb0 */
+               trap_ddcb,                      /* 0xb1 */
+               trap_ddcb,                      /* 0xb2 */
+               trap_ddcb,                      /* 0xb3 */
+               trap_ddcb,                      /* 0xb4 */
+               trap_ddcb,                      /* 0xb5 */
+               op_rb6ixd,                      /* 0xb6 */
+               trap_ddcb,                      /* 0xb7 */
+               trap_ddcb,                      /* 0xb8 */
+               trap_ddcb,                      /* 0xb9 */
+               trap_ddcb,                      /* 0xba */
+               trap_ddcb,                      /* 0xbb */
+               trap_ddcb,                      /* 0xbc */
+               trap_ddcb,                      /* 0xbd */
+               op_rb7ixd,                      /* 0xbe */
+               trap_ddcb,                      /* 0xbf */
+               trap_ddcb,                      /* 0xc0 */
+               trap_ddcb,                      /* 0xc1 */
+               trap_ddcb,                      /* 0xc2 */
+               trap_ddcb,                      /* 0xc3 */
+               trap_ddcb,                      /* 0xc4 */
+               trap_ddcb,                      /* 0xc5 */
+               op_sb0ixd,                      /* 0xc6 */
+               trap_ddcb,                      /* 0xc7 */
+               trap_ddcb,                      /* 0xc8 */
+               trap_ddcb,                      /* 0xc9 */
+               trap_ddcb,                      /* 0xca */
+               trap_ddcb,                      /* 0xcb */
+               trap_ddcb,                      /* 0xcc */
+               trap_ddcb,                      /* 0xcd */
+               op_sb1ixd,                      /* 0xce */
+               trap_ddcb,                      /* 0xcf */
+               trap_ddcb,                      /* 0xd0 */
+               trap_ddcb,                      /* 0xd1 */
+               trap_ddcb,                      /* 0xd2 */
+               trap_ddcb,                      /* 0xd3 */
+               trap_ddcb,                      /* 0xd4 */
+               trap_ddcb,                      /* 0xd5 */
+               op_sb2ixd,                      /* 0xd6 */
+               trap_ddcb,                      /* 0xd7 */
+               trap_ddcb,                      /* 0xd8 */
+               trap_ddcb,                      /* 0xd9 */
+               trap_ddcb,                      /* 0xda */
+               trap_ddcb,                      /* 0xdb */
+               trap_ddcb,                      /* 0xdc */
+               trap_ddcb,                      /* 0xdd */
+               op_sb3ixd,                      /* 0xde */
+               trap_ddcb,                      /* 0xdf */
+               trap_ddcb,                      /* 0xe0 */
+               trap_ddcb,                      /* 0xe1 */
+               trap_ddcb,                      /* 0xe2 */
+               trap_ddcb,                      /* 0xe3 */
+               trap_ddcb,                      /* 0xe4 */
+               trap_ddcb,                      /* 0xe5 */
+               op_sb4ixd,                      /* 0xe6 */
+               trap_ddcb,                      /* 0xe7 */
+               trap_ddcb,                      /* 0xe8 */
+               trap_ddcb,                      /* 0xe9 */
+               trap_ddcb,                      /* 0xea */
+               trap_ddcb,                      /* 0xeb */
+               trap_ddcb,                      /* 0xec */
+               trap_ddcb,                      /* 0xed */
+               op_sb5ixd,                      /* 0xee */
+               trap_ddcb,                      /* 0xef */
+               trap_ddcb,                      /* 0xf0 */
+               trap_ddcb,                      /* 0xf1 */
+               trap_ddcb,                      /* 0xf2 */
+               trap_ddcb,                      /* 0xf3 */
+               trap_ddcb,                      /* 0xf4 */
+               trap_ddcb,                      /* 0xf5 */
+               op_sb6ixd,                      /* 0xf6 */
+               trap_ddcb,                      /* 0xf7 */
+               trap_ddcb,                      /* 0xf8 */
+               trap_ddcb,                      /* 0xf9 */
+               trap_ddcb,                      /* 0xfa */
+               trap_ddcb,                      /* 0xfb */
+               trap_ddcb,                      /* 0xfc */
+               trap_ddcb,                      /* 0xfd */
+               op_sb7ixd,                      /* 0xfe */
+               trap_ddcb                       /* 0xff */
+       };
+
+       register int d;
+       register int t;
+
+       d = (signed char) memrdr(PC++);
+       t = (*op_ddcb[memrdr(PC++)]) (d); /* execute next opcode */
+
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xdd 0xcb of a 4 byte opcode.
+ */
+static int trap_ddcb(void)
+{
+       cpu_error = OPTRAP4;
+       cpu_state = STOPPED;
+       return(0);
+}
+
+static int op_tb0ixd(int data)         /* BIT 0,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb1ixd(int data)         /* BIT 1,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb2ixd(int data)         /* BIT 2,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb3ixd(int data)         /* BIT 3,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb4ixd(int data)         /* BIT 4,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG))
+                                : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb5ixd(int data)         /* BIT 5,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG))
+                                : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb6ixd(int data)         /* BIT 6,(IX+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IX + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG))
+                                : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb7ixd(int data)         /* BIT 7,(IX+d) */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (memrdr(IX + data) & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(20);
+}
+
+static int op_rb0ixd(int data)         /* RES 0,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~1);
+       return(23);
+}
+
+static int op_rb1ixd(int data)         /* RES 1,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~2);
+       return(23);
+}
+
+static int op_rb2ixd(int data)         /* RES 2,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~4);
+       return(23);
+}
+
+static int op_rb3ixd(int data)         /* RES 3,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~8);
+       return(23);
+}
+
+static int op_rb4ixd(int data)         /* RES 4,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~16);
+       return(23);
+}
+
+static int op_rb5ixd(int data)         /* RES 5,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~32);
+       return(23);
+}
+
+static int op_rb6ixd(int data)         /* RES 6,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~64);
+       return(23);
+}
+
+static int op_rb7ixd(int data)         /* RES 7,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) & ~128);
+       return(23);
+}
+
+static int op_sb0ixd(int data)         /* SET 0,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 1);
+       return(23);
+}
+
+static int op_sb1ixd(int data)         /* SET 1,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 2);
+       return(23);
+}
+
+static int op_sb2ixd(int data)         /* SET 2,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 4);
+       return(23);
+}
+
+static int op_sb3ixd(int data)         /* SET 3,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 8);
+       return(23);
+}
+
+static int op_sb4ixd(int data)         /* SET 4,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 16);
+       return(23);
+}
+
+static int op_sb5ixd(int data)         /* SET 5,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 32);
+       return(23);
+}
+
+static int op_sb6ixd(int data)         /* SET 6,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 64);
+       return(23);
+}
+
+static int op_sb7ixd(int data)         /* SET 7,(IX+d) */
+{
+       memwrt(IX + data, memrdr(IX + data) | 128);
+       return(23);
+}
+
+static int op_rlcixd(int data)         /* RLC (IX+d) */
+{
+       register BYTE P;
+        WORD addr;
+       int i;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       i = P & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (i) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rrcixd(int data)         /* RRC (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       i = P & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (i) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rlixd(int data)          /* RL (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (old_c_flag) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rrixd(int data)          /* RR (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (old_c_flag) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_slaixd(int data)         /* SLA (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_sraixd(int data)         /* SRA (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       i = P & 128;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P = (P >> 1) | i;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?(F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_srlixd(int data)         /* SRL (IX+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IX + data;
+       P = memrdr(addr);
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
diff --git a/sim/sim7.c b/sim/sim7.c
new file mode 100644 (file)
index 0000000..3f823d9
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Like the function "cpu_z80()" this one emulates 4 byte opcodes
+ *     starting with 0xfd 0xcb
+ */
+
+#include "sim.h"
+#include "simglb.h"
+#include "config.h"
+#ifdef FRONTPANEL
+#include "../../frontpanel/frontpanel.h"
+#endif
+#include "memory.h"
+
+static int trap_fdcb(void);
+static int op_tb0iyd(int), op_tb1iyd(int), op_tb2iyd(int), op_tb3iyd(int);
+static int op_tb4iyd(int), op_tb5iyd(int), op_tb6iyd(int), op_tb7iyd(int);
+static int op_rb0iyd(int), op_rb1iyd(int), op_rb2iyd(int), op_rb3iyd(int);
+static int op_rb4iyd(int), op_rb5iyd(int), op_rb6iyd(int), op_rb7iyd(int);
+static int op_sb0iyd(int), op_sb1iyd(int), op_sb2iyd(int), op_sb3iyd(int);
+static int op_sb4iyd(int), op_sb5iyd(int), op_sb6iyd(int), op_sb7iyd(int);
+static int op_rlciyd(int), op_rrciyd(int), op_rliyd(int), op_rriyd(int);
+static int op_slaiyd(int), op_sraiyd(int), op_srliyd(int);
+
+int op_fdcb_handel(void)
+{
+       static int (*op_fdcb[256]) () = {
+               trap_fdcb,                      /* 0x00 */
+               trap_fdcb,                      /* 0x01 */
+               trap_fdcb,                      /* 0x02 */
+               trap_fdcb,                      /* 0x03 */
+               trap_fdcb,                      /* 0x04 */
+               trap_fdcb,                      /* 0x05 */
+               op_rlciyd,                      /* 0x06 */
+               trap_fdcb,                      /* 0x07 */
+               trap_fdcb,                      /* 0x08 */
+               trap_fdcb,                      /* 0x09 */
+               trap_fdcb,                      /* 0x0a */
+               trap_fdcb,                      /* 0x0b */
+               trap_fdcb,                      /* 0x0c */
+               trap_fdcb,                      /* 0x0d */
+               op_rrciyd,                      /* 0x0e */
+               trap_fdcb,                      /* 0x0f */
+               trap_fdcb,                      /* 0x10 */
+               trap_fdcb,                      /* 0x11 */
+               trap_fdcb,                      /* 0x12 */
+               trap_fdcb,                      /* 0x13 */
+               trap_fdcb,                      /* 0x14 */
+               trap_fdcb,                      /* 0x15 */
+               op_rliyd,                       /* 0x16 */
+               trap_fdcb,                      /* 0x17 */
+               trap_fdcb,                      /* 0x18 */
+               trap_fdcb,                      /* 0x19 */
+               trap_fdcb,                      /* 0x1a */
+               trap_fdcb,                      /* 0x1b */
+               trap_fdcb,                      /* 0x1c */
+               trap_fdcb,                      /* 0x1d */
+               op_rriyd,                       /* 0x1e */
+               trap_fdcb,                      /* 0x1f */
+               trap_fdcb,                      /* 0x20 */
+               trap_fdcb,                      /* 0x21 */
+               trap_fdcb,                      /* 0x22 */
+               trap_fdcb,                      /* 0x23 */
+               trap_fdcb,                      /* 0x24 */
+               trap_fdcb,                      /* 0x25 */
+               op_slaiyd,                      /* 0x26 */
+               trap_fdcb,                      /* 0x27 */
+               trap_fdcb,                      /* 0x28 */
+               trap_fdcb,                      /* 0x29 */
+               trap_fdcb,                      /* 0x2a */
+               trap_fdcb,                      /* 0x2b */
+               trap_fdcb,                      /* 0x2c */
+               trap_fdcb,                      /* 0x2d */
+               op_sraiyd,                      /* 0x2e */
+               trap_fdcb,                      /* 0x2f */
+               trap_fdcb,                      /* 0x30 */
+               trap_fdcb,                      /* 0x31 */
+               trap_fdcb,                      /* 0x32 */
+               trap_fdcb,                      /* 0x33 */
+               trap_fdcb,                      /* 0x34 */
+               trap_fdcb,                      /* 0x35 */
+               trap_fdcb,                      /* 0x36 */
+               trap_fdcb,                      /* 0x37 */
+               trap_fdcb,                      /* 0x38 */
+               trap_fdcb,                      /* 0x39 */
+               trap_fdcb,                      /* 0x3a */
+               trap_fdcb,                      /* 0x3b */
+               trap_fdcb,                      /* 0x3c */
+               trap_fdcb,                      /* 0x3d */
+               op_srliyd,                      /* 0x3e */
+               trap_fdcb,                      /* 0x3f */
+               trap_fdcb,                      /* 0x40 */
+               trap_fdcb,                      /* 0x41 */
+               trap_fdcb,                      /* 0x42 */
+               trap_fdcb,                      /* 0x43 */
+               trap_fdcb,                      /* 0x44 */
+               trap_fdcb,                      /* 0x45 */
+               op_tb0iyd,                      /* 0x46 */
+               trap_fdcb,                      /* 0x47 */
+               trap_fdcb,                      /* 0x48 */
+               trap_fdcb,                      /* 0x49 */
+               trap_fdcb,                      /* 0x4a */
+               trap_fdcb,                      /* 0x4b */
+               trap_fdcb,                      /* 0x4c */
+               trap_fdcb,                      /* 0x4d */
+               op_tb1iyd,                      /* 0x4e */
+               trap_fdcb,                      /* 0x4f */
+               trap_fdcb,                      /* 0x50 */
+               trap_fdcb,                      /* 0x51 */
+               trap_fdcb,                      /* 0x52 */
+               trap_fdcb,                      /* 0x53 */
+               trap_fdcb,                      /* 0x54 */
+               trap_fdcb,                      /* 0x55 */
+               op_tb2iyd,                      /* 0x56 */
+               trap_fdcb,                      /* 0x57 */
+               trap_fdcb,                      /* 0x58 */
+               trap_fdcb,                      /* 0x59 */
+               trap_fdcb,                      /* 0x5a */
+               trap_fdcb,                      /* 0x5b */
+               trap_fdcb,                      /* 0x5c */
+               trap_fdcb,                      /* 0x5d */
+               op_tb3iyd,                      /* 0x5e */
+               trap_fdcb,                      /* 0x5f */
+               trap_fdcb,                      /* 0x60 */
+               trap_fdcb,                      /* 0x61 */
+               trap_fdcb,                      /* 0x62 */
+               trap_fdcb,                      /* 0x63 */
+               trap_fdcb,                      /* 0x64 */
+               trap_fdcb,                      /* 0x65 */
+               op_tb4iyd,                      /* 0x66 */
+               trap_fdcb,                      /* 0x67 */
+               trap_fdcb,                      /* 0x68 */
+               trap_fdcb,                      /* 0x69 */
+               trap_fdcb,                      /* 0x6a */
+               trap_fdcb,                      /* 0x6b */
+               trap_fdcb,                      /* 0x6c */
+               trap_fdcb,                      /* 0x6d */
+               op_tb5iyd,                      /* 0x6e */
+               trap_fdcb,                      /* 0x6f */
+               trap_fdcb,                      /* 0x70 */
+               trap_fdcb,                      /* 0x71 */
+               trap_fdcb,                      /* 0x72 */
+               trap_fdcb,                      /* 0x73 */
+               trap_fdcb,                      /* 0x74 */
+               trap_fdcb,                      /* 0x75 */
+               op_tb6iyd,                      /* 0x76 */
+               trap_fdcb,                      /* 0x77 */
+               trap_fdcb,                      /* 0x78 */
+               trap_fdcb,                      /* 0x79 */
+               trap_fdcb,                      /* 0x7a */
+               trap_fdcb,                      /* 0x7b */
+               trap_fdcb,                      /* 0x7c */
+               trap_fdcb,                      /* 0x7d */
+               op_tb7iyd,                      /* 0x7e */
+               trap_fdcb,                      /* 0x7f */
+               trap_fdcb,                      /* 0x80 */
+               trap_fdcb,                      /* 0x81 */
+               trap_fdcb,                      /* 0x82 */
+               trap_fdcb,                      /* 0x83 */
+               trap_fdcb,                      /* 0x84 */
+               trap_fdcb,                      /* 0x85 */
+               op_rb0iyd,                      /* 0x86 */
+               trap_fdcb,                      /* 0x87 */
+               trap_fdcb,                      /* 0x88 */
+               trap_fdcb,                      /* 0x89 */
+               trap_fdcb,                      /* 0x8a */
+               trap_fdcb,                      /* 0x8b */
+               trap_fdcb,                      /* 0x8c */
+               trap_fdcb,                      /* 0x8d */
+               op_rb1iyd,                      /* 0x8e */
+               trap_fdcb,                      /* 0x8f */
+               trap_fdcb,                      /* 0x90 */
+               trap_fdcb,                      /* 0x91 */
+               trap_fdcb,                      /* 0x92 */
+               trap_fdcb,                      /* 0x93 */
+               trap_fdcb,                      /* 0x94 */
+               trap_fdcb,                      /* 0x95 */
+               op_rb2iyd,                      /* 0x96 */
+               trap_fdcb,                      /* 0x97 */
+               trap_fdcb,                      /* 0x98 */
+               trap_fdcb,                      /* 0x99 */
+               trap_fdcb,                      /* 0x9a */
+               trap_fdcb,                      /* 0x9b */
+               trap_fdcb,                      /* 0x9c */
+               trap_fdcb,                      /* 0x9d */
+               op_rb3iyd,                      /* 0x9e */
+               trap_fdcb,                      /* 0x9f */
+               trap_fdcb,                      /* 0xa0 */
+               trap_fdcb,                      /* 0xa1 */
+               trap_fdcb,                      /* 0xa2 */
+               trap_fdcb,                      /* 0xa3 */
+               trap_fdcb,                      /* 0xa4 */
+               trap_fdcb,                      /* 0xa5 */
+               op_rb4iyd,                      /* 0xa6 */
+               trap_fdcb,                      /* 0xa7 */
+               trap_fdcb,                      /* 0xa8 */
+               trap_fdcb,                      /* 0xa9 */
+               trap_fdcb,                      /* 0xaa */
+               trap_fdcb,                      /* 0xab */
+               trap_fdcb,                      /* 0xac */
+               trap_fdcb,                      /* 0xad */
+               op_rb5iyd,                      /* 0xae */
+               trap_fdcb,                      /* 0xaf */
+               trap_fdcb,                      /* 0xb0 */
+               trap_fdcb,                      /* 0xb1 */
+               trap_fdcb,                      /* 0xb2 */
+               trap_fdcb,                      /* 0xb3 */
+               trap_fdcb,                      /* 0xb4 */
+               trap_fdcb,                      /* 0xb5 */
+               op_rb6iyd,                      /* 0xb6 */
+               trap_fdcb,                      /* 0xb7 */
+               trap_fdcb,                      /* 0xb8 */
+               trap_fdcb,                      /* 0xb9 */
+               trap_fdcb,                      /* 0xba */
+               trap_fdcb,                      /* 0xbb */
+               trap_fdcb,                      /* 0xbc */
+               trap_fdcb,                      /* 0xbd */
+               op_rb7iyd,                      /* 0xbe */
+               trap_fdcb,                      /* 0xbf */
+               trap_fdcb,                      /* 0xc0 */
+               trap_fdcb,                      /* 0xc1 */
+               trap_fdcb,                      /* 0xc2 */
+               trap_fdcb,                      /* 0xc3 */
+               trap_fdcb,                      /* 0xc4 */
+               trap_fdcb,                      /* 0xc5 */
+               op_sb0iyd,                      /* 0xc6 */
+               trap_fdcb,                      /* 0xc7 */
+               trap_fdcb,                      /* 0xc8 */
+               trap_fdcb,                      /* 0xc9 */
+               trap_fdcb,                      /* 0xca */
+               trap_fdcb,                      /* 0xcb */
+               trap_fdcb,                      /* 0xcc */
+               trap_fdcb,                      /* 0xcd */
+               op_sb1iyd,                      /* 0xce */
+               trap_fdcb,                      /* 0xcf */
+               trap_fdcb,                      /* 0xd0 */
+               trap_fdcb,                      /* 0xd1 */
+               trap_fdcb,                      /* 0xd2 */
+               trap_fdcb,                      /* 0xd3 */
+               trap_fdcb,                      /* 0xd4 */
+               trap_fdcb,                      /* 0xd5 */
+               op_sb2iyd,                      /* 0xd6 */
+               trap_fdcb,                      /* 0xd7 */
+               trap_fdcb,                      /* 0xd8 */
+               trap_fdcb,                      /* 0xd9 */
+               trap_fdcb,                      /* 0xda */
+               trap_fdcb,                      /* 0xdb */
+               trap_fdcb,                      /* 0xdc */
+               trap_fdcb,                      /* 0xdd */
+               op_sb3iyd,                      /* 0xde */
+               trap_fdcb,                      /* 0xdf */
+               trap_fdcb,                      /* 0xe0 */
+               trap_fdcb,                      /* 0xe1 */
+               trap_fdcb,                      /* 0xe2 */
+               trap_fdcb,                      /* 0xe3 */
+               trap_fdcb,                      /* 0xe4 */
+               trap_fdcb,                      /* 0xe5 */
+               op_sb4iyd,                      /* 0xe6 */
+               trap_fdcb,                      /* 0xe7 */
+               trap_fdcb,                      /* 0xe8 */
+               trap_fdcb,                      /* 0xe9 */
+               trap_fdcb,                      /* 0xea */
+               trap_fdcb,                      /* 0xeb */
+               trap_fdcb,                      /* 0xec */
+               trap_fdcb,                      /* 0xed */
+               op_sb5iyd,                      /* 0xee */
+               trap_fdcb,                      /* 0xef */
+               trap_fdcb,                      /* 0xf0 */
+               trap_fdcb,                      /* 0xf1 */
+               trap_fdcb,                      /* 0xf2 */
+               trap_fdcb,                      /* 0xf3 */
+               trap_fdcb,                      /* 0xf4 */
+               trap_fdcb,                      /* 0xf5 */
+               op_sb6iyd,                      /* 0xf6 */
+               trap_fdcb,                      /* 0xf7 */
+               trap_fdcb,                      /* 0xf8 */
+               trap_fdcb,                      /* 0xf9 */
+               trap_fdcb,                      /* 0xfa */
+               trap_fdcb,                      /* 0xfb */
+               trap_fdcb,                      /* 0xfc */
+               trap_fdcb,                      /* 0xfd */
+               op_sb7iyd,                      /* 0xfe */
+               trap_fdcb                       /* 0xff */
+       };
+
+       register int d;
+       register int t;
+
+       d = (signed char) memrdr(PC++);
+       t = (*op_fdcb[memrdr(PC++)]) (d); /* execute next opcode */
+
+       return(t);
+}
+
+/*
+ *     This function traps all illegal opcodes following the
+ *     initial 0xfd 0xcb of a 4 byte opcode.
+ */
+static int trap_fdcb(void)
+{
+       cpu_error = OPTRAP4;
+       cpu_state = STOPPED;
+       return(0L);
+}
+
+static int op_tb0iyd(int data)         /* BIT 0,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb1iyd(int data)         /* BIT 1,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb2iyd(int data)         /* BIT 2,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb3iyd(int data)         /* BIT 3,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG))
+                               : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb4iyd(int data)         /* BIT 4,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG))
+                                : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb5iyd(int data)         /* BIT 5,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr( IY + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG))
+                                 : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb6iyd(int data)         /* BIT 6,(IY+d) */
+{
+       F &= ~(N_FLAG | S_FLAG);
+       F |= H_FLAG;
+       (memrdr(IY + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG))
+                                : (F |= (Z_FLAG | P_FLAG));
+       return(20);
+}
+
+static int op_tb7iyd(int data)         /* BIT 7,(IY+d) */
+{
+       F &= ~N_FLAG;
+       F |= H_FLAG;
+       if (memrdr(IY + data) & 128) {
+               F &= ~(Z_FLAG | P_FLAG);
+               F |= S_FLAG;
+       } else {
+               F |= (Z_FLAG | P_FLAG);
+               F &= ~S_FLAG;
+       }
+       return(20);
+}
+
+static int op_rb0iyd(int data)         /* RES 0,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~1);
+       return(23);
+}
+
+static int op_rb1iyd(int data)         /* RES 1,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~2);
+       return(23);
+}
+
+static int op_rb2iyd(int data)         /* RES 2,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~4);
+       return(23);
+}
+
+static int op_rb3iyd(int data)         /* RES 3,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~8);
+       return(23);
+}
+
+static int op_rb4iyd(int data)         /* RES 4,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~16);
+       return(23);
+}
+
+static int op_rb5iyd(int data)         /* RES 5,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~32);
+       return(23);
+}
+
+static int op_rb6iyd(int data)         /* RES 6,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~64);
+       return(23);
+}
+
+static int op_rb7iyd(int data)         /* RES 7,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) & ~128);
+       return(23);
+}
+
+static int op_sb0iyd(int data)         /* SET 0,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 1);
+       return(23);
+}
+
+static int op_sb1iyd(int data)         /* SET 1,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 2);
+       return(23);
+}
+
+static int op_sb2iyd(int data)         /* SET 2,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 4);
+       return(23);
+}
+
+static int op_sb3iyd(int data)         /* SET 3,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 8);
+       return(23);
+}
+
+static int op_sb4iyd(int data)         /* SET 4,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 16);
+       return(23);
+}
+
+static int op_sb5iyd(int data)         /* SET 5,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 32);
+       return(23);
+}
+
+static int op_sb6iyd(int data)         /* SET 6,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 64);
+       return(23);
+}
+
+static int op_sb7iyd(int data)         /* SET 7,(IY+d) */
+{
+       memwrt(IY + data, memrdr(IY + data) | 128);
+       return(23);
+}
+
+static int op_rlciyd(int data)         /* RLC (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       i = P & 128;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (i) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rrciyd(int data)         /* RRC (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       i = P & 1;
+       (i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (i) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rliyd(int data)          /* RL (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       if (old_c_flag) P |= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_rriyd(int data)          /* RR (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int old_c_flag;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       old_c_flag = F & C_FLAG;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       if (old_c_flag) P |= 128;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_slaiyd(int data)         /* SLA (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       (P & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P <<= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_sraiyd(int data)         /* SRA (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+       int i;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       i = P & 128;
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P = (P >> 1) | i;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
+
+static int op_srliyd(int data)         /* SRL (IY+d) */
+{
+       register BYTE P;
+       WORD addr;
+
+       addr = IY + data;
+       P = memrdr(addr);
+       (P & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
+       P >>= 1;
+       memwrt(addr, P);
+       F &= ~(H_FLAG | N_FLAG);
+       (P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
+       (P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
+       (parity[P]) ?   (F &= ~P_FLAG) : (F |= P_FLAG);
+       return(23);
+}
diff --git a/sim/simctl.c b/sim/simctl.c
new file mode 100644 (file)
index 0000000..fccd8b1
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 some improvements here and there
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 20-JUL-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <termios.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "sim.h"
+#include "simglb.h"
+#include "memory.h"
+#include "../../iodevices/unix_terminal.h"
+
+int boot(void);
+
+extern int load_file(char *);
+extern int load_core(void);
+extern void cpu_z80(void), cpu_8080(void);
+extern struct dskdef disks[];
+
+struct termios old_term, new_term;
+
+/*
+ *     This function initialises the terminal, loads boot code
+ *     and then the Z80 CPU emulation is started.
+ */
+void mon(void)
+{
+       /* load boot code into memory */
+       if (boot())
+               exit(1);
+
+       /* empty buffer for teletype */
+       fflush(stdout);
+
+       /* initialise terminal */
+       set_unix_terminal();
+
+       /* start CPU emulation */
+       cpu_state = CONTIN_RUN;
+       cpu_error = NONE;
+       switch(cpu) {
+       case Z80:
+               cpu_z80();
+               break;
+       case I8080:
+               cpu_8080();
+               break;
+       }
+
+       /* reset terminal */
+       reset_unix_terminal();
+
+       /* check for CPU emulation errors and report */
+       switch (cpu_error) {
+       case NONE:
+               break;
+       case OPHALT:
+               printf("\nINT disabled and HALT Op-Code reached at %04x\n",
+                      PC - 1);
+               break;
+       case IOTRAPIN:
+               printf("\nI/O input Trap at %04x, port %02x\n",
+                       PC, io_port);
+               break;
+       case IOTRAPOUT:
+               printf("\nI/O output Trap at %04x, port %02x\n",
+                       PC, io_port);
+               break;
+       case IOHALT:
+               printf("\nSystem halted, bye.\n");
+               break;
+       case IOERROR:
+               printf("\nFatal I/O Error at %04x\n", PC);
+               break;
+       case OPTRAP1:
+               printf("\nOp-code trap at %04x %02x\n", PC - 1,
+                      *(mem_base() + PC - 1));
+               break;
+       case OPTRAP2:
+               printf("\nOp-code trap at %04x %02x %02x\n",
+                      PC - 2, *(mem_base() + PC - 2), *(mem_base() + PC - 1));
+               break;
+       case OPTRAP4:
+               printf("\nOp-code trap at %04x %02x %02x %02x %02x\n",
+                      PC - 4, *(mem_base() + PC - 4), *(mem_base() + PC - 3),
+                      *(mem_base() + PC - 2), *(mem_base() + PC - 1));
+               break;
+       case USERINT:
+               printf("\nUser Interrupt at %04x\n", PC);
+               break;
+       case POWEROFF:
+               break;
+       default:
+               printf("\nUnknown error %d\n", cpu_error);
+               break;
+       }
+}
+
+/*
+ *     Load boot code from a saved core image, a boot file or from
+ *     first sector of disk drive A:
+ */
+int boot(void)
+{
+       register int fd;
+       struct stat sbuf;
+       static char fn[4096];
+       static char err[256];
+
+       puts("\r\nBooting...\r\n");
+
+       if (l_flag) {
+               return(load_core());
+       }
+
+       if (x_flag) {
+               return(load_file(xfn));
+       }
+
+       /* if option -d is used disks are there */
+       if (diskdir != NULL) {
+               strcpy(fn, diskd);
+       } else {
+               /* if not first try ./disks */
+               if ((stat("./disks", &sbuf) == 0) && S_ISDIR(sbuf.st_mode)) {
+                       strcpy(fn, "./disks");
+               /* nope, then DISKSDIR as set in Makefile */
+               } else {
+                       strcpy(fn, DISKSDIR);
+               }
+       }
+
+       strcat(fn, "/");
+       strcat(fn, disks[0].fn);
+
+       strcpy(err, "file ");
+       strcat(err, fn);
+
+       if ((fd = open(fn, O_RDONLY)) == -1) {
+               perror(err);
+               puts("\r\n");
+               close(fd);
+               return(1);
+       }
+       if (read(fd, mem_base(), 128) != 128) {
+               perror(err);
+               puts("\r\n");
+               close(fd);
+               return(1);
+       }
+       close(fd);
+       return(0);
+}
diff --git a/sim/simfun.c b/sim/simfun.c
new file mode 100644 (file)
index 0000000..1422c0f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     This module contains some commonly used functions
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <termios.h>
+#include "sim.h"
+
+/*
+ *     atoi for hexadecimal numbers
+ */
+int exatoi(char *str)
+{
+       register int num = 0;
+
+       while (isxdigit((int)*str)) {
+               num *= 16;
+               if (*str <= '9')
+                       num += *str - '0';
+               else
+                       num += toupper((int)*str) - '7';
+               str++;
+       }
+       return(num);
+}
+
+/*
+ *     Wait for a single keystroke without echo
+ */
+int getkey(void)
+{
+       register int c;
+       struct termios old_term, new_term;
+
+       tcgetattr(0, &old_term);
+       new_term = old_term;
+       new_term.c_lflag &= ~(ICANON | ECHO);
+       new_term.c_cc[VMIN] = 1;
+       tcsetattr(0, TCSADRAIN, &new_term);
+       c = getchar();
+       tcsetattr(0, TCSADRAIN, &old_term);
+       return(c);
+}
diff --git a/sim/simglb.c b/sim/simglb.c
new file mode 100644 (file)
index 0000000..bc8cd96
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     This module contains the global variables other than memory management
+ */
+
+#include <stddef.h>
+#include "sim.h"
+
+#define MAXCHAN 5      /* max number of channels for I/O busy detect */
+
+/*
+ *     Type of CPU, either Z80 or 8080
+ */
+int cpu = DEFAULT_CPU;
+
+/*
+ *     CPU Registers
+ */
+BYTE A,B,C,D,E,H,L;            /* primary registers */
+int  F;                                /* normally 8-Bit, but int is faster */
+WORD IX, IY;                   /* Z80 index registers */
+BYTE A_,B_,C_,D_,E_,H_,L_;     /* Z80 alternate registers */
+int  F_;
+WORD PC;                       /* programm counter */
+WORD SP;                       /* stackpointer */
+BYTE I;                                /* Z80 interrupt register */
+BYTE IFF;                      /* interrupt flags */
+long R;                                /* Z80 refresh register */
+                               /* is normally a 8 bit register */
+                               /* the larger bits are used to measure the */
+                               /* clock frequency */
+
+#ifdef BUS_8080
+BYTE cpu_bus;                  /* CPU bus status, for frontpanels */
+int m1_step;                   /* flag for waiting at M1 in single step */
+#endif
+
+BYTE io_port;                  /* I/O port used */
+BYTE io_data;                  /* data on I/O port */
+int busy_loop_cnt[MAXCHAN];    /* counters for I/O busy loop detection */
+
+BYTE cpu_state;                        /* state of CPU emulation */
+int cpu_error;                 /* error status of CPU emulation */
+int int_mode;                  /* CPU interrupt mode (IM 0, IM 1, IM 2) */
+int int_nmi;                   /* non maskable interrupt request */
+int int_int;                   /* interrupt request */
+int int_data = -1;             /* data from interrupting device on data bus */
+int int_protection;            /* to delay interrupts after EI */
+BYTE bus_request;              /* request address/data bus from CPU */
+int tmax;                      /* max t-states to execute in 10ms */
+
+/*
+ *     Variables for history memory
+ */
+#ifdef HISIZE
+struct history his[HISIZE];    /* memory to hold trace informations */
+int h_next;                    /* index into trace memory */
+int h_flag;                    /* flag for trace memory overrun */
+#endif
+
+/*
+ *     Variables for breakpoint memory
+ */
+#ifdef SBSIZE
+struct softbreak soft[SBSIZE]; /* memory to hold breakpoint informations */
+int sb_next;                   /* index into breakpoint memory */
+#endif
+
+/*
+ *     Variables for runtime measurement
+ */
+long t_states;                 /* number of counted T states */
+int t_flag;                    /* flag, 1 = on, 0 = off */
+WORD t_start = 65535;          /* start address for measurement */
+WORD t_end = 65535;            /* end address for measurement */
+
+/*
+ *     Variables for frontpanel emulation
+ */
+#ifdef FRONTPANEL
+unsigned long long fp_clock;   /* simulation clock */
+float fp_fps = 30.0;           /* frame rate, default 30 usually works */
+WORD fp_led_address;           /* lights for address bus */
+BYTE fp_led_data;              /* lights for data bus */
+WORD address_switch;           /* address and programmed input switches */
+BYTE fp_led_output = 0xff;     /* IMSAI/Cromemco programmed output, inverted */
+#endif
+
+/*
+ *     Flags to control operation of simulation
+ */
+int s_flag;                    /* flag for -s option */
+int l_flag;                    /* flag for -l option */
+int m_flag = -1;               /* flag for -m option */
+int x_flag;                    /* flag for -x option */
+int i_flag;                    /* flag for -i option */
+int f_flag;                    /* flag for -f option */
+#ifdef Z80_UNDOC
+int u_flag;                    /* flag for -u option */
+#endif
+
+/*
+ *     Variables for configuration and disk images
+ */
+char xfn[4096];                        /* buffer for filename (option -x) */
+char *diskdir = NULL;          /* path for disk images (option -d) */
+char diskd[4096];              /* disk image directory in use */
+char confdir[4096];            /* path for configuration files */
+
+/*
+ *     Precompiled table to get parity as fast as possible
+ */
+int parity[256] = {
+               0 /* 00000000 */, 1 /* 00000001 */, 1 /* 00000010 */,
+               0 /* 00000011 */, 1 /* 00000100 */, 0 /* 00000101 */,
+               0 /* 00000110 */, 1 /* 00000111 */, 1 /* 00001000 */,
+               0 /* 00001001 */, 0 /* 00001010 */, 1 /* 00001011 */,
+               0 /* 00001100 */, 1 /* 00001101 */, 1 /* 00001110 */,
+               0 /* 00001111 */, 1 /* 00010000 */, 0 /* 00010001 */,
+               0 /* 00010010 */, 1 /* 00010011 */, 0 /* 00010100 */,
+               1 /* 00010101 */, 1 /* 00010110 */, 0 /* 00010111 */,
+               0 /* 00011000 */, 1 /* 00011001 */, 1 /* 00011010 */,
+               0 /* 00011011 */, 1 /* 00011100 */, 0 /* 00011101 */,
+               0 /* 00011110 */, 1 /* 00011111 */, 1 /* 00100000 */,
+               0 /* 00100001 */, 0 /* 00100010 */, 1 /* 00100011 */,
+               0 /* 00100100 */, 1 /* 00100101 */, 1 /* 00100110 */,
+               0 /* 00100111 */, 0 /* 00101000 */, 1 /* 00101001 */,
+               1 /* 00101010 */, 0 /* 00101011 */, 1 /* 00101100 */,
+               0 /* 00101101 */, 0 /* 00101110 */, 1 /* 00101111 */,
+               0 /* 00110000 */, 1 /* 00110001 */, 1 /* 00110010 */,
+               0 /* 00110011 */, 1 /* 00110100 */, 0 /* 00110101 */,
+               0 /* 00110110 */, 1 /* 00110111 */, 1 /* 00111000 */,
+               0 /* 00111001 */, 0 /* 00111010 */, 1 /* 00111011 */,
+               0 /* 00111100 */, 1 /* 00111101 */, 1 /* 00111110 */,
+               0 /* 00111111 */, 1 /* 01000000 */, 0 /* 01000001 */,
+               0 /* 01000010 */, 1 /* 01000011 */, 0 /* 01000100 */,
+               1 /* 01000101 */, 1 /* 01000110 */, 0 /* 01000111 */,
+               0 /* 01001000 */, 1 /* 01001001 */, 1 /* 01001010 */,
+               0 /* 01001011 */, 1 /* 01001100 */, 0 /* 01001101 */,
+               0 /* 01001110 */, 1 /* 01001111 */, 0 /* 01010000 */,
+               1 /* 01010001 */, 1 /* 01010010 */, 0 /* 01010011 */,
+               1 /* 01010100 */, 0 /* 01010101 */, 0 /* 01010110 */,
+               1 /* 01010111 */, 1 /* 01011000 */, 0 /* 01011001 */,
+               0 /* 01011010 */, 1 /* 01011011 */, 0 /* 01011100 */,
+               1 /* 01011101 */, 1 /* 01011110 */, 0 /* 01011111 */,
+               0 /* 01100000 */, 1 /* 01100001 */, 1 /* 01100010 */,
+               0 /* 01100011 */, 1 /* 01100100 */, 0 /* 01100101 */,
+               0 /* 01100110 */, 1 /* 01100111 */, 1 /* 01101000 */,
+               0 /* 01101001 */, 0 /* 01101010 */, 1 /* 01101011 */,
+               0 /* 01101100 */, 1 /* 01101101 */, 1 /* 01101110 */,
+               0 /* 01101111 */, 1 /* 01110000 */, 0 /* 01110001 */,
+               0 /* 01110010 */, 1 /* 01110011 */, 0 /* 01110100 */,
+               1 /* 01110101 */, 1 /* 01110110 */, 0 /* 01110111 */,
+               0 /* 01111000 */, 1 /* 01111001 */, 1 /* 01111010 */,
+               0 /* 01111011 */, 1 /* 01111100 */, 0 /* 01111101 */,
+               0 /* 01111110 */, 1 /* 01111111 */,
+               1 /* 10000000 */, 0 /* 10000001 */, 0 /* 10000010 */,
+               1 /* 10000011 */, 0 /* 10000100 */, 1 /* 10000101 */,
+               1 /* 10000110 */, 0 /* 10000111 */, 0 /* 10001000 */,
+               1 /* 10001001 */, 1 /* 10001010 */, 0 /* 10001011 */,
+               1 /* 10001100 */, 0 /* 10001101 */, 0 /* 10001110 */,
+               1 /* 10001111 */, 0 /* 10010000 */, 1 /* 10010001 */,
+               1 /* 10010010 */, 0 /* 10010011 */, 1 /* 10010100 */,
+               0 /* 10010101 */, 0 /* 10010110 */, 1 /* 10010111 */,
+               1 /* 10011000 */, 0 /* 10011001 */, 0 /* 10011010 */,
+               1 /* 10011011 */, 0 /* 10011100 */, 1 /* 10011101 */,
+               1 /* 10011110 */, 0 /* 10011111 */, 0 /* 10100000 */,
+               1 /* 10100001 */, 1 /* 10100010 */, 0 /* 10100011 */,
+               1 /* 10100100 */, 0 /* 10100101 */, 0 /* 10100110 */,
+               1 /* 10100111 */, 1 /* 10101000 */, 0 /* 10101001 */,
+               0 /* 10101010 */, 1 /* 10101011 */, 0 /* 10101100 */,
+               1 /* 10101101 */, 1 /* 10101110 */, 0 /* 10101111 */,
+               1 /* 10110000 */, 0 /* 10110001 */, 0 /* 10110010 */,
+               1 /* 10110011 */, 0 /* 10110100 */, 1 /* 10110101 */,
+               1 /* 10110110 */, 0 /* 10110111 */, 0 /* 10111000 */,
+               1 /* 10111001 */, 1 /* 10111010 */, 0 /* 10111011 */,
+               1 /* 10111100 */, 0 /* 10111101 */, 0 /* 10111110 */,
+               1 /* 10111111 */, 0 /* 11000000 */, 1 /* 11000001 */,
+               1 /* 11000010 */, 0 /* 11000011 */, 1 /* 11000100 */,
+               0 /* 11000101 */, 0 /* 11000110 */, 1 /* 11000111 */,
+               1 /* 11001000 */, 0 /* 11001001 */, 0 /* 11001010 */,
+               1 /* 11001011 */, 0 /* 11001100 */, 1 /* 11001101 */,
+               1 /* 11001110 */, 0 /* 11001111 */, 1 /* 11010000 */,
+               0 /* 11010001 */, 0 /* 11010010 */, 1 /* 11010011 */,
+               0 /* 11010100 */, 1 /* 11010101 */, 1 /* 11010110 */,
+               0 /* 11010111 */, 0 /* 11011000 */, 1 /* 11011001 */,
+               1 /* 11011010 */, 0 /* 11011011 */, 1 /* 11011100 */,
+               0 /* 11011101 */, 0 /* 11011110 */, 1 /* 11011111 */,
+               1 /* 11100000 */, 0 /* 11100001 */, 0 /* 11100010 */,
+               1 /* 11100011 */, 0 /* 11100100 */, 1 /* 11100101 */,
+               1 /* 11100110 */, 0 /* 11100111 */, 0 /* 11101000 */,
+               1 /* 11101001 */, 1 /* 11101010 */, 0 /* 11101011 */,
+               1 /* 11101100 */, 0 /* 11101101 */, 0 /* 11101110 */,
+               1 /* 11101111 */, 0 /* 11110000 */, 1 /* 11110001 */,
+               1 /* 11110010 */, 0 /* 11110011 */, 1 /* 11110100 */,
+               0 /* 11110101 */, 0 /* 11110110 */, 1 /* 11110111 */,
+               1 /* 11111000 */, 0 /* 11111001 */, 0 /* 11111010 */,
+               1 /* 11111011 */, 0 /* 11111100 */, 1 /* 11111101 */,
+               1 /* 11111110 */, 0 /* 11111111 */
+};
diff --git a/sim/simglb.h b/sim/simglb.h
new file mode 100644 (file)
index 0000000..b9a96de
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     Declaration of variables in simglb.c
+ */
+
+extern int     cpu;
+
+extern BYTE    A, B, C, D, E, H, L, A_, B_, C_, D_, E_, H_, L_, I, IFF;
+extern WORD    PC, SP, IX, IY;
+extern int     F, F_;
+extern long    R;
+extern BYTE    io_port, io_data;
+
+#ifdef BUS_8080
+extern BYTE    cpu_bus;
+extern int     m1_step;
+#endif
+
+extern BYTE    cpu_state, bus_request;
+extern int     int_data;
+
+extern int     s_flag, l_flag, m_flag, x_flag, break_flag, i_flag, f_flag,
+               cpu_error, int_nmi, int_int, int_mode, parity[], sb_next,
+               int_protection;
+
+#ifdef Z80_UNDOC
+extern int     u_flag;
+#endif
+
+extern int     tmax;
+extern int     busy_loop_cnt[];
+
+extern char    xfn[];
+extern char    *diskdir, diskd[];
+extern char    confdir[];
+
+#ifdef HISIZE
+extern struct  history his[];
+extern int     h_next, h_flag;
+#endif
+
+#ifdef SBSIZE
+extern struct  softbreak soft[];
+#endif
+
+extern long    t_states;
+extern int     t_flag;
+extern WORD    t_start, t_end;
+
+#ifdef FRONTPANEL
+extern unsigned long long fp_clock;
+extern float   fp_fps;
+extern WORD    fp_led_address;
+extern BYTE    fp_led_data;
+extern WORD    address_switch;
+extern BYTE    fp_led_output;
+#endif
diff --git a/sim/simint.c b/sim/simint.c
new file mode 100644 (file)
index 0000000..fbc770a
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Z80SIM  -  a Z80-CPU simulator
+ *
+ * Copyright (C) 1987-2017 by Udo Munk
+ *
+ * History:
+ * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
+ * 11-JAN-89 Release 1.1
+ * 08-FEB-89 Release 1.2
+ * 13-MAR-89 Release 1.3
+ * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
+ * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
+ * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
+ *                       and some optimisation
+ * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
+ * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
+ * 18-NOV-06 Release 1.9  modified to work with CP/M sources
+ * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
+ * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
+ * 25-DEC-06 Release 1.12 CPU speed option
+ * 19-FEB-07 Release 1.13 various improvements
+ * 06-OCT-07 Release 1.14 bug fixes and improvements
+ * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
+ * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
+ * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
+ * 24-JAN-14 Release 1.18 bug fixes and improvements
+ * 02-MAR-14 Release 1.19 source cleanup and improvements
+ * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
+ * 29-MAR-14 Release 1.21 many improvements
+ * 29-MAY-14 Release 1.22 improved networking and bugfixes
+ * 04-JUN-14 Release 1.23 added 8080 emulation
+ * 06-SEP-14 Release 1.24 bugfixes and improvements
+ * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
+ * 18-APR-15 Release 1.26 bugfixes and improvements
+ * 18-JAN-16 Release 1.27 bugfixes and improvements
+ * 05-MAY-16 Release 1.28 improved usability
+ * 20-NOV-16 Release 1.29 bugfixes and improvements
+ * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
+ * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
+ * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
+ * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
+ * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
+ * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
+ * 21-DEC-17 Release 1.36 bugfixes and improvements
+ */
+
+/*
+ *     This module contain the interrupt handlers for the OS:
+ *
+ *     int_on()        : initialise interrupt handlers
+ *     int_off()       : reset interrupts to default
+ *     user_int()      : handler for user interrupt (CNTL-C)
+ *     quit_int()      : handler for signal "quit" (CNTL-\)
+ *     term_int()      : handler for signal SIGTERM when process is killed
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <signal.h>
+#include "sim.h"
+#include "simglb.h"
+
+static void user_int(int), quit_int(int), term_int(int);
+extern void exit_io(void);
+extern struct termios old_term;
+
+void int_on(void)
+{
+       static struct sigaction newact;
+
+       newact.sa_handler = user_int;
+       memset((void *) &newact.sa_mask, 0, sizeof(newact.sa_mask));
+       newact.sa_flags = 0;
+       sigaction(SIGINT, &newact, NULL);
+       newact.sa_handler = quit_int;
+       sigaction(SIGQUIT, &newact, NULL);
+       newact.sa_handler = term_int;
+       sigaction(SIGTERM, &newact, NULL);
+}
+
+void int_off(void)
+{
+       static struct sigaction newact;
+
+       newact.sa_handler = SIG_DFL;
+       memset((void *) &newact.sa_mask, 0, sizeof(newact.sa_mask));
+       newact.sa_flags = 0;
+       sigaction(SIGINT, &newact, NULL);
+       sigaction(SIGQUIT, &newact, NULL);
+       sigaction(SIGTERM, &newact, NULL);
+}
+
+static void user_int(int sig)
+{
+       sig = sig;      /* to avoid compiler warning */
+
+       cpu_error = USERINT;
+       cpu_state = STOPPED;
+}
+
+static void quit_int(int sig)
+{
+       sig = sig;      /* to avoid compiler warning */
+
+       cpu_error = USERINT;
+       cpu_state = STOPPED;
+}
+
+static void term_int(int sig)
+{
+       sig = sig;      /* to avoid compiler warning */
+
+       exit_io();
+       int_off();
+       tcsetattr(0, TCSADRAIN, &old_term);
+       puts("\nKilled by user");
+       exit(0);
+}
diff --git a/sim/ulnsrc b/sim/ulnsrc
new file mode 100755 (executable)
index 0000000..457699c
--- /dev/null
@@ -0,0 +1,6 @@
+# use this to unlink the common parts of Z80 simulation
+
+rm -f sim[0-7]*.c
+rm -f simfun.c
+rm -f simint.c
+rm -f simglb.[hc]
diff --git a/z180/z180.cpp b/z180/z180.cpp
new file mode 100644 (file)
index 0000000..b9b3c0f
--- /dev/null
@@ -0,0 +1,2645 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/*****************************************************************************
+ *
+ *   z180.c
+ *   Portable Z180 emulator V0.3
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+
+    TODO:
+        - HALT processing is not yet perfect. The manual states that
+          during HALT, all dma and internal i/o incl. timers continue to
+          work. Currently, only timers are implemented. Ideally, the
+          burn_cycles routine would go away and halt processing be
+          implemented in cpu_execute.
+ *****************************************************************************/
+
+/*****************************************************************************
+
+Z180 Info:
+
+Known clock speeds (from ZiLOG): 6, 8, 10, 20 & 33MHz
+
+ZiLOG Z180 codes:
+
+  Speed: 10 = 10MHZ
+         20 = 20MHz
+         33 = 33MHz
+Package: P = 60-Pin Plastic DIP
+         V = 68-Pin PLCC
+         F = 80-Pin QFP
+   Temp: S = 0C to +70C
+         E = -40C to +85C
+
+Environmental Flow: C = Plastic Standard
+
+
+Example from Ms.Pac-Man/Galaga - 20 year Reunion hardare (see src/mame/drivers/20pacgal.c):
+
+   CPU is Z8S18020VSC = Z180, 20MHz, 68-Pin PLCC, 0C to +70C, Plastic Standard
+
+
+Other CPUs that use a compatible Z180 core:
+
+Hitachi HD647180 series:
+  Available in QFP80, PLCC84 & DIP90 packages (the QFP80 is not pinout compatible)
+  The HD647180 also has an internal ROM
+
+ *****************************************************************************/
+
+#include "emu.h"
+#include "z180.h"
+#include "z180dasm.h"
+#include "debugger.h"
+
+//#define VERBOSE 1
+#include "logmacro.h"
+
+/* interrupt priorities */
+#define Z180_INT_TRAP   0           /* Undefined opcode */
+#define Z180_INT_NMI    1           /* NMI */
+#define Z180_INT_IRQ0   2           /* Execute IRQ1 */
+#define Z180_INT_IRQ1   3           /* Execute IRQ1 */
+#define Z180_INT_IRQ2   4           /* Execute IRQ2 */
+#define Z180_INT_PRT0   5           /* Internal PRT channel 0 */
+#define Z180_INT_PRT1   6           /* Internal PRT channel 1 */
+#define Z180_INT_DMA0   7           /* Internal DMA channel 0 */
+#define Z180_INT_DMA1   8           /* Internal DMA channel 1 */
+#define Z180_INT_CSIO   9           /* Internal CSI/O */
+#define Z180_INT_ASCI0  10          /* Internal ASCI channel 0 */
+#define Z180_INT_ASCI1  11          /* Internal ASCI channel 1 */
+#define Z180_INT_MAX    Z180_INT_ASCI1
+
+/****************************************************************************/
+/* The Z180 registers. HALT is set to 1 when the CPU is halted, the refresh */
+/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128)    */
+/****************************************************************************/
+
+DEFINE_DEVICE_TYPE(Z180, z180_device, "z180", "Zilog Z180")
+
+
+z180_device::z180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+       : cpu_device(mconfig, Z180, tag, owner, clock)
+       , z80_daisy_chain_interface(mconfig, *this)
+       , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0)
+       , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0)
+       , m_decrypted_opcodes_config("program", ENDIANNESS_LITTLE, 8, 20, 0)
+{
+}
+
+std::unique_ptr<util::disasm_interface> z180_device::create_disassembler()
+{
+       return std::make_unique<z180_disassembler>();
+}
+
+#define CF  0x01
+#define NF  0x02
+#define PF  0x04
+#define VF  PF
+#define XF  0x08
+#define HF  0x10
+#define YF  0x20
+#define ZF  0x40
+#define SF  0x80
+
+/* I/O line status flags */
+#define Z180_CKA0     0x00000001  /* I/O asynchronous clock 0 (active high) or DREQ0 (mux) */
+#define Z180_CKA1     0x00000002  /* I/O asynchronous clock 1 (active high) or TEND1 (mux) */
+#define Z180_CKS      0x00000004  /* I/O serial clock (active high) */
+#define Z180_CTS0     0x00000100  /* I   clear to send 0 (active low) */
+#define Z180_CTS1     0x00000200  /* I   clear to send 1 (active low) or RXS (mux) */
+#define Z180_DCD0     0x00000400  /* I   data carrier detect (active low) */
+#define Z180_DREQ0    0x00000800  /* I   data request DMA ch 0 (active low) or CKA0 (mux) */
+#define Z180_DREQ1    0x00001000  /* I   data request DMA ch 1 (active low) */
+#define Z180_RXA0     0x00002000  /* I   asynchronous receive data 0 (active high) */
+#define Z180_RXA1     0x00004000  /* I   asynchronous receive data 1 (active high) */
+#define Z180_RXS      0x00008000  /* I   clocked serial receive data (active high) or CTS1 (mux) */
+#define Z180_RTS0     0x00010000  /*   O request to send (active low) */
+#define Z180_TEND0    0x00020000  /*   O transfer end 0 (active low) or CKA1 (mux) */
+#define Z180_TEND1    0x00040000  /*   O transfer end 1 (active low) */
+#define Z180_A18_TOUT 0x00080000  /*   O transfer out (PRT channel, active low) or A18 (mux) */
+#define Z180_TXA0     0x00100000  /*   O asynchronous transmit data 0 (active high) */
+#define Z180_TXA1     0x00200000  /*   O asynchronous transmit data 1 (active high) */
+#define Z180_TXS      0x00400000  /*   O clocked serial transmit data (active high) */
+
+bool z180_device::get_tend0()
+{
+       return !!(m_iol & Z180_TEND0);
+}
+
+bool z180_device::get_tend1()
+{
+       return !!(m_iol & Z180_TEND1);
+}
+
+/*
+ * Prevent warnings on NetBSD.  All identifiers beginning with an underscore
+ * followed by an uppercase letter are reserved by the C standard (ISO/IEC
+ * 9899:1999, 7.1.3) to be used by the implementation.  It'd be best to rename
+ * all such instances, but this is less intrusive and error-prone.
+ */
+#undef _B
+#undef _C
+#undef _L
+
+#define _PPC    m_PREPC.d /* previous program counter */
+
+#define _PCD    m_PC.d
+#define _PC     m_PC.w.l
+
+#define _SPD    m_SP.d
+#define _SP     m_SP.w.l
+
+#define _AFD    m_AF.d
+#define _AF     m_AF.w.l
+#define _A      m_AF.b.h
+#define _F      m_AF.b.l
+
+#define _BCD    m_BC.d
+#define _BC     m_BC.w.l
+#define _B      m_BC.b.h
+#define _C      m_BC.b.l
+
+#define _DED    m_DE.d
+#define _DE     m_DE.w.l
+#define _D      m_DE.b.h
+#define _E      m_DE.b.l
+
+#define _HLD    m_HL.d
+#define _HL     m_HL.w.l
+#define _H      m_HL.b.h
+#define _L      m_HL.b.l
+
+#define _IXD    m_IX.d
+#define _IX     m_IX.w.l
+#define _HX     m_IX.b.h
+#define _LX     m_IX.b.l
+
+#define _IYD    m_IY.d
+#define _IY     m_IY.w.l
+#define _HY     m_IY.b.h
+#define _LY     m_IY.b.l
+
+#define IO(n)       m_io[(n)-Z180_CNTLA0]
+#define IO_CNTLA0   IO(Z180_CNTLA0)
+#define IO_CNTLA1   IO(Z180_CNTLA1)
+#define IO_CNTLB0   IO(Z180_CNTLB0)
+#define IO_CNTLB1   IO(Z180_CNTLB1)
+#define IO_STAT0    IO(Z180_STAT0)
+#define IO_STAT1    IO(Z180_STAT1)
+#define IO_TDR0     IO(Z180_TDR0)
+#define IO_TDR1     IO(Z180_TDR1)
+#define IO_RDR0     IO(Z180_RDR0)
+#define IO_RDR1     IO(Z180_RDR1)
+#define IO_CNTR     IO(Z180_CNTR)
+#define IO_TRDR     IO(Z180_TRDR)
+#define IO_TMDR0L   IO(Z180_TMDR0L)
+#define IO_TMDR0H   IO(Z180_TMDR0H)
+#define IO_RLDR0L   IO(Z180_RLDR0L)
+#define IO_RLDR0H   IO(Z180_RLDR0H)
+#define IO_TCR      IO(Z180_TCR)
+#define IO_IO11     IO(Z180_IO11)
+#define IO_ASEXT0   IO(Z180_ASEXT0)
+#define IO_ASEXT1   IO(Z180_ASEXT1)
+#define IO_TMDR1L   IO(Z180_TMDR1L)
+#define IO_TMDR1H   IO(Z180_TMDR1H)
+#define IO_RLDR1L   IO(Z180_RLDR1L)
+#define IO_RLDR1H   IO(Z180_RLDR1H)
+#define IO_FRC      IO(Z180_FRC)
+#define IO_IO19     IO(Z180_IO19)
+#define IO_ASTC0L   IO(Z180_ASTC0L)
+#define IO_ASTC0H   IO(Z180_ASTC0H)
+#define IO_ASTC1L   IO(Z180_ASTC1L)
+#define IO_ASTC1H   IO(Z180_ASTC1H)
+#define IO_CMR      IO(Z180_CMR)
+#define IO_CCR      IO(Z180_CCR)
+#define IO_SAR0L    IO(Z180_SAR0L)
+#define IO_SAR0H    IO(Z180_SAR0H)
+#define IO_SAR0B    IO(Z180_SAR0B)
+#define IO_DAR0L    IO(Z180_DAR0L)
+#define IO_DAR0H    IO(Z180_DAR0H)
+#define IO_DAR0B    IO(Z180_DAR0B)
+#define IO_BCR0L    IO(Z180_BCR0L)
+#define IO_BCR0H    IO(Z180_BCR0H)
+#define IO_MAR1L    IO(Z180_MAR1L)
+#define IO_MAR1H    IO(Z180_MAR1H)
+#define IO_MAR1B    IO(Z180_MAR1B)
+#define IO_IAR1L    IO(Z180_IAR1L)
+#define IO_IAR1H    IO(Z180_IAR1H)
+#define IO_IAR1B    IO(Z180_IAR1B)
+#define IO_BCR1L    IO(Z180_BCR1L)
+#define IO_BCR1H    IO(Z180_BCR1H)
+#define IO_DSTAT    IO(Z180_DSTAT)
+#define IO_DMODE    IO(Z180_DMODE)
+#define IO_DCNTL    IO(Z180_DCNTL)
+#define IO_IL       IO(Z180_IL)
+#define IO_ITC      IO(Z180_ITC)
+#define IO_IO35     IO(Z180_IO35)
+#define IO_RCR      IO(Z180_RCR)
+#define IO_IO37     IO(Z180_IO37)
+#define IO_CBR      IO(Z180_CBR)
+#define IO_BBR      IO(Z180_BBR)
+#define IO_CBAR     IO(Z180_CBAR)
+#define IO_IO3B     IO(Z180_IO3B)
+#define IO_IO3C     IO(Z180_IO3C)
+#define IO_IO3D     IO(Z180_IO3D)
+#define IO_OMCR     IO(Z180_OMCR)
+#define IO_IOCR     IO(Z180_IOCR)
+
+/* 00 ASCI control register A ch 0 */
+#define Z180_CNTLA0_MPE         0x80
+#define Z180_CNTLA0_RE          0x40
+#define Z180_CNTLA0_TE          0x20
+#define Z180_CNTLA0_RTS0        0x10
+#define Z180_CNTLA0_MPBR_EFR    0x08
+#define Z180_CNTLA0_MODE_DATA   0x04
+#define Z180_CNTLA0_MODE_PARITY 0x02
+#define Z180_CNTLA0_MODE_STOPB  0x01
+
+#define Z180_CNTLA0_RESET       0x10
+#define Z180_CNTLA0_RMASK       0xff
+#define Z180_CNTLA0_WMASK       0xff
+
+/* 01 ASCI control register A ch 1 */
+#define Z180_CNTLA1_MPE         0x80
+#define Z180_CNTLA1_RE          0x40
+#define Z180_CNTLA1_TE          0x20
+#define Z180_CNTLA1_CKA1D       0x10
+#define Z180_CNTLA1_MPBR_EFR    0x08
+#define Z180_CNTLA1_MODE        0x07
+
+#define Z180_CNTLA1_RESET       0x10
+#define Z180_CNTLA1_RMASK       0xff
+#define Z180_CNTLA1_WMASK       0xff
+
+/* 02 ASCI control register B ch 0 */
+#define Z180_CNTLB0_MPBT        0x80
+#define Z180_CNTLB0_MP          0x40
+#define Z180_CNTLB0_CTS_PS      0x20
+#define Z180_CNTLB0_PEO         0x10
+#define Z180_CNTLB0_DR          0x08
+#define Z180_CNTLB0_SS          0x07
+
+#define Z180_CNTLB0_RESET       0x07
+#define Z180_CNTLB0_RMASK       0xff
+#define Z180_CNTLB0_WMASK       0xff
+
+/* 03 ASCI control register B ch 1 */
+#define Z180_CNTLB1_MPBT        0x80
+#define Z180_CNTLB1_MP          0x40
+#define Z180_CNTLB1_CTS_PS      0x20
+#define Z180_CNTLB1_PEO         0x10
+#define Z180_CNTLB1_DR          0x08
+#define Z180_CNTLB1_SS          0x07
+
+#define Z180_CNTLB1_RESET       0x07
+#define Z180_CNTLB1_RMASK       0xff
+#define Z180_CNTLB1_WMASK       0xff
+
+/* 04 ASCI status register 0 */
+#define Z180_STAT0_RDRF         0x80
+#define Z180_STAT0_OVRN         0x40
+#define Z180_STAT0_PE           0x20
+#define Z180_STAT0_FE           0x10
+#define Z180_STAT0_RIE          0x08
+#define Z180_STAT0_DCD0         0x04
+#define Z180_STAT0_TDRE         0x02
+#define Z180_STAT0_TIE          0x01
+
+#define Z180_STAT0_RESET        0x00
+#define Z180_STAT0_RMASK        0xff
+#define Z180_STAT0_WMASK        0x09
+
+/* 05 ASCI status register 1 */
+#define Z180_STAT1_RDRF         0x80
+#define Z180_STAT1_OVRN         0x40
+#define Z180_STAT1_PE           0x20
+#define Z180_STAT1_FE           0x10
+#define Z180_STAT1_RIE          0x08
+#define Z180_STAT1_CTS1E        0x04
+#define Z180_STAT1_TDRE         0x02
+#define Z180_STAT1_TIE          0x01
+
+#define Z180_STAT1_RESET        0x02
+#define Z180_STAT1_RMASK        0xff
+#define Z180_STAT1_WMASK        0x0d
+
+/* 06 ASCI transmit data register 0 */
+#define Z180_TDR0_TDR           0xff
+
+#define Z180_TDR0_RESET         0x00
+#define Z180_TDR0_RMASK         0xff
+#define Z180_TDR0_WMASK         0xff
+
+/* 07 ASCI transmit data register 1 */
+#define Z180_TDR1_TDR           0xff
+
+#define Z180_TDR1_RESET         0x00
+#define Z180_TDR1_RMASK         0xff
+#define Z180_TDR1_WMASK         0xff
+
+/* 08 ASCI receive register 0 */
+#define Z180_RDR0_RDR           0xff
+
+#define Z180_RDR0_RESET         0x00
+#define Z180_RDR0_RMASK         0xff
+#define Z180_RDR0_WMASK         0xff
+
+/* 09 ASCI receive register 1 */
+#define Z180_RDR1_RDR           0xff
+
+#define Z180_RDR1_RESET         0x00
+#define Z180_RDR1_RMASK         0xff
+#define Z180_RDR1_WMASK         0xff
+
+/* 0a CSI/O control/status register */
+#define Z180_CNTR_EF            0x80
+#define Z180_CNTR_EIE           0x40
+#define Z180_CNTR_RE            0x20
+#define Z180_CNTR_TE            0x10
+#define Z180_CNTR_SS            0x07
+
+#define Z180_CNTR_RESET         0x07
+#define Z180_CNTR_RMASK         0xff
+#define Z180_CNTR_WMASK         0x4f        /* Original: 0x7f - Modified: 0x4f - Inhibits setting up TI & RI flags due to the lack of CSIO implementation */
+
+/* 0b CSI/O transmit/receive register */
+#define Z180_TRDR_RESET         0x00
+#define Z180_TRDR_RMASK         0xff
+#define Z180_TRDR_WMASK         0xff
+
+/* 0c TIMER data register ch 0 L */
+#define Z180_TMDR0L_RESET       0x00
+#define Z180_TMDR0L_RMASK       0xff
+#define Z180_TMDR0L_WMASK       0xff
+
+/* 0d TIMER data register ch 0 H */
+#define Z180_TMDR0H_RESET       0x00
+#define Z180_TMDR0H_RMASK       0xff
+#define Z180_TMDR0H_WMASK       0xff
+
+/* 0e TIMER reload register ch 0 L */
+#define Z180_RLDR0L_RESET       0xff
+#define Z180_RLDR0L_RMASK       0xff
+#define Z180_RLDR0L_WMASK       0xff
+
+/* 0f TIMER reload register ch 0 H */
+#define Z180_RLDR0H_RESET       0xff
+#define Z180_RLDR0H_RMASK       0xff
+#define Z180_RLDR0H_WMASK       0xff
+
+/* 10 TIMER control register */
+#define Z180_TCR_TIF1           0x80
+#define Z180_TCR_TIF0           0x40
+#define Z180_TCR_TIE1           0x20
+#define Z180_TCR_TIE0           0x10
+#define Z180_TCR_TOC1           0x08
+#define Z180_TCR_TOC0           0x04
+#define Z180_TCR_TDE1           0x02
+#define Z180_TCR_TDE0           0x01
+
+#define Z180_TCR_RESET          0x00
+#define Z180_TCR_RMASK          0xff
+#define Z180_TCR_WMASK          0x3f
+
+/* 11 reserved */
+#define Z180_IO11_RESET         0x00
+#define Z180_IO11_RMASK         0xff
+#define Z180_IO11_WMASK         0xff
+
+/* 12 (Z8S180/Z8L180) ASCI extension control register 0 */
+#define Z180_ASEXT0_RDRF        0x80
+#define Z180_ASEXT0_DCD0        0x40
+#define Z180_ASEXT0_CTS0        0x20
+#define Z180_ASEXT0_X1_BIT_CLK0 0x10
+#define Z180_ASEXT0_BRG0_MODE   0x08
+#define Z180_ASEXT0_BRK_EN      0x04
+#define Z180_ASEXT0_BRK_DET     0x02
+#define Z180_ASEXT0_BRK_SEND    0x01
+
+#define Z180_ASEXT0_RESET       0x00
+#define Z180_ASEXT0_RMASK       0xff
+#define Z180_ASEXT0_WMASK       0xfd
+
+/* 13 (Z8S180/Z8L180) ASCI extension control register 0 */
+#define Z180_ASEXT1_RDRF        0x80
+#define Z180_ASEXT1_X1_BIT_CLK1 0x10
+#define Z180_ASEXT1_BRG1_MODE   0x08
+#define Z180_ASEXT1_BRK_EN      0x04
+#define Z180_ASEXT1_BRK_DET     0x02
+#define Z180_ASEXT1_BRK_SEND    0x01
+
+#define Z180_ASEXT1_RESET       0x00
+#define Z180_ASEXT1_RMASK       0xff
+#define Z180_ASEXT1_WMASK       0xfd
+
+
+/* 14 TIMER data register ch 1 L */
+#define Z180_TMDR1L_RESET       0x00
+#define Z180_TMDR1L_RMASK       0xff
+#define Z180_TMDR1L_WMASK       0xff
+
+/* 15 TIMER data register ch 1 H */
+#define Z180_TMDR1H_RESET       0x00
+#define Z180_TMDR1H_RMASK       0xff
+#define Z180_TMDR1H_WMASK       0xff
+
+/* 16 TIMER reload register ch 1 L */
+#define Z180_RLDR1L_RESET       0x00
+#define Z180_RLDR1L_RMASK       0xff
+#define Z180_RLDR1L_WMASK       0xff
+
+/* 17 TIMER reload register ch 1 H */
+#define Z180_RLDR1H_RESET       0x00
+#define Z180_RLDR1H_RMASK       0xff
+#define Z180_RLDR1H_WMASK       0xff
+
+/* 18 free running counter */
+#define Z180_FRC_RESET          0x00
+#define Z180_FRC_RMASK          0xff
+#define Z180_FRC_WMASK          0xff
+
+/* 19 reserved */
+#define Z180_IO19_RESET         0x00
+#define Z180_IO19_RMASK         0xff
+#define Z180_IO19_WMASK         0xff
+
+/* 1a ASCI time constant ch 0 L */
+#define Z180_ASTC0L_RESET       0x00
+#define Z180_ASTC0L_RMASK       0xff
+#define Z180_ASTC0L_WMASK       0xff
+
+/* 1b ASCI time constant ch 0 H */
+#define Z180_ASTC0H_RESET       0x00
+#define Z180_ASTC0H_RMASK       0xff
+#define Z180_ASTC0H_WMASK       0xff
+
+/* 1c ASCI time constant ch 1 L */
+#define Z180_ASTC1L_RESET       0x00
+#define Z180_ASTC1L_RMASK       0xff
+#define Z180_ASTC1L_WMASK       0xff
+
+/* 1d ASCI time constant ch 1 H */
+#define Z180_ASTC1H_RESET       0x00
+#define Z180_ASTC1H_RMASK       0xff
+#define Z180_ASTC1H_WMASK       0xff
+
+/* 1e clock multiplier */
+#define Z180_CMR_X2             0x80
+
+#define Z180_CMR_RESET          0x7f
+#define Z180_CMR_RMASK          0x80
+#define Z180_CMR_WMASK          0x80
+
+/* 1f chip control register */
+#define Z180_CCR_CLOCK_DIVIDE   0x80
+#define Z180_CCR_STDBY_IDLE1    0x40
+#define Z180_CCR_BREXT          0x20
+#define Z180_CCR_LNPHI          0x10
+#define Z180_CCR_STDBY_IDLE0    0x08
+#define Z180_CCR_LNIO           0x04
+#define Z180_CCR_LNCPU_CTL      0x02
+#define Z180_CCR_LNAD_DATA      0x01
+
+#define Z180_CCR_RESET          0x00
+#define Z180_CCR_RMASK          0xff
+#define Z180_CCR_WMASK          0xff
+
+/* 20 DMA source address register ch 0 L */
+#define Z180_SAR0L_SAR          0xff
+
+#define Z180_SAR0L_RESET        0x00
+#define Z180_SAR0L_RMASK        0xff
+#define Z180_SAR0L_WMASK        0xff
+
+/* 21 DMA source address register ch 0 H */
+#define Z180_SAR0H_SAR          0xff
+
+#define Z180_SAR0H_RESET        0x00
+#define Z180_SAR0H_RMASK        0xff
+#define Z180_SAR0H_WMASK        0xff
+
+/* 22 DMA source address register ch 0 B */
+#define Z180_SAR0B_SAR          0x0f
+
+#define Z180_SAR0B_RESET        0x00
+#define Z180_SAR0B_RMASK        0x0f
+#define Z180_SAR0B_WMASK        0x0f
+
+/* 23 DMA destination address register ch 0 L */
+#define Z180_DAR0L_DAR          0xff
+
+#define Z180_DAR0L_RESET        0x00
+#define Z180_DAR0L_RMASK        0xff
+#define Z180_DAR0L_WMASK        0xff
+
+/* 24 DMA destination address register ch 0 H */
+#define Z180_DAR0H_DAR          0xff
+
+#define Z180_DAR0H_RESET        0x00
+#define Z180_DAR0H_RMASK        0xff
+#define Z180_DAR0H_WMASK        0xff
+
+/* 25 DMA destination address register ch 0 B */
+#define Z180_DAR0B_DAR          0x00
+
+#define Z180_DAR0B_RESET        0x00
+#define Z180_DAR0B_RMASK        0x0f
+#define Z180_DAR0B_WMASK        0x0f
+
+/* 26 DMA byte count register ch 0 L */
+#define Z180_BCR0L_BCR          0xff
+
+#define Z180_BCR0L_RESET        0x00
+#define Z180_BCR0L_RMASK        0xff
+#define Z180_BCR0L_WMASK        0xff
+
+/* 27 DMA byte count register ch 0 H */
+#define Z180_BCR0H_BCR          0xff
+
+#define Z180_BCR0H_RESET        0x00
+#define Z180_BCR0H_RMASK        0xff
+#define Z180_BCR0H_WMASK        0xff
+
+/* 28 DMA memory address register ch 1 L */
+#define Z180_MAR1L_MAR          0xff
+
+#define Z180_MAR1L_RESET        0x00
+#define Z180_MAR1L_RMASK        0xff
+#define Z180_MAR1L_WMASK        0xff
+
+/* 29 DMA memory address register ch 1 H */
+#define Z180_MAR1H_MAR          0xff
+
+#define Z180_MAR1H_RESET        0x00
+#define Z180_MAR1H_RMASK        0xff
+#define Z180_MAR1H_WMASK        0xff
+
+/* 2a DMA memory address register ch 1 B */
+#define Z180_MAR1B_MAR          0x0f
+
+#define Z180_MAR1B_RESET        0x00
+#define Z180_MAR1B_RMASK        0x0f
+#define Z180_MAR1B_WMASK        0x0f
+
+/* 2b DMA I/O address register ch 1 L */
+#define Z180_IAR1L_IAR          0xff
+
+#define Z180_IAR1L_RESET        0x00
+#define Z180_IAR1L_RMASK        0xff
+#define Z180_IAR1L_WMASK        0xff
+
+/* 2c DMA I/O address register ch 1 H */
+#define Z180_IAR1H_IAR          0xff
+
+#define Z180_IAR1H_RESET        0x00
+#define Z180_IAR1H_RMASK        0xff
+#define Z180_IAR1H_WMASK        0xff
+
+/* 2d (Z8S180/Z8L180) DMA I/O address register ch 1 B */
+#define Z180_IAR1B_IAR          0x0f
+
+#define Z180_IAR1B_RESET        0x00
+#define Z180_IAR1B_RMASK        0x0f
+#define Z180_IAR1B_WMASK        0x0f
+
+/* 2e DMA byte count register ch 1 L */
+#define Z180_BCR1L_BCR          0xff
+
+#define Z180_BCR1L_RESET        0x00
+#define Z180_BCR1L_RMASK        0xff
+#define Z180_BCR1L_WMASK        0xff
+
+/* 2f DMA byte count register ch 1 H */
+#define Z180_BCR1H_BCR          0xff
+
+#define Z180_BCR1H_RESET        0x00
+#define Z180_BCR1H_RMASK        0xff
+#define Z180_BCR1H_WMASK        0xff
+
+/* 30 DMA status register */
+#define Z180_DSTAT_DE1          0x80    /* DMA enable ch 1 */
+#define Z180_DSTAT_DE0          0x40    /* DMA enable ch 0 */
+#define Z180_DSTAT_DWE1         0x20    /* DMA write enable ch 0 (active low) */
+#define Z180_DSTAT_DWE0         0x10    /* DMA write enable ch 1 (active low) */
+#define Z180_DSTAT_DIE1         0x08    /* DMA IRQ enable ch 1 */
+#define Z180_DSTAT_DIE0         0x04    /* DMA IRQ enable ch 0 */
+#define Z180_DSTAT_DME          0x01    /* DMA enable (read only) */
+
+#define Z180_DSTAT_RESET        0x30
+#define Z180_DSTAT_RMASK        0xfd
+#define Z180_DSTAT_WMASK        0xcc
+
+/* 31 DMA mode register */
+#define Z180_DMODE_DM           0x30    /* DMA ch 0 destination addressing mode */
+#define Z180_DMODE_SM           0x0c    /* DMA ch 0 source addressing mode */
+#define Z180_DMODE_MMOD         0x02    /* DMA cycle steal/burst mode select */
+
+#define Z180_DMODE_RESET        0x00
+#define Z180_DMODE_RMASK        0x3e
+#define Z180_DMODE_WMASK        0x3e
+
+/* 32 DMA/WAIT control register */
+#define Z180_DCNTL_MWI1         0x80
+#define Z180_DCNTL_MWI0         0x40
+#define Z180_DCNTL_IWI1         0x20
+#define Z180_DCNTL_IWI0         0x10
+#define Z180_DCNTL_DMS1         0x08
+#define Z180_DCNTL_DMS0         0x04
+#define Z180_DCNTL_DIM1         0x02
+#define Z180_DCNTL_DIM0         0x01
+
+#define Z180_DCNTL_RESET        0x00
+#define Z180_DCNTL_RMASK        0xff
+#define Z180_DCNTL_WMASK        0xff
+
+/* 33 INT vector low register */
+#define Z180_IL_IL              0xe0
+
+#define Z180_IL_RESET           0x00
+#define Z180_IL_RMASK           0xe0
+#define Z180_IL_WMASK           0xe0
+
+/* 34 INT/TRAP control register */
+#define Z180_ITC_TRAP           0x80
+#define Z180_ITC_UFO            0x40
+#define Z180_ITC_ITE2           0x04
+#define Z180_ITC_ITE1           0x02
+#define Z180_ITC_ITE0           0x01
+
+#define Z180_ITC_RESET          0x01
+#define Z180_ITC_RMASK          0xc7
+#define Z180_ITC_WMASK          0x87
+
+/* 35 reserved */
+#define Z180_IO35_RESET         0x00
+#define Z180_IO35_RMASK         0xff
+#define Z180_IO35_WMASK         0xff
+
+/* 36 refresh control register */
+#define Z180_RCR_REFE           0x80
+#define Z180_RCR_REFW           0x40
+#define Z180_RCR_CYC            0x03
+
+#define Z180_RCR_RESET          0xc0
+#define Z180_RCR_RMASK          0xc3
+#define Z180_RCR_WMASK          0xc3
+
+/* 37 reserved */
+#define Z180_IO37_RESET         0x00
+#define Z180_IO37_RMASK         0xff
+#define Z180_IO37_WMASK         0xff
+
+/* 38 MMU common base register */
+#define Z180_CBR_CB             0xff
+
+#define Z180_CBR_RESET          0x00
+#define Z180_CBR_RMASK          0xff
+#define Z180_CBR_WMASK          0xff
+
+/* 39 MMU bank base register */
+#define Z180_BBR_BB             0xff
+
+#define Z180_BBR_RESET          0x00
+#define Z180_BBR_RMASK          0xff
+#define Z180_BBR_WMASK          0xff
+
+/* 3a MMU common/bank area register */
+#define Z180_CBAR_CA            0xf0
+#define Z180_CBAR_BA            0x0f
+
+#define Z180_CBAR_RESET         0xf0
+#define Z180_CBAR_RMASK         0xff
+#define Z180_CBAR_WMASK         0xff
+
+/* 3b reserved */
+#define Z180_IO3B_RESET         0x00
+#define Z180_IO3B_RMASK         0xff
+#define Z180_IO3B_WMASK         0xff
+
+/* 3c reserved */
+#define Z180_IO3C_RESET         0x00
+#define Z180_IO3C_RMASK         0xff
+#define Z180_IO3C_WMASK         0xff
+
+/* 3d reserved */
+#define Z180_IO3D_RESET         0x00
+#define Z180_IO3D_RMASK         0xff
+#define Z180_IO3D_WMASK         0xff
+
+/* 3e operation mode control register */
+#define Z180_OMCR_RESET         0x00
+#define Z180_OMCR_RMASK         0xff
+#define Z180_OMCR_WMASK         0xff
+
+/* 3f I/O control register */
+#define Z180_IOCR_RESET         0x00
+#define Z180_IOCR_RMASK         0xff
+#define Z180_IOCR_WMASK         0xff
+
+/***************************************************************************
+    CPU PREFIXES
+
+    order is important here - see z180tbl.h
+***************************************************************************/
+
+#define Z180_PREFIX_op          0
+#define Z180_PREFIX_cb          1
+#define Z180_PREFIX_dd          2
+#define Z180_PREFIX_ed          3
+#define Z180_PREFIX_fd          4
+#define Z180_PREFIX_xycb        5
+
+#define Z180_PREFIX_COUNT       (Z180_PREFIX_xycb + 1)
+
+
+
+static uint8_t SZ[256];       /* zero and sign flags */
+static uint8_t SZ_BIT[256];   /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
+static uint8_t SZP[256];      /* zero, sign and parity flags */
+static uint8_t SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */
+static uint8_t SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */
+
+static std::unique_ptr<uint8_t[]> SZHVC_add;
+static std::unique_ptr<uint8_t[]> SZHVC_sub;
+
+#include "z180ops.h"
+#include "z180tbl.h"
+
+#include "z180cb.hxx"
+#include "z180xy.hxx"
+#include "z180dd.hxx"
+#include "z180fd.hxx"
+#include "z180ed.hxx"
+#include "z180op.hxx"
+
+
+device_memory_interface::space_config_vector z180_device::memory_space_config() const
+{
+       if(has_configured_map(AS_OPCODES))
+               return space_config_vector {
+                       std::make_pair(AS_PROGRAM, &m_program_config),
+                       std::make_pair(AS_OPCODES, &m_decrypted_opcodes_config),
+                       std::make_pair(AS_IO,      &m_io_config)
+               };
+       else
+               return space_config_vector {
+                       std::make_pair(AS_PROGRAM, &m_program_config),
+                       std::make_pair(AS_IO,      &m_io_config)
+               };
+}
+
+uint8_t z180_device::z180_readcontrol(offs_t port)
+{
+       /* normal external readport */
+       uint8_t data = m_iospace->read_byte(port);
+
+       /* remap internal I/O registers */
+       if((port & (IO_IOCR & 0xc0)) == (IO_IOCR & 0xc0))
+               port = port - (IO_IOCR & 0xc0);
+
+       /* but ignore the data and read the internal register */
+       switch (port + Z180_CNTLA0)
+       {
+       case Z180_CNTLA0:
+               data = IO_CNTLA0 & Z180_CNTLA0_RMASK;
+               LOG("Z180 CNTLA0 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CNTLA1:
+               data = IO_CNTLA1 & Z180_CNTLA1_RMASK;
+               LOG("Z180 CNTLA1 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CNTLB0:
+               data = IO_CNTLB0 & Z180_CNTLB0_RMASK;
+               LOG("Z180 CNTLB0 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CNTLB1:
+               data = IO_CNTLB1 & Z180_CNTLB1_RMASK;
+               LOG("Z180 CNTLB1 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_STAT0:
+               data = IO_STAT0 & Z180_STAT0_RMASK;
+               data |= 0x02; // kludge for 20pacgal
+               LOG("Z180 STAT0  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_STAT1:
+               data = IO_STAT1 & Z180_STAT1_RMASK;
+               LOG("Z180 STAT1  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TDR0:
+               data = IO_TDR0 & Z180_TDR0_RMASK;
+               LOG("Z180 TDR0   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TDR1:
+               data = IO_TDR1 & Z180_TDR1_RMASK;
+               LOG("Z180 TDR1   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RDR0:
+               data = IO_RDR0 & Z180_RDR0_RMASK;
+               LOG("Z180 RDR0   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RDR1:
+               data = IO_RDR1 & Z180_RDR1_RMASK;
+               LOG("Z180 RDR1   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CNTR:
+               data = IO_CNTR & Z180_CNTR_RMASK;
+               LOG("Z180 CNTR   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TRDR:
+               data = IO_TRDR & Z180_TRDR_RMASK;
+               logerror("Z180 TRDR   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TMDR0L:
+               data = m_tmdr_value[0] & Z180_TMDR0L_RMASK;
+               LOG("Z180 TMDR0L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               /* if timer is counting, latch the MSB and set the latch flag */
+               if ((IO_TCR & Z180_TCR_TDE0) == 0)
+               {
+                       m_tmdr_latch |= 1;
+                       m_tmdrh[0] = (m_tmdr_value[0] & 0xff00) >> 8;
+               }
+
+               if(m_read_tcr_tmdr[0])
+               {
+                       m_tif[0] = 0; // reset TIF0
+                       m_read_tcr_tmdr[0] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[0] = 1;
+               }
+               break;
+
+       case Z180_TMDR0H:
+               /* read latched value? */
+               if (m_tmdr_latch & 1)
+               {
+                       m_tmdr_latch &= ~1;
+                       data = m_tmdrh[0];
+               }
+               else
+               {
+                       data = (m_tmdr_value[0] & 0xff00) >> 8;
+               }
+
+               if(m_read_tcr_tmdr[0])
+               {
+                       m_tif[0] = 0; // reset TIF0
+                       m_read_tcr_tmdr[0] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[0] = 1;
+               }
+               LOG("Z180 TMDR0H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RLDR0L:
+               data = IO_RLDR0L & Z180_RLDR0L_RMASK;
+               LOG("Z180 RLDR0L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RLDR0H:
+               data = IO_RLDR0H & Z180_RLDR0H_RMASK;
+               LOG("Z180 RLDR0H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TCR:
+               data = (IO_TCR & Z180_TCR_RMASK) | (m_tif[0] << 6) | (m_tif[1] << 7);
+
+               if(m_read_tcr_tmdr[0])
+               {
+                       m_tif[0] = 0; // reset TIF0
+                       m_read_tcr_tmdr[0] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[0] = 1;
+               }
+
+               if(m_read_tcr_tmdr[1])
+               {
+                       m_tif[1] = 0; // reset TIF1
+                       m_read_tcr_tmdr[1] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[1] = 1;
+               }
+
+               LOG("Z180 TCR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO11:
+               data = IO_IO11 & Z180_IO11_RMASK;
+               LOG("Z180 IO11   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASEXT0:
+               data = IO_ASEXT0 & Z180_ASEXT0_RMASK;
+               LOG("Z180 ASEXT0 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASEXT1:
+               data = IO_ASEXT1 & Z180_ASEXT1_RMASK;
+               LOG("Z180 ASEXT1 rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_TMDR1L:
+               data = m_tmdr_value[1] & Z180_TMDR1L_RMASK;
+               LOG("Z180 TMDR1L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               /* if timer is counting, latch the MSB and set the latch flag */
+               if ((IO_TCR & Z180_TCR_TDE1) == 0)
+               {
+                       m_tmdr_latch |= 2;
+                       m_tmdrh[1] = (m_tmdr_value[1] & 0xff00) >> 8;
+               }
+
+               if(m_read_tcr_tmdr[1])
+               {
+                       m_tif[1] = 0; // reset TIF1
+                       m_read_tcr_tmdr[1] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[1] = 1;
+               }
+               break;
+
+       case Z180_TMDR1H:
+               /* read latched value? */
+               if (m_tmdr_latch & 2)
+               {
+                       m_tmdr_latch &= ~2;
+                       data = m_tmdrh[1];
+               }
+               else
+               {
+                       data = (m_tmdr_value[1] & 0xff00) >> 8;
+               }
+
+               if(m_read_tcr_tmdr[1])
+               {
+                       m_tif[1] = 0; // reset TIF1
+                       m_read_tcr_tmdr[1] = 0;
+               }
+               else
+               {
+                       m_read_tcr_tmdr[1] = 1;
+               }
+               LOG("Z180 TMDR1H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RLDR1L:
+               data = IO_RLDR1L & Z180_RLDR1L_RMASK;
+               LOG("Z180 RLDR1L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RLDR1H:
+               data = IO_RLDR1H & Z180_RLDR1H_RMASK;
+               LOG("Z180 RLDR1H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_FRC:
+               data = IO_FRC & Z180_FRC_RMASK;
+               LOG("Z180 FRC    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO19:
+               data = IO_IO19 & Z180_IO19_RMASK;
+               LOG("Z180 IO19   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASTC0L:
+               data = IO_ASTC0L & Z180_ASTC0L_RMASK;
+               LOG("Z180 ASTC0L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASTC0H:
+               data = IO_ASTC0H & Z180_ASTC0H_RMASK;
+               LOG("Z180 ASTC0H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASTC1L:
+               data = IO_ASTC1L & Z180_ASTC1L_RMASK;
+               LOG("Z180 ASTC1L rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ASTC1H:
+               data = IO_ASTC1H & Z180_ASTC1H_RMASK;
+               LOG("Z180 ASTC1H rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CMR:
+               data = IO_CMR & Z180_CMR_RMASK;
+               LOG("Z180 CMR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CCR:
+               data = IO_CCR & Z180_CCR_RMASK;
+               LOG("Z180 CCR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_SAR0L:
+               data = IO_SAR0L & Z180_SAR0L_RMASK;
+               LOG("Z180 SAR0L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_SAR0H:
+               data = IO_SAR0H & Z180_SAR0H_RMASK;
+               LOG("Z180 SAR0H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_SAR0B:
+               data = IO_SAR0B & Z180_SAR0B_RMASK;
+               LOG("Z180 SAR0B  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DAR0L:
+               data = IO_DAR0L & Z180_DAR0L_RMASK;
+               LOG("Z180 DAR0L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DAR0H:
+               data = IO_DAR0H & Z180_DAR0H_RMASK;
+               LOG("Z180 DAR0H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DAR0B:
+               data = IO_DAR0B & Z180_DAR0B_RMASK;
+               LOG("Z180 DAR0B  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_BCR0L:
+               data = IO_BCR0L & Z180_BCR0L_RMASK;
+               LOG("Z180 BCR0L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_BCR0H:
+               data = IO_BCR0H & Z180_BCR0H_RMASK;
+               LOG("Z180 BCR0H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_MAR1L:
+               data = IO_MAR1L & Z180_MAR1L_RMASK;
+               LOG("Z180 MAR1L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_MAR1H:
+               data = IO_MAR1H & Z180_MAR1H_RMASK;
+               LOG("Z180 MAR1H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_MAR1B:
+               data = IO_MAR1B & Z180_MAR1B_RMASK;
+               LOG("Z180 MAR1B  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IAR1L:
+               data = IO_IAR1L & Z180_IAR1L_RMASK;
+               LOG("Z180 IAR1L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IAR1H:
+               data = IO_IAR1H & Z180_IAR1H_RMASK;
+               LOG("Z180 IAR1H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IAR1B:
+               data = IO_IAR1B & Z180_IAR1B_RMASK;
+               LOG("Z180 IAR1B  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_BCR1L:
+               data = IO_BCR1L & Z180_BCR1L_RMASK;
+               LOG("Z180 BCR1L  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_BCR1H:
+               data = IO_BCR1H & Z180_BCR1H_RMASK;
+               LOG("Z180 BCR1H  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DSTAT:
+               data = IO_DSTAT & Z180_DSTAT_RMASK;
+               LOG("Z180 DSTAT  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DMODE:
+               data = IO_DMODE & Z180_DMODE_RMASK;
+               LOG("Z180 DMODE  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_DCNTL:
+               data = IO_DCNTL & Z180_DCNTL_RMASK;
+               LOG("Z180 DCNTL  rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IL:
+               data = IO_IL & Z180_IL_RMASK;
+               LOG("Z180 IL     rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_ITC:
+               data = IO_ITC & Z180_ITC_RMASK;
+               LOG("Z180 ITC    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO35:
+               data = IO_IO35 & Z180_IO35_RMASK;
+               LOG("Z180 IO35   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_RCR:
+               data = IO_RCR & Z180_RCR_RMASK;
+               LOG("Z180 RCR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO37:
+               data = IO_IO37 & Z180_IO37_RMASK;
+               LOG("Z180 IO37   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CBR:
+               data = IO_CBR & Z180_CBR_RMASK;
+               LOG("Z180 CBR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_BBR:
+               data = IO_BBR & Z180_BBR_RMASK;
+               LOG("Z180 BBR    rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_CBAR:
+               data = IO_CBAR & Z180_CBAR_RMASK;
+               LOG("Z180 CBAR   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO3B:
+               data = IO_IO3B & Z180_IO3B_RMASK;
+               LOG("Z180 IO3B   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO3C:
+               data = IO_IO3C & Z180_IO3C_RMASK;
+               LOG("Z180 IO3C   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IO3D:
+               data = IO_IO3D & Z180_IO3D_RMASK;
+               LOG("Z180 IO3D   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_OMCR:
+               data = IO_OMCR & Z180_OMCR_RMASK;
+               LOG("Z180 OMCR   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+
+       case Z180_IOCR:
+               data = IO_IOCR & Z180_IOCR_RMASK;
+               LOG("Z180 IOCR   rd $%02x ($%02x)\n", data, m_io[port & 0x3f]);
+               break;
+       }
+
+       return data;
+}
+
+void z180_device::z180_writecontrol(offs_t port, uint8_t data)
+{
+       /* normal external write port */
+       m_iospace->write_byte(port, data);
+
+       /* remap internal I/O registers */
+       if((port & (IO_IOCR & 0xc0)) == (IO_IOCR & 0xc0))
+               port = port - (IO_IOCR & 0xc0);
+
+       /* store the data in the internal register */
+       switch (port + Z180_CNTLA0)
+       {
+       case Z180_CNTLA0:
+               LOG("Z180 CNTLA0 wr $%02x ($%02x)\n", data,  data & Z180_CNTLA0_WMASK);
+               IO_CNTLA0 = (IO_CNTLA0 & ~Z180_CNTLA0_WMASK) | (data & Z180_CNTLA0_WMASK);
+               break;
+
+       case Z180_CNTLA1:
+               LOG("Z180 CNTLA1 wr $%02x ($%02x)\n", data,  data & Z180_CNTLA1_WMASK);
+               IO_CNTLA1 = (IO_CNTLA1 & ~Z180_CNTLA1_WMASK) | (data & Z180_CNTLA1_WMASK);
+               break;
+
+       case Z180_CNTLB0:
+               LOG("Z180 CNTLB0 wr $%02x ($%02x)\n", data,  data & Z180_CNTLB0_WMASK);
+               IO_CNTLB0 = (IO_CNTLB0 & ~Z180_CNTLB0_WMASK) | (data & Z180_CNTLB0_WMASK);
+               break;
+
+       case Z180_CNTLB1:
+               LOG("Z180 CNTLB1 wr $%02x ($%02x)\n", data,  data & Z180_CNTLB1_WMASK);
+               IO_CNTLB1 = (IO_CNTLB1 & ~Z180_CNTLB1_WMASK) | (data & Z180_CNTLB1_WMASK);
+               break;
+
+       case Z180_STAT0:
+               LOG("Z180 STAT0  wr $%02x ($%02x)\n", data,  data & Z180_STAT0_WMASK);
+               IO_STAT0 = (IO_STAT0 & ~Z180_STAT0_WMASK) | (data & Z180_STAT0_WMASK);
+               break;
+
+       case Z180_STAT1:
+               LOG("Z180 STAT1  wr $%02x ($%02x)\n", data,  data & Z180_STAT1_WMASK);
+               IO_STAT1 = (IO_STAT1 & ~Z180_STAT1_WMASK) | (data & Z180_STAT1_WMASK);
+               break;
+
+       case Z180_TDR0:
+               LOG("Z180 TDR0   wr $%02x ($%02x)\n", data,  data & Z180_TDR0_WMASK);
+               IO_TDR0 = (IO_TDR0 & ~Z180_TDR0_WMASK) | (data & Z180_TDR0_WMASK);
+               break;
+
+       case Z180_TDR1:
+               LOG("Z180 TDR1   wr $%02x ($%02x)\n", data,  data & Z180_TDR1_WMASK);
+               IO_TDR1 = (IO_TDR1 & ~Z180_TDR1_WMASK) | (data & Z180_TDR1_WMASK);
+               break;
+
+       case Z180_RDR0:
+               LOG("Z180 RDR0   wr $%02x ($%02x)\n", data,  data & Z180_RDR0_WMASK);
+               IO_RDR0 = (IO_RDR0 & ~Z180_RDR0_WMASK) | (data & Z180_RDR0_WMASK);
+               break;
+
+       case Z180_RDR1:
+               LOG("Z180 RDR1   wr $%02x ($%02x)\n", data,  data & Z180_RDR1_WMASK);
+               IO_RDR1 = (IO_RDR1 & ~Z180_RDR1_WMASK) | (data & Z180_RDR1_WMASK);
+               break;
+
+       case Z180_CNTR:
+               LOG("Z180 CNTR   wr $%02x ($%02x)\n", data,  data & Z180_CNTR_WMASK);
+               IO_CNTR = (IO_CNTR & ~Z180_CNTR_WMASK) | (data & Z180_CNTR_WMASK);
+               break;
+
+       case Z180_TRDR:
+               LOG("Z180 TRDR   wr $%02x ($%02x)\n", data,  data & Z180_TRDR_WMASK);
+               IO_TRDR = (IO_TRDR & ~Z180_TRDR_WMASK) | (data & Z180_TRDR_WMASK);
+               break;
+
+       case Z180_TMDR0L:
+               LOG("Z180 TMDR0L wr $%02x ($%02x)\n", data,  data & Z180_TMDR0L_WMASK);
+               IO_TMDR0L = data & Z180_TMDR0L_WMASK;
+               m_tmdr_value[0] = (m_tmdr_value[0] & 0xff00) | IO_TMDR0L;
+               break;
+
+       case Z180_TMDR0H:
+               LOG("Z180 TMDR0H wr $%02x ($%02x)\n", data,  data & Z180_TMDR0H_WMASK);
+               IO_TMDR0H = data & Z180_TMDR0H_WMASK;
+               m_tmdr_value[0] = (m_tmdr_value[0] & 0x00ff) | (IO_TMDR0H << 8);
+               break;
+
+       case Z180_RLDR0L:
+               LOG("Z180 RLDR0L wr $%02x ($%02x)\n", data,  data & Z180_RLDR0L_WMASK);
+               IO_RLDR0L = (IO_RLDR0L & ~Z180_RLDR0L_WMASK) | (data & Z180_RLDR0L_WMASK);
+               break;
+
+       case Z180_RLDR0H:
+               LOG("Z180 RLDR0H wr $%02x ($%02x)\n", data,  data & Z180_RLDR0H_WMASK);
+               IO_RLDR0H = (IO_RLDR0H & ~Z180_RLDR0H_WMASK) | (data & Z180_RLDR0H_WMASK);
+               break;
+
+       case Z180_TCR:
+               LOG("Z180 TCR    wr $%02x ($%02x)\n", data,  data & Z180_TCR_WMASK);
+               {
+                       uint16_t old = IO_TCR;
+                       /* Force reload on state change */
+                       IO_TCR = (IO_TCR & ~Z180_TCR_WMASK) | (data & Z180_TCR_WMASK);
+                       if (!(old & Z180_TCR_TDE0) && (IO_TCR & Z180_TCR_TDE0))
+                               m_tmdr_value[0] = 0; //IO_RLDR0L | (IO_RLDR0H << 8);
+                       if (!(old & Z180_TCR_TDE1) && (IO_TCR & Z180_TCR_TDE1))
+                               m_tmdr_value[1] = 0; //IO_RLDR1L | (IO_RLDR1H << 8);
+               }
+
+               break;
+
+       case Z180_IO11:
+               LOG("Z180 IO11   wr $%02x ($%02x)\n", data,  data & Z180_IO11_WMASK);
+               IO_IO11 = (IO_IO11 & ~Z180_IO11_WMASK) | (data & Z180_IO11_WMASK);
+               break;
+
+       case Z180_ASEXT0:
+               LOG("Z180 ASEXT0 wr $%02x ($%02x)\n", data,  data & Z180_ASEXT0_WMASK);
+               IO_ASEXT0 = (IO_ASEXT0 & ~Z180_ASEXT0_WMASK) | (data & Z180_ASEXT0_WMASK);
+               break;
+
+       case Z180_ASEXT1:
+               LOG("Z180 ASEXT1 wr $%02x ($%02x)\n", data,  data & Z180_ASEXT1_WMASK);
+               IO_ASEXT1 = (IO_ASEXT1 & ~Z180_ASEXT1_WMASK) | (data & Z180_ASEXT1_WMASK);
+               break;
+
+       case Z180_TMDR1L:
+               LOG("Z180 TMDR1L wr $%02x ($%02x)\n", data,  data & Z180_TMDR1L_WMASK);
+               IO_TMDR1L = data & Z180_TMDR1L_WMASK;
+               m_tmdr_value[1] = (m_tmdr_value[1] & 0xff00) | IO_TMDR1L;
+               break;
+
+       case Z180_TMDR1H:
+               LOG("Z180 TMDR1H wr $%02x ($%02x)\n", data,  data & Z180_TMDR1H_WMASK);
+               IO_TMDR1H = data & Z180_TMDR1H_WMASK;
+               m_tmdr_value[1] = (m_tmdr_value[1] & 0x00ff) | IO_TMDR1H;
+               break;
+
+       case Z180_RLDR1L:
+               LOG("Z180 RLDR1L wr $%02x ($%02x)\n", data,  data & Z180_RLDR1L_WMASK);
+               IO_RLDR1L = (IO_RLDR1L & ~Z180_RLDR1L_WMASK) | (data & Z180_RLDR1L_WMASK);
+               break;
+
+       case Z180_RLDR1H:
+               LOG("Z180 RLDR1H wr $%02x ($%02x)\n", data,  data & Z180_RLDR1H_WMASK);
+               IO_RLDR1H = (IO_RLDR1H & ~Z180_RLDR1H_WMASK) | (data & Z180_RLDR1H_WMASK);
+               break;
+
+       case Z180_FRC:
+               LOG("Z180 FRC    wr $%02x ($%02x)\n", data,  data & Z180_FRC_WMASK);
+               IO_FRC = (IO_FRC & ~Z180_FRC_WMASK) | (data & Z180_FRC_WMASK);
+               break;
+
+       case Z180_IO19:
+               LOG("Z180 IO19   wr $%02x ($%02x)\n", data,  data & Z180_IO19_WMASK);
+               IO_IO19 = (IO_IO19 & ~Z180_IO19_WMASK) | (data & Z180_IO19_WMASK);
+               break;
+
+       case Z180_ASTC0L:
+               LOG("Z180 ASTC0L wr $%02x ($%02x)\n", data,  data & Z180_ASTC0L_WMASK);
+               IO_ASTC0L = (IO_ASTC0L & ~Z180_ASTC0L_WMASK) | (data & Z180_ASTC0L_WMASK);
+               break;
+
+       case Z180_ASTC0H:
+               LOG("Z180 ASTC0H wr $%02x ($%02x)\n", data,  data & Z180_ASTC0H_WMASK);
+               IO_ASTC0H = (IO_ASTC0H & ~Z180_ASTC0H_WMASK) | (data & Z180_ASTC0H_WMASK);
+               break;
+
+       case Z180_ASTC1L:
+               LOG("Z180 ASTC1L wr $%02x ($%02x)\n", data,  data & Z180_ASTC1L_WMASK);
+               IO_ASTC1L = (IO_ASTC1L & ~Z180_ASTC1L_WMASK) | (data & Z180_ASTC1L_WMASK);
+               break;
+
+       case Z180_ASTC1H:
+               LOG("Z180 ASTC1H wr $%02x ($%02x)\n", data,  data & Z180_ASTC1H_WMASK);
+               IO_ASTC1H = (IO_ASTC1H & ~Z180_ASTC1H_WMASK) | (data & Z180_ASTC1H_WMASK);
+               break;
+
+       case Z180_CMR:
+               LOG("Z180 CMR    wr $%02x ($%02x)\n", data,  data & Z180_CMR_WMASK);
+               IO_CMR = (IO_CMR & ~Z180_CMR_WMASK) | (data & Z180_CMR_WMASK);
+               break;
+
+       case Z180_CCR:
+               LOG("Z180 CCR    wr $%02x ($%02x)\n", data,  data & Z180_CCR_WMASK);
+               IO_CCR = (IO_CCR & ~Z180_CCR_WMASK) | (data & Z180_CCR_WMASK);
+               break;
+
+       case Z180_SAR0L:
+               LOG("Z180 SAR0L  wr $%02x ($%02x)\n", data,  data & Z180_SAR0L_WMASK);
+               IO_SAR0L = (IO_SAR0L & ~Z180_SAR0L_WMASK) | (data & Z180_SAR0L_WMASK);
+               break;
+
+       case Z180_SAR0H:
+               LOG("Z180 SAR0H  wr $%02x ($%02x)\n", data,  data & Z180_SAR0H_WMASK);
+               IO_SAR0H = (IO_SAR0H & ~Z180_SAR0H_WMASK) | (data & Z180_SAR0H_WMASK);
+               break;
+
+       case Z180_SAR0B:
+               LOG("Z180 SAR0B  wr $%02x ($%02x)\n", data,  data & Z180_SAR0B_WMASK);
+               IO_SAR0B = (IO_SAR0B & ~Z180_SAR0B_WMASK) | (data & Z180_SAR0B_WMASK);
+               break;
+
+       case Z180_DAR0L:
+               LOG("Z180 DAR0L  wr $%02x ($%02x)\n", data,  data & Z180_DAR0L_WMASK);
+               IO_DAR0L = (IO_DAR0L & ~Z180_DAR0L_WMASK) | (data & Z180_DAR0L_WMASK);
+               break;
+
+       case Z180_DAR0H:
+               LOG("Z180 DAR0H  wr $%02x ($%02x)\n", data,  data & Z180_DAR0H_WMASK);
+               IO_DAR0H = (IO_DAR0H & ~Z180_DAR0H_WMASK) | (data & Z180_DAR0H_WMASK);
+               break;
+
+       case Z180_DAR0B:
+               LOG("Z180 DAR0B  wr $%02x ($%02x)\n", data,  data & Z180_DAR0B_WMASK);
+               IO_DAR0B = (IO_DAR0B & ~Z180_DAR0B_WMASK) | (data & Z180_DAR0B_WMASK);
+               break;
+
+       case Z180_BCR0L:
+               LOG("Z180 BCR0L  wr $%02x ($%02x)\n", data,  data & Z180_BCR0L_WMASK);
+               IO_BCR0L = (IO_BCR0L & ~Z180_BCR0L_WMASK) | (data & Z180_BCR0L_WMASK);
+               break;
+
+       case Z180_BCR0H:
+               LOG("Z180 BCR0H  wr $%02x ($%02x)\n", data,  data & Z180_BCR0H_WMASK);
+               IO_BCR0H = (IO_BCR0H & ~Z180_BCR0H_WMASK) | (data & Z180_BCR0H_WMASK);
+               break;
+
+       case Z180_MAR1L:
+               LOG("Z180 MAR1L  wr $%02x ($%02x)\n", data,  data & Z180_MAR1L_WMASK);
+               IO_MAR1L = (IO_MAR1L & ~Z180_MAR1L_WMASK) | (data & Z180_MAR1L_WMASK);
+               break;
+
+       case Z180_MAR1H:
+               LOG("Z180 MAR1H  wr $%02x ($%02x)\n", data,  data & Z180_MAR1H_WMASK);
+               IO_MAR1H = (IO_MAR1H & ~Z180_MAR1H_WMASK) | (data & Z180_MAR1H_WMASK);
+               break;
+
+       case Z180_MAR1B:
+               LOG("Z180 MAR1B  wr $%02x ($%02x)\n", data,  data & Z180_MAR1B_WMASK);
+               IO_MAR1B = (IO_MAR1B & ~Z180_MAR1B_WMASK) | (data & Z180_MAR1B_WMASK);
+               break;
+
+       case Z180_IAR1L:
+               LOG("Z180 IAR1L  wr $%02x ($%02x)\n", data,  data & Z180_IAR1L_WMASK);
+               IO_IAR1L = (IO_IAR1L & ~Z180_IAR1L_WMASK) | (data & Z180_IAR1L_WMASK);
+               break;
+
+       case Z180_IAR1H:
+               LOG("Z180 IAR1H  wr $%02x ($%02x)\n", data,  data & Z180_IAR1H_WMASK);
+               IO_IAR1H = (IO_IAR1H & ~Z180_IAR1H_WMASK) | (data & Z180_IAR1H_WMASK);
+               break;
+
+       case Z180_IAR1B:
+               LOG("Z180 IAR1B  wr $%02x ($%02x)\n", data,  data & Z180_IAR1B_WMASK);
+               IO_IAR1B = (IO_IAR1B & ~Z180_IAR1B_WMASK) | (data & Z180_IAR1B_WMASK);
+               break;
+
+       case Z180_BCR1L:
+               LOG("Z180 BCR1L  wr $%02x ($%02x)\n", data,  data & Z180_BCR1L_WMASK);
+               IO_BCR1L = (IO_BCR1L & ~Z180_BCR1L_WMASK) | (data & Z180_BCR1L_WMASK);
+               break;
+
+       case Z180_BCR1H:
+               LOG("Z180 BCR1H  wr $%02x ($%02x)\n", data,  data & Z180_BCR1H_WMASK);
+               IO_BCR1H = (IO_BCR1H & ~Z180_BCR1H_WMASK) | (data & Z180_BCR1H_WMASK);
+               break;
+
+       case Z180_DSTAT:
+               LOG("Z180 DSTAT  wr $%02x ($%02x)\n", data,  data & Z180_DSTAT_WMASK);
+               IO_DSTAT = (IO_DSTAT & ~Z180_DSTAT_WMASK) | (data & Z180_DSTAT_WMASK);
+               if ((data & (Z180_DSTAT_DE1 | Z180_DSTAT_DWE1)) == Z180_DSTAT_DE1)
+               {
+                       IO_DSTAT |= Z180_DSTAT_DME;  /* DMA enable */
+               }
+               if ((data & (Z180_DSTAT_DE0 | Z180_DSTAT_DWE0)) == Z180_DSTAT_DE0)
+               {
+                       IO_DSTAT |= Z180_DSTAT_DME;  /* DMA enable */
+               }
+               break;
+
+       case Z180_DMODE:
+               LOG("Z180 DMODE  wr $%02x ($%02x)\n", data,  data & Z180_DMODE_WMASK);
+               IO_DMODE = (IO_DMODE & ~Z180_DMODE_WMASK) | (data & Z180_DMODE_WMASK);
+               break;
+
+       case Z180_DCNTL:
+               LOG("Z180 DCNTL  wr $%02x ($%02x)\n", data,  data & Z180_DCNTL_WMASK);
+               IO_DCNTL = (IO_DCNTL & ~Z180_DCNTL_WMASK) | (data & Z180_DCNTL_WMASK);
+               break;
+
+       case Z180_IL:
+               LOG("Z180 IL     wr $%02x ($%02x)\n", data,  data & Z180_IL_WMASK);
+               IO_IL = (IO_IL & ~Z180_IL_WMASK) | (data & Z180_IL_WMASK);
+               break;
+
+       case Z180_ITC:
+               LOG("Z180 ITC    wr $%02x ($%02x)\n", data,  data & Z180_ITC_WMASK);
+               IO_ITC = (IO_ITC & ~Z180_ITC_WMASK) | (data & Z180_ITC_WMASK);
+               break;
+
+       case Z180_IO35:
+               LOG("Z180 IO35   wr $%02x ($%02x)\n", data,  data & Z180_IO35_WMASK);
+               IO_IO35 = (IO_IO35 & ~Z180_IO35_WMASK) | (data & Z180_IO35_WMASK);
+               break;
+
+       case Z180_RCR:
+               LOG("Z180 RCR    wr $%02x ($%02x)\n", data,  data & Z180_RCR_WMASK);
+               IO_RCR = (IO_RCR & ~Z180_RCR_WMASK) | (data & Z180_RCR_WMASK);
+               break;
+
+       case Z180_IO37:
+               LOG("Z180 IO37   wr $%02x ($%02x)\n", data,  data & Z180_IO37_WMASK);
+               IO_IO37 = (IO_IO37 & ~Z180_IO37_WMASK) | (data & Z180_IO37_WMASK);
+               break;
+
+       case Z180_CBR:
+               LOG("Z180 CBR    wr $%02x ($%02x)\n", data,  data & Z180_CBR_WMASK);
+               IO_CBR = (IO_CBR & ~Z180_CBR_WMASK) | (data & Z180_CBR_WMASK);
+               z180_mmu();
+               break;
+
+       case Z180_BBR:
+               LOG("Z180 BBR    wr $%02x ($%02x)\n", data,  data & Z180_BBR_WMASK);
+               IO_BBR = (IO_BBR & ~Z180_BBR_WMASK) | (data & Z180_BBR_WMASK);
+               z180_mmu();
+               break;
+
+       case Z180_CBAR:
+               LOG("Z180 CBAR   wr $%02x ($%02x)\n", data,  data & Z180_CBAR_WMASK);
+               IO_CBAR = (IO_CBAR & ~Z180_CBAR_WMASK) | (data & Z180_CBAR_WMASK);
+               z180_mmu();
+               break;
+
+       case Z180_IO3B:
+               LOG("Z180 IO3B   wr $%02x ($%02x)\n", data,  data & Z180_IO3B_WMASK);
+               IO_IO3B = (IO_IO3B & ~Z180_IO3B_WMASK) | (data & Z180_IO3B_WMASK);
+               break;
+
+       case Z180_IO3C:
+               LOG("Z180 IO3C   wr $%02x ($%02x)\n", data,  data & Z180_IO3C_WMASK);
+               IO_IO3C = (IO_IO3C & ~Z180_IO3C_WMASK) | (data & Z180_IO3C_WMASK);
+               break;
+
+       case Z180_IO3D:
+               LOG("Z180 IO3D   wr $%02x ($%02x)\n", data,  data & Z180_IO3D_WMASK);
+               IO_IO3D = (IO_IO3D & ~Z180_IO3D_WMASK) | (data & Z180_IO3D_WMASK);
+               break;
+
+       case Z180_OMCR:
+               LOG("Z180 OMCR   wr $%02x ($%02x)\n", data,  data & Z180_OMCR_WMASK);
+               IO_OMCR = (IO_OMCR & ~Z180_OMCR_WMASK) | (data & Z180_OMCR_WMASK);
+               break;
+
+       case Z180_IOCR:
+               LOG("Z180 IOCR   wr $%02x ($%02x)\n", data,  data & Z180_IOCR_WMASK);
+               IO_IOCR = (IO_IOCR & ~Z180_IOCR_WMASK) | (data & Z180_IOCR_WMASK);
+               break;
+       }
+}
+
+int z180_device::z180_dma0(int max_cycles)
+{
+       offs_t sar0 = 65536 * IO_SAR0B + 256 * IO_SAR0H + IO_SAR0L;
+       offs_t dar0 = 65536 * IO_DAR0B + 256 * IO_DAR0H + IO_DAR0L;
+       int bcr0 = 256 * IO_BCR0H + IO_BCR0L;
+
+       if (bcr0 == 0)
+       {
+               bcr0 = 0x10000;
+       }
+
+       int count = (IO_DMODE & Z180_DMODE_MMOD) ? bcr0 : 1;
+       int cycles = 0;
+
+       if (!(IO_DSTAT & Z180_DSTAT_DE0))
+       {
+               return 0;
+       }
+
+       while (count > 0)
+       {
+               m_extra_cycles = 0;
+               /* last transfer happening now? */
+               if (bcr0 == 1)
+               {
+                       m_iol |= Z180_TEND0;
+               }
+               switch( IO_DMODE & (Z180_DMODE_SM | Z180_DMODE_DM) )
+               {
+               case 0x00:  /* memory SAR0+1 to memory DAR0+1 */
+                       m_program->write_byte(dar0++, m_program->read_byte(sar0++));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x04:  /* memory SAR0-1 to memory DAR0+1 */
+                       m_program->write_byte(dar0++, m_program->read_byte(sar0--));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x08:  /* memory SAR0 fixed to memory DAR0+1 */
+                       m_program->write_byte(dar0++, m_program->read_byte(sar0));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x0c:  /* I/O SAR0 fixed to memory DAR0+1 */
+                       if (m_iol & Z180_DREQ0)
+                       {
+                               m_program->write_byte(dar0++, IN(sar0));
+                               cycles += IO_DCNTL >> 6; // memory wait states
+                               bcr0--;
+                               /* edge sensitive DREQ0 ? */
+                               if (IO_DCNTL & Z180_DCNTL_DMS0)
+                               {
+                                       m_iol &= ~Z180_DREQ0;
+                                       count = 0;
+                               }
+                       }
+                       break;
+               case 0x10:  /* memory SAR0+1 to memory DAR0-1 */
+                       m_program->write_byte(dar0--, m_program->read_byte(sar0++));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x14:  /* memory SAR0-1 to memory DAR0-1 */
+                       m_program->write_byte(dar0--, m_program->read_byte(sar0--));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x18:  /* memory SAR0 fixed to memory DAR0-1 */
+                       m_program->write_byte(dar0--, m_program->read_byte(sar0));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x1c:  /* I/O SAR0 fixed to memory DAR0-1 */
+                       if (m_iol & Z180_DREQ0)
+                       {
+                               m_program->write_byte(dar0--, IN(sar0));
+                               cycles += IO_DCNTL >> 6; // memory wait states
+                               bcr0--;
+                               /* edge sensitive DREQ0 ? */
+                               if (IO_DCNTL & Z180_DCNTL_DMS0)
+                               {
+                                       m_iol &= ~Z180_DREQ0;
+                                       count = 0;
+                               }
+                       }
+                       break;
+               case 0x20:  /* memory SAR0+1 to memory DAR0 fixed */
+                       m_program->write_byte(dar0, m_program->read_byte(sar0++));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x24:  /* memory SAR0-1 to memory DAR0 fixed */
+                       m_program->write_byte(dar0, m_program->read_byte(sar0--));
+                       cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+                       bcr0--;
+                       break;
+               case 0x28:  /* reserved */
+                       break;
+               case 0x2c:  /* reserved */
+                       break;
+               case 0x30:  /* memory SAR0+1 to I/O DAR0 fixed */
+                       if (m_iol & Z180_DREQ0)
+                       {
+                               OUT(dar0, m_program->read_byte(sar0++));
+                               cycles += IO_DCNTL >> 6; // memory wait states
+                               bcr0--;
+                               /* edge sensitive DREQ0 ? */
+                               if (IO_DCNTL & Z180_DCNTL_DMS0)
+                               {
+                                       m_iol &= ~Z180_DREQ0;
+                                       count = 0;
+                               }
+                       }
+                       break;
+               case 0x34:  /* memory SAR0-1 to I/O DAR0 fixed */
+                       if (m_iol & Z180_DREQ0)
+                       {
+                               OUT(dar0, m_program->read_byte(sar0--));
+                               cycles += IO_DCNTL >> 6; // memory wait states
+                               bcr0--;
+                               /* edge sensitive DREQ0 ? */
+                               if (IO_DCNTL & Z180_DCNTL_DMS0)
+                               {
+                                       m_iol &= ~Z180_DREQ0;
+                                       count = 0;
+                               }
+                       }
+                       break;
+               case 0x38:  /* reserved */
+                       break;
+               case 0x3c:  /* reserved */
+                       break;
+               }
+               count--;
+               cycles += 6 + m_extra_cycles; // use extra_cycles for I/O wait states
+               if (cycles > max_cycles)
+                       break;
+       }
+
+       IO_SAR0L = sar0;
+       IO_SAR0H = sar0 >> 8;
+       IO_SAR0B = sar0 >> 16;
+       IO_DAR0L = dar0;
+       IO_DAR0H = dar0 >> 8;
+       IO_DAR0B = dar0 >> 16;
+       IO_BCR0L = bcr0;
+       IO_BCR0H = bcr0 >> 8;
+
+       /* DMA terminal count? */
+       if (bcr0 == 0)
+       {
+               m_iol &= ~Z180_TEND0;
+               IO_DSTAT &= ~Z180_DSTAT_DE0;
+               /* terminal count interrupt enabled? */
+               if (IO_DSTAT & Z180_DSTAT_DIE0 && m_IFF1)
+                       m_int_pending[Z180_INT_DMA0] = 1;
+       }
+       return cycles;
+}
+
+int z180_device::z180_dma1()
+{
+       offs_t mar1 = 65536 * IO_MAR1B + 256 * IO_MAR1H + IO_MAR1L;
+       offs_t iar1 = 256 * IO_IAR1H + IO_IAR1L;
+       int bcr1 = 256 * IO_BCR1H + IO_BCR1L;
+
+       if (bcr1 == 0)
+       {
+               bcr1 = 0x10000;
+       }
+
+       int cycles = 0;
+
+       if ((m_iol & Z180_DREQ1) == 0)
+               return 0;
+
+       if (!(IO_DSTAT & Z180_DSTAT_DE1))
+       {
+               return 0;
+       }
+
+       /* last transfer happening now? */
+       if (bcr1 == 1)
+       {
+               m_iol |= Z180_TEND1;
+       }
+
+       m_extra_cycles = 0;
+
+       switch (IO_DCNTL & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0))
+       {
+       case 0x00:  /* memory MAR1+1 to I/O IAR1 fixed */
+               m_iospace->write_byte(iar1, m_program->read_byte(mar1++));
+               break;
+       case 0x01:  /* memory MAR1-1 to I/O IAR1 fixed */
+               m_iospace->write_byte(iar1, m_program->read_byte(mar1--));
+               break;
+       case 0x02:  /* I/O IAR1 fixed to memory MAR1+1 */
+               m_program->write_byte(mar1++, m_iospace->read_byte(iar1));
+               break;
+       case 0x03:  /* I/O IAR1 fixed to memory MAR1-1 */
+               m_program->write_byte(mar1--, m_iospace->read_byte(iar1));
+               break;
+       }
+
+       cycles += IO_DCNTL >> 6; // memory wait states
+       cycles += m_extra_cycles; // use extra_cycles for I/O wait states
+
+       /* edge sensitive DREQ1 ? */
+       if (IO_DCNTL & Z180_DCNTL_DIM1)
+               m_iol &= ~Z180_DREQ1;
+
+       IO_MAR1L = mar1;
+       IO_MAR1H = mar1 >> 8;
+       IO_MAR1B = mar1 >> 16;
+       IO_BCR1L = bcr1;
+       IO_BCR1H = bcr1 >> 8;
+
+       /* DMA terminal count? */
+       if (bcr1 == 0)
+       {
+               m_iol &= ~Z180_TEND1;
+               IO_DSTAT &= ~Z180_DSTAT_DE1;
+               if (IO_DSTAT & Z180_DSTAT_DIE1 && m_IFF1)
+                       m_int_pending[Z180_INT_DMA1] = 1;
+       }
+
+       /* six cycles per transfer (minimum) */
+       return 6 + cycles;
+}
+
+void z180_device::z180_write_iolines(uint32_t data)
+{
+       uint32_t changes = m_iol ^ data;
+
+       /* I/O asynchronous clock 0 (active high) or DREQ0 (mux) */
+       if (changes & Z180_CKA0)
+       {
+               LOG("Z180 CKA0   %d\n", data & Z180_CKA0 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_CKA0) | (data & Z180_CKA0);
+       }
+
+       /* I/O asynchronous clock 1 (active high) or TEND1 (mux) */
+       if (changes & Z180_CKA1)
+       {
+               LOG("Z180 CKA1   %d\n", data & Z180_CKA1 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_CKA1) | (data & Z180_CKA1);
+       }
+
+       /* I/O serial clock (active high) */
+       if (changes & Z180_CKS)
+       {
+               LOG("Z180 CKS    %d\n", data & Z180_CKS ? 1 : 0);
+               m_iol = (m_iol & ~Z180_CKS) | (data & Z180_CKS);
+       }
+
+       /* I   clear to send 0 (active low) */
+       if (changes & Z180_CTS0)
+       {
+               LOG("Z180 CTS0   %d\n", data & Z180_CTS0 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_CTS0) | (data & Z180_CTS0);
+       }
+
+       /* I   clear to send 1 (active low) or RXS (mux) */
+       if (changes & Z180_CTS1)
+       {
+               LOG("Z180 CTS1   %d\n", data & Z180_CTS1 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_CTS1) | (data & Z180_CTS1);
+       }
+
+       /* I   data carrier detect (active low) */
+       if (changes & Z180_DCD0)
+       {
+               LOG("Z180 DCD0   %d\n", data & Z180_DCD0 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_DCD0) | (data & Z180_DCD0);
+       }
+
+       /* I   data request DMA ch 0 (active low) or CKA0 (mux) */
+       if (changes & Z180_DREQ0)
+       {
+               LOG("Z180 DREQ0  %d\n", data & Z180_DREQ0 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_DREQ0) | (data & Z180_DREQ0);
+       }
+
+       /* I   data request DMA ch 1 (active low) */
+       if (changes & Z180_DREQ1)
+       {
+               LOG("Z180 DREQ1  %d\n", data & Z180_DREQ1 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_DREQ1) | (data & Z180_DREQ1);
+       }
+
+       /* I   asynchronous receive data 0 (active high) */
+       if (changes & Z180_RXA0)
+       {
+               LOG("Z180 RXA0   %d\n", data & Z180_RXA0 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_RXA0) | (data & Z180_RXA0);
+       }
+
+       /* I   asynchronous receive data 1 (active high) */
+       if (changes & Z180_RXA1)
+       {
+               LOG("Z180 RXA1   %d\n", data & Z180_RXA1 ? 1 : 0);
+               m_iol = (m_iol & ~Z180_RXA1) | (data & Z180_RXA1);
+       }
+
+       /* I   clocked serial receive data (active high) or CTS1 (mux) */
+       if (changes & Z180_RXS)
+       {
+               LOG("Z180 RXS    %d\n", data & Z180_RXS ? 1 : 0);
+               m_iol = (m_iol & ~Z180_RXS) | (data & Z180_RXS);
+       }
+
+       /*   O request to send (active low) */
+       if (changes & Z180_RTS0)
+       {
+               LOG("Z180 RTS0   won't change output\n");
+       }
+
+       /*   O transfer end 0 (active low) or CKA1 (mux) */
+       if (changes & Z180_TEND0)
+       {
+               LOG("Z180 TEND0  won't change output\n");
+       }
+
+       /*   O transfer end 1 (active low) */
+       if (changes & Z180_TEND1)
+       {
+               LOG("Z180 TEND1  won't change output\n");
+       }
+
+       /*   O transfer out (PRT channel, active low) or A18 (mux) */
+       if (changes & Z180_A18_TOUT)
+       {
+               LOG("Z180 TOUT   won't change output\n");
+       }
+
+       /*   O asynchronous transmit data 0 (active high) */
+       if (changes & Z180_TXA0)
+       {
+               LOG("Z180 TXA0   won't change output\n");
+       }
+
+       /*   O asynchronous transmit data 1 (active high) */
+       if (changes & Z180_TXA1)
+       {
+               LOG("Z180 TXA1   won't change output\n");
+       }
+
+       /*   O clocked serial transmit data (active high) */
+       if (changes & Z180_TXS)
+       {
+               LOG("Z180 TXS    won't change output\n");
+       }
+}
+
+void z180_device::device_start()
+{
+       int i, p;
+       int oldval, newval, val;
+       uint8_t *padd, *padc, *psub, *psbc;
+
+       /* allocate big flag arrays once */
+       SZHVC_add = std::make_unique<uint8_t[]>(2*256*256);
+       SZHVC_sub = std::make_unique<uint8_t[]>(2*256*256);
+
+       padd = &SZHVC_add[  0*256];
+       padc = &SZHVC_add[256*256];
+       psub = &SZHVC_sub[  0*256];
+       psbc = &SZHVC_sub[256*256];
+       for (oldval = 0; oldval < 256; oldval++)
+       {
+               for (newval = 0; newval < 256; newval++)
+               {
+                       /* add or adc w/o carry set */
+                       val = newval - oldval;
+                       *padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
+                       *padd |= (newval & (YF | XF));  /* undocumented flag bits 5+3 */
+
+                       if( (newval & 0x0f) < (oldval & 0x0f) ) *padd |= HF;
+                       if( newval < oldval ) *padd |= CF;
+                       if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padd |= VF;
+                       padd++;
+
+                       /* adc with carry set */
+                       val = newval - oldval - 1;
+                       *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
+                       *padc |= (newval & (YF | XF));  /* undocumented flag bits 5+3 */
+                       if( (newval & 0x0f) <= (oldval & 0x0f) ) *padc |= HF;
+                       if( newval <= oldval ) *padc |= CF;
+                       if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padc |= VF;
+                       padc++;
+
+                       /* cp, sub or sbc w/o carry set */
+                       val = oldval - newval;
+                       *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
+                       *psub |= (newval & (YF | XF));  /* undocumented flag bits 5+3 */
+                       if( (newval & 0x0f) > (oldval & 0x0f) ) *psub |= HF;
+                       if( newval > oldval ) *psub |= CF;
+                       if( (val^oldval) & (oldval^newval) & 0x80 ) *psub |= VF;
+                       psub++;
+
+                       /* sbc with carry set */
+                       val = oldval - newval - 1;
+                       *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
+                       *psbc |= (newval & (YF | XF));  /* undocumented flag bits 5+3 */
+                       if( (newval & 0x0f) >= (oldval & 0x0f) ) *psbc |= HF;
+                       if( newval >= oldval ) *psbc |= CF;
+                       if( (val^oldval) & (oldval^newval) & 0x80 ) *psbc |= VF;
+                       psbc++;
+               }
+       }
+       for (i = 0; i < 256; i++)
+       {
+               p = 0;
+               if( i&0x01 ) ++p;
+               if( i&0x02 ) ++p;
+               if( i&0x04 ) ++p;
+               if( i&0x08 ) ++p;
+               if( i&0x10 ) ++p;
+               if( i&0x20 ) ++p;
+               if( i&0x40 ) ++p;
+               if( i&0x80 ) ++p;
+               SZ[i] = i ? i & SF : ZF;
+               SZ[i] |= (i & (YF | XF));       /* undocumented flag bits 5+3 */
+               SZ_BIT[i] = i ? i & SF : ZF | PF;
+               SZ_BIT[i] |= (i & (YF | XF));   /* undocumented flag bits 5+3 */
+               SZP[i] = SZ[i] | ((p & 1) ? 0 : PF);
+               SZHV_inc[i] = SZ[i];
+               if( i == 0x80 ) SZHV_inc[i] |= VF;
+               if( (i & 0x0f) == 0x00 ) SZHV_inc[i] |= HF;
+               SZHV_dec[i] = SZ[i] | NF;
+               if( i == 0x7f ) SZHV_dec[i] |= VF;
+               if( (i & 0x0f) == 0x0f ) SZHV_dec[i] |= HF;
+       }
+
+       m_program = &space(AS_PROGRAM);
+       m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
+       m_oprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program;
+       m_ocache = m_oprogram->cache<0, 0, ENDIANNESS_LITTLE>();
+       m_iospace = &space(AS_IO);
+
+       /* set up the state table */
+       {
+               state_add(Z180_PC,         "PC",        m_PC.w.l);
+               state_add(STATE_GENPC,     "GENPC",     _PCD).noshow();
+               state_add(STATE_GENPCBASE, "CURPC",     m_PREPC.w.l).noshow();
+               state_add(Z180_SP,         "SP",        _SPD);
+               state_add(STATE_GENSP,     "GENSP",     m_SP.w.l).noshow();
+               state_add(STATE_GENFLAGS,  "GENFLAGS",  m_AF.b.l).noshow().formatstr("%8s");
+               state_add(Z180_A,          "A",         _A).noshow();
+               state_add(Z180_B,          "B",         _B).noshow();
+               state_add(Z180_C,          "C",         _C).noshow();
+               state_add(Z180_D,          "D",         _D).noshow();
+               state_add(Z180_E,          "E",         _E).noshow();
+               state_add(Z180_H,          "H",         _H).noshow();
+               state_add(Z180_L,          "L",         _L).noshow();
+               state_add(Z180_AF,         "AF",        m_AF.w.l);
+               state_add(Z180_BC,         "BC",        m_BC.w.l);
+               state_add(Z180_DE,         "DE",        m_DE.w.l);
+               state_add(Z180_HL,         "HL",        m_HL.w.l);
+               state_add(Z180_IX,         "IX",        m_IX.w.l);
+               state_add(Z180_IY,         "IY",        m_IY.w.l);
+               state_add(Z180_AF2,        "AF2",       m_AF2.w.l);
+               state_add(Z180_BC2,        "BC2",       m_BC2.w.l);
+               state_add(Z180_DE2,        "DE2",       m_DE2.w.l);
+               state_add(Z180_HL2,        "HL2",       m_HL2.w.l);
+               state_add(Z180_R,          "R",         m_rtemp).callimport().callexport();
+               state_add(Z180_I,          "I",         m_I);
+               state_add(Z180_IM,         "IM",        m_IM).mask(0x3);
+               state_add(Z180_IFF1,       "IFF1",      m_IFF1).mask(0x1);
+               state_add(Z180_IFF2,       "IFF2",      m_IFF2).mask(0x1);
+               state_add(Z180_HALT,       "HALT",      m_HALT).mask(0x1);
+
+               state_add(Z180_IOLINES,    "IOLINES",   m_ioltemp).mask(0xffffff).callimport();
+
+               state_add(Z180_CNTLA0,     "CNTLA0",    IO_CNTLA0);
+               state_add(Z180_CNTLA1,     "CNTLA1",    IO_CNTLA1);
+               state_add(Z180_CNTLB0,     "CNTLB0",    IO_CNTLB0);
+               state_add(Z180_CNTLB1,     "CNTLB1",    IO_CNTLB1);
+               state_add(Z180_STAT0,      "STAT0",     IO_STAT0);
+               state_add(Z180_STAT1,      "STAT1",     IO_STAT1);
+               state_add(Z180_TDR0,       "TDR0",      IO_TDR0);
+               state_add(Z180_TDR1,       "TDR1",      IO_TDR1);
+               state_add(Z180_RDR0,       "RDR0",      IO_RDR0);
+               state_add(Z180_RDR1,       "RDR1",      IO_RDR1);
+               state_add(Z180_CNTR,       "CNTR",      IO_CNTR);
+               state_add(Z180_TRDR,       "TRDR",      IO_TRDR);
+               state_add(Z180_TMDR0L,     "TMDR0L",    IO_TMDR0L);
+               state_add(Z180_TMDR0H,     "TMDR0H",    IO_TMDR0H);
+               state_add(Z180_RLDR0L,     "RLDR0L",    IO_RLDR0L);
+               state_add(Z180_RLDR0H,     "RLDR0H",    IO_RLDR0H);
+               state_add(Z180_TCR,        "TCR",       IO_TCR);
+               state_add(Z180_IO11,       "IO11",      IO_IO11);
+               state_add(Z180_ASEXT0,     "ASEXT0",    IO_ASEXT0);
+               state_add(Z180_ASEXT1,     "ASEXT1",    IO_ASEXT1);
+               state_add(Z180_TMDR1L,     "TMDR1L",    IO_TMDR1L);
+               state_add(Z180_TMDR1H,     "TMDR1H",    IO_TMDR1H);
+               state_add(Z180_RLDR1L,     "RLDR1L",    IO_RLDR1L);
+               state_add(Z180_RLDR1H,     "RLDR1H",    IO_RLDR1H);
+               state_add(Z180_FRC,        "FRC",       IO_FRC);
+               state_add(Z180_IO19,       "IO19",      IO_IO19);
+               state_add(Z180_ASTC0L,     "ASTC0L",    IO_ASTC0L);
+               state_add(Z180_ASTC0H,     "ASTC0H",    IO_ASTC0H);
+               state_add(Z180_ASTC1L,     "ASTC1L",    IO_ASTC1L);
+               state_add(Z180_ASTC1H,     "ASTC1H",    IO_ASTC1H);
+               state_add(Z180_CMR,        "CMR",       IO_CMR);
+               state_add(Z180_CCR,        "CCR",       IO_CCR);
+               state_add(Z180_SAR0L,      "SAR0L",     IO_SAR0L);
+               state_add(Z180_SAR0H,      "SAR0H",     IO_SAR0H);
+               state_add(Z180_SAR0B,      "SAR0B",     IO_SAR0B);
+               state_add(Z180_DAR0L,      "DAR0L",     IO_DAR0L);
+               state_add(Z180_DAR0H,      "DAR0H",     IO_DAR0H);
+               state_add(Z180_DAR0B,      "DAR0B",     IO_DAR0B);
+               state_add(Z180_BCR0L,      "BCR0L",     IO_BCR0L);
+               state_add(Z180_BCR0H,      "BCR0H",     IO_BCR0H);
+               state_add(Z180_MAR1L,      "MAR1L",     IO_MAR1L);
+               state_add(Z180_MAR1H,      "MAR1H",     IO_MAR1H);
+               state_add(Z180_MAR1B,      "MAR1B",     IO_MAR1B);
+               state_add(Z180_IAR1L,      "IAR1L",     IO_IAR1L);
+               state_add(Z180_IAR1H,      "IAR1H",     IO_IAR1H);
+               state_add(Z180_IAR1B,      "IAR1B",     IO_IAR1B);
+               state_add(Z180_BCR1L,      "BCR1L",     IO_BCR1L);
+               state_add(Z180_BCR1H,      "BCR1H",     IO_BCR1H);
+               state_add(Z180_DSTAT,      "DSTAT",     IO_DSTAT);
+               state_add(Z180_DMODE,      "DMODE",     IO_DMODE);
+               state_add(Z180_DCNTL,      "DCNTL",     IO_DCNTL);
+               state_add(Z180_IL,         "IL",        IO_IL);
+               state_add(Z180_ITC,        "ITC",       IO_ITC);
+               state_add(Z180_IO35,       "IO35",      IO_IO35);
+               state_add(Z180_RCR,        "RCR",       IO_RCR);
+               state_add(Z180_IO37,       "IO37",      IO_IO37);
+               state_add(Z180_CBR,        "CBR",       IO_CBR).callimport();
+               state_add(Z180_BBR,        "BBR",       IO_BBR).callimport();
+               state_add(Z180_CBAR,       "CBAR",      IO_CBAR).callimport();
+               state_add(Z180_IO3B,       "IO3B",      IO_IO3B);
+               state_add(Z180_IO3C,       "IO3C",      IO_IO3C);
+               state_add(Z180_IO3D,       "IO3D",      IO_IO3D);
+               state_add(Z180_OMCR,       "OMCR",      IO_OMCR);
+               state_add(Z180_IOCR,       "IOCR",      IO_IOCR);
+       }
+
+       save_item(NAME(m_AF.w.l));
+       save_item(NAME(m_BC.w.l));
+       save_item(NAME(m_DE.w.l));
+       save_item(NAME(m_HL.w.l));
+       save_item(NAME(m_IX.w.l));
+       save_item(NAME(m_IY.w.l));
+       save_item(NAME(m_PC.w.l));
+       save_item(NAME(m_SP.w.l));
+       save_item(NAME(m_AF2.w.l));
+       save_item(NAME(m_BC2.w.l));
+       save_item(NAME(m_DE2.w.l));
+       save_item(NAME(m_HL2.w.l));
+       save_item(NAME(m_R));
+       save_item(NAME(m_R2));
+       save_item(NAME(m_IFF1));
+       save_item(NAME(m_IFF2));
+       save_item(NAME(m_HALT));
+       save_item(NAME(m_IM));
+       save_item(NAME(m_I));
+       save_item(NAME(m_nmi_state));
+       save_item(NAME(m_nmi_pending));
+       save_item(NAME(m_irq_state));
+       save_item(NAME(m_int_pending));
+       save_item(NAME(m_timer_cnt));
+       save_item(NAME(m_dma0_cnt));
+       save_item(NAME(m_dma1_cnt));
+       save_item(NAME(m_after_EI));
+
+       save_item(NAME(m_tif));
+
+       save_item(NAME(m_read_tcr_tmdr));
+       save_item(NAME(m_tmdr_value));
+       save_item(NAME(m_tmdrh));
+       save_item(NAME(m_tmdr_latch));
+
+       save_item(NAME(m_io));
+       save_item(NAME(m_iol));
+       save_item(NAME(m_ioltemp));
+
+       save_item(NAME(m_mmu));
+
+       set_icountptr(m_icount);
+}
+
+/****************************************************************************
+ * Reset registers to their initial values
+ ****************************************************************************/
+void z180_device::device_reset()
+{
+       _PPC = 0;
+       _PCD = 0;
+       _SPD = 0;
+       _AFD = 0;
+       _BCD = 0;
+       _DED = 0;
+       _HLD = 0;
+       _IXD = 0;
+       _IYD = 0;
+       m_AF2.d = 0;
+       m_BC2.d = 0;
+       m_DE2.d = 0;
+       m_HL2.d = 0;
+       m_R = 0;
+       m_R2 = 0;
+       m_IFF1 = 0;
+       m_IFF2 = 0;
+       m_HALT = 0;
+       m_IM = 0;
+       m_I = 0;
+       m_tmdr_latch = 0;
+       m_read_tcr_tmdr[0] = 0;
+       m_read_tcr_tmdr[1] = 0;
+       m_iol = 0;
+       memset(m_io, 0, sizeof(m_io));
+       memset(m_mmu, 0, sizeof(m_mmu));
+       m_tmdrh[0] = 0;
+       m_tmdrh[1] = 0;
+       m_tmdr_value[0] = 0xffff;
+       m_tmdr_value[1] = 0xffff;
+       m_tif[0] = 0;
+       m_tif[1] = 0;
+       m_nmi_state = CLEAR_LINE;
+       m_nmi_pending = 0;
+       m_irq_state[0] = CLEAR_LINE;
+       m_irq_state[1] = CLEAR_LINE;
+       m_irq_state[2] = CLEAR_LINE;
+       m_after_EI = 0;
+       m_ea = 0;
+
+       memcpy(m_cc, (uint8_t *)cc_default, sizeof(m_cc));
+       _IX = _IY = 0xffff; /* IX and IY are FFFF after a reset! */
+       _F = ZF;          /* Zero flag is set */
+
+       for (int i=0; i <= Z180_INT_MAX; i++)
+       {
+               m_int_pending[i] = 0;
+       }
+
+       m_timer_cnt = 0;
+       m_dma0_cnt = 0;
+       m_dma1_cnt = 0;
+
+       /* reset io registers */
+       IO_CNTLA0  = Z180_CNTLA0_RESET;
+       IO_CNTLA1  = Z180_CNTLA1_RESET;
+       IO_CNTLB0  = Z180_CNTLB0_RESET;
+       IO_CNTLB1  = Z180_CNTLB1_RESET;
+       IO_STAT0   = Z180_STAT0_RESET;
+       IO_STAT1   = Z180_STAT1_RESET;
+       IO_TDR0    = Z180_TDR0_RESET;
+       IO_TDR1    = Z180_TDR1_RESET;
+       IO_RDR0    = Z180_RDR0_RESET;
+       IO_RDR1    = Z180_RDR1_RESET;
+       IO_CNTR    = Z180_CNTR_RESET;
+       IO_TRDR    = Z180_TRDR_RESET;
+       IO_TMDR0L  = Z180_TMDR0L_RESET;
+       IO_TMDR0H  = Z180_TMDR0H_RESET;
+       IO_RLDR0L  = Z180_RLDR0L_RESET;
+       IO_RLDR0H  = Z180_RLDR0H_RESET;
+       IO_TCR       = Z180_TCR_RESET;
+       IO_IO11    = Z180_IO11_RESET;
+       IO_ASEXT0  = Z180_ASEXT0_RESET;
+       IO_ASEXT1  = Z180_ASEXT1_RESET;
+       IO_TMDR1L  = Z180_TMDR1L_RESET;
+       IO_TMDR1H  = Z180_TMDR1H_RESET;
+       IO_RLDR1L  = Z180_RLDR1L_RESET;
+       IO_RLDR1H  = Z180_RLDR1H_RESET;
+       IO_FRC       = Z180_FRC_RESET;
+       IO_IO19    = Z180_IO19_RESET;
+       IO_ASTC0L  = Z180_ASTC0L_RESET;
+       IO_ASTC0H  = Z180_ASTC0H_RESET;
+       IO_ASTC1L  = Z180_ASTC1L_RESET;
+       IO_ASTC1H  = Z180_ASTC1H_RESET;
+       IO_CMR       = Z180_CMR_RESET;
+       IO_CCR       = Z180_CCR_RESET;
+       IO_SAR0L   = Z180_SAR0L_RESET;
+       IO_SAR0H   = Z180_SAR0H_RESET;
+       IO_SAR0B   = Z180_SAR0B_RESET;
+       IO_DAR0L   = Z180_DAR0L_RESET;
+       IO_DAR0H   = Z180_DAR0H_RESET;
+       IO_DAR0B   = Z180_DAR0B_RESET;
+       IO_BCR0L   = Z180_BCR0L_RESET;
+       IO_BCR0H   = Z180_BCR0H_RESET;
+       IO_MAR1L   = Z180_MAR1L_RESET;
+       IO_MAR1H   = Z180_MAR1H_RESET;
+       IO_MAR1B   = Z180_MAR1B_RESET;
+       IO_IAR1L   = Z180_IAR1L_RESET;
+       IO_IAR1H   = Z180_IAR1H_RESET;
+       IO_IAR1B   = Z180_IAR1B_RESET;
+       IO_BCR1L   = Z180_BCR1L_RESET;
+       IO_BCR1H   = Z180_BCR1H_RESET;
+       IO_DSTAT   = Z180_DSTAT_RESET;
+       IO_DMODE   = Z180_DMODE_RESET;
+       IO_DCNTL   = Z180_DCNTL_RESET;
+       IO_IL    = Z180_IL_RESET;
+       IO_ITC       = Z180_ITC_RESET;
+       IO_IO35    = Z180_IO35_RESET;
+       IO_RCR       = Z180_RCR_RESET;
+       IO_IO37    = Z180_IO37_RESET;
+       IO_CBR       = Z180_CBR_RESET;
+       IO_BBR       = Z180_BBR_RESET;
+       IO_CBAR    = Z180_CBAR_RESET;
+       IO_IO3B    = Z180_IO3B_RESET;
+       IO_IO3C    = Z180_IO3C_RESET;
+       IO_IO3D    = Z180_IO3D_RESET;
+       IO_OMCR    = Z180_OMCR_RESET;
+       IO_IOCR    = Z180_IOCR_RESET;
+
+       z180_mmu();
+}
+
+/* Handle PRT timers, decreasing them after 20 clocks and returning the new icount base that needs to be used for the next check */
+void z180_device::clock_timers()
+{
+       m_timer_cnt++;
+       if (m_timer_cnt >= 20)
+       {
+               m_timer_cnt = 0;
+               /* Programmable Reload Timer 0 */
+               if(IO_TCR & Z180_TCR_TDE0)
+               {
+                       if(m_tmdr_value[0] == 0)
+                       {
+                               m_tmdr_value[0] = IO_RLDR0L | (IO_RLDR0H << 8);
+                               m_tif[0] = 1;
+                       }
+                       else
+                               m_tmdr_value[0]--;
+               }
+
+               /* Programmable Reload Timer 1 */
+               if(IO_TCR & Z180_TCR_TDE1)
+               {
+                       if(m_tmdr_value[1] == 0)
+                       {
+                               m_tmdr_value[1] = IO_RLDR1L | (IO_RLDR1H << 8);
+                               m_tif[1] = 1;
+                       }
+                       else
+                               m_tmdr_value[1]--;
+               }
+
+               if((IO_TCR & Z180_TCR_TIE0) && m_tif[0])
+               {
+                       // check if we can take the interrupt
+                       if(m_IFF1 && !m_after_EI)
+                       {
+                               m_int_pending[Z180_INT_PRT0] = 1;
+                       }
+               }
+
+               if((IO_TCR & Z180_TCR_TIE1) && m_tif[1])
+               {
+                       // check if we can take the interrupt
+                       if(m_IFF1 && !m_after_EI)
+                       {
+                               m_int_pending[Z180_INT_PRT1] = 1;
+                       }
+               }
+
+       }
+}
+
+int z180_device::check_interrupts()
+{
+       int i;
+       int cycles = 0;
+
+       /* check for IRQs before each instruction */
+       if (m_IFF1 && !m_after_EI)
+       {
+               if (m_irq_state[0] != CLEAR_LINE && (IO_ITC & Z180_ITC_ITE0) == Z180_ITC_ITE0)
+                       m_int_pending[Z180_INT_IRQ0] = 1;
+
+               if (m_irq_state[1] != CLEAR_LINE && (IO_ITC & Z180_ITC_ITE1) == Z180_ITC_ITE1)
+                       m_int_pending[Z180_INT_IRQ1] = 1;
+
+               if (m_irq_state[2] != CLEAR_LINE && (IO_ITC & Z180_ITC_ITE2) == Z180_ITC_ITE2)
+                       m_int_pending[Z180_INT_IRQ2] = 1;
+       }
+
+       for (i = 0; i <= Z180_INT_MAX; i++)
+               if (m_int_pending[i])
+               {
+                       cycles += take_interrupt(i);
+                       m_int_pending[i] = 0;
+                       break;
+               }
+
+       return cycles;
+}
+
+/****************************************************************************
+ * Handle I/O and timers
+ ****************************************************************************/
+
+void z180_device::handle_io_timers(int cycles)
+{
+       while (cycles-- > 0)
+       {
+               clock_timers();
+       }
+}
+
+/****************************************************************************
+ * Execute 'cycles' T-states. Return number of T-states really executed
+ ****************************************************************************/
+void z180_device::execute_run()
+{
+       int curcycles;
+
+       /* check for NMIs on the way in; they can only be set externally */
+       /* via timers, and can't be dynamically enabled, so it is safe */
+       /* to just check here */
+       if (m_nmi_pending)
+       {
+               LOG("Z180 take NMI\n");
+               LEAVE_HALT();       /* Check if processor was halted */
+
+               /* disable DMA transfers!! */
+               IO_DSTAT &= ~Z180_DSTAT_DME;
+
+               m_IFF2 = m_IFF1;
+               m_IFF1 = 0;
+               PUSH( PC );
+               _PCD = 0x0066;
+               m_icount -= 11;
+               m_nmi_pending = 0;
+               handle_io_timers(11);
+       }
+
+again:
+       /* check if any DMA transfer is running */
+       if ((IO_DSTAT & Z180_DSTAT_DME) == Z180_DSTAT_DME)
+       {
+               /* check if DMA channel 0 is running and also is in burst mode */
+               if ((IO_DSTAT & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 &&
+                       (IO_DMODE & Z180_DMODE_MMOD) == Z180_DMODE_MMOD)
+               {
+                       debugger_instruction_hook(_PCD);
+
+                       /* FIXME z180_dma0 should be handled in handle_io_timers */
+                       curcycles = z180_dma0(m_icount);
+                       m_icount -= curcycles;
+                       handle_io_timers(curcycles);
+               }
+               else
+               {
+                       do
+                       {
+                               curcycles = check_interrupts();
+                               m_icount -= curcycles;
+                               handle_io_timers(curcycles);
+                               m_after_EI = 0;
+
+                               _PPC = _PCD;
+                               debugger_instruction_hook(_PCD);
+
+                               if (!m_HALT)
+                               {
+                                       m_R++;
+                                       IO_FRC++;   /* Added FRC counting, not implemented yet */
+                                       m_extra_cycles = 0;
+                                       curcycles = exec_op(ROP());
+                                       curcycles += m_extra_cycles;
+                               }
+                               else
+                                       curcycles = 3;
+
+                               m_icount -= curcycles;
+
+                               handle_io_timers(curcycles);
+
+                               /* if channel 0 was started in burst mode, go recheck the mode */
+                               if ((IO_DSTAT & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 &&
+                                       (IO_DMODE & Z180_DMODE_MMOD) == Z180_DMODE_MMOD)
+                                       goto again;
+
+                               /* FIXME:
+                                * For simultaneous DREQ0 and DREQ1 requests, channel 0 has priority
+                                * over channel 1. When channel 0 is performing a memory to/from memory
+                                * transfer, channel 1 cannot operate until the channel 0 operation has
+                                * terminated. If channel 1 is operating, channel 0 cannot operate until
+                                * channel 1 releases control of the bus.
+                                *
+                                */
+                               curcycles = z180_dma0(6);
+                               m_icount -= curcycles;
+                               handle_io_timers(curcycles);
+
+                               curcycles = z180_dma1();
+                               m_icount -= curcycles;
+                               handle_io_timers(curcycles);
+
+                               /* If DMA is done break out to the faster loop */
+                               if ((IO_DSTAT & Z180_DSTAT_DME) != Z180_DSTAT_DME)
+                                       break;
+                       } while( m_icount > 0 );
+               }
+       }
+
+       if (m_icount > 0)
+       {
+               do
+               {
+                       /* If DMA is started go to check the mode */
+                       if ((IO_DSTAT & Z180_DSTAT_DME) == Z180_DSTAT_DME)
+                               goto again;
+
+                       curcycles = check_interrupts();
+                       m_icount -= curcycles;
+                       handle_io_timers(curcycles);
+                       m_after_EI = 0;
+
+                       _PPC = _PCD;
+                       debugger_instruction_hook(_PCD);
+
+                       if (!m_HALT)
+                       {
+                               m_R++;
+                               IO_FRC++;   /* Added FRC counting, not implemented yet */
+                               m_extra_cycles = 0;
+                               curcycles = exec_op(ROP());
+                               curcycles += m_extra_cycles;
+                       }
+                       else
+                               curcycles = 3;
+
+                       m_icount -= curcycles;
+                       handle_io_timers(curcycles);
+               } while( m_icount > 0 );
+       }
+}
+
+/****************************************************************************
+ * Burn 'cycles' T-states. Adjust R register for the lost time
+ ****************************************************************************/
+void z180_device::execute_burn(int32_t cycles)
+{
+       int extra_cycles = IO_DCNTL >> 6; // memory wait states
+
+       /* FIXME: This is not appropriate for dma */
+       while ( (cycles > 0) )
+       {
+               handle_io_timers(3 + extra_cycles);
+               /* NOP takes 3 cycles per instruction */
+               m_R += 1;
+               m_icount -= 3 + extra_cycles;
+               cycles -= 3 + extra_cycles;
+       }
+}
+
+/****************************************************************************
+ * Set IRQ line state
+ ****************************************************************************/
+void z180_device::execute_set_input(int irqline, int state)
+{
+       if (irqline == INPUT_LINE_NMI)
+       {
+               /* mark an NMI pending on the rising edge */
+               if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE)
+                       m_nmi_pending = 1;
+               m_nmi_state = state;
+       }
+       else
+       {
+               LOG("Z180 set_irq_line %d = %d\n", irqline,state);
+
+               if(irqline == Z180_INPUT_LINE_IRQ0 || irqline == Z180_INPUT_LINE_IRQ1 || irqline == Z180_INPUT_LINE_IRQ2) {
+                       /* update the IRQ state */
+                       m_irq_state[irqline] = state;
+                       if(daisy_chain_present())
+                               m_irq_state[0] = daisy_update_irq_state();
+
+                       /* the main execute loop will take the interrupt */
+               } else if(irqline == Z180_INPUT_LINE_DREQ0) {
+                       uint32_t iol = m_iol & ~Z180_DREQ0;
+                       if(state == ASSERT_LINE)
+                               iol |= Z180_DREQ0;
+                       z180_write_iolines(iol);
+               } else if(irqline == Z180_INPUT_LINE_DREQ1) {
+                       uint32_t iol = m_iol & ~Z180_DREQ1;
+                       if(state == ASSERT_LINE)
+                               iol |= Z180_DREQ1;
+                       z180_write_iolines(iol);
+               }
+       }
+}
+
+/* logical to physical address translation */
+bool z180_device::memory_translate(int spacenum, int intention, offs_t &address)
+{
+       if (spacenum == AS_PROGRAM)
+       {
+               address = MMU_REMAP_ADDR(address);
+       }
+       return true;
+}
+
+
+/**************************************************************************
+ * STATE IMPORT/EXPORT
+ **************************************************************************/
+
+void z180_device::state_import(const device_state_entry &entry)
+{
+       switch (entry.index())
+       {
+               case Z180_R:
+                       m_R = m_rtemp & 0x7f;
+                       m_R2 = m_rtemp & 0x80;
+                       break;
+
+               case Z180_CBR:
+               case Z180_BBR:
+               case Z180_CBAR:
+                       z180_mmu();
+                       break;
+
+               case Z180_IOLINES:
+                       z180_write_iolines(m_ioltemp);
+                       break;
+
+               default:
+                       fatalerror("CPU_IMPORT_STATE(z80) called for unexpected value\n");
+       }
+}
+
+
+void z180_device::state_export(const device_state_entry &entry)
+{
+       switch (entry.index())
+       {
+               case Z180_R:
+                       m_rtemp = (m_R & 0x7f) | (m_R2 & 0x80);
+                       break;
+
+               case Z180_IOLINES:
+                       m_ioltemp = m_iol;
+                       break;
+
+               default:
+                       fatalerror("CPU_EXPORT_STATE(z80) called for unexpected value\n");
+       }
+}
+
+void z180_device::state_string_export(const device_state_entry &entry, std::string &str) const
+{
+       switch (entry.index())
+       {
+               case STATE_GENFLAGS:
+                       str = string_format("%c%c%c%c%c%c%c%c",
+                               m_AF.b.l & 0x80 ? 'S':'.',
+                               m_AF.b.l & 0x40 ? 'Z':'.',
+                               m_AF.b.l & 0x20 ? '5':'.',
+                               m_AF.b.l & 0x10 ? 'H':'.',
+                               m_AF.b.l & 0x08 ? '3':'.',
+                               m_AF.b.l & 0x04 ? 'P':'.',
+                               m_AF.b.l & 0x02 ? 'N':'.',
+                               m_AF.b.l & 0x01 ? 'C':'.');
+                       break;
+       }
+}
diff --git a/z180/z180.h b/z180/z180.h
new file mode 100644 (file)
index 0000000..ad5d158
--- /dev/null
@@ -0,0 +1,1783 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+#ifndef MAME_CPU_Z180_Z180_H
+#define MAME_CPU_Z180_Z180_H
+
+#pragma once
+
+#include "machine/z80daisy.h"
+
+
+enum
+{
+       Z180_PC,
+       Z180_SP,
+       Z180_AF,
+       Z180_BC,
+       Z180_DE,
+       Z180_HL,
+       Z180_IX,
+       Z180_IY,
+       Z180_A,
+       Z180_B,
+       Z180_C,
+       Z180_D,
+       Z180_E,
+       Z180_H,
+       Z180_L,
+       Z180_AF2,
+       Z180_BC2,
+       Z180_DE2,
+       Z180_HL2,
+       Z180_R,
+       Z180_I,
+       Z180_IM,
+       Z180_IFF1,
+       Z180_IFF2,
+       Z180_HALT,
+       Z180_DC0,
+       Z180_DC1,
+       Z180_DC2,
+       Z180_DC3,
+       Z180_CNTLA0,    /* 00 ASCI control register A ch 0 */
+       Z180_CNTLA1,    /* 01 ASCI control register A ch 1 */
+       Z180_CNTLB0,    /* 02 ASCI control register B ch 0 */
+       Z180_CNTLB1,    /* 03 ASCI control register B ch 1 */
+       Z180_STAT0,     /* 04 ASCI status register 0 */
+       Z180_STAT1,     /* 05 ASCI status register 1 */
+       Z180_TDR0,      /* 06 ASCI transmit data register 0 */
+       Z180_TDR1,      /* 07 ASCI transmit data register 1 */
+       Z180_RDR0,      /* 08 ASCI receive data register 0 */
+       Z180_RDR1,      /* 09 ASCI receive data register 1 */
+       Z180_CNTR,      /* 0a CSI/O control/status register */
+       Z180_TRDR,      /* 0b CSI/O transmit/receive register */
+       Z180_TMDR0L,    /* 0c TIMER data register ch 0 L */
+       Z180_TMDR0H,    /* 0d TIMER data register ch 0 H */
+       Z180_RLDR0L,    /* 0e TIMER reload register ch 0 L */
+       Z180_RLDR0H,    /* 0f TIMER reload register ch 0 H */
+       Z180_TCR,       /* 10 TIMER control register */
+       Z180_IO11,      /* 11 reserved */
+       Z180_ASEXT0,    /* 12 (Z8S180/Z8L180) ASCI extension control register 0 */
+       Z180_ASEXT1,    /* 13 (Z8S180/Z8L180) ASCI extension control register 0 */
+       Z180_TMDR1L,    /* 14 TIMER data register ch 1 L */
+       Z180_TMDR1H,    /* 15 TIMER data register ch 1 H */
+       Z180_RLDR1L,    /* 16 TIMER reload register ch 1 L */
+       Z180_RLDR1H,    /* 17 TIMER reload register ch 1 H */
+       Z180_FRC,       /* 18 free running counter */
+       Z180_IO19,      /* 19 reserved */
+       Z180_ASTC0L,    /* 1a ASCI time constant ch 0 L */
+       Z180_ASTC0H,    /* 1b ASCI time constant ch 0 H */
+       Z180_ASTC1L,    /* 1c ASCI time constant ch 1 L */
+       Z180_ASTC1H,    /* 1d ASCI time constant ch 1 H */
+       Z180_CMR,       /* 1e clock multiplier */
+       Z180_CCR,       /* 1f chip control register */
+       Z180_SAR0L,     /* 20 DMA source address register ch 0 L */
+       Z180_SAR0H,     /* 21 DMA source address register ch 0 H */
+       Z180_SAR0B,     /* 22 DMA source address register ch 0 B */
+       Z180_DAR0L,     /* 23 DMA destination address register ch 0 L */
+       Z180_DAR0H,     /* 24 DMA destination address register ch 0 H */
+       Z180_DAR0B,     /* 25 DMA destination address register ch 0 B */
+       Z180_BCR0L,     /* 26 DMA byte count register ch 0 L */
+       Z180_BCR0H,     /* 27 DMA byte count register ch 0 H */
+       Z180_MAR1L,     /* 28 DMA memory address register ch 1 L */
+       Z180_MAR1H,     /* 29 DMA memory address register ch 1 H */
+       Z180_MAR1B,     /* 2a DMA memory address register ch 1 B */
+       Z180_IAR1L,     /* 2b DMA I/O address register ch 1 L */
+       Z180_IAR1H,     /* 2c DMA I/O address register ch 1 H */
+       Z180_IAR1B,     /* 2d (Z8S180/Z8L180) DMA I/O address register ch 1 B */
+       Z180_BCR1L,     /* 2e DMA byte count register ch 1 L */
+       Z180_BCR1H,     /* 2f DMA byte count register ch 1 H */
+       Z180_DSTAT,     /* 30 DMA status register */
+       Z180_DMODE,     /* 31 DMA mode register */
+       Z180_DCNTL,     /* 32 DMA/WAIT control register */
+       Z180_IL,        /* 33 INT vector low register */
+       Z180_ITC,       /* 34 INT/TRAP control register */
+       Z180_IO35,      /* 35 reserved */
+       Z180_RCR,       /* 36 refresh control register */
+       Z180_IO37,      /* 37 reserved */
+       Z180_CBR,       /* 38 MMU common base register */
+       Z180_BBR,       /* 39 MMU bank base register */
+       Z180_CBAR,      /* 3a MMU common/bank area register */
+       Z180_IO3B,      /* 3b reserved */
+       Z180_IO3C,      /* 3c reserved */
+       Z180_IO3D,      /* 3d reserved */
+       Z180_OMCR,      /* 3e operation mode control register */
+       Z180_IOCR,      /* 3f I/O control register */
+       Z180_IOLINES    /* read/write I/O lines */
+};
+
+enum
+{
+       Z180_TABLE_op,
+       Z180_TABLE_cb,
+       Z180_TABLE_ed,
+       Z180_TABLE_xy,
+       Z180_TABLE_xycb,
+       Z180_TABLE_ex    /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */
+};
+
+// input lines
+enum {
+       Z180_INPUT_LINE_IRQ0,           /* Execute IRQ1 */
+       Z180_INPUT_LINE_IRQ1,           /* Execute IRQ1 */
+       Z180_INPUT_LINE_IRQ2,           /* Execute IRQ2 */
+       Z180_INPUT_LINE_DREQ0,          /* Start DMA0 */
+       Z180_INPUT_LINE_DREQ1           /* Start DMA1 */
+};
+
+class z180_device : public cpu_device, public z80_daisy_chain_interface
+{
+public:
+       // construction/destruction
+       z180_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
+
+       bool get_tend0();
+       bool get_tend1();
+
+protected:
+       // device-level overrides
+       virtual void device_start() override;
+       virtual void device_reset() override;
+
+       // device_execute_interface overrides
+       virtual uint32_t execute_min_cycles() const override { return 1; }
+       virtual uint32_t execute_max_cycles() const override { return 16; }
+       virtual uint32_t execute_input_lines() const override { return 5; }
+       virtual uint32_t execute_default_irq_vector(int inputnum) const override { return 0xff; }
+       virtual bool execute_input_edge_triggered(int inputnum) const override { return inputnum == INPUT_LINE_NMI; }
+       virtual void execute_run() override;
+       virtual void execute_burn(int32_t cycles) override;
+       virtual void execute_set_input(int inputnum, int state) override;
+
+       // device_memory_interface overrides
+       virtual space_config_vector memory_space_config() const override;
+       virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
+
+       // device_state_interface overrides
+       virtual void state_import(const device_state_entry &entry) override;
+       virtual void state_export(const device_state_entry &entry) override;
+       virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+
+       // device_disasm_interface overrides
+       virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+private:
+       address_space_config m_program_config;
+       address_space_config m_io_config;
+       address_space_config m_decrypted_opcodes_config;
+
+       PAIR    m_PREPC,m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_IX,m_IY;
+       PAIR    m_AF2,m_BC2,m_DE2,m_HL2;
+       uint8_t   m_R,m_R2,m_IFF1,m_IFF2,m_HALT,m_IM,m_I;
+       uint8_t   m_tmdr_latch;                     /* flag latched TMDR0H, TMDR1H values */
+       uint8_t   m_read_tcr_tmdr[2];               /* flag to indicate that TCR or TMDR was read */
+       uint32_t  m_iol;                            /* I/O line status bits */
+       uint8_t   m_io[64];                         /* 64 internal 8 bit registers */
+       offs_t  m_mmu[16];                        /* MMU address translation */
+       uint8_t   m_tmdrh[2];                       /* latched TMDR0H and TMDR1H values */
+       uint16_t  m_tmdr_value[2];                  /* TMDR values used byt PRT0 and PRT1 as down counter */
+       uint8_t   m_tif[2];                         /* TIF0 and TIF1 values */
+       uint8_t   m_nmi_state;                      /* nmi line state */
+       uint8_t   m_nmi_pending;                    /* nmi pending */
+       uint8_t   m_irq_state[3];                   /* irq line states (INT0,INT1,INT2) */
+       uint8_t   m_int_pending[11 + 1];  /* interrupt pending */
+       uint8_t   m_after_EI;                       /* are we in the EI shadow? */
+       uint32_t  m_ea;
+       uint8_t   m_timer_cnt;                      /* timer counter / divide by 20 */
+       uint8_t   m_dma0_cnt;                       /* dma0 counter / divide by 20 */
+       uint8_t   m_dma1_cnt;                       /* dma1 counter / divide by 20 */
+       address_space *m_program;
+       memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_cache;
+       address_space *m_oprogram;
+       memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_ocache;
+       address_space *m_iospace;
+       uint8_t   m_rtemp;
+       uint32_t  m_ioltemp;
+       int m_icount;
+       int m_extra_cycles;           /* extra cpu cycles */
+       uint8_t *m_cc[6];
+
+       typedef void (z180_device::*opcode_func)();
+       static const opcode_func s_z180ops[6][0x100];
+
+       inline void z180_mmu();
+       inline u8 RM(offs_t addr);
+       inline u8 IN(u16 port);
+       inline void OUT(u16 port, u8 value);
+       inline void RM16( offs_t addr, PAIR *r );
+       inline void WM16( offs_t addr, PAIR *r );
+       inline uint8_t ROP();
+       inline uint8_t ARG();
+       inline uint32_t ARG16();
+       inline uint8_t INC(uint8_t value);
+       inline uint8_t DEC(uint8_t value);
+       inline uint8_t RLC(uint8_t value);
+       inline uint8_t RRC(uint8_t value);
+       inline uint8_t RL(uint8_t value);
+       inline uint8_t RR(uint8_t value);
+       inline uint8_t SLA(uint8_t value);
+       inline uint8_t SRA(uint8_t value);
+       inline uint8_t SLL(uint8_t value);
+       inline uint8_t SRL(uint8_t value);
+       inline uint8_t RES(uint8_t bit, uint8_t value);
+       inline uint8_t SET(uint8_t bit, uint8_t value);
+       inline int exec_op(const uint8_t opcode);
+       inline int exec_cb(const uint8_t opcode);
+       inline int exec_dd(const uint8_t opcode);
+       inline int exec_ed(const uint8_t opcode);
+       inline int exec_fd(const uint8_t opcode);
+       inline int exec_xycb(const uint8_t opcode);
+       int take_interrupt(int irq);
+       uint8_t z180_readcontrol(offs_t port);
+       void z180_writecontrol(offs_t port, uint8_t data);
+       int z180_dma0(int max_cycles);
+       int z180_dma1();
+       void z180_write_iolines(uint32_t data);
+       void clock_timers();
+       int check_interrupts();
+       void handle_io_timers(int cycles);
+
+       void op_00();
+       void op_01();
+       void op_02();
+       void op_03();
+       void op_04();
+       void op_05();
+       void op_06();
+       void op_07();
+       void op_08();
+       void op_09();
+       void op_0a();
+       void op_0b();
+       void op_0c();
+       void op_0d();
+       void op_0e();
+       void op_0f();
+       void op_10();
+       void op_11();
+       void op_12();
+       void op_13();
+       void op_14();
+       void op_15();
+       void op_16();
+       void op_17();
+       void op_18();
+       void op_19();
+       void op_1a();
+       void op_1b();
+       void op_1c();
+       void op_1d();
+       void op_1e();
+       void op_1f();
+       void op_20();
+       void op_21();
+       void op_22();
+       void op_23();
+       void op_24();
+       void op_25();
+       void op_26();
+       void op_27();
+       void op_28();
+       void op_29();
+       void op_2a();
+       void op_2b();
+       void op_2c();
+       void op_2d();
+       void op_2e();
+       void op_2f();
+       void op_30();
+       void op_31();
+       void op_32();
+       void op_33();
+       void op_34();
+       void op_35();
+       void op_36();
+       void op_37();
+       void op_38();
+       void op_39();
+       void op_3a();
+       void op_3b();
+       void op_3c();
+       void op_3d();
+       void op_3e();
+       void op_3f();
+       void op_40();
+       void op_41();
+       void op_42();
+       void op_43();
+       void op_44();
+       void op_45();
+       void op_46();
+       void op_47();
+       void op_48();
+       void op_49();
+       void op_4a();
+       void op_4b();
+       void op_4c();
+       void op_4d();
+       void op_4e();
+       void op_4f();
+       void op_50();
+       void op_51();
+       void op_52();
+       void op_53();
+       void op_54();
+       void op_55();
+       void op_56();
+       void op_57();
+       void op_58();
+       void op_59();
+       void op_5a();
+       void op_5b();
+       void op_5c();
+       void op_5d();
+       void op_5e();
+       void op_5f();
+       void op_60();
+       void op_61();
+       void op_62();
+       void op_63();
+       void op_64();
+       void op_65();
+       void op_66();
+       void op_67();
+       void op_68();
+       void op_69();
+       void op_6a();
+       void op_6b();
+       void op_6c();
+       void op_6d();
+       void op_6e();
+       void op_6f();
+       void op_70();
+       void op_71();
+       void op_72();
+       void op_73();
+       void op_74();
+       void op_75();
+       void op_76();
+       void op_77();
+       void op_78();
+       void op_79();
+       void op_7a();
+       void op_7b();
+       void op_7c();
+       void op_7d();
+       void op_7e();
+       void op_7f();
+       void op_80();
+       void op_81();
+       void op_82();
+       void op_83();
+       void op_84();
+       void op_85();
+       void op_86();
+       void op_87();
+       void op_88();
+       void op_89();
+       void op_8a();
+       void op_8b();
+       void op_8c();
+       void op_8d();
+       void op_8e();
+       void op_8f();
+       void op_90();
+       void op_91();
+       void op_92();
+       void op_93();
+       void op_94();
+       void op_95();
+       void op_96();
+       void op_97();
+       void op_98();
+       void op_99();
+       void op_9a();
+       void op_9b();
+       void op_9c();
+       void op_9d();
+       void op_9e();
+       void op_9f();
+       void op_a0();
+       void op_a1();
+       void op_a2();
+       void op_a3();
+       void op_a4();
+       void op_a5();
+       void op_a6();
+       void op_a7();
+       void op_a8();
+       void op_a9();
+       void op_aa();
+       void op_ab();
+       void op_ac();
+       void op_ad();
+       void op_ae();
+       void op_af();
+       void op_b0();
+       void op_b1();
+       void op_b2();
+       void op_b3();
+       void op_b4();
+       void op_b5();
+       void op_b6();
+       void op_b7();
+       void op_b8();
+       void op_b9();
+       void op_ba();
+       void op_bb();
+       void op_bc();
+       void op_bd();
+       void op_be();
+       void op_bf();
+       void op_c0();
+       void op_c1();
+       void op_c2();
+       void op_c3();
+       void op_c4();
+       void op_c5();
+       void op_c6();
+       void op_c7();
+       void op_c8();
+       void op_c9();
+       void op_ca();
+       void op_cb();
+       void op_cc();
+       void op_cd();
+       void op_ce();
+       void op_cf();
+       void op_d0();
+       void op_d1();
+       void op_d2();
+       void op_d3();
+       void op_d4();
+       void op_d5();
+       void op_d6();
+       void op_d7();
+       void op_d8();
+       void op_d9();
+       void op_da();
+       void op_db();
+       void op_dc();
+       void op_dd();
+       void op_de();
+       void op_df();
+       void op_e0();
+       void op_e1();
+       void op_e2();
+       void op_e3();
+       void op_e4();
+       void op_e5();
+       void op_e6();
+       void op_e7();
+       void op_e8();
+       void op_e9();
+       void op_ea();
+       void op_eb();
+       void op_ec();
+       void op_ed();
+       void op_ee();
+       void op_ef();
+       void op_f0();
+       void op_f1();
+       void op_f2();
+       void op_f3();
+       void op_f4();
+       void op_f5();
+       void op_f6();
+       void op_f7();
+       void op_f8();
+       void op_f9();
+       void op_fa();
+       void op_fb();
+       void op_fc();
+       void op_fd();
+       void op_fe();
+       void op_ff();
+       void cb_00();
+       void cb_01();
+       void cb_02();
+       void cb_03();
+       void cb_04();
+       void cb_05();
+       void cb_06();
+       void cb_07();
+       void cb_08();
+       void cb_09();
+       void cb_0a();
+       void cb_0b();
+       void cb_0c();
+       void cb_0d();
+       void cb_0e();
+       void cb_0f();
+       void cb_10();
+       void cb_11();
+       void cb_12();
+       void cb_13();
+       void cb_14();
+       void cb_15();
+       void cb_16();
+       void cb_17();
+       void cb_18();
+       void cb_19();
+       void cb_1a();
+       void cb_1b();
+       void cb_1c();
+       void cb_1d();
+       void cb_1e();
+       void cb_1f();
+       void cb_20();
+       void cb_21();
+       void cb_22();
+       void cb_23();
+       void cb_24();
+       void cb_25();
+       void cb_26();
+       void cb_27();
+       void cb_28();
+       void cb_29();
+       void cb_2a();
+       void cb_2b();
+       void cb_2c();
+       void cb_2d();
+       void cb_2e();
+       void cb_2f();
+       void cb_30();
+       void cb_31();
+       void cb_32();
+       void cb_33();
+       void cb_34();
+       void cb_35();
+       void cb_36();
+       void cb_37();
+       void cb_38();
+       void cb_39();
+       void cb_3a();
+       void cb_3b();
+       void cb_3c();
+       void cb_3d();
+       void cb_3e();
+       void cb_3f();
+       void cb_40();
+       void cb_41();
+       void cb_42();
+       void cb_43();
+       void cb_44();
+       void cb_45();
+       void cb_46();
+       void cb_47();
+       void cb_48();
+       void cb_49();
+       void cb_4a();
+       void cb_4b();
+       void cb_4c();
+       void cb_4d();
+       void cb_4e();
+       void cb_4f();
+       void cb_50();
+       void cb_51();
+       void cb_52();
+       void cb_53();
+       void cb_54();
+       void cb_55();
+       void cb_56();
+       void cb_57();
+       void cb_58();
+       void cb_59();
+       void cb_5a();
+       void cb_5b();
+       void cb_5c();
+       void cb_5d();
+       void cb_5e();
+       void cb_5f();
+       void cb_60();
+       void cb_61();
+       void cb_62();
+       void cb_63();
+       void cb_64();
+       void cb_65();
+       void cb_66();
+       void cb_67();
+       void cb_68();
+       void cb_69();
+       void cb_6a();
+       void cb_6b();
+       void cb_6c();
+       void cb_6d();
+       void cb_6e();
+       void cb_6f();
+       void cb_70();
+       void cb_71();
+       void cb_72();
+       void cb_73();
+       void cb_74();
+       void cb_75();
+       void cb_76();
+       void cb_77();
+       void cb_78();
+       void cb_79();
+       void cb_7a();
+       void cb_7b();
+       void cb_7c();
+       void cb_7d();
+       void cb_7e();
+       void cb_7f();
+       void cb_80();
+       void cb_81();
+       void cb_82();
+       void cb_83();
+       void cb_84();
+       void cb_85();
+       void cb_86();
+       void cb_87();
+       void cb_88();
+       void cb_89();
+       void cb_8a();
+       void cb_8b();
+       void cb_8c();
+       void cb_8d();
+       void cb_8e();
+       void cb_8f();
+       void cb_90();
+       void cb_91();
+       void cb_92();
+       void cb_93();
+       void cb_94();
+       void cb_95();
+       void cb_96();
+       void cb_97();
+       void cb_98();
+       void cb_99();
+       void cb_9a();
+       void cb_9b();
+       void cb_9c();
+       void cb_9d();
+       void cb_9e();
+       void cb_9f();
+       void cb_a0();
+       void cb_a1();
+       void cb_a2();
+       void cb_a3();
+       void cb_a4();
+       void cb_a5();
+       void cb_a6();
+       void cb_a7();
+       void cb_a8();
+       void cb_a9();
+       void cb_aa();
+       void cb_ab();
+       void cb_ac();
+       void cb_ad();
+       void cb_ae();
+       void cb_af();
+       void cb_b0();
+       void cb_b1();
+       void cb_b2();
+       void cb_b3();
+       void cb_b4();
+       void cb_b5();
+       void cb_b6();
+       void cb_b7();
+       void cb_b8();
+       void cb_b9();
+       void cb_ba();
+       void cb_bb();
+       void cb_bc();
+       void cb_bd();
+       void cb_be();
+       void cb_bf();
+       void cb_c0();
+       void cb_c1();
+       void cb_c2();
+       void cb_c3();
+       void cb_c4();
+       void cb_c5();
+       void cb_c6();
+       void cb_c7();
+       void cb_c8();
+       void cb_c9();
+       void cb_ca();
+       void cb_cb();
+       void cb_cc();
+       void cb_cd();
+       void cb_ce();
+       void cb_cf();
+       void cb_d0();
+       void cb_d1();
+       void cb_d2();
+       void cb_d3();
+       void cb_d4();
+       void cb_d5();
+       void cb_d6();
+       void cb_d7();
+       void cb_d8();
+       void cb_d9();
+       void cb_da();
+       void cb_db();
+       void cb_dc();
+       void cb_dd();
+       void cb_de();
+       void cb_df();
+       void cb_e0();
+       void cb_e1();
+       void cb_e2();
+       void cb_e3();
+       void cb_e4();
+       void cb_e5();
+       void cb_e6();
+       void cb_e7();
+       void cb_e8();
+       void cb_e9();
+       void cb_ea();
+       void cb_eb();
+       void cb_ec();
+       void cb_ed();
+       void cb_ee();
+       void cb_ef();
+       void cb_f0();
+       void cb_f1();
+       void cb_f2();
+       void cb_f3();
+       void cb_f4();
+       void cb_f5();
+       void cb_f6();
+       void cb_f7();
+       void cb_f8();
+       void cb_f9();
+       void cb_fa();
+       void cb_fb();
+       void cb_fc();
+       void cb_fd();
+       void cb_fe();
+       void cb_ff();
+       void illegal_1();
+       void dd_00();
+       void dd_01();
+       void dd_02();
+       void dd_03();
+       void dd_04();
+       void dd_05();
+       void dd_06();
+       void dd_07();
+       void dd_08();
+       void dd_09();
+       void dd_0a();
+       void dd_0b();
+       void dd_0c();
+       void dd_0d();
+       void dd_0e();
+       void dd_0f();
+       void dd_10();
+       void dd_11();
+       void dd_12();
+       void dd_13();
+       void dd_14();
+       void dd_15();
+       void dd_16();
+       void dd_17();
+       void dd_18();
+       void dd_19();
+       void dd_1a();
+       void dd_1b();
+       void dd_1c();
+       void dd_1d();
+       void dd_1e();
+       void dd_1f();
+       void dd_20();
+       void dd_21();
+       void dd_22();
+       void dd_23();
+       void dd_24();
+       void dd_25();
+       void dd_26();
+       void dd_27();
+       void dd_28();
+       void dd_29();
+       void dd_2a();
+       void dd_2b();
+       void dd_2c();
+       void dd_2d();
+       void dd_2e();
+       void dd_2f();
+       void dd_30();
+       void dd_31();
+       void dd_32();
+       void dd_33();
+       void dd_34();
+       void dd_35();
+       void dd_36();
+       void dd_37();
+       void dd_38();
+       void dd_39();
+       void dd_3a();
+       void dd_3b();
+       void dd_3c();
+       void dd_3d();
+       void dd_3e();
+       void dd_3f();
+       void dd_40();
+       void dd_41();
+       void dd_42();
+       void dd_43();
+       void dd_44();
+       void dd_45();
+       void dd_46();
+       void dd_47();
+       void dd_48();
+       void dd_49();
+       void dd_4a();
+       void dd_4b();
+       void dd_4c();
+       void dd_4d();
+       void dd_4e();
+       void dd_4f();
+       void dd_50();
+       void dd_51();
+       void dd_52();
+       void dd_53();
+       void dd_54();
+       void dd_55();
+       void dd_56();
+       void dd_57();
+       void dd_58();
+       void dd_59();
+       void dd_5a();
+       void dd_5b();
+       void dd_5c();
+       void dd_5d();
+       void dd_5e();
+       void dd_5f();
+       void dd_60();
+       void dd_61();
+       void dd_62();
+       void dd_63();
+       void dd_64();
+       void dd_65();
+       void dd_66();
+       void dd_67();
+       void dd_68();
+       void dd_69();
+       void dd_6a();
+       void dd_6b();
+       void dd_6c();
+       void dd_6d();
+       void dd_6e();
+       void dd_6f();
+       void dd_70();
+       void dd_71();
+       void dd_72();
+       void dd_73();
+       void dd_74();
+       void dd_75();
+       void dd_76();
+       void dd_77();
+       void dd_78();
+       void dd_79();
+       void dd_7a();
+       void dd_7b();
+       void dd_7c();
+       void dd_7d();
+       void dd_7e();
+       void dd_7f();
+       void dd_80();
+       void dd_81();
+       void dd_82();
+       void dd_83();
+       void dd_84();
+       void dd_85();
+       void dd_86();
+       void dd_87();
+       void dd_88();
+       void dd_89();
+       void dd_8a();
+       void dd_8b();
+       void dd_8c();
+       void dd_8d();
+       void dd_8e();
+       void dd_8f();
+       void dd_90();
+       void dd_91();
+       void dd_92();
+       void dd_93();
+       void dd_94();
+       void dd_95();
+       void dd_96();
+       void dd_97();
+       void dd_98();
+       void dd_99();
+       void dd_9a();
+       void dd_9b();
+       void dd_9c();
+       void dd_9d();
+       void dd_9e();
+       void dd_9f();
+       void dd_a0();
+       void dd_a1();
+       void dd_a2();
+       void dd_a3();
+       void dd_a4();
+       void dd_a5();
+       void dd_a6();
+       void dd_a7();
+       void dd_a8();
+       void dd_a9();
+       void dd_aa();
+       void dd_ab();
+       void dd_ac();
+       void dd_ad();
+       void dd_ae();
+       void dd_af();
+       void dd_b0();
+       void dd_b1();
+       void dd_b2();
+       void dd_b3();
+       void dd_b4();
+       void dd_b5();
+       void dd_b6();
+       void dd_b7();
+       void dd_b8();
+       void dd_b9();
+       void dd_ba();
+       void dd_bb();
+       void dd_bc();
+       void dd_bd();
+       void dd_be();
+       void dd_bf();
+       void dd_c0();
+       void dd_c1();
+       void dd_c2();
+       void dd_c3();
+       void dd_c4();
+       void dd_c5();
+       void dd_c6();
+       void dd_c7();
+       void dd_c8();
+       void dd_c9();
+       void dd_ca();
+       void dd_cb();
+       void dd_cc();
+       void dd_cd();
+       void dd_ce();
+       void dd_cf();
+       void dd_d0();
+       void dd_d1();
+       void dd_d2();
+       void dd_d3();
+       void dd_d4();
+       void dd_d5();
+       void dd_d6();
+       void dd_d7();
+       void dd_d8();
+       void dd_d9();
+       void dd_da();
+       void dd_db();
+       void dd_dc();
+       void dd_dd();
+       void dd_de();
+       void dd_df();
+       void dd_e0();
+       void dd_e1();
+       void dd_e2();
+       void dd_e3();
+       void dd_e4();
+       void dd_e5();
+       void dd_e6();
+       void dd_e7();
+       void dd_e8();
+       void dd_e9();
+       void dd_ea();
+       void dd_eb();
+       void dd_ec();
+       void dd_ed();
+       void dd_ee();
+       void dd_ef();
+       void dd_f0();
+       void dd_f1();
+       void dd_f2();
+       void dd_f3();
+       void dd_f4();
+       void dd_f5();
+       void dd_f6();
+       void dd_f7();
+       void dd_f8();
+       void dd_f9();
+       void dd_fa();
+       void dd_fb();
+       void dd_fc();
+       void dd_fd();
+       void dd_fe();
+       void dd_ff();
+       void illegal_2();
+       void ed_00();
+       void ed_01();
+       void ed_02();
+       void ed_03();
+       void ed_04();
+       void ed_05();
+       void ed_06();
+       void ed_07();
+       void ed_08();
+       void ed_09();
+       void ed_0a();
+       void ed_0b();
+       void ed_0c();
+       void ed_0d();
+       void ed_0e();
+       void ed_0f();
+       void ed_10();
+       void ed_11();
+       void ed_12();
+       void ed_13();
+       void ed_14();
+       void ed_15();
+       void ed_16();
+       void ed_17();
+       void ed_18();
+       void ed_19();
+       void ed_1a();
+       void ed_1b();
+       void ed_1c();
+       void ed_1d();
+       void ed_1e();
+       void ed_1f();
+       void ed_20();
+       void ed_21();
+       void ed_22();
+       void ed_23();
+       void ed_24();
+       void ed_25();
+       void ed_26();
+       void ed_27();
+       void ed_28();
+       void ed_29();
+       void ed_2a();
+       void ed_2b();
+       void ed_2c();
+       void ed_2d();
+       void ed_2e();
+       void ed_2f();
+       void ed_30();
+       void ed_31();
+       void ed_32();
+       void ed_33();
+       void ed_34();
+       void ed_35();
+       void ed_36();
+       void ed_37();
+       void ed_38();
+       void ed_39();
+       void ed_3a();
+       void ed_3b();
+       void ed_3c();
+       void ed_3d();
+       void ed_3e();
+       void ed_3f();
+       void ed_40();
+       void ed_41();
+       void ed_42();
+       void ed_43();
+       void ed_44();
+       void ed_45();
+       void ed_46();
+       void ed_47();
+       void ed_48();
+       void ed_49();
+       void ed_4a();
+       void ed_4b();
+       void ed_4c();
+       void ed_4d();
+       void ed_4e();
+       void ed_4f();
+       void ed_50();
+       void ed_51();
+       void ed_52();
+       void ed_53();
+       void ed_54();
+       void ed_55();
+       void ed_56();
+       void ed_57();
+       void ed_58();
+       void ed_59();
+       void ed_5a();
+       void ed_5b();
+       void ed_5c();
+       void ed_5d();
+       void ed_5e();
+       void ed_5f();
+       void ed_60();
+       void ed_61();
+       void ed_62();
+       void ed_63();
+       void ed_64();
+       void ed_65();
+       void ed_66();
+       void ed_67();
+       void ed_68();
+       void ed_69();
+       void ed_6a();
+       void ed_6b();
+       void ed_6c();
+       void ed_6d();
+       void ed_6e();
+       void ed_6f();
+       void ed_70();
+       void ed_71();
+       void ed_72();
+       void ed_73();
+       void ed_74();
+       void ed_75();
+       void ed_76();
+       void ed_77();
+       void ed_78();
+       void ed_79();
+       void ed_7a();
+       void ed_7b();
+       void ed_7c();
+       void ed_7d();
+       void ed_7e();
+       void ed_7f();
+       void ed_80();
+       void ed_81();
+       void ed_82();
+       void ed_83();
+       void ed_84();
+       void ed_85();
+       void ed_86();
+       void ed_87();
+       void ed_88();
+       void ed_89();
+       void ed_8a();
+       void ed_8b();
+       void ed_8c();
+       void ed_8d();
+       void ed_8e();
+       void ed_8f();
+       void ed_90();
+       void ed_91();
+       void ed_92();
+       void ed_93();
+       void ed_94();
+       void ed_95();
+       void ed_96();
+       void ed_97();
+       void ed_98();
+       void ed_99();
+       void ed_9a();
+       void ed_9b();
+       void ed_9c();
+       void ed_9d();
+       void ed_9e();
+       void ed_9f();
+       void ed_a0();
+       void ed_a1();
+       void ed_a2();
+       void ed_a3();
+       void ed_a4();
+       void ed_a5();
+       void ed_a6();
+       void ed_a7();
+       void ed_a8();
+       void ed_a9();
+       void ed_aa();
+       void ed_ab();
+       void ed_ac();
+       void ed_ad();
+       void ed_ae();
+       void ed_af();
+       void ed_b0();
+       void ed_b1();
+       void ed_b2();
+       void ed_b3();
+       void ed_b4();
+       void ed_b5();
+       void ed_b6();
+       void ed_b7();
+       void ed_b8();
+       void ed_b9();
+       void ed_ba();
+       void ed_bb();
+       void ed_bc();
+       void ed_bd();
+       void ed_be();
+       void ed_bf();
+       void ed_c0();
+       void ed_c1();
+       void ed_c2();
+       void ed_c3();
+       void ed_c4();
+       void ed_c5();
+       void ed_c6();
+       void ed_c7();
+       void ed_c8();
+       void ed_c9();
+       void ed_ca();
+       void ed_cb();
+       void ed_cc();
+       void ed_cd();
+       void ed_ce();
+       void ed_cf();
+       void ed_d0();
+       void ed_d1();
+       void ed_d2();
+       void ed_d3();
+       void ed_d4();
+       void ed_d5();
+       void ed_d6();
+       void ed_d7();
+       void ed_d8();
+       void ed_d9();
+       void ed_da();
+       void ed_db();
+       void ed_dc();
+       void ed_dd();
+       void ed_de();
+       void ed_df();
+       void ed_e0();
+       void ed_e1();
+       void ed_e2();
+       void ed_e3();
+       void ed_e4();
+       void ed_e5();
+       void ed_e6();
+       void ed_e7();
+       void ed_e8();
+       void ed_e9();
+       void ed_ea();
+       void ed_eb();
+       void ed_ec();
+       void ed_ed();
+       void ed_ee();
+       void ed_ef();
+       void ed_f0();
+       void ed_f1();
+       void ed_f2();
+       void ed_f3();
+       void ed_f4();
+       void ed_f5();
+       void ed_f6();
+       void ed_f7();
+       void ed_f8();
+       void ed_f9();
+       void ed_fa();
+       void ed_fb();
+       void ed_fc();
+       void ed_fd();
+       void ed_fe();
+       void ed_ff();
+       void fd_00();
+       void fd_01();
+       void fd_02();
+       void fd_03();
+       void fd_04();
+       void fd_05();
+       void fd_06();
+       void fd_07();
+       void fd_08();
+       void fd_09();
+       void fd_0a();
+       void fd_0b();
+       void fd_0c();
+       void fd_0d();
+       void fd_0e();
+       void fd_0f();
+       void fd_10();
+       void fd_11();
+       void fd_12();
+       void fd_13();
+       void fd_14();
+       void fd_15();
+       void fd_16();
+       void fd_17();
+       void fd_18();
+       void fd_19();
+       void fd_1a();
+       void fd_1b();
+       void fd_1c();
+       void fd_1d();
+       void fd_1e();
+       void fd_1f();
+       void fd_20();
+       void fd_21();
+       void fd_22();
+       void fd_23();
+       void fd_24();
+       void fd_25();
+       void fd_26();
+       void fd_27();
+       void fd_28();
+       void fd_29();
+       void fd_2a();
+       void fd_2b();
+       void fd_2c();
+       void fd_2d();
+       void fd_2e();
+       void fd_2f();
+       void fd_30();
+       void fd_31();
+       void fd_32();
+       void fd_33();
+       void fd_34();
+       void fd_35();
+       void fd_36();
+       void fd_37();
+       void fd_38();
+       void fd_39();
+       void fd_3a();
+       void fd_3b();
+       void fd_3c();
+       void fd_3d();
+       void fd_3e();
+       void fd_3f();
+       void fd_40();
+       void fd_41();
+       void fd_42();
+       void fd_43();
+       void fd_44();
+       void fd_45();
+       void fd_46();
+       void fd_47();
+       void fd_48();
+       void fd_49();
+       void fd_4a();
+       void fd_4b();
+       void fd_4c();
+       void fd_4d();
+       void fd_4e();
+       void fd_4f();
+       void fd_50();
+       void fd_51();
+       void fd_52();
+       void fd_53();
+       void fd_54();
+       void fd_55();
+       void fd_56();
+       void fd_57();
+       void fd_58();
+       void fd_59();
+       void fd_5a();
+       void fd_5b();
+       void fd_5c();
+       void fd_5d();
+       void fd_5e();
+       void fd_5f();
+       void fd_60();
+       void fd_61();
+       void fd_62();
+       void fd_63();
+       void fd_64();
+       void fd_65();
+       void fd_66();
+       void fd_67();
+       void fd_68();
+       void fd_69();
+       void fd_6a();
+       void fd_6b();
+       void fd_6c();
+       void fd_6d();
+       void fd_6e();
+       void fd_6f();
+       void fd_70();
+       void fd_71();
+       void fd_72();
+       void fd_73();
+       void fd_74();
+       void fd_75();
+       void fd_76();
+       void fd_77();
+       void fd_78();
+       void fd_79();
+       void fd_7a();
+       void fd_7b();
+       void fd_7c();
+       void fd_7d();
+       void fd_7e();
+       void fd_7f();
+       void fd_80();
+       void fd_81();
+       void fd_82();
+       void fd_83();
+       void fd_84();
+       void fd_85();
+       void fd_86();
+       void fd_87();
+       void fd_88();
+       void fd_89();
+       void fd_8a();
+       void fd_8b();
+       void fd_8c();
+       void fd_8d();
+       void fd_8e();
+       void fd_8f();
+       void fd_90();
+       void fd_91();
+       void fd_92();
+       void fd_93();
+       void fd_94();
+       void fd_95();
+       void fd_96();
+       void fd_97();
+       void fd_98();
+       void fd_99();
+       void fd_9a();
+       void fd_9b();
+       void fd_9c();
+       void fd_9d();
+       void fd_9e();
+       void fd_9f();
+       void fd_a0();
+       void fd_a1();
+       void fd_a2();
+       void fd_a3();
+       void fd_a4();
+       void fd_a5();
+       void fd_a6();
+       void fd_a7();
+       void fd_a8();
+       void fd_a9();
+       void fd_aa();
+       void fd_ab();
+       void fd_ac();
+       void fd_ad();
+       void fd_ae();
+       void fd_af();
+       void fd_b0();
+       void fd_b1();
+       void fd_b2();
+       void fd_b3();
+       void fd_b4();
+       void fd_b5();
+       void fd_b6();
+       void fd_b7();
+       void fd_b8();
+       void fd_b9();
+       void fd_ba();
+       void fd_bb();
+       void fd_bc();
+       void fd_bd();
+       void fd_be();
+       void fd_bf();
+       void fd_c0();
+       void fd_c1();
+       void fd_c2();
+       void fd_c3();
+       void fd_c4();
+       void fd_c5();
+       void fd_c6();
+       void fd_c7();
+       void fd_c8();
+       void fd_c9();
+       void fd_ca();
+       void fd_cb();
+       void fd_cc();
+       void fd_cd();
+       void fd_ce();
+       void fd_cf();
+       void fd_d0();
+       void fd_d1();
+       void fd_d2();
+       void fd_d3();
+       void fd_d4();
+       void fd_d5();
+       void fd_d6();
+       void fd_d7();
+       void fd_d8();
+       void fd_d9();
+       void fd_da();
+       void fd_db();
+       void fd_dc();
+       void fd_dd();
+       void fd_de();
+       void fd_df();
+       void fd_e0();
+       void fd_e1();
+       void fd_e2();
+       void fd_e3();
+       void fd_e4();
+       void fd_e5();
+       void fd_e6();
+       void fd_e7();
+       void fd_e8();
+       void fd_e9();
+       void fd_ea();
+       void fd_eb();
+       void fd_ec();
+       void fd_ed();
+       void fd_ee();
+       void fd_ef();
+       void fd_f0();
+       void fd_f1();
+       void fd_f2();
+       void fd_f3();
+       void fd_f4();
+       void fd_f5();
+       void fd_f6();
+       void fd_f7();
+       void fd_f8();
+       void fd_f9();
+       void fd_fa();
+       void fd_fb();
+       void fd_fc();
+       void fd_fd();
+       void fd_fe();
+       void fd_ff();
+       void xycb_00();
+       void xycb_01();
+       void xycb_02();
+       void xycb_03();
+       void xycb_04();
+       void xycb_05();
+       void xycb_06();
+       void xycb_07();
+       void xycb_08();
+       void xycb_09();
+       void xycb_0a();
+       void xycb_0b();
+       void xycb_0c();
+       void xycb_0d();
+       void xycb_0e();
+       void xycb_0f();
+       void xycb_10();
+       void xycb_11();
+       void xycb_12();
+       void xycb_13();
+       void xycb_14();
+       void xycb_15();
+       void xycb_16();
+       void xycb_17();
+       void xycb_18();
+       void xycb_19();
+       void xycb_1a();
+       void xycb_1b();
+       void xycb_1c();
+       void xycb_1d();
+       void xycb_1e();
+       void xycb_1f();
+       void xycb_20();
+       void xycb_21();
+       void xycb_22();
+       void xycb_23();
+       void xycb_24();
+       void xycb_25();
+       void xycb_26();
+       void xycb_27();
+       void xycb_28();
+       void xycb_29();
+       void xycb_2a();
+       void xycb_2b();
+       void xycb_2c();
+       void xycb_2d();
+       void xycb_2e();
+       void xycb_2f();
+       void xycb_30();
+       void xycb_31();
+       void xycb_32();
+       void xycb_33();
+       void xycb_34();
+       void xycb_35();
+       void xycb_36();
+       void xycb_37();
+       void xycb_38();
+       void xycb_39();
+       void xycb_3a();
+       void xycb_3b();
+       void xycb_3c();
+       void xycb_3d();
+       void xycb_3e();
+       void xycb_3f();
+       void xycb_40();
+       void xycb_41();
+       void xycb_42();
+       void xycb_43();
+       void xycb_44();
+       void xycb_45();
+       void xycb_46();
+       void xycb_47();
+       void xycb_48();
+       void xycb_49();
+       void xycb_4a();
+       void xycb_4b();
+       void xycb_4c();
+       void xycb_4d();
+       void xycb_4e();
+       void xycb_4f();
+       void xycb_50();
+       void xycb_51();
+       void xycb_52();
+       void xycb_53();
+       void xycb_54();
+       void xycb_55();
+       void xycb_56();
+       void xycb_57();
+       void xycb_58();
+       void xycb_59();
+       void xycb_5a();
+       void xycb_5b();
+       void xycb_5c();
+       void xycb_5d();
+       void xycb_5e();
+       void xycb_5f();
+       void xycb_60();
+       void xycb_61();
+       void xycb_62();
+       void xycb_63();
+       void xycb_64();
+       void xycb_65();
+       void xycb_66();
+       void xycb_67();
+       void xycb_68();
+       void xycb_69();
+       void xycb_6a();
+       void xycb_6b();
+       void xycb_6c();
+       void xycb_6d();
+       void xycb_6e();
+       void xycb_6f();
+       void xycb_70();
+       void xycb_71();
+       void xycb_72();
+       void xycb_73();
+       void xycb_74();
+       void xycb_75();
+       void xycb_76();
+       void xycb_77();
+       void xycb_78();
+       void xycb_79();
+       void xycb_7a();
+       void xycb_7b();
+       void xycb_7c();
+       void xycb_7d();
+       void xycb_7e();
+       void xycb_7f();
+       void xycb_80();
+       void xycb_81();
+       void xycb_82();
+       void xycb_83();
+       void xycb_84();
+       void xycb_85();
+       void xycb_86();
+       void xycb_87();
+       void xycb_88();
+       void xycb_89();
+       void xycb_8a();
+       void xycb_8b();
+       void xycb_8c();
+       void xycb_8d();
+       void xycb_8e();
+       void xycb_8f();
+       void xycb_90();
+       void xycb_91();
+       void xycb_92();
+       void xycb_93();
+       void xycb_94();
+       void xycb_95();
+       void xycb_96();
+       void xycb_97();
+       void xycb_98();
+       void xycb_99();
+       void xycb_9a();
+       void xycb_9b();
+       void xycb_9c();
+       void xycb_9d();
+       void xycb_9e();
+       void xycb_9f();
+       void xycb_a0();
+       void xycb_a1();
+       void xycb_a2();
+       void xycb_a3();
+       void xycb_a4();
+       void xycb_a5();
+       void xycb_a6();
+       void xycb_a7();
+       void xycb_a8();
+       void xycb_a9();
+       void xycb_aa();
+       void xycb_ab();
+       void xycb_ac();
+       void xycb_ad();
+       void xycb_ae();
+       void xycb_af();
+       void xycb_b0();
+       void xycb_b1();
+       void xycb_b2();
+       void xycb_b3();
+       void xycb_b4();
+       void xycb_b5();
+       void xycb_b6();
+       void xycb_b7();
+       void xycb_b8();
+       void xycb_b9();
+       void xycb_ba();
+       void xycb_bb();
+       void xycb_bc();
+       void xycb_bd();
+       void xycb_be();
+       void xycb_bf();
+       void xycb_c0();
+       void xycb_c1();
+       void xycb_c2();
+       void xycb_c3();
+       void xycb_c4();
+       void xycb_c5();
+       void xycb_c6();
+       void xycb_c7();
+       void xycb_c8();
+       void xycb_c9();
+       void xycb_ca();
+       void xycb_cb();
+       void xycb_cc();
+       void xycb_cd();
+       void xycb_ce();
+       void xycb_cf();
+       void xycb_d0();
+       void xycb_d1();
+       void xycb_d2();
+       void xycb_d3();
+       void xycb_d4();
+       void xycb_d5();
+       void xycb_d6();
+       void xycb_d7();
+       void xycb_d8();
+       void xycb_d9();
+       void xycb_da();
+       void xycb_db();
+       void xycb_dc();
+       void xycb_dd();
+       void xycb_de();
+       void xycb_df();
+       void xycb_e0();
+       void xycb_e1();
+       void xycb_e2();
+       void xycb_e3();
+       void xycb_e4();
+       void xycb_e5();
+       void xycb_e6();
+       void xycb_e7();
+       void xycb_e8();
+       void xycb_e9();
+       void xycb_ea();
+       void xycb_eb();
+       void xycb_ec();
+       void xycb_ed();
+       void xycb_ee();
+       void xycb_ef();
+       void xycb_f0();
+       void xycb_f1();
+       void xycb_f2();
+       void xycb_f3();
+       void xycb_f4();
+       void xycb_f5();
+       void xycb_f6();
+       void xycb_f7();
+       void xycb_f8();
+       void xycb_f9();
+       void xycb_fa();
+       void xycb_fb();
+       void xycb_fc();
+       void xycb_fd();
+       void xycb_fe();
+       void xycb_ff();
+};
+
+
+DECLARE_DEVICE_TYPE(Z180, z180_device)
+
+#endif // MAME_CPU_Z180_Z180_H
diff --git a/z180/z180cb.hxx b/z180/z180cb.hxx
new file mode 100644 (file)
index 0000000..3a58725
--- /dev/null
@@ -0,0 +1,293 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/**********************************************************
+ * opcodes with CB prefix
+ * rotate, shift and bit operations
+ **********************************************************/
+OP(cb,00) { _B = RLC(_B);                                         } /* RLC  B           */
+OP(cb,01) { _C = RLC(_C);                                         } /* RLC  C           */
+OP(cb,02) { _D = RLC(_D);                                         } /* RLC  D           */
+OP(cb,03) { _E = RLC(_E);                                         } /* RLC  E           */
+OP(cb,04) { _H = RLC(_H);                                         } /* RLC  H           */
+OP(cb,05) { _L = RLC(_L);                                         } /* RLC  L           */
+OP(cb,06) { WM( _HL, RLC(RM(_HL)) );                              } /* RLC  (HL)        */
+OP(cb,07) { _A = RLC(_A);                                         } /* RLC  A           */
+
+OP(cb,08) { _B = RRC(_B);                                         } /* RRC  B           */
+OP(cb,09) { _C = RRC(_C);                                         } /* RRC  C           */
+OP(cb,0a) { _D = RRC(_D);                                         } /* RRC  D           */
+OP(cb,0b) { _E = RRC(_E);                                         } /* RRC  E           */
+OP(cb,0c) { _H = RRC(_H);                                         } /* RRC  H           */
+OP(cb,0d) { _L = RRC(_L);                                         } /* RRC  L           */
+OP(cb,0e) { WM( _HL, RRC(RM(_HL)) );                              } /* RRC  (HL)        */
+OP(cb,0f) { _A = RRC(_A);                                         } /* RRC  A           */
+
+OP(cb,10) { _B = RL(_B);                                          } /* RL   B           */
+OP(cb,11) { _C = RL(_C);                                          } /* RL   C           */
+OP(cb,12) { _D = RL(_D);                                          } /* RL   D           */
+OP(cb,13) { _E = RL(_E);                                          } /* RL   E           */
+OP(cb,14) { _H = RL(_H);                                          } /* RL   H           */
+OP(cb,15) { _L = RL(_L);                                          } /* RL   L           */
+OP(cb,16) { WM( _HL, RL(RM(_HL)) );                               } /* RL   (HL)        */
+OP(cb,17) { _A = RL(_A);                                          } /* RL   A           */
+
+OP(cb,18) { _B = RR(_B);                                          } /* RR   B           */
+OP(cb,19) { _C = RR(_C);                                          } /* RR   C           */
+OP(cb,1a) { _D = RR(_D);                                          } /* RR   D           */
+OP(cb,1b) { _E = RR(_E);                                          } /* RR   E           */
+OP(cb,1c) { _H = RR(_H);                                          } /* RR   H           */
+OP(cb,1d) { _L = RR(_L);                                          } /* RR   L           */
+OP(cb,1e) { WM( _HL, RR(RM(_HL)) );                               } /* RR   (HL)        */
+OP(cb,1f) { _A = RR(_A);                                          } /* RR   A           */
+
+OP(cb,20) { _B = SLA(_B);                                         } /* SLA  B           */
+OP(cb,21) { _C = SLA(_C);                                         } /* SLA  C           */
+OP(cb,22) { _D = SLA(_D);                                         } /* SLA  D           */
+OP(cb,23) { _E = SLA(_E);                                         } /* SLA  E           */
+OP(cb,24) { _H = SLA(_H);                                         } /* SLA  H           */
+OP(cb,25) { _L = SLA(_L);                                         } /* SLA  L           */
+OP(cb,26) { WM( _HL, SLA(RM(_HL)) );                              } /* SLA  (HL)        */
+OP(cb,27) { _A = SLA(_A);                                         } /* SLA  A           */
+
+OP(cb,28) { _B = SRA(_B);                                         } /* SRA  B           */
+OP(cb,29) { _C = SRA(_C);                                         } /* SRA  C           */
+OP(cb,2a) { _D = SRA(_D);                                         } /* SRA  D           */
+OP(cb,2b) { _E = SRA(_E);                                         } /* SRA  E           */
+OP(cb,2c) { _H = SRA(_H);                                         } /* SRA  H           */
+OP(cb,2d) { _L = SRA(_L);                                         } /* SRA  L           */
+OP(cb,2e) { WM( _HL, SRA(RM(_HL)) );                              } /* SRA  (HL)        */
+OP(cb,2f) { _A = SRA(_A);                                         } /* SRA  A           */
+
+OP(cb,30) { _B = SLL(_B);                                         } /* SLL  B           */
+OP(cb,31) { _C = SLL(_C);                                         } /* SLL  C           */
+OP(cb,32) { _D = SLL(_D);                                         } /* SLL  D           */
+OP(cb,33) { _E = SLL(_E);                                         } /* SLL  E           */
+OP(cb,34) { _H = SLL(_H);                                         } /* SLL  H           */
+OP(cb,35) { _L = SLL(_L);                                         } /* SLL  L           */
+OP(cb,36) { WM( _HL, SLL(RM(_HL)) );                              } /* SLL  (HL)        */
+OP(cb,37) { _A = SLL(_A);                                         } /* SLL  A           */
+
+OP(cb,38) { _B = SRL(_B);                                         } /* SRL  B           */
+OP(cb,39) { _C = SRL(_C);                                         } /* SRL  C           */
+OP(cb,3a) { _D = SRL(_D);                                         } /* SRL  D           */
+OP(cb,3b) { _E = SRL(_E);                                         } /* SRL  E           */
+OP(cb,3c) { _H = SRL(_H);                                         } /* SRL  H           */
+OP(cb,3d) { _L = SRL(_L);                                         } /* SRL  L           */
+OP(cb,3e) { WM( _HL, SRL(RM(_HL)) );                              } /* SRL  (HL)        */
+OP(cb,3f) { _A = SRL(_A);                                         } /* SRL  A           */
+
+OP(cb,40) { BIT(0,_B);                                                } /* BIT  0,B         */
+OP(cb,41) { BIT(0,_C);                                                } /* BIT  0,C         */
+OP(cb,42) { BIT(0,_D);                                                } /* BIT  0,D         */
+OP(cb,43) { BIT(0,_E);                                                } /* BIT  0,E         */
+OP(cb,44) { BIT(0,_H);                                                } /* BIT  0,H         */
+OP(cb,45) { BIT(0,_L);                                                } /* BIT  0,L         */
+OP(cb,46) { BIT(0,RM(_HL));                                         } /* BIT  0,(HL)      */
+OP(cb,47) { BIT(0,_A);                                                } /* BIT  0,A         */
+
+OP(cb,48) { BIT(1,_B);                                                } /* BIT  1,B         */
+OP(cb,49) { BIT(1,_C);                                                } /* BIT  1,C         */
+OP(cb,4a) { BIT(1,_D);                                                } /* BIT  1,D         */
+OP(cb,4b) { BIT(1,_E);                                                } /* BIT  1,E         */
+OP(cb,4c) { BIT(1,_H);                                                } /* BIT  1,H         */
+OP(cb,4d) { BIT(1,_L);                                                } /* BIT  1,L         */
+OP(cb,4e) { BIT(1,RM(_HL));                                         } /* BIT  1,(HL)      */
+OP(cb,4f) { BIT(1,_A);                                                } /* BIT  1,A         */
+
+OP(cb,50) { BIT(2,_B);                                                } /* BIT  2,B         */
+OP(cb,51) { BIT(2,_C);                                                } /* BIT  2,C         */
+OP(cb,52) { BIT(2,_D);                                                } /* BIT  2,D         */
+OP(cb,53) { BIT(2,_E);                                                } /* BIT  2,E         */
+OP(cb,54) { BIT(2,_H);                                                } /* BIT  2,H         */
+OP(cb,55) { BIT(2,_L);                                                } /* BIT  2,L         */
+OP(cb,56) { BIT(2,RM(_HL));                                         } /* BIT  2,(HL)      */
+OP(cb,57) { BIT(2,_A);                                                } /* BIT  2,A         */
+
+OP(cb,58) { BIT(3,_B);                                                } /* BIT  3,B         */
+OP(cb,59) { BIT(3,_C);                                                } /* BIT  3,C         */
+OP(cb,5a) { BIT(3,_D);                                                } /* BIT  3,D         */
+OP(cb,5b) { BIT(3,_E);                                                } /* BIT  3,E         */
+OP(cb,5c) { BIT(3,_H);                                                } /* BIT  3,H         */
+OP(cb,5d) { BIT(3,_L);                                                } /* BIT  3,L         */
+OP(cb,5e) { BIT(3,RM(_HL));                                         } /* BIT  3,(HL)      */
+OP(cb,5f) { BIT(3,_A);                                                } /* BIT  3,A         */
+
+OP(cb,60) { BIT(4,_B);                                                } /* BIT  4,B         */
+OP(cb,61) { BIT(4,_C);                                                } /* BIT  4,C         */
+OP(cb,62) { BIT(4,_D);                                                } /* BIT  4,D         */
+OP(cb,63) { BIT(4,_E);                                                } /* BIT  4,E         */
+OP(cb,64) { BIT(4,_H);                                                } /* BIT  4,H         */
+OP(cb,65) { BIT(4,_L);                                                } /* BIT  4,L         */
+OP(cb,66) { BIT(4,RM(_HL));                                         } /* BIT  4,(HL)      */
+OP(cb,67) { BIT(4,_A);                                                } /* BIT  4,A         */
+
+OP(cb,68) { BIT(5,_B);                                                } /* BIT  5,B         */
+OP(cb,69) { BIT(5,_C);                                                } /* BIT  5,C         */
+OP(cb,6a) { BIT(5,_D);                                                } /* BIT  5,D         */
+OP(cb,6b) { BIT(5,_E);                                                } /* BIT  5,E         */
+OP(cb,6c) { BIT(5,_H);                                                } /* BIT  5,H         */
+OP(cb,6d) { BIT(5,_L);                                                } /* BIT  5,L         */
+OP(cb,6e) { BIT(5,RM(_HL));                                         } /* BIT  5,(HL)      */
+OP(cb,6f) { BIT(5,_A);                                                } /* BIT  5,A         */
+
+OP(cb,70) { BIT(6,_B);                                                } /* BIT  6,B         */
+OP(cb,71) { BIT(6,_C);                                                } /* BIT  6,C         */
+OP(cb,72) { BIT(6,_D);                                                } /* BIT  6,D         */
+OP(cb,73) { BIT(6,_E);                                                } /* BIT  6,E         */
+OP(cb,74) { BIT(6,_H);                                                } /* BIT  6,H         */
+OP(cb,75) { BIT(6,_L);                                                } /* BIT  6,L         */
+OP(cb,76) { BIT(6,RM(_HL));                                         } /* BIT  6,(HL)      */
+OP(cb,77) { BIT(6,_A);                                                } /* BIT  6,A         */
+
+OP(cb,78) { BIT(7,_B);                                                } /* BIT  7,B         */
+OP(cb,79) { BIT(7,_C);                                                } /* BIT  7,C         */
+OP(cb,7a) { BIT(7,_D);                                                } /* BIT  7,D         */
+OP(cb,7b) { BIT(7,_E);                                                } /* BIT  7,E         */
+OP(cb,7c) { BIT(7,_H);                                                } /* BIT  7,H         */
+OP(cb,7d) { BIT(7,_L);                                                } /* BIT  7,L         */
+OP(cb,7e) { BIT(7,RM(_HL));                                         } /* BIT  7,(HL)      */
+OP(cb,7f) { BIT(7,_A);                                                } /* BIT  7,A         */
+
+OP(cb,80) { _B = RES(0,_B);                                         } /* RES  0,B         */
+OP(cb,81) { _C = RES(0,_C);                                         } /* RES  0,C         */
+OP(cb,82) { _D = RES(0,_D);                                         } /* RES  0,D         */
+OP(cb,83) { _E = RES(0,_E);                                         } /* RES  0,E         */
+OP(cb,84) { _H = RES(0,_H);                                         } /* RES  0,H         */
+OP(cb,85) { _L = RES(0,_L);                                         } /* RES  0,L         */
+OP(cb,86) { WM( _HL, RES(0,RM(_HL)) );                              } /* RES  0,(HL)      */
+OP(cb,87) { _A = RES(0,_A);                                         } /* RES  0,A         */
+
+OP(cb,88) { _B = RES(1,_B);                                         } /* RES  1,B         */
+OP(cb,89) { _C = RES(1,_C);                                         } /* RES  1,C         */
+OP(cb,8a) { _D = RES(1,_D);                                         } /* RES  1,D         */
+OP(cb,8b) { _E = RES(1,_E);                                         } /* RES  1,E         */
+OP(cb,8c) { _H = RES(1,_H);                                         } /* RES  1,H         */
+OP(cb,8d) { _L = RES(1,_L);                                         } /* RES  1,L         */
+OP(cb,8e) { WM( _HL, RES(1,RM(_HL)) );                              } /* RES  1,(HL)      */
+OP(cb,8f) { _A = RES(1,_A);                                         } /* RES  1,A         */
+
+OP(cb,90) { _B = RES(2,_B);                                         } /* RES  2,B         */
+OP(cb,91) { _C = RES(2,_C);                                         } /* RES  2,C         */
+OP(cb,92) { _D = RES(2,_D);                                         } /* RES  2,D         */
+OP(cb,93) { _E = RES(2,_E);                                         } /* RES  2,E         */
+OP(cb,94) { _H = RES(2,_H);                                         } /* RES  2,H         */
+OP(cb,95) { _L = RES(2,_L);                                         } /* RES  2,L         */
+OP(cb,96) { WM( _HL, RES(2,RM(_HL)) );                              } /* RES  2,(HL)      */
+OP(cb,97) { _A = RES(2,_A);                                         } /* RES  2,A         */
+
+OP(cb,98) { _B = RES(3,_B);                                         } /* RES  3,B         */
+OP(cb,99) { _C = RES(3,_C);                                         } /* RES  3,C         */
+OP(cb,9a) { _D = RES(3,_D);                                         } /* RES  3,D         */
+OP(cb,9b) { _E = RES(3,_E);                                         } /* RES  3,E         */
+OP(cb,9c) { _H = RES(3,_H);                                         } /* RES  3,H         */
+OP(cb,9d) { _L = RES(3,_L);                                         } /* RES  3,L         */
+OP(cb,9e) { WM( _HL, RES(3,RM(_HL)) );                              } /* RES  3,(HL)      */
+OP(cb,9f) { _A = RES(3,_A);                                         } /* RES  3,A         */
+
+OP(cb,a0) { _B = RES(4,_B);                                         } /* RES  4,B         */
+OP(cb,a1) { _C = RES(4,_C);                                         } /* RES  4,C         */
+OP(cb,a2) { _D = RES(4,_D);                                         } /* RES  4,D         */
+OP(cb,a3) { _E = RES(4,_E);                                         } /* RES  4,E         */
+OP(cb,a4) { _H = RES(4,_H);                                         } /* RES  4,H         */
+OP(cb,a5) { _L = RES(4,_L);                                         } /* RES  4,L         */
+OP(cb,a6) { WM( _HL, RES(4,RM(_HL)) );                              } /* RES  4,(HL)      */
+OP(cb,a7) { _A = RES(4,_A);                                         } /* RES  4,A         */
+
+OP(cb,a8) { _B = RES(5,_B);                                         } /* RES  5,B         */
+OP(cb,a9) { _C = RES(5,_C);                                         } /* RES  5,C         */
+OP(cb,aa) { _D = RES(5,_D);                                         } /* RES  5,D         */
+OP(cb,ab) { _E = RES(5,_E);                                         } /* RES  5,E         */
+OP(cb,ac) { _H = RES(5,_H);                                         } /* RES  5,H         */
+OP(cb,ad) { _L = RES(5,_L);                                         } /* RES  5,L         */
+OP(cb,ae) { WM( _HL, RES(5,RM(_HL)) );                              } /* RES  5,(HL)      */
+OP(cb,af) { _A = RES(5,_A);                                         } /* RES  5,A         */
+
+OP(cb,b0) { _B = RES(6,_B);                                         } /* RES  6,B         */
+OP(cb,b1) { _C = RES(6,_C);                                         } /* RES  6,C         */
+OP(cb,b2) { _D = RES(6,_D);                                         } /* RES  6,D         */
+OP(cb,b3) { _E = RES(6,_E);                                         } /* RES  6,E         */
+OP(cb,b4) { _H = RES(6,_H);                                         } /* RES  6,H         */
+OP(cb,b5) { _L = RES(6,_L);                                         } /* RES  6,L         */
+OP(cb,b6) { WM( _HL, RES(6,RM(_HL)) );                              } /* RES  6,(HL)      */
+OP(cb,b7) { _A = RES(6,_A);                                         } /* RES  6,A         */
+
+OP(cb,b8) { _B = RES(7,_B);                                         } /* RES  7,B         */
+OP(cb,b9) { _C = RES(7,_C);                                         } /* RES  7,C         */
+OP(cb,ba) { _D = RES(7,_D);                                         } /* RES  7,D         */
+OP(cb,bb) { _E = RES(7,_E);                                         } /* RES  7,E         */
+OP(cb,bc) { _H = RES(7,_H);                                         } /* RES  7,H         */
+OP(cb,bd) { _L = RES(7,_L);                                         } /* RES  7,L         */
+OP(cb,be) { WM( _HL, RES(7,RM(_HL)) );                              } /* RES  7,(HL)      */
+OP(cb,bf) { _A = RES(7,_A);                                         } /* RES  7,A         */
+
+OP(cb,c0) { _B = SET(0,_B);                                         } /* SET  0,B         */
+OP(cb,c1) { _C = SET(0,_C);                                         } /* SET  0,C         */
+OP(cb,c2) { _D = SET(0,_D);                                         } /* SET  0,D         */
+OP(cb,c3) { _E = SET(0,_E);                                         } /* SET  0,E         */
+OP(cb,c4) { _H = SET(0,_H);                                         } /* SET  0,H         */
+OP(cb,c5) { _L = SET(0,_L);                                         } /* SET  0,L         */
+OP(cb,c6) { WM( _HL, SET(0,RM(_HL)) );                              } /* SET  0,(HL)      */
+OP(cb,c7) { _A = SET(0,_A);                                         } /* SET  0,A         */
+
+OP(cb,c8) { _B = SET(1,_B);                                         } /* SET  1,B         */
+OP(cb,c9) { _C = SET(1,_C);                                         } /* SET  1,C         */
+OP(cb,ca) { _D = SET(1,_D);                                         } /* SET  1,D         */
+OP(cb,cb) { _E = SET(1,_E);                                         } /* SET  1,E         */
+OP(cb,cc) { _H = SET(1,_H);                                         } /* SET  1,H         */
+OP(cb,cd) { _L = SET(1,_L);                                         } /* SET  1,L         */
+OP(cb,ce) { WM( _HL, SET(1,RM(_HL)) );                              } /* SET  1,(HL)      */
+OP(cb,cf) { _A = SET(1,_A);                                         } /* SET  1,A         */
+
+OP(cb,d0) { _B = SET(2,_B);                                         } /* SET  2,B         */
+OP(cb,d1) { _C = SET(2,_C);                                         } /* SET  2,C         */
+OP(cb,d2) { _D = SET(2,_D);                                         } /* SET  2,D         */
+OP(cb,d3) { _E = SET(2,_E);                                         } /* SET  2,E         */
+OP(cb,d4) { _H = SET(2,_H);                                         } /* SET  2,H         */
+OP(cb,d5) { _L = SET(2,_L);                                         } /* SET  2,L         */
+OP(cb,d6) { WM( _HL, SET(2,RM(_HL)) );                              }/* SET  2,(HL)      */
+OP(cb,d7) { _A = SET(2,_A);                                         } /* SET  2,A         */
+
+OP(cb,d8) { _B = SET(3,_B);                                         } /* SET  3,B         */
+OP(cb,d9) { _C = SET(3,_C);                                         } /* SET  3,C         */
+OP(cb,da) { _D = SET(3,_D);                                         } /* SET  3,D         */
+OP(cb,db) { _E = SET(3,_E);                                         } /* SET  3,E         */
+OP(cb,dc) { _H = SET(3,_H);                                         } /* SET  3,H         */
+OP(cb,dd) { _L = SET(3,_L);                                         } /* SET  3,L         */
+OP(cb,de) { WM( _HL, SET(3,RM(_HL)) );                              } /* SET  3,(HL)      */
+OP(cb,df) { _A = SET(3,_A);                                         } /* SET  3,A         */
+
+OP(cb,e0) { _B = SET(4,_B);                                         } /* SET  4,B         */
+OP(cb,e1) { _C = SET(4,_C);                                         } /* SET  4,C         */
+OP(cb,e2) { _D = SET(4,_D);                                         } /* SET  4,D         */
+OP(cb,e3) { _E = SET(4,_E);                                         } /* SET  4,E         */
+OP(cb,e4) { _H = SET(4,_H);                                         } /* SET  4,H         */
+OP(cb,e5) { _L = SET(4,_L);                                         } /* SET  4,L         */
+OP(cb,e6) { WM( _HL, SET(4,RM(_HL)) );                              } /* SET  4,(HL)      */
+OP(cb,e7) { _A = SET(4,_A);                                         } /* SET  4,A         */
+
+OP(cb,e8) { _B = SET(5,_B);                                         } /* SET  5,B         */
+OP(cb,e9) { _C = SET(5,_C);                                         } /* SET  5,C         */
+OP(cb,ea) { _D = SET(5,_D);                                         } /* SET  5,D         */
+OP(cb,eb) { _E = SET(5,_E);                                         } /* SET  5,E         */
+OP(cb,ec) { _H = SET(5,_H);                                         } /* SET  5,H         */
+OP(cb,ed) { _L = SET(5,_L);                                         } /* SET  5,L         */
+OP(cb,ee) { WM( _HL, SET(5,RM(_HL)) );                              } /* SET  5,(HL)      */
+OP(cb,ef) { _A = SET(5,_A);                                         } /* SET  5,A         */
+
+OP(cb,f0) { _B = SET(6,_B);                                         } /* SET  6,B         */
+OP(cb,f1) { _C = SET(6,_C);                                         } /* SET  6,C         */
+OP(cb,f2) { _D = SET(6,_D);                                         } /* SET  6,D         */
+OP(cb,f3) { _E = SET(6,_E);                                         } /* SET  6,E         */
+OP(cb,f4) { _H = SET(6,_H);                                         } /* SET  6,H         */
+OP(cb,f5) { _L = SET(6,_L);                                         } /* SET  6,L         */
+OP(cb,f6) { WM( _HL, SET(6,RM(_HL)) );                              } /* SET  6,(HL)      */
+OP(cb,f7) { _A = SET(6,_A);                                         } /* SET  6,A         */
+
+OP(cb,f8) { _B = SET(7,_B);                                         } /* SET  7,B         */
+OP(cb,f9) { _C = SET(7,_C);                                         } /* SET  7,C         */
+OP(cb,fa) { _D = SET(7,_D);                                         } /* SET  7,D         */
+OP(cb,fb) { _E = SET(7,_E);                                         } /* SET  7,E         */
+OP(cb,fc) { _H = SET(7,_H);                                         } /* SET  7,H         */
+OP(cb,fd) { _L = SET(7,_L);                                         } /* SET  7,L         */
+OP(cb,fe) { WM( _HL, SET(7,RM(_HL)) );                              } /* SET  7,(HL)      */
+OP(cb,ff) { _A = SET(7,_A);                                         } /* SET  7,A         */
diff --git a/z180/z180dasm.cpp b/z180/z180dasm.cpp
new file mode 100644 (file)
index 0000000..521ec1b
--- /dev/null
@@ -0,0 +1,500 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/*****************************************************************************
+ *
+ *   z180dasm.c
+ *   Portable Z8x180 disassembler
+ *
+ *****************************************************************************/
+
+#include "emu.h"
+#include "z180dasm.h"
+
+const char *const z180_disassembler::s_mnemonic[] = {
+       "adc"  ,"add"  ,"and"  ,"bit"  ,"call" ,"ccf"  ,"cp"   ,"cpd"  ,
+       "cpdr" ,"cpi"  ,"cpir" ,"cpl"  ,"daa"  ,"db"   ,"dec"  ,"di"   ,
+       "djnz" ,"ei"   ,"ex"   ,"exx"  ,"halt" ,"im"   ,"in"   ,"in0"  ,
+       "inc"  ,"ind"  ,"indr" ,"ini"  ,"inir" ,"jp"   ,"jr"   ,"ld"   ,
+       "ldd"  ,"lddr" ,"ldi"  ,"ldir" ,"mlt"  ,"neg"  ,"nop"  ,"or"   ,
+       "otdm" ,"otdmr","otdr" ,"otim" ,"otimr","otir" ,"out"  ,"out0" ,
+       "outd" ,"outi" ,"pop"  ,"push" ,"res"  ,"ret"  ,"reti" ,"retn" ,
+       "rl"   ,"rla"  ,"rlc"  ,"rlca" ,"rld"  ,"rr"   ,"rra"  ,"rrc"  ,
+       "rrca" ,"rrd"  ,"rst"  ,"sbc"  ,"scf"  ,"set"  ,"sla"  ,"sll"  ,
+       "slp"  ,"sra"  ,"srl"  ,"sub"  ,"tst"  ,"tstio","xor "
+};
+
+const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx_cb[256]= {
+       {zRLC,"b=Y"},   {zRLC,"c=Y"},   {zRLC,"d=Y"},   {zRLC,"e=Y"},
+       {zRLC,"h=Y"},   {zRLC,"l=Y"},   {zRLC,"Y"},     {zRLC,"a=Y"},
+       {zRRC,"b=Y"},   {zRRC,"c=Y"},   {zRRC,"d=Y"},   {zRRC,"e=Y"},
+       {zRRC,"h=Y"},   {zRRC,"l=Y"},   {zRRC,"Y"},     {zRRC,"a=Y"},
+       {zRL,"b=Y"},    {zRL,"c=Y"},    {zRL,"d=Y"},    {zRL,"e=Y"},
+       {zRL,"h=Y"},    {zRL,"l=Y"},    {zRL,"Y"},      {zRL,"a=Y"},
+       {zRR,"b=Y"},    {zRR,"c=Y"},    {zRR,"d=Y"},    {zRR,"e=Y"},
+       {zRR,"h=Y"},    {zRR,"l=Y"},    {zRR,"Y"},      {zRR,"a=Y"},
+       {zSLA,"b=Y"},   {zSLA,"c=Y"},   {zSLA,"d=Y"},   {zSLA,"e=Y"},
+       {zSLA,"h=Y"},   {zSLA,"l=Y"},   {zSLA,"Y"},     {zSLA,"a=Y"},
+       {zSRA,"b=Y"},   {zSRA,"c=Y"},   {zSRA,"d=Y"},   {zSRA,"e=Y"},
+       {zSRA,"h=Y"},   {zSRA,"l=Y"},   {zSRA,"Y"},     {zSRA,"a=Y"},
+       {zSLL,"b=Y"},   {zSLL,"c=Y"},   {zSLL,"d=Y"},   {zSLL,"e=Y"},
+       {zSLL,"h=Y"},   {zSLL,"l=Y"},   {zSLL,"Y"},     {zSLL,"a=Y"},
+       {zSRL,"b=Y"},   {zSRL,"c=Y"},   {zSRL,"d=Y"},   {zSRL,"e=Y"},
+       {zSRL,"h=Y"},   {zSRL,"l=Y"},   {zSRL,"Y"},     {zSRL,"a=Y"},
+       {zBIT,"b=0,Y"}, {zBIT,"c=0,Y"}, {zBIT,"d=0,Y"}, {zBIT,"e=0,Y"},
+       {zBIT,"h=0,Y"}, {zBIT,"l=0,Y"}, {zBIT,"0,Y"},   {zBIT,"a=0,Y"},
+       {zBIT,"b=1,Y"}, {zBIT,"c=1,Y"}, {zBIT,"d=1,Y"}, {zBIT,"e=1,Y"},
+       {zBIT,"h=1,Y"}, {zBIT,"l=1,Y"}, {zBIT,"1,Y"},   {zBIT,"a=1,Y"},
+       {zBIT,"b=2,Y"}, {zBIT,"c=2,Y"}, {zBIT,"d=2,Y"}, {zBIT,"e=2,Y"},
+       {zBIT,"h=2,Y"}, {zBIT,"l=2,Y"}, {zBIT,"2,Y"},   {zBIT,"a=2,Y"},
+       {zBIT,"b=3,Y"}, {zBIT,"c=3,Y"}, {zBIT,"d=3,Y"}, {zBIT,"e=3,Y"},
+       {zBIT,"h=3,Y"}, {zBIT,"l=3,Y"}, {zBIT,"3,Y"},   {zBIT,"a=3,Y"},
+       {zBIT,"b=4,Y"}, {zBIT,"c=4,Y"}, {zBIT,"d=4,Y"}, {zBIT,"e=4,Y"},
+       {zBIT,"h=4,Y"}, {zBIT,"l=4,Y"}, {zBIT,"4,Y"},   {zBIT,"a=4,Y"},
+       {zBIT,"b=5,Y"}, {zBIT,"c=5,Y"}, {zBIT,"d=5,Y"}, {zBIT,"e=5,Y"},
+       {zBIT,"h=5,Y"}, {zBIT,"l=5,Y"}, {zBIT,"5,Y"},   {zBIT,"a=5,Y"},
+       {zBIT,"b=6,Y"}, {zBIT,"c=6,Y"}, {zBIT,"d=6,Y"}, {zBIT,"e=6,Y"},
+       {zBIT,"h=6,Y"}, {zBIT,"l=6,Y"}, {zBIT,"6,Y"},   {zBIT,"a=6,Y"},
+       {zBIT,"b=7,Y"}, {zBIT,"c=7,Y"}, {zBIT,"d=7,Y"}, {zBIT,"e=7,Y"},
+       {zBIT,"h=7,Y"}, {zBIT,"l=7,Y"}, {zBIT,"7,Y"},   {zBIT,"a=7,Y"},
+       {zRES,"b=0,Y"}, {zRES,"c=0,Y"}, {zRES,"d=0,Y"}, {zRES,"e=0,Y"},
+       {zRES,"h=0,Y"}, {zRES,"l=0,Y"}, {zRES,"0,Y"},   {zRES,"a=0,Y"},
+       {zRES,"b=1,Y"}, {zRES,"c=1,Y"}, {zRES,"d=1,Y"}, {zRES,"e=1,Y"},
+       {zRES,"h=1,Y"}, {zRES,"l=1,Y"}, {zRES,"1,Y"},   {zRES,"a=1,Y"},
+       {zRES,"b=2,Y"}, {zRES,"c=2,Y"}, {zRES,"d=2,Y"}, {zRES,"e=2,Y"},
+       {zRES,"h=2,Y"}, {zRES,"l=2,Y"}, {zRES,"2,Y"},   {zRES,"a=2,Y"},
+       {zRES,"b=3,Y"}, {zRES,"c=3,Y"}, {zRES,"d=3,Y"}, {zRES,"e=3,Y"},
+       {zRES,"h=3,Y"}, {zRES,"l=3,Y"}, {zRES,"3,Y"},   {zRES,"a=3,Y"},
+       {zRES,"b=4,Y"}, {zRES,"c=4,Y"}, {zRES,"d=4,Y"}, {zRES,"e=4,Y"},
+       {zRES,"h=4,Y"}, {zRES,"l=4,Y"}, {zRES,"4,Y"},   {zRES,"a=4,Y"},
+       {zRES,"b=5,Y"}, {zRES,"c=5,Y"}, {zRES,"d=5,Y"}, {zRES,"e=5,Y"},
+       {zRES,"h=5,Y"}, {zRES,"l=5,Y"}, {zRES,"5,Y"},   {zRES,"a=5,Y"},
+       {zRES,"b=6,Y"}, {zRES,"c=6,Y"}, {zRES,"d=6,Y"}, {zRES,"e=6,Y"},
+       {zRES,"h=6,Y"}, {zRES,"l=6,Y"}, {zRES,"6,Y"},   {zRES,"a=6,Y"},
+       {zRES,"b=7,Y"}, {zRES,"c=7,Y"}, {zRES,"d=7,Y"}, {zRES,"e=7,Y"},
+       {zRES,"h=7,Y"}, {zRES,"l=7,Y"}, {zRES,"7,Y"},   {zRES,"a=7,Y"},
+       {zSET,"b=0,Y"}, {zSET,"c=0,Y"}, {zSET,"d=0,Y"}, {zSET,"e=0,Y"},
+       {zSET,"h=0,Y"}, {zSET,"l=0,Y"}, {zSET,"0,Y"},   {zSET,"a=0,Y"},
+       {zSET,"b=1,Y"}, {zSET,"c=1,Y"}, {zSET,"d=1,Y"}, {zSET,"e=1,Y"},
+       {zSET,"h=1,Y"}, {zSET,"l=1,Y"}, {zSET,"1,Y"},   {zSET,"a=1,Y"},
+       {zSET,"b=2,Y"}, {zSET,"c=2,Y"}, {zSET,"d=2,Y"}, {zSET,"e=2,Y"},
+       {zSET,"h=2,Y"}, {zSET,"l=2,Y"}, {zSET,"2,Y"},   {zSET,"a=2,Y"},
+       {zSET,"b=3,Y"}, {zSET,"c=3,Y"}, {zSET,"d=3,Y"}, {zSET,"e=3,Y"},
+       {zSET,"h=3,Y"}, {zSET,"l=3,Y"}, {zSET,"3,Y"},   {zSET,"a=3,Y"},
+       {zSET,"b=4,Y"}, {zSET,"c=4,Y"}, {zSET,"d=4,Y"}, {zSET,"e=4,Y"},
+       {zSET,"h=4,Y"}, {zSET,"l=4,Y"}, {zSET,"4,Y"},   {zSET,"a=4,Y"},
+       {zSET,"b=5,Y"}, {zSET,"c=5,Y"}, {zSET,"d=5,Y"}, {zSET,"e=5,Y"},
+       {zSET,"h=5,Y"}, {zSET,"l=5,Y"}, {zSET,"5,Y"},   {zSET,"a=5,Y"},
+       {zSET,"b=6,Y"}, {zSET,"c=6,Y"}, {zSET,"d=6,Y"}, {zSET,"e=6,Y"},
+       {zSET,"h=6,Y"}, {zSET,"l=6,Y"}, {zSET,"6,Y"},   {zSET,"a=6,Y"},
+       {zSET,"b=7,Y"}, {zSET,"c=7,Y"}, {zSET,"d=7,Y"}, {zSET,"e=7,Y"},
+       {zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"},   {zSET,"a=7,Y"}
+};
+
+const z180_disassembler::z80dasm z180_disassembler::mnemonic_cb[256] = {
+       {zRLC,"b"},     {zRLC,"c"},     {zRLC,"d"},     {zRLC,"e"},
+       {zRLC,"h"},     {zRLC,"l"},     {zRLC,"(hl)"},  {zRLC,"a"},
+       {zRRC,"b"},     {zRRC,"c"},     {zRRC,"d"},     {zRRC,"e"},
+       {zRRC,"h"},     {zRRC,"l"},     {zRRC,"(hl)"},  {zRRC,"a"},
+       {zRL,"b"},      {zRL,"c"},      {zRL,"d"},      {zRL,"e"},
+       {zRL,"h"},      {zRL,"l"},      {zRL,"(hl)"},   {zRL,"a"},
+       {zRR,"b"},      {zRR,"c"},      {zRR,"d"},      {zRR,"e"},
+       {zRR,"h"},      {zRR,"l"},      {zRR,"(hl)"},   {zRR,"a"},
+       {zSLA,"b"},     {zSLA,"c"},     {zSLA,"d"},     {zSLA,"e"},
+       {zSLA,"h"},     {zSLA,"l"},     {zSLA,"(hl)"},  {zSLA,"a"},
+       {zSRA,"b"},     {zSRA,"c"},     {zSRA,"d"},     {zSRA,"e"},
+       {zSRA,"h"},     {zSRA,"l"},     {zSRA,"(hl)"},  {zSRA,"a"},
+       {zSLL,"b"},     {zSLL,"c"},     {zSLL,"d"},     {zSLL,"e"},
+       {zSLL,"h"},     {zSLL,"l"},     {zSLL,"(hl)"},  {zSLL,"a"},
+       {zSRL,"b"},     {zSRL,"c"},     {zSRL,"d"},     {zSRL,"e"},
+       {zSRL,"h"},     {zSRL,"l"},     {zSRL,"(hl)"},  {zSRL,"a"},
+       {zBIT,"0,b"},   {zBIT,"0,c"},   {zBIT,"0,d"},   {zBIT,"0,e"},
+       {zBIT,"0,h"},   {zBIT,"0,l"},   {zBIT,"0,(hl)"},{zBIT,"0,a"},
+       {zBIT,"1,b"},   {zBIT,"1,c"},   {zBIT,"1,d"},   {zBIT,"1,e"},
+       {zBIT,"1,h"},   {zBIT,"1,l"},   {zBIT,"1,(hl)"},{zBIT,"1,a"},
+       {zBIT,"2,b"},   {zBIT,"2,c"},   {zBIT,"2,d"},   {zBIT,"2,e"},
+       {zBIT,"2,h"},   {zBIT,"2,l"},   {zBIT,"2,(hl)"},{zBIT,"2,a"},
+       {zBIT,"3,b"},   {zBIT,"3,c"},   {zBIT,"3,d"},   {zBIT,"3,e"},
+       {zBIT,"3,h"},   {zBIT,"3,l"},   {zBIT,"3,(hl)"},{zBIT,"3,a"},
+       {zBIT,"4,b"},   {zBIT,"4,c"},   {zBIT,"4,d"},   {zBIT,"4,e"},
+       {zBIT,"4,h"},   {zBIT,"4,l"},   {zBIT,"4,(hl)"},{zBIT,"4,a"},
+       {zBIT,"5,b"},   {zBIT,"5,c"},   {zBIT,"5,d"},   {zBIT,"5,e"},
+       {zBIT,"5,h"},   {zBIT,"5,l"},   {zBIT,"5,(hl)"},{zBIT,"5,a"},
+       {zBIT,"6,b"},   {zBIT,"6,c"},   {zBIT,"6,d"},   {zBIT,"6,e"},
+       {zBIT,"6,h"},   {zBIT,"6,l"},   {zBIT,"6,(hl)"},{zBIT,"6,a"},
+       {zBIT,"7,b"},   {zBIT,"7,c"},   {zBIT,"7,d"},   {zBIT,"7,e"},
+       {zBIT,"7,h"},   {zBIT,"7,l"},   {zBIT,"7,(hl)"},{zBIT,"7,a"},
+       {zRES,"0,b"},   {zRES,"0,c"},   {zRES,"0,d"},   {zRES,"0,e"},
+       {zRES,"0,h"},   {zRES,"0,l"},   {zRES,"0,(hl)"},{zRES,"0,a"},
+       {zRES,"1,b"},   {zRES,"1,c"},   {zRES,"1,d"},   {zRES,"1,e"},
+       {zRES,"1,h"},   {zRES,"1,l"},   {zRES,"1,(hl)"},{zRES,"1,a"},
+       {zRES,"2,b"},   {zRES,"2,c"},   {zRES,"2,d"},   {zRES,"2,e"},
+       {zRES,"2,h"},   {zRES,"2,l"},   {zRES,"2,(hl)"},{zRES,"2,a"},
+       {zRES,"3,b"},   {zRES,"3,c"},   {zRES,"3,d"},   {zRES,"3,e"},
+       {zRES,"3,h"},   {zRES,"3,l"},   {zRES,"3,(hl)"},{zRES,"3,a"},
+       {zRES,"4,b"},   {zRES,"4,c"},   {zRES,"4,d"},   {zRES,"4,e"},
+       {zRES,"4,h"},   {zRES,"4,l"},   {zRES,"4,(hl)"},{zRES,"4,a"},
+       {zRES,"5,b"},   {zRES,"5,c"},   {zRES,"5,d"},   {zRES,"5,e"},
+       {zRES,"5,h"},   {zRES,"5,l"},   {zRES,"5,(hl)"},{zRES,"5,a"},
+       {zRES,"6,b"},   {zRES,"6,c"},   {zRES,"6,d"},   {zRES,"6,e"},
+       {zRES,"6,h"},   {zRES,"6,l"},   {zRES,"6,(hl)"},{zRES,"6,a"},
+       {zRES,"7,b"},   {zRES,"7,c"},   {zRES,"7,d"},   {zRES,"7,e"},
+       {zRES,"7,h"},   {zRES,"7,l"},   {zRES,"7,(hl)"},{zRES,"7,a"},
+       {zSET,"0,b"},   {zSET,"0,c"},   {zSET,"0,d"},   {zSET,"0,e"},
+       {zSET,"0,h"},   {zSET,"0,l"},   {zSET,"0,(hl)"},{zSET,"0,a"},
+       {zSET,"1,b"},   {zSET,"1,c"},   {zSET,"1,d"},   {zSET,"1,e"},
+       {zSET,"1,h"},   {zSET,"1,l"},   {zSET,"1,(hl)"},{zSET,"1,a"},
+       {zSET,"2,b"},   {zSET,"2,c"},   {zSET,"2,d"},   {zSET,"2,e"},
+       {zSET,"2,h"},   {zSET,"2,l"},   {zSET,"2,(hl)"},{zSET,"2,a"},
+       {zSET,"3,b"},   {zSET,"3,c"},   {zSET,"3,d"},   {zSET,"3,e"},
+       {zSET,"3,h"},   {zSET,"3,l"},   {zSET,"3,(hl)"},{zSET,"3,a"},
+       {zSET,"4,b"},   {zSET,"4,c"},   {zSET,"4,d"},   {zSET,"4,e"},
+       {zSET,"4,h"},   {zSET,"4,l"},   {zSET,"4,(hl)"},{zSET,"4,a"},
+       {zSET,"5,b"},   {zSET,"5,c"},   {zSET,"5,d"},   {zSET,"5,e"},
+       {zSET,"5,h"},   {zSET,"5,l"},   {zSET,"5,(hl)"},{zSET,"5,a"},
+       {zSET,"6,b"},   {zSET,"6,c"},   {zSET,"6,d"},   {zSET,"6,e"},
+       {zSET,"6,h"},   {zSET,"6,l"},   {zSET,"6,(hl)"},{zSET,"6,a"},
+       {zSET,"7,b"},   {zSET,"7,c"},   {zSET,"7,d"},   {zSET,"7,e"},
+       {zSET,"7,h"},   {zSET,"7,l"},   {zSET,"7,(hl)"},{zSET,"7,a"}
+};
+
+const z180_disassembler::z80dasm z180_disassembler::mnemonic_ed[256]= {
+       {zIN0,"b,(B)"}, {zOUT0,"(B),b"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"b"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"c,(B)"}, {zOUT0,"(B),c"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"c"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"d,(B)"}, {zOUT0,"(B),d"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"d"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"e,(B)"}, {zOUT0,"(B),e"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"e"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"h,(B)"}, {zOUT0,"(B),h"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"h"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"l,(B)"}, {zOUT0,"(B),l"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"l"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"f,(B)"}, {zOUT0,"(B),0"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"(hl)"},  {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN0,"a,(B)"}, {zOUT0,"(B),a"},{zDB,"?"},      {zDB,"?"},
+       {zTST,"a"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zIN,"b,(c)"},  {zOUT,"(c),b"}, {zSBC,"hl,bc"}, {zLD,"(W),bc"},
+       {zNEG,nullptr},       {zRETN,nullptr},      {zIM,"0"},      {zLD,"i,a"},
+       {zIN,"c,(c)"},  {zOUT,"(c),c"}, {zADC,"hl,bc"}, {zLD,"bc,(W)"},
+       {zMLT,"bc"},    {zRETI,nullptr},      {zIM,"0"},      {zLD,"r,a"},
+       {zIN,"d,(c)"},  {zOUT,"(c),d"}, {zSBC,"hl,de"}, {zLD,"(W),de"},
+       {zNEG,"*"},     {zRETN,nullptr},      {zIM,"1"},      {zLD,"a,i"},
+       {zIN,"e,(c)"},  {zOUT,"(c),e"}, {zADC,"hl,de"}, {zLD,"de,(W)"},
+       {zMLT,"de"},    {zRETI,nullptr},      {zIM,"2"},      {zLD,"a,r"},
+       {zIN,"h,(c)"},  {zOUT,"(c),h"}, {zSBC,"hl,hl"}, {zLD,"(W),hl"},
+       {zTST,"B"},     {zRETN,nullptr},      {zIM,"0"},      {zRRD,"(hl)"},
+       {zIN,"l,(c)"},  {zOUT,"(c),l"}, {zADC,"hl,hl"}, {zLD,"hl,(W)"},
+       {zMLT,"hl"},    {zRETI,nullptr},      {zIM,"0"},      {zRLD,"(hl)"},
+       {zIN,"0,(c)"},  {zOUT,"(c),0"}, {zSBC,"hl,sp"}, {zLD,"(W),sp"},
+       {zTSTIO,"B"},   {zRETN,nullptr},      {zSLP,nullptr},       {zDB,"?"},
+       {zIN,"a,(c)"},  {zOUT,"(c),a"}, {zADC,"hl,sp"}, {zLD,"sp,(W)"},
+       {zMLT,"sp"},    {zRETI,nullptr},      {zIM,"2"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTIM,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTDM,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTIMR,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTDMR,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLDI,nullptr},       {zCPI,nullptr},       {zINI,nullptr},       {zOUTI,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLDD,nullptr},       {zCPD,nullptr},       {zIND,nullptr},       {zOUTD,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLDIR,nullptr},      {zCPIR,nullptr},      {zINIR,nullptr},      {zOTIR,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLDDR,nullptr},      {zCPDR,nullptr},      {zINDR,nullptr},      {zOTDR,nullptr},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"}
+};
+
+const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx[256]= {
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zADD,"I,bc"},  {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zADD,"I,de"},  {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zLD,"I,N"},    {zLD,"(W),I"},  {zINC,"I"},
+       {zINC,"Ih"},    {zDEC,"Ih"},    {zLD,"Ih,B"},   {zDB,"?"},
+       {zDB,"?"},      {zADD,"I,I"},   {zLD,"I,(W)"},  {zDEC,"I"},
+       {zINC,"Il"},    {zDEC,"Il"},    {zLD,"Il,B"},   {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zINC,"X"},     {zDEC,"X"},     {zLD,"X,B"},    {zDB,"?"},
+       {zDB,"?"},      {zADD,"I,sp"},  {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLD,"b,Ih"},   {zLD,"b,Il"},   {zLD,"b,X"},    {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLD,"c,Ih"},   {zLD,"c,Il"},   {zLD,"c,X"},    {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLD,"d,Ih"},   {zLD,"d,Il"},   {zLD,"d,X"},    {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLD,"e,Ih"},   {zLD,"e,Il"},   {zLD,"e,X"},    {zDB,"?"},
+       {zLD,"Ih,b"},   {zLD,"Ih,c"},   {zLD,"Ih,d"},   {zLD,"Ih,e"},
+       {zLD,"Ih,Ih"},  {zLD,"Ih,Il"},  {zLD,"h,X"},    {zLD,"Ih,a"},
+       {zLD,"Il,b"},   {zLD,"Il,c"},   {zLD,"Il,d"},   {zLD,"Il,e"},
+       {zLD,"Il,Ih"},  {zLD,"Il,Il"},  {zLD,"l,X"},    {zLD,"Il,a"},
+       {zLD,"X,b"},    {zLD,"X,c"},    {zLD,"X,d"},    {zLD,"X,e"},
+       {zLD,"X,h"},    {zLD,"X,l"},    {zDB,"?"},      {zLD,"X,a"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zLD,"a,Ih"},   {zLD,"a,Il"},   {zLD,"a,X"},    {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zADD,"a,Ih"},  {zADD,"a,Il"},  {zADD,"a,X"},   {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zADC,"a,Ih"},  {zADC,"a,Il"},  {zADC,"a,X"},   {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zSUB,"Ih"},    {zSUB,"Il"},    {zSUB,"X"},     {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zSBC,"a,Ih"},  {zSBC,"a,Il"},  {zSBC,"a,X"},   {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zAND,"Ih"},    {zAND,"Il"},    {zAND,"X"},     {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zXOR,"Ih"},    {zXOR,"Il"},    {zXOR,"X"},     {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zOR,"Ih"},     {zOR,"Il"},     {zOR,"X"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zCP,"Ih"},     {zCP,"Il"},     {zCP,"X"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"cb"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zPOP,"I"},     {zDB,"?"},      {zEX,"(sp),I"},
+       {zDB,"?"},      {zPUSH,"I"},    {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zJP,"(I)"},    {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zLD,"sp,I"},   {zDB,"?"},      {zDB,"?"},
+       {zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"}
+};
+
+const z180_disassembler::z80dasm z180_disassembler::mnemonic_main[256]= {
+       {zNOP,nullptr},       {zLD,"bc,N"},   {zLD,"(bc),a"}, {zINC,"bc"},
+       {zINC,"b"},     {zDEC,"b"},     {zLD,"b,B"},    {zRLCA,nullptr},
+       {zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"},
+       {zINC,"c"},     {zDEC,"c"},     {zLD,"c,B"},    {zRRCA,nullptr},
+       {zDJNZ,"O"},    {zLD,"de,N"},   {zLD,"(de),a"}, {zINC,"de"},
+       {zINC,"d"},     {zDEC,"d"},     {zLD,"d,B"},    {zRLA,nullptr},
+       {zJR,"O"},      {zADD,"hl,de"}, {zLD,"a,(de)"}, {zDEC,"de"},
+       {zINC,"e"},     {zDEC,"e"},     {zLD,"e,B"},    {zRRA,nullptr},
+       {zJR,"nz,O"},   {zLD,"hl,N"},   {zLD,"(W),hl"}, {zINC,"hl"},
+       {zINC,"h"},     {zDEC,"h"},     {zLD,"h,B"},    {zDAA,nullptr},
+       {zJR,"z,O"},    {zADD,"hl,hl"}, {zLD,"hl,(W)"}, {zDEC,"hl"},
+       {zINC,"l"},     {zDEC,"l"},     {zLD,"l,B"},    {zCPL,nullptr},
+       {zJR,"nc,O"},   {zLD,"sp,N"},   {zLD,"(W),a"},  {zINC,"sp"},
+       {zINC,"(hl)"},  {zDEC,"(hl)"},  {zLD,"(hl),B"}, {zSCF,nullptr},
+       {zJR,"c,O"},    {zADD,"hl,sp"}, {zLD,"a,(W)"},  {zDEC,"sp"},
+       {zINC,"a"},     {zDEC,"a"},     {zLD,"a,B"},    {zCCF,nullptr},
+       {zLD,"b,b"},    {zLD,"b,c"},    {zLD,"b,d"},    {zLD,"b,e"},
+       {zLD,"b,h"},    {zLD,"b,l"},    {zLD,"b,(hl)"}, {zLD,"b,a"},
+       {zLD,"c,b"},    {zLD,"c,c"},    {zLD,"c,d"},    {zLD,"c,e"},
+       {zLD,"c,h"},    {zLD,"c,l"},    {zLD,"c,(hl)"}, {zLD,"c,a"},
+       {zLD,"d,b"},    {zLD,"d,c"},    {zLD,"d,d"},    {zLD,"d,e"},
+       {zLD,"d,h"},    {zLD,"d,l"},    {zLD,"d,(hl)"}, {zLD,"d,a"},
+       {zLD,"e,b"},    {zLD,"e,c"},    {zLD,"e,d"},    {zLD,"e,e"},
+       {zLD,"e,h"},    {zLD,"e,l"},    {zLD,"e,(hl)"}, {zLD,"e,a"},
+       {zLD,"h,b"},    {zLD,"h,c"},    {zLD,"h,d"},    {zLD,"h,e"},
+       {zLD,"h,h"},    {zLD,"h,l"},    {zLD,"h,(hl)"}, {zLD,"h,a"},
+       {zLD,"l,b"},    {zLD,"l,c"},    {zLD,"l,d"},    {zLD,"l,e"},
+       {zLD,"l,h"},    {zLD,"l,l"},    {zLD,"l,(hl)"}, {zLD,"l,a"},
+       {zLD,"(hl),b"}, {zLD,"(hl),c"}, {zLD,"(hl),d"}, {zLD,"(hl),e"},
+       {zLD,"(hl),h"}, {zLD,"(hl),l"}, {zHLT,nullptr},       {zLD,"(hl),a"},
+       {zLD,"a,b"},    {zLD,"a,c"},    {zLD,"a,d"},    {zLD,"a,e"},
+       {zLD,"a,h"},    {zLD,"a,l"},    {zLD,"a,(hl)"}, {zLD,"a,a"},
+       {zADD,"a,b"},   {zADD,"a,c"},   {zADD,"a,d"},   {zADD,"a,e"},
+       {zADD,"a,h"},   {zADD,"a,l"},   {zADD,"a,(hl)"},{zADD,"a,a"},
+       {zADC,"a,b"},   {zADC,"a,c"},   {zADC,"a,d"},   {zADC,"a,e"},
+       {zADC,"a,h"},   {zADC,"a,l"},   {zADC,"a,(hl)"},{zADC,"a,a"},
+       {zSUB,"b"},     {zSUB,"c"},     {zSUB,"d"},     {zSUB,"e"},
+       {zSUB,"h"},     {zSUB,"l"},     {zSUB,"(hl)"},  {zSUB,"a"},
+       {zSBC,"a,b"},   {zSBC,"a,c"},   {zSBC,"a,d"},   {zSBC,"a,e"},
+       {zSBC,"a,h"},   {zSBC,"a,l"},   {zSBC,"a,(hl)"},{zSBC,"a,a"},
+       {zAND,"b"},     {zAND,"c"},     {zAND,"d"},     {zAND,"e"},
+       {zAND,"h"},     {zAND,"l"},     {zAND,"(hl)"},  {zAND,"a"},
+       {zXOR,"b"},     {zXOR,"c"},     {zXOR,"d"},     {zXOR,"e"},
+       {zXOR,"h"},     {zXOR,"l"},     {zXOR,"(hl)"},  {zXOR,"a"},
+       {zOR,"b"},      {zOR,"c"},      {zOR,"d"},      {zOR,"e"},
+       {zOR,"h"},      {zOR,"l"},      {zOR,"(hl)"},   {zOR,"a"},
+       {zCP,"b"},      {zCP,"c"},      {zCP,"d"},      {zCP,"e"},
+       {zCP,"h"},      {zCP,"l"},      {zCP,"(hl)"},   {zCP,"a"},
+       {zRET,"nz"},    {zPOP,"bc"},    {zJP,"nz,A"},   {zJP,"A"},
+       {zCALL,"nz,A"}, {zPUSH,"bc"},   {zADD,"a,B"},   {zRST,"V"},
+       {zRET,"z"},     {zRET,nullptr},       {zJP,"z,A"},    {zDB,"cb"},
+       {zCALL,"z,A"},  {zCALL,"A"},    {zADC,"a,B"},   {zRST,"V"},
+       {zRET,"nc"},    {zPOP,"de"},    {zJP,"nc,A"},   {zOUT,"(P),a"},
+       {zCALL,"nc,A"}, {zPUSH,"de"},   {zSUB,"B"},     {zRST,"V"},
+       {zRET,"c"},     {zEXX,nullptr},       {zJP,"c,A"},    {zIN,"a,(P)"},
+       {zCALL,"c,A"},  {zDB,"dd"},     {zSBC,"a,B"},   {zRST,"V"},
+       {zRET,"po"},    {zPOP,"hl"},    {zJP,"po,A"},   {zEX,"(sp),hl"},
+       {zCALL,"po,A"}, {zPUSH,"hl"},   {zAND,"B"},     {zRST,"V"},
+       {zRET,"pe"},    {zJP,"(hl)"},   {zJP,"pe,A"},   {zEX,"de,hl"},
+       {zCALL,"pe,A"}, {zDB,"ed"},     {zXOR,"B"},     {zRST,"V"},
+       {zRET,"p"},     {zPOP,"af"},    {zJP,"p,A"},    {zDI,nullptr},
+       {zCALL,"p,A"},  {zPUSH,"af"},   {zOR,"B"},      {zRST,"V"},
+       {zRET,"m"},     {zLD,"sp,hl"},  {zJP,"m,A"},    {zEI,nullptr},
+       {zCALL,"m,A"},  {zDB,"fd"},     {zCP,"B"},      {zRST,"V"}
+};
+
+char z180_disassembler::sign(int8_t offset)
+{
+       return (offset < 0)? '-':'+';
+}
+
+int z180_disassembler::offs(int8_t offset)
+{
+       if (offset < 0) return -offset;
+       return offset;
+}
+
+/****************************************************************************
+ * Disassemble opcode at PC and return number of bytes it takes
+ ****************************************************************************/
+offs_t z180_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+       const z80dasm *d;
+       const char *src, *ixy;
+       int8_t offset = 0;
+       uint8_t op, op1 = 0;
+       uint16_t ea;
+       offs_t pos = pc;
+       uint32_t flags = 0;
+
+       ixy = "oops!!";
+
+       op = opcodes.r8(pos++);
+
+       switch (op)
+       {
+       case 0xcb:
+               op = opcodes.r8(pos++);
+               d = &mnemonic_cb[op];
+               break;
+       case 0xed:
+               op1 = opcodes.r8(pos++);
+               d = &mnemonic_ed[op1];
+               break;
+       case 0xdd:
+               ixy = "ix";
+               op1 = opcodes.r8(pos++);
+               if( op1 == 0xcb )
+               {
+                       offset = (int8_t) params.r8(pos++);
+                       op1 = params.r8(pos++); /* fourth byte from opbase.ram! */
+                       d = &mnemonic_xx_cb[op1];
+               }
+               else d = &mnemonic_xx[op1];
+               break;
+       case 0xfd:
+               ixy = "iy";
+               op1 = opcodes.r8(pos++);
+               if( op1 == 0xcb )
+               {
+                       offset = (int8_t) params.r8(pos++);
+                       op1 = params.r8(pos++); /* fourth byte from opbase.ram! */
+                       d = &mnemonic_xx_cb[op1];
+               }
+               else d = &mnemonic_xx[op1];
+               break;
+       default:
+               d = &mnemonic_main[op];
+               break;
+       }
+
+       if( d->arguments )
+       {
+               util::stream_format(stream, "%-5s ", s_mnemonic[d->mnemonic]);
+               src = d->arguments;
+               while( *src )
+               {
+                       switch( *src )
+                       {
+                       case '?':   /* illegal opcode */
+                               util::stream_format(stream, "$%02x,$%02x", op, op1);
+                               break;
+                       case 'A':
+                               ea = params.r16(pos);
+                               pos += 2;
+                               util::stream_format(stream, "$%04X", ea);
+                               break;
+                       case 'B':   /* Byte op arg */
+                               ea = params.r8(pos++);
+                               util::stream_format(stream, "$%02X", ea);
+                               break;
+                       case 'N':   /* Immediate 16 bit */
+                               ea = params.r16(pos);
+                               pos += 2;
+                               util::stream_format(stream, "$%04X", ea);
+                               break;
+                       case 'O':   /* Offset relative to PC */
+                               offset = (int8_t) params.r8(pos++);
+                               util::stream_format(stream, "$%05X", pc + offset + 2);
+                               break;
+                       case 'P':   /* Port number */
+                               ea = params.r8(pos++);
+                               util::stream_format(stream, "$%02X", ea);
+                               break;
+                       case 'V':   /* Restart vector */
+                               ea = op & 0x38;
+                               util::stream_format(stream, "$%02X", ea);
+                               break;
+                       case 'W':   /* Memory address word */
+                               ea = params.r16(pos);
+                               pos += 2;
+                               util::stream_format(stream, "$%05X", ea);
+                               break;
+                       case 'X':
+                               offset = (int8_t) params.r8(pos++);
+                       case 'Y':
+                               util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset));
+                               break;
+                       case 'I':
+                               util::stream_format(stream, "%s", ixy);
+                               break;
+                       default:
+                               stream << *src;
+                       }
+                       src++;
+               }
+       }
+       else
+       {
+               util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]);
+       }
+
+       if (d->mnemonic == zCALL || d->mnemonic == zCPDR || d->mnemonic == zCPIR || d->mnemonic == zDJNZ ||
+               d->mnemonic == zHLT  || d->mnemonic == zINDR || d->mnemonic == zINIR || d->mnemonic == zLDDR ||
+               d->mnemonic == zLDIR || d->mnemonic == zOTDR || d->mnemonic == zOTIR || d->mnemonic == zRST)
+               flags = STEP_OVER;
+       else if (d->mnemonic == zRETN || d->mnemonic == zRET || d->mnemonic == zRETI)
+               flags = STEP_OUT;
+
+       return (pos - pc) | flags | SUPPORTED;
+}
+
+u32 z180_disassembler::opcode_alignment() const
+{
+       return 1;
+}
diff --git a/z180/z180dasm.h b/z180/z180dasm.h
new file mode 100644 (file)
index 0000000..a13c7d9
--- /dev/null
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/*****************************************************************************
+ *
+ *   z180dasm.c
+ *   Portable Z8x180 disassembler
+ *
+ *****************************************************************************/
+
+#ifndef MAME_CPU_Z180_Z180DASM_H
+#define MAME_CPU_Z180_Z180DASM_H
+
+#pragma once
+
+class z180_disassembler : public util::disasm_interface
+{
+public:
+       z180_disassembler() = default;
+       virtual ~z180_disassembler() = default;
+
+       virtual u32 opcode_alignment() const override;
+       virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+
+private:
+       struct z80dasm {
+               uint8_t mnemonic;
+               const char *arguments;
+       };
+
+       enum e_mnemonics {
+               zADC   ,zADD   ,zAND   ,zBIT   ,zCALL  ,zCCF   ,zCP    ,zCPD   ,
+               zCPDR  ,zCPI   ,zCPIR  ,zCPL   ,zDAA   ,zDB    ,zDEC   ,zDI    ,
+               zDJNZ  ,zEI    ,zEX    ,zEXX   ,zHLT   ,zIM    ,zIN    ,zIN0   ,
+               zINC   ,zIND   ,zINDR  ,zINI   ,zINIR  ,zJP    ,zJR    ,zLD    ,
+               zLDD   ,zLDDR  ,zLDI   ,zLDIR  ,zMLT   ,zNEG   ,zNOP   ,zOR    ,
+               zOTDM  ,zOTDMR ,zOTDR  ,zOTIM  ,zOTIMR ,zOTIR  ,zOUT   ,zOUT0  ,
+               zOUTD  ,zOUTI  ,zPOP   ,zPUSH  ,zRES   ,zRET   ,zRETI  ,zRETN  ,
+               zRL    ,zRLA   ,zRLC   ,zRLCA  ,zRLD   ,zRR    ,zRRA   ,zRRC   ,
+               zRRCA  ,zRRD   ,zRST   ,zSBC   ,zSCF   ,zSET   ,zSLA   ,zSLL   ,
+               zSLP   ,zSRA   ,zSRL   ,zSUB   ,zTST   ,zTSTIO ,zXOR
+       };
+
+       static const char *const s_mnemonic[];
+       static const z80dasm mnemonic_xx_cb[256];
+       static const z80dasm mnemonic_cb[256];
+       static const z80dasm mnemonic_ed[256];
+       static const z80dasm mnemonic_xx[256];
+       static const z80dasm mnemonic_main[256];
+
+       static char sign(int8_t offset);
+       static int offs(int8_t offset);
+};
+
+#endif
diff --git a/z180/z180dd.hxx b/z180/z180dd.hxx
new file mode 100644 (file)
index 0000000..0676af9
--- /dev/null
@@ -0,0 +1,297 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+OP(illegal,1) {
+       logerror("Z180 '%s' ill. opcode $%02x $%02x\n",
+                       tag(), m_ocache->read_byte((_PCD-1)&0xffff), m_ocache->read_byte(_PCD));
+}
+
+/**********************************************************
+ * IX register related opcodes (DD prefix)
+ **********************************************************/
+OP(dd,00) { illegal_1(); op_00();                                   } /* DB   DD          */
+OP(dd,01) { illegal_1(); op_01();                                   } /* DB   DD          */
+OP(dd,02) { illegal_1(); op_02();                                   } /* DB   DD          */
+OP(dd,03) { illegal_1(); op_03();                                   } /* DB   DD          */
+OP(dd,04) { illegal_1(); op_04();                                   } /* DB   DD          */
+OP(dd,05) { illegal_1(); op_05();                                   } /* DB   DD          */
+OP(dd,06) { illegal_1(); op_06();                                   } /* DB   DD          */
+OP(dd,07) { illegal_1(); op_07();                                   } /* DB   DD          */
+
+OP(dd,08) { illegal_1(); op_08();                                   } /* DB   DD          */
+OP(dd,09) { m_R++; ADD16(IX,BC);                                    } /* ADD  IX,BC       */
+OP(dd,0a) { illegal_1(); op_0a();                                   } /* DB   DD          */
+OP(dd,0b) { illegal_1(); op_0b();                                   } /* DB   DD          */
+OP(dd,0c) { illegal_1(); op_0c();                                   } /* DB   DD          */
+OP(dd,0d) { illegal_1(); op_0d();                                   } /* DB   DD          */
+OP(dd,0e) { illegal_1(); op_0e();                                   } /* DB   DD          */
+OP(dd,0f) { illegal_1(); op_0f();                                   } /* DB   DD          */
+
+OP(dd,10) { illegal_1(); op_10();                                   } /* DB   DD          */
+OP(dd,11) { illegal_1(); op_11();                                   } /* DB   DD          */
+OP(dd,12) { illegal_1(); op_12();                                   } /* DB   DD          */
+OP(dd,13) { illegal_1(); op_13();                                   } /* DB   DD          */
+OP(dd,14) { illegal_1(); op_14();                                   } /* DB   DD          */
+OP(dd,15) { illegal_1(); op_15();                                   } /* DB   DD          */
+OP(dd,16) { illegal_1(); op_16();                                   } /* DB   DD          */
+OP(dd,17) { illegal_1(); op_17();                                   } /* DB   DD          */
+
+OP(dd,18) { illegal_1(); op_18();                                   } /* DB   DD          */
+OP(dd,19) { m_R++; ADD16(IX,DE);                                    } /* ADD  IX,DE       */
+OP(dd,1a) { illegal_1(); op_1a();                                   } /* DB   DD          */
+OP(dd,1b) { illegal_1(); op_1b();                                   } /* DB   DD          */
+OP(dd,1c) { illegal_1(); op_1c();                                   } /* DB   DD          */
+OP(dd,1d) { illegal_1(); op_1d();                                   } /* DB   DD          */
+OP(dd,1e) { illegal_1(); op_1e();                                   } /* DB   DD          */
+OP(dd,1f) { illegal_1(); op_1f();                                   } /* DB   DD          */
+
+OP(dd,20) { illegal_1(); op_20();                                   } /* DB   DD          */
+OP(dd,21) { m_R++; _IX = ARG16();                                 } /* LD   IX,w        */
+OP(dd,22) { m_R++; m_ea = ARG16(); WM16( m_ea, &m_IX );               } /* LD   (w),IX      */
+OP(dd,23) { m_R++; _IX++;                                         } /* INC  IX          */
+OP(dd,24) { m_R++; _HX = INC(_HX);                                    } /* INC  HX          */
+OP(dd,25) { m_R++; _HX = DEC(_HX);                                    } /* DEC  HX          */
+OP(dd,26) { m_R++; _HX = ARG();                                       } /* LD   HX,n        */
+OP(dd,27) { illegal_1(); op_27();                                   } /* DB   DD          */
+
+OP(dd,28) { illegal_1(); op_28();                                   } /* DB   DD          */
+OP(dd,29) { m_R++; ADD16(IX,IX);                                    } /* ADD  IX,IX       */
+OP(dd,2a) { m_R++; m_ea = ARG16(); RM16( m_ea, &m_IX );               } /* LD   IX,(w)      */
+OP(dd,2b) { m_R++; _IX--;                                         } /* DEC  IX          */
+OP(dd,2c) { m_R++; _LX = INC(_LX);                                    } /* INC  LX          */
+OP(dd,2d) { m_R++; _LX = DEC(_LX);                                    } /* DEC  LX          */
+OP(dd,2e) { m_R++; _LX = ARG();                                       } /* LD   LX,n        */
+OP(dd,2f) { illegal_1(); op_2f();                                   } /* DB   DD          */
+
+OP(dd,30) { illegal_1(); op_30();                                   } /* DB   DD          */
+OP(dd,31) { illegal_1(); op_31();                                   } /* DB   DD          */
+OP(dd,32) { illegal_1(); op_32();                                   } /* DB   DD          */
+OP(dd,33) { illegal_1(); op_33();                                   } /* DB   DD          */
+OP(dd,34) { m_R++; EAX(); WM( m_ea, INC(RM(m_ea)) );                      } /* INC  (IX+o)      */
+OP(dd,35) { m_R++; EAX(); WM( m_ea, DEC(RM(m_ea)) );                      } /* DEC  (IX+o)      */
+OP(dd,36) { m_R++; EAX(); WM( m_ea, ARG() );                          } /* LD   (IX+o),n    */
+OP(dd,37) { illegal_1(); op_37();                                   } /* DB   DD          */
+
+OP(dd,38) { illegal_1(); op_38();                                   } /* DB   DD          */
+OP(dd,39) { m_R++; ADD16(IX,SP);                                    } /* ADD  IX,SP       */
+OP(dd,3a) { illegal_1(); op_3a();                                   } /* DB   DD          */
+OP(dd,3b) { illegal_1(); op_3b();                                   } /* DB   DD          */
+OP(dd,3c) { illegal_1(); op_3c();                                   } /* DB   DD          */
+OP(dd,3d) { illegal_1(); op_3d();                                   } /* DB   DD          */
+OP(dd,3e) { illegal_1(); op_3e();                                   } /* DB   DD          */
+OP(dd,3f) { illegal_1(); op_3f();                                   } /* DB   DD          */
+
+OP(dd,40) { illegal_1(); op_40();                                   } /* DB   DD          */
+OP(dd,41) { illegal_1(); op_41();                                   } /* DB   DD          */
+OP(dd,42) { illegal_1(); op_42();                                   } /* DB   DD          */
+OP(dd,43) { illegal_1(); op_43();                                   } /* DB   DD          */
+OP(dd,44) { m_R++; _B = _HX;                                        } /* LD   B,HX        */
+OP(dd,45) { m_R++; _B = _LX;                                        } /* LD   B,LX        */
+OP(dd,46) { m_R++; EAX(); _B = RM(m_ea);                                } /* LD   B,(IX+o)    */
+OP(dd,47) { illegal_1(); op_47();                                   } /* DB   DD          */
+
+OP(dd,48) { illegal_1(); op_48();                                   } /* DB   DD          */
+OP(dd,49) { illegal_1(); op_49();                                   } /* DB   DD          */
+OP(dd,4a) { illegal_1(); op_4a();                                   } /* DB   DD          */
+OP(dd,4b) { illegal_1(); op_4b();                                   } /* DB   DD          */
+OP(dd,4c) { m_R++; _C = _HX;                                        } /* LD   C,HX        */
+OP(dd,4d) { m_R++; _C = _LX;                                        } /* LD   C,LX        */
+OP(dd,4e) { m_R++; EAX(); _C = RM(m_ea);                                } /* LD   C,(IX+o)    */
+OP(dd,4f) { illegal_1(); op_4f();                                   } /* DB   DD          */
+
+OP(dd,50) { illegal_1(); op_50();                                   } /* DB   DD          */
+OP(dd,51) { illegal_1(); op_51();                                   } /* DB   DD          */
+OP(dd,52) { illegal_1(); op_52();                                   } /* DB   DD          */
+OP(dd,53) { illegal_1(); op_53();                                   } /* DB   DD          */
+OP(dd,54) { m_R++; _D = _HX;                                        } /* LD   D,HX        */
+OP(dd,55) { m_R++; _D = _LX;                                        } /* LD   D,LX        */
+OP(dd,56) { m_R++; EAX(); _D = RM(m_ea);                                } /* LD   D,(IX+o)    */
+OP(dd,57) { illegal_1(); op_57();                                   } /* DB   DD          */
+
+OP(dd,58) { illegal_1(); op_58();                                   } /* DB   DD          */
+OP(dd,59) { illegal_1(); op_59();                                   } /* DB   DD          */
+OP(dd,5a) { illegal_1(); op_5a();                                   } /* DB   DD          */
+OP(dd,5b) { illegal_1(); op_5b();                                   } /* DB   DD          */
+OP(dd,5c) { m_R++; _E = _HX;                                        } /* LD   E,HX        */
+OP(dd,5d) { m_R++; _E = _LX;                                        } /* LD   E,LX        */
+OP(dd,5e) { m_R++; EAX(); _E = RM(m_ea);                                } /* LD   E,(IX+o)    */
+OP(dd,5f) { illegal_1(); op_5f();                                   } /* DB   DD          */
+
+OP(dd,60) { m_R++; _HX = _B;                                        } /* LD   HX,B        */
+OP(dd,61) { m_R++; _HX = _C;                                        } /* LD   HX,C        */
+OP(dd,62) { m_R++; _HX = _D;                                        } /* LD   HX,D        */
+OP(dd,63) { m_R++; _HX = _E;                                        } /* LD   HX,E        */
+OP(dd,64) {                                                         } /* LD   HX,HX       */
+OP(dd,65) { m_R++; _HX = _LX;                                       } /* LD   HX,LX       */
+OP(dd,66) { m_R++; EAX(); _H = RM(m_ea);                                } /* LD   H,(IX+o)    */
+OP(dd,67) { m_R++; _HX = _A;                                        } /* LD   HX,A        */
+
+OP(dd,68) { m_R++; _LX = _B;                                        } /* LD   LX,B        */
+OP(dd,69) { m_R++; _LX = _C;                                        } /* LD   LX,C        */
+OP(dd,6a) { m_R++; _LX = _D;                                        } /* LD   LX,D        */
+OP(dd,6b) { m_R++; _LX = _E;                                        } /* LD   LX,E        */
+OP(dd,6c) { m_R++; _LX = _HX;                                       } /* LD   LX,HX       */
+OP(dd,6d) {                                                         } /* LD   LX,LX       */
+OP(dd,6e) { m_R++; EAX(); _L = RM(m_ea);                                } /* LD   L,(IX+o)    */
+OP(dd,6f) { m_R++; _LX = _A;                                        } /* LD   LX,A        */
+
+OP(dd,70) { m_R++; EAX(); WM( m_ea, _B );                               } /* LD   (IX+o),B    */
+OP(dd,71) { m_R++; EAX(); WM( m_ea, _C );                               } /* LD   (IX+o),C    */
+OP(dd,72) { m_R++; EAX(); WM( m_ea, _D );                               } /* LD   (IX+o),D    */
+OP(dd,73) { m_R++; EAX(); WM( m_ea, _E );                               } /* LD   (IX+o),E    */
+OP(dd,74) { m_R++; EAX(); WM( m_ea, _H );                               } /* LD   (IX+o),H    */
+OP(dd,75) { m_R++; EAX(); WM( m_ea, _L );                               } /* LD   (IX+o),L    */
+OP(dd,76) { illegal_1(); op_76();                                   }         /* DB   DD          */
+OP(dd,77) { m_R++; EAX(); WM( m_ea, _A );                               } /* LD   (IX+o),A    */
+
+OP(dd,78) { illegal_1(); op_78();                                   } /* DB   DD          */
+OP(dd,79) { illegal_1(); op_79();                                   } /* DB   DD          */
+OP(dd,7a) { illegal_1(); op_7a();                                   } /* DB   DD          */
+OP(dd,7b) { illegal_1(); op_7b();                                   } /* DB   DD          */
+OP(dd,7c) { m_R++; _A = _HX;                                        } /* LD   A,HX        */
+OP(dd,7d) { m_R++; _A = _LX;                                        } /* LD   A,LX        */
+OP(dd,7e) { m_R++; EAX(); _A = RM(m_ea);                                } /* LD   A,(IX+o)    */
+OP(dd,7f) { illegal_1(); op_7f();                                   } /* DB   DD          */
+
+OP(dd,80) { illegal_1(); op_80();                                   } /* DB   DD          */
+OP(dd,81) { illegal_1(); op_81();                                   } /* DB   DD          */
+OP(dd,82) { illegal_1(); op_82();                                   } /* DB   DD          */
+OP(dd,83) { illegal_1(); op_83();                                   } /* DB   DD          */
+OP(dd,84) { m_R++; ADD(_HX);                                      } /* ADD  A,HX        */
+OP(dd,85) { m_R++; ADD(_LX);                                      } /* ADD  A,LX        */
+OP(dd,86) { m_R++; EAX(); ADD(RM(m_ea));                              } /* ADD  A,(IX+o)    */
+OP(dd,87) { illegal_1(); op_87();                                   } /* DB   DD          */
+
+OP(dd,88) { illegal_1(); op_88();                                   } /* DB   DD          */
+OP(dd,89) { illegal_1(); op_89();                                   } /* DB   DD          */
+OP(dd,8a) { illegal_1(); op_8a();                                   } /* DB   DD          */
+OP(dd,8b) { illegal_1(); op_8b();                                   } /* DB   DD          */
+OP(dd,8c) { m_R++; ADC(_HX);                                      } /* ADC  A,HX        */
+OP(dd,8d) { m_R++; ADC(_LX);                                      } /* ADC  A,LX        */
+OP(dd,8e) { m_R++; EAX(); ADC(RM(m_ea));                              } /* ADC  A,(IX+o)    */
+OP(dd,8f) { illegal_1(); op_8f();                                   } /* DB   DD          */
+
+OP(dd,90) { illegal_1(); op_90();                                   } /* DB   DD          */
+OP(dd,91) { illegal_1(); op_91();                                   } /* DB   DD          */
+OP(dd,92) { illegal_1(); op_92();                                   } /* DB   DD          */
+OP(dd,93) { illegal_1(); op_93();                                   } /* DB   DD          */
+OP(dd,94) { m_R++; SUB(_HX);                                      } /* SUB  HX          */
+OP(dd,95) { m_R++; SUB(_LX);                                      } /* SUB  LX          */
+OP(dd,96) { m_R++; EAX(); SUB(RM(m_ea));                              } /* SUB  (IX+o)      */
+OP(dd,97) { illegal_1(); op_97();                                   } /* DB   DD          */
+
+OP(dd,98) { illegal_1(); op_98();                                   } /* DB   DD          */
+OP(dd,99) { illegal_1(); op_99();                                   } /* DB   DD          */
+OP(dd,9a) { illegal_1(); op_9a();                                   } /* DB   DD          */
+OP(dd,9b) { illegal_1(); op_9b();                                   } /* DB   DD          */
+OP(dd,9c) { m_R++; SBC(_HX);                                      } /* SBC  A,HX        */
+OP(dd,9d) { m_R++; SBC(_LX);                                      } /* SBC  A,LX        */
+OP(dd,9e) { m_R++; EAX(); SBC(RM(m_ea));                              } /* SBC  A,(IX+o)    */
+OP(dd,9f) { illegal_1(); op_9f();                                   } /* DB   DD          */
+
+OP(dd,a0) { illegal_1(); op_a0();                                   } /* DB   DD          */
+OP(dd,a1) { illegal_1(); op_a1();                                   } /* DB   DD          */
+OP(dd,a2) { illegal_1(); op_a2();                                   } /* DB   DD          */
+OP(dd,a3) { illegal_1(); op_a3();                                   } /* DB   DD          */
+OP(dd,a4) { m_R++; AND(_HX);                                      } /* AND  HX          */
+OP(dd,a5) { m_R++; AND(_LX);                                      } /* AND  LX          */
+OP(dd,a6) { m_R++; EAX(); AND(RM(m_ea));                              } /* AND  (IX+o)      */
+OP(dd,a7) { illegal_1(); op_a7();                                   } /* DB   DD          */
+
+OP(dd,a8) { illegal_1(); op_a8();                                   } /* DB   DD          */
+OP(dd,a9) { illegal_1(); op_a9();                                   } /* DB   DD          */
+OP(dd,aa) { illegal_1(); op_aa();                                   } /* DB   DD          */
+OP(dd,ab) { illegal_1(); op_ab();                                   } /* DB   DD          */
+OP(dd,ac) { m_R++; XOR(_HX);                                      } /* XOR  HX          */
+OP(dd,ad) { m_R++; XOR(_LX);                                      } /* XOR  LX          */
+OP(dd,ae) { m_R++; EAX(); XOR(RM(m_ea));                              } /* XOR  (IX+o)      */
+OP(dd,af) { illegal_1(); op_af();                                   } /* DB   DD          */
+
+OP(dd,b0) { illegal_1(); op_b0();                                   } /* DB   DD          */
+OP(dd,b1) { illegal_1(); op_b1();                                   } /* DB   DD          */
+OP(dd,b2) { illegal_1(); op_b2();                                   } /* DB   DD          */
+OP(dd,b3) { illegal_1(); op_b3();                                   } /* DB   DD          */
+OP(dd,b4) { m_R++; OR(_HX);                                           } /* OR   HX          */
+OP(dd,b5) { m_R++; OR(_LX);                                           } /* OR   LX          */
+OP(dd,b6) { m_R++; EAX(); OR(RM(m_ea));                                   } /* OR   (IX+o)      */
+OP(dd,b7) { illegal_1(); op_b7();                                   } /* DB   DD          */
+
+OP(dd,b8) { illegal_1(); op_b8();                                   } /* DB   DD          */
+OP(dd,b9) { illegal_1(); op_b9();                                   } /* DB   DD          */
+OP(dd,ba) { illegal_1(); op_ba();                                   } /* DB   DD          */
+OP(dd,bb) { illegal_1(); op_bb();                                   } /* DB   DD          */
+OP(dd,bc) { m_R++; CP(_HX);                                           } /* CP   HX          */
+OP(dd,bd) { m_R++; CP(_LX);                                           } /* CP   LX          */
+OP(dd,be) { m_R++; EAX(); CP(RM(m_ea));                                   } /* CP   (IX+o)      */
+OP(dd,bf) { illegal_1(); op_bf();                                   } /* DB   DD          */
+
+OP(dd,c0) { illegal_1(); op_c0();                                   } /* DB   DD          */
+OP(dd,c1) { illegal_1(); op_c1();                                   } /* DB   DD          */
+OP(dd,c2) { illegal_1(); op_c2();                                   } /* DB   DD          */
+OP(dd,c3) { illegal_1(); op_c3();                                   } /* DB   DD          */
+OP(dd,c4) { illegal_1(); op_c4();                                   } /* DB   DD          */
+OP(dd,c5) { illegal_1(); op_c5();                                   } /* DB   DD          */
+OP(dd,c6) { illegal_1(); op_c6();                                   } /* DB   DD          */
+OP(dd,c7) { illegal_1(); op_c7();                                   }         /* DB   DD          */
+
+OP(dd,c8) { illegal_1(); op_c8();                                   } /* DB   DD          */
+OP(dd,c9) { illegal_1(); op_c9();                                   } /* DB   DD          */
+OP(dd,ca) { illegal_1(); op_ca();                                   } /* DB   DD          */
+OP(dd,cb) { m_R++; EAX(); m_extra_cycles += exec_xycb(ARG());                          } /* **   DD CB xx    */
+OP(dd,cc) { illegal_1(); op_cc();                                   } /* DB   DD          */
+OP(dd,cd) { illegal_1(); op_cd();                                   } /* DB   DD          */
+OP(dd,ce) { illegal_1(); op_ce();                                   } /* DB   DD          */
+OP(dd,cf) { illegal_1(); op_cf();                                   } /* DB   DD          */
+
+OP(dd,d0) { illegal_1(); op_d0();                                   } /* DB   DD          */
+OP(dd,d1) { illegal_1(); op_d1();                                   } /* DB   DD          */
+OP(dd,d2) { illegal_1(); op_d2();                                   } /* DB   DD          */
+OP(dd,d3) { illegal_1(); op_d3();                                   } /* DB   DD          */
+OP(dd,d4) { illegal_1(); op_d4();                                   } /* DB   DD          */
+OP(dd,d5) { illegal_1(); op_d5();                                   } /* DB   DD          */
+OP(dd,d6) { illegal_1(); op_d6();                                   } /* DB   DD          */
+OP(dd,d7) { illegal_1(); op_d7();                                   } /* DB   DD          */
+
+OP(dd,d8) { illegal_1(); op_d8();                                   } /* DB   DD          */
+OP(dd,d9) { illegal_1(); op_d9();                                   } /* DB   DD          */
+OP(dd,da) { illegal_1(); op_da();                                   } /* DB   DD          */
+OP(dd,db) { illegal_1(); op_db();                                   } /* DB   DD          */
+OP(dd,dc) { illegal_1(); op_dc();                                   } /* DB   DD          */
+OP(dd,dd) { illegal_1(); op_dd();                                   } /* DB   DD          */
+OP(dd,de) { illegal_1(); op_de();                                   } /* DB   DD          */
+OP(dd,df) { illegal_1(); op_df();                                   } /* DB   DD          */
+
+OP(dd,e0) { illegal_1(); op_e0();                                   } /* DB   DD          */
+OP(dd,e1) { m_R++; POP(IX);                                           } /* POP  IX          */
+OP(dd,e2) { illegal_1(); op_e2();                                   } /* DB   DD          */
+OP(dd,e3) { m_R++; EXSP(IX);                                        } /* EX   (SP),IX     */
+OP(dd,e4) { illegal_1(); op_e4();                                   } /* DB   DD          */
+OP(dd,e5) { m_R++; PUSH( IX );                                        } /* PUSH IX          */
+OP(dd,e6) { illegal_1(); op_e6();                                   } /* DB   DD          */
+OP(dd,e7) { illegal_1(); op_e7();                                   } /* DB   DD          */
+
+OP(dd,e8) { illegal_1(); op_e8();                                   } /* DB   DD          */
+OP(dd,e9) { m_R++; _PC = _IX;                                       } /* JP   (IX)        */
+OP(dd,ea) { illegal_1(); op_ea();                                   } /* DB   DD          */
+OP(dd,eb) { illegal_1(); op_eb();                                   } /* DB   DD          */
+OP(dd,ec) { illegal_1(); op_ec();                                   } /* DB   DD          */
+OP(dd,ed) { illegal_1(); op_ed();                                   } /* DB   DD          */
+OP(dd,ee) { illegal_1(); op_ee();                                   } /* DB   DD          */
+OP(dd,ef) { illegal_1(); op_ef();                                   } /* DB   DD          */
+
+OP(dd,f0) { illegal_1(); op_f0();                                   } /* DB   DD          */
+OP(dd,f1) { illegal_1(); op_f1();                                   } /* DB   DD          */
+OP(dd,f2) { illegal_1(); op_f2();                                   } /* DB   DD          */
+OP(dd,f3) { illegal_1(); op_f3();                                   } /* DB   DD          */
+OP(dd,f4) { illegal_1(); op_f4();                                   } /* DB   DD          */
+OP(dd,f5) { illegal_1(); op_f5();                                   } /* DB   DD          */
+OP(dd,f6) { illegal_1(); op_f6();                                   } /* DB   DD          */
+OP(dd,f7) { illegal_1(); op_f7();                                   } /* DB   DD          */
+
+OP(dd,f8) { illegal_1(); op_f8();                                   } /* DB   DD          */
+OP(dd,f9) { m_R++; _SP = _IX;                                       } /* LD   SP,IX       */
+OP(dd,fa) { illegal_1(); op_fa();                                   } /* DB   DD          */
+OP(dd,fb) { illegal_1(); op_fb();                                   } /* DB   DD          */
+OP(dd,fc) { illegal_1(); op_fc();                                   } /* DB   DD          */
+OP(dd,fd) { illegal_1(); op_fd();                                   } /* DB   DD          */
+OP(dd,fe) { illegal_1(); op_fe();                                   } /* DB   DD          */
+OP(dd,ff) { illegal_1(); op_ff();                                   } /* DB   DD          */
diff --git a/z180/z180ed.hxx b/z180/z180ed.hxx
new file mode 100644 (file)
index 0000000..6892510
--- /dev/null
@@ -0,0 +1,298 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+OP(illegal,2)
+{
+       logerror("Z180 '%s' ill. opcode $ed $%02x\n",
+                       tag(), m_ocache->read_byte((_PCD-1)&0xffff));
+}
+
+/**********************************************************
+ * special opcodes (ED prefix)
+ **********************************************************/
+OP(ed,00) { unsigned n = ARG(); _B = IN( n );                       } /* IN0  B,(n)       */
+OP(ed,01) { unsigned n = ARG(); OUT( n, _B );                       } /* OUT0 (n),B       */
+OP(ed,02) { illegal_2();                                            } /* DB   ED          */
+OP(ed,03) { illegal_2();                                            } /* DB   ED          */
+OP(ed,04) { TST( _B );                                                } /* TST  B           */
+OP(ed,05) { illegal_2();                                            } /* DB   ED          */
+OP(ed,06) { illegal_2();                                            } /* DB   ED          */
+OP(ed,07) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,08) { unsigned n = ARG(); _C = IN( n );                       } /* IN0  C,(n)       */
+OP(ed,09) { unsigned n = ARG(); OUT( n, _C );                       } /* OUT0 (n),C       */
+OP(ed,0a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,0b) { illegal_2();                                            } /* DB   ED          */
+OP(ed,0c) { TST( _C );                                                } /* TST  C           */
+OP(ed,0d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,0e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,0f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,10) { unsigned n = ARG(); _D = IN( n );                       } /* IN0  D,(n)       */
+OP(ed,11) { unsigned n = ARG(); OUT( n, _D );                       } /* OUT0 (n),D       */
+OP(ed,12) { illegal_2();                                            } /* DB   ED          */
+OP(ed,13) { illegal_2();                                            } /* DB   ED          */
+OP(ed,14) { TST( _D );                                                } /* TST  D           */
+OP(ed,15) { illegal_2();                                            } /* DB   ED          */
+OP(ed,16) { illegal_2();                                            } /* DB   ED          */
+OP(ed,17) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,18) { unsigned n = ARG(); _E = IN( n );                       } /* IN0  E,(n)       */
+OP(ed,19) { unsigned n = ARG(); OUT( n, _E );                       } /* OUT0 (n),E       */
+OP(ed,1a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,1b) { illegal_2();                                            } /* DB   ED          */
+OP(ed,1c) { TST( _E );                                                } /* TST  E           */
+OP(ed,1d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,1e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,1f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,20) { unsigned n = ARG(); _H = IN( n );                       } /* IN0  H,(n)       */
+OP(ed,21) { unsigned n = ARG(); OUT( n, _H );                       } /* OUT0 (n),H       */
+OP(ed,22) { illegal_2();                                            } /* DB   ED          */
+OP(ed,23) { illegal_2();                                            } /* DB   ED          */
+OP(ed,24) { TST( _H );                                                } /* TST  H           */
+OP(ed,25) { illegal_2();                                            } /* DB   ED          */
+OP(ed,26) { illegal_2();                                            } /* DB   ED          */
+OP(ed,27) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,28) { unsigned n = ARG(); _L = IN( n );                       } /* IN0  L,(n)       */
+OP(ed,29) { unsigned n = ARG(); OUT( n, _L );                       } /* OUT0 (n),L       */
+OP(ed,2a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,2b) { illegal_2();                                            } /* DB   ED          */
+OP(ed,2c) { TST( _L );                                                } /* TST  L           */
+OP(ed,2d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,2e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,2f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,30) { unsigned n = ARG(); IN( n );                          } /* IN0  (n)         */
+OP(ed,31) { unsigned n = ARG(); OUT( n, 0 );                      } /* OUT0 (n)         */
+OP(ed,32) { illegal_2();                                            } /* DB   ED          */
+OP(ed,33) { illegal_2();                                            } /* DB   ED          */
+OP(ed,34) { TST( RM(_HL) );                                         } /* TST  (HL)        */
+OP(ed,35) { illegal_2();                                            } /* DB   ED          */
+OP(ed,36) { illegal_2();                                            } /* DB   ED          */
+OP(ed,37) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,38) { unsigned n = ARG(); _A = IN( n );                       } /* IN0  A,(n)       */
+OP(ed,39) { unsigned n = ARG(); OUT( n, _A );                       } /* OUT0 (n),A       */
+OP(ed,3a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,3b) { illegal_2();                                            } /* DB   ED          */
+OP(ed,3c) { TST( _A );                                                } /* TST  A           */
+OP(ed,3d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,3e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,3f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,40) { _B = IN(_BC); _F = (_F & CF) | SZP[_B];                 } /* IN   B,(C)       */
+OP(ed,41) { OUT(_BC,_B);                                          } /* OUT  (C),B       */
+OP(ed,42) { SBC16( BC );                                            } /* SBC  HL,BC       */
+OP(ed,43) { m_ea = ARG16(); WM16( m_ea, &m_BC );                  } /* LD   (w),BC      */
+OP(ed,44) { NEG;                                                    } /* NEG              */
+OP(ed,45) { RETN;                                                   } /* RETN;            */
+OP(ed,46) { m_IM = 0;                                               } /* IM   0           */
+OP(ed,47) { LD_I_A;                                                 } /* LD   I,A         */
+
+OP(ed,48) { _C = IN(_BC); _F = (_F & CF) | SZP[_C];                 } /* IN   C,(C)       */
+OP(ed,49) { OUT(_BC,_C);                                          } /* OUT  (C),C       */
+OP(ed,4a) { ADC16( BC );                                            } /* ADC  HL,BC       */
+OP(ed,4b) { m_ea = ARG16(); RM16( m_ea, &m_BC );                  } /* LD   BC,(w)      */
+OP(ed,4c) { MLT( BC );                                              } /* MLT  BC          */
+OP(ed,4d) { RETI;                                                   } /* RETI             */
+OP(ed,4e) { m_IM = 0;                                               } /* IM   0           */
+OP(ed,4f) { LD_R_A;                                                 } /* LD   R,A         */
+
+OP(ed,50) { _D = IN(_BC); _F = (_F & CF) | SZP[_D];                 } /* IN   D,(C)       */
+OP(ed,51) { OUT(_BC,_D);                                          } /* OUT  (C),D       */
+OP(ed,52) { SBC16( DE );                                            } /* SBC  HL,DE       */
+OP(ed,53) { m_ea = ARG16(); WM16( m_ea, &m_DE );                  } /* LD   (w),DE      */
+OP(ed,54) { NEG;                                                    } /* NEG              */
+OP(ed,55) { RETN;                                                   } /* RETN;            */
+OP(ed,56) { m_IM = 1;                                               } /* IM   1           */
+OP(ed,57) { LD_A_I;                                                 } /* LD   A,I         */
+
+OP(ed,58) { _E = IN(_BC); _F = (_F & CF) | SZP[_E];                 } /* IN   E,(C)       */
+OP(ed,59) { OUT(_BC,_E);                                          } /* OUT  (C),E       */
+OP(ed,5a) { ADC16( DE );                                            } /* ADC  HL,DE       */
+OP(ed,5b) { m_ea = ARG16(); RM16( m_ea, &m_DE );                  } /* LD   DE,(w)      */
+OP(ed,5c) { MLT( DE );                                              } /* MLT  DE          */
+OP(ed,5d) { RETI;                                                   } /* RETI             */
+OP(ed,5e) { m_IM = 2;                                               } /* IM   2           */
+OP(ed,5f) { LD_A_R;                                                 } /* LD   A,R         */
+
+OP(ed,60) { _H = IN(_BC); _F = (_F & CF) | SZP[_H];                 } /* IN   H,(C)       */
+OP(ed,61) { OUT(_BC,_H);                                          } /* OUT  (C),H       */
+OP(ed,62) { SBC16( HL );                                            } /* SBC  HL,HL       */
+OP(ed,63) { m_ea = ARG16(); WM16( m_ea, &m_HL );                  } /* LD   (w),HL      */
+OP(ed,64) { unsigned m = ARG(); TST( m );                           } /* TST  m           */
+OP(ed,65) { RETN;                                                   } /* RETN;            */
+OP(ed,66) { m_IM = 0;                                               } /* IM   0           */
+OP(ed,67) { RRD;                                                    } /* RRD  (HL)        */
+
+OP(ed,68) { _L = IN(_BC); _F = (_F & CF) | SZP[_L];                 } /* IN   L,(C)       */
+OP(ed,69) { OUT(_BC,_L);                                          } /* OUT  (C),L       */
+OP(ed,6a) { ADC16( HL );                                            } /* ADC  HL,HL       */
+OP(ed,6b) { m_ea = ARG16(); RM16( m_ea, &m_HL );                  } /* LD   HL,(w)      */
+OP(ed,6c) { MLT( HL );                                              } /* MLT  HL          */
+OP(ed,6d) { RETI;                                                   } /* RETI             */
+OP(ed,6e) { m_IM = 0;                                               } /* IM   0           */
+OP(ed,6f) { RLD;                                                    } /* RLD  (HL)        */
+
+OP(ed,70) { uint8_t res = IN(_BC); _F = (_F & CF) | SZP[res];         } /* IN   0,(C)       */
+OP(ed,71) { OUT(_BC,0);                                             } /* OUT  (C),0       */
+OP(ed,72) { SBC16( SP );                                            } /* SBC  HL,SP       */
+OP(ed,73) { m_ea = ARG16(); WM16( m_ea, &m_SP );                  } /* LD   (w),SP      */
+OP(ed,74) { unsigned m = ARG(); _F = (_F & CF) | SZP[IN(_C) & m];   } /* TSTIO m          */
+OP(ed,75) { RETN;                                                   } /* RETN;            */
+OP(ed,76) { SLP;                                                    } /* SLP              */
+OP(ed,77) { illegal_2();                                            } /* DB   ED,77       */
+
+OP(ed,78) { _A = IN(_BC); _F = (_F & CF) | SZP[_A];                 } /* IN   E,(C)       */
+OP(ed,79) { OUT(_BC,_A);                                          } /* OUT  (C),E       */
+OP(ed,7a) { ADC16( SP );                                            } /* ADC  HL,SP       */
+OP(ed,7b) { m_ea = ARG16(); RM16( m_ea, &m_SP );                  } /* LD   SP,(w)      */
+OP(ed,7c) { MLT( SP );                                              } /* MLT  SP          */
+OP(ed,7d) { RETI;                                                   } /* RETI             */
+OP(ed,7e) { m_IM = 2;                                               } /* IM   2           */
+OP(ed,7f) { illegal_2();                                            } /* DB   ED,7F       */
+
+OP(ed,80) { illegal_2();                                            } /* DB   ED          */
+OP(ed,81) { illegal_2();                                            } /* DB   ED          */
+OP(ed,82) { illegal_2();                                            } /* DB   ED          */
+OP(ed,83) { OTIM;                                                   } /* OTIM             */
+OP(ed,84) { illegal_2();                                            } /* DB   ED          */
+OP(ed,85) { illegal_2();                                            } /* DB   ED          */
+OP(ed,86) { illegal_2();                                            } /* DB   ED          */
+OP(ed,87) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,88) { illegal_2();                                            } /* DB   ED          */
+OP(ed,89) { illegal_2();                                            } /* DB   ED          */
+OP(ed,8a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,8b) { OTDM;                                                   } /* OTDM             */
+OP(ed,8c) { illegal_2();                                            } /* DB   ED          */
+OP(ed,8d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,8e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,8f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,90) { illegal_2();                                            } /* DB   ED          */
+OP(ed,91) { illegal_2();                                            } /* DB   ED          */
+OP(ed,92) { illegal_2();                                            } /* DB   ED          */
+OP(ed,93) { OTIMR;                                                  } /* OTIMR            */
+OP(ed,94) { illegal_2();                                            } /* DB   ED          */
+OP(ed,95) { illegal_2();                                            } /* DB   ED          */
+OP(ed,96) { illegal_2();                                            } /* DB   ED          */
+OP(ed,97) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,98) { illegal_2();                                            } /* DB   ED          */
+OP(ed,99) { illegal_2();                                            } /* DB   ED          */
+OP(ed,9a) { illegal_2();                                            } /* DB   ED          */
+OP(ed,9b) { OTDMR;                                                  } /* OTDMR            */
+OP(ed,9c) { illegal_2();                                            } /* DB   ED          */
+OP(ed,9d) { illegal_2();                                            } /* DB   ED          */
+OP(ed,9e) { illegal_2();                                            } /* DB   ED          */
+OP(ed,9f) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,a0) { LDI;                                                    } /* LDI              */
+OP(ed,a1) { CPI;                                                    } /* CPI              */
+OP(ed,a2) { INI;                                                    } /* INI              */
+OP(ed,a3) { OUTI;                                                   } /* OUTI             */
+OP(ed,a4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,a5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,a6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,a7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,a8) { LDD;                                                    } /* LDD              */
+OP(ed,a9) { CPD;                                                    } /* CPD              */
+OP(ed,aa) { IND;                                                    } /* IND              */
+OP(ed,ab) { OUTD;                                                   } /* OUTD             */
+OP(ed,ac) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ad) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ae) { illegal_2();                                            } /* DB   ED          */
+OP(ed,af) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,b0) { LDIR;                                                   } /* LDIR             */
+OP(ed,b1) { CPIR;                                                   } /* CPIR             */
+OP(ed,b2) { INIR;                                                   } /* INIR             */
+OP(ed,b3) { OTIR;                                                   } /* OTIR             */
+OP(ed,b4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,b5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,b6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,b7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,b8) { LDDR;                                                   } /* LDDR             */
+OP(ed,b9) { CPDR;                                                   } /* CPDR             */
+OP(ed,ba) { INDR;                                                   } /* INDR             */
+OP(ed,bb) { OTDR;                                                   } /* OTDR             */
+OP(ed,bc) { illegal_2();                                            } /* DB   ED          */
+OP(ed,bd) { illegal_2();                                            } /* DB   ED          */
+OP(ed,be) { illegal_2();                                            } /* DB   ED          */
+OP(ed,bf) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,c0) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c1) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c2) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c3) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,c8) { illegal_2();                                            } /* DB   ED          */
+OP(ed,c9) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ca) { illegal_2();                                            } /* DB   ED          */
+OP(ed,cb) { illegal_2();                                            } /* DB   ED          */
+OP(ed,cc) { illegal_2();                                            } /* DB   ED          */
+OP(ed,cd) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ce) { illegal_2();                                            } /* DB   ED          */
+OP(ed,cf) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,d0) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d1) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d2) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d3) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,d8) { illegal_2();                                            } /* DB   ED          */
+OP(ed,d9) { illegal_2();                                            } /* DB   ED          */
+OP(ed,da) { illegal_2();                                            } /* DB   ED          */
+OP(ed,db) { illegal_2();                                            } /* DB   ED          */
+OP(ed,dc) { illegal_2();                                            } /* DB   ED          */
+OP(ed,dd) { illegal_2();                                            } /* DB   ED          */
+OP(ed,de) { illegal_2();                                            } /* DB   ED          */
+OP(ed,df) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,e0) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e1) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e2) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e3) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,e8) { illegal_2();                                            } /* DB   ED          */
+OP(ed,e9) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ea) { illegal_2();                                            } /* DB   ED          */
+OP(ed,eb) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ec) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ed) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ee) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ef) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,f0) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f1) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f2) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f3) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f4) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f5) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f6) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f7) { illegal_2();                                            } /* DB   ED          */
+
+OP(ed,f8) { illegal_2();                                            } /* DB   ED          */
+OP(ed,f9) { illegal_2();                                            } /* DB   ED          */
+OP(ed,fa) { illegal_2();                                            } /* DB   ED          */
+OP(ed,fb) { illegal_2();                                            } /* DB   ED          */
+OP(ed,fc) { illegal_2();                                            } /* DB   ED          */
+OP(ed,fd) { illegal_2();                                            } /* DB   ED          */
+OP(ed,fe) { illegal_2();                                            } /* DB   ED          */
+OP(ed,ff) { illegal_2();                                            } /* DB   ED          */
diff --git a/z180/z180fd.hxx b/z180/z180fd.hxx
new file mode 100644 (file)
index 0000000..66697a9
--- /dev/null
@@ -0,0 +1,292 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/**********************************************************
+ * IY register related opcodes (FD prefix)
+ **********************************************************/
+OP(fd,00) { illegal_1(); op_00();                                   } /* DB   FD          */
+OP(fd,01) { illegal_1(); op_01();                                   } /* DB   FD          */
+OP(fd,02) { illegal_1(); op_02();                                   } /* DB   FD          */
+OP(fd,03) { illegal_1(); op_03();                                   } /* DB   FD          */
+OP(fd,04) { illegal_1(); op_04();                                   } /* DB   FD          */
+OP(fd,05) { illegal_1(); op_05();                                   } /* DB   FD          */
+OP(fd,06) { illegal_1(); op_06();                                   } /* DB   FD          */
+OP(fd,07) { illegal_1(); op_07();                                   } /* DB   FD          */
+
+OP(fd,08) { illegal_1(); op_08();                                   } /* DB   FD          */
+OP(fd,09) { m_R++; ADD16(IY,BC);                                    } /* ADD  IY,BC       */
+OP(fd,0a) { illegal_1(); op_0a();                                   } /* DB   FD          */
+OP(fd,0b) { illegal_1(); op_0b();                                   } /* DB   FD          */
+OP(fd,0c) { illegal_1(); op_0c();                                   } /* DB   FD          */
+OP(fd,0d) { illegal_1(); op_0d();                                   } /* DB   FD          */
+OP(fd,0e) { illegal_1(); op_0e();                                   } /* DB   FD          */
+OP(fd,0f) { illegal_1(); op_0f();                                   } /* DB   FD          */
+
+OP(fd,10) { illegal_1(); op_10();                                   } /* DB   FD          */
+OP(fd,11) { illegal_1(); op_11();                                   } /* DB   FD          */
+OP(fd,12) { illegal_1(); op_12();                                   } /* DB   FD          */
+OP(fd,13) { illegal_1(); op_13();                                   } /* DB   FD          */
+OP(fd,14) { illegal_1(); op_14();                                   } /* DB   FD          */
+OP(fd,15) { illegal_1(); op_15();                                   } /* DB   FD          */
+OP(fd,16) { illegal_1(); op_16();                                   } /* DB   FD          */
+OP(fd,17) { illegal_1(); op_17();                                   } /* DB   FD          */
+
+OP(fd,18) { illegal_1(); op_18();                                   } /* DB   FD          */
+OP(fd,19) { m_R++; ADD16(IY,DE);                                    } /* ADD  IY,DE       */
+OP(fd,1a) { illegal_1(); op_1a();                                   } /* DB   FD          */
+OP(fd,1b) { illegal_1(); op_1b();                                   } /* DB   FD          */
+OP(fd,1c) { illegal_1(); op_1c();                                   } /* DB   FD          */
+OP(fd,1d) { illegal_1(); op_1d();                                   } /* DB   FD          */
+OP(fd,1e) { illegal_1(); op_1e();                                   } /* DB   FD          */
+OP(fd,1f) { illegal_1(); op_1f();                                   } /* DB   FD          */
+
+OP(fd,20) { illegal_1(); op_20();                                   } /* DB   FD          */
+OP(fd,21) { m_R++; _IY = ARG16();                                 } /* LD   IY,w        */
+OP(fd,22) { m_R++; m_ea = ARG16(); WM16( m_ea, &m_IY );               } /* LD   (w),IY      */
+OP(fd,23) { m_R++; _IY++;                                         } /* INC  IY          */
+OP(fd,24) { m_R++; _HY = INC(_HY);                                    } /* INC  HY          */
+OP(fd,25) { m_R++; _HY = DEC(_HY);                                    } /* DEC  HY          */
+OP(fd,26) { m_R++; _HY = ARG();                                       } /* LD   HY,n        */
+OP(fd,27) { illegal_1(); op_27();                                   } /* DB   FD          */
+
+OP(fd,28) { illegal_1(); op_28();                                   } /* DB   FD          */
+OP(fd,29) { m_R++; ADD16(IY,IY);                                    } /* ADD  IY,IY       */
+OP(fd,2a) { m_R++; m_ea = ARG16(); RM16( m_ea, &m_IY );               } /* LD   IY,(w)      */
+OP(fd,2b) { m_R++; _IY--;                                         } /* DEC  IY          */
+OP(fd,2c) { m_R++; _LY = INC(_LY);                                    } /* INC  LY          */
+OP(fd,2d) { m_R++; _LY = DEC(_LY);                                    } /* DEC  LY          */
+OP(fd,2e) { m_R++; _LY = ARG();                                       } /* LD   LY,n        */
+OP(fd,2f) { illegal_1(); op_2f();                                   } /* DB   FD          */
+
+OP(fd,30) { illegal_1(); op_30();                                   } /* DB   FD          */
+OP(fd,31) { illegal_1(); op_31();                                   } /* DB   FD          */
+OP(fd,32) { illegal_1(); op_32();                                   } /* DB   FD          */
+OP(fd,33) { illegal_1(); op_33();                                   } /* DB   FD          */
+OP(fd,34) { m_R++; EAY(); WM( m_ea, INC(RM(m_ea)) );                      } /* INC  (IY+o)      */
+OP(fd,35) { m_R++; EAY(); WM( m_ea, DEC(RM(m_ea)) );                      } /* DEC  (IY+o)      */
+OP(fd,36) { m_R++; EAY(); WM( m_ea, ARG() );                          } /* LD   (IY+o),n    */
+OP(fd,37) { illegal_1(); op_37();                                   } /* DB   FD          */
+
+OP(fd,38) { illegal_1(); op_38();                                   } /* DB   FD          */
+OP(fd,39) { m_R++; ADD16(IY,SP);                                    } /* ADD  IY,SP       */
+OP(fd,3a) { illegal_1(); op_3a();                                   } /* DB   FD          */
+OP(fd,3b) { illegal_1(); op_3b();                                   } /* DB   FD          */
+OP(fd,3c) { illegal_1(); op_3c();                                   } /* DB   FD          */
+OP(fd,3d) { illegal_1(); op_3d();                                   } /* DB   FD          */
+OP(fd,3e) { illegal_1(); op_3e();                                   } /* DB   FD          */
+OP(fd,3f) { illegal_1(); op_3f();                                   } /* DB   FD          */
+
+OP(fd,40) { illegal_1(); op_40();                                   } /* DB   FD          */
+OP(fd,41) { illegal_1(); op_41();                                   } /* DB   FD          */
+OP(fd,42) { illegal_1(); op_42();                                   } /* DB   FD          */
+OP(fd,43) { illegal_1(); op_43();                                   } /* DB   FD          */
+OP(fd,44) { m_R++; _B = _HY;                                        } /* LD   B,HY        */
+OP(fd,45) { m_R++; _B = _LY;                                        } /* LD   B,LY        */
+OP(fd,46) { m_R++; EAY(); _B = RM(m_ea);                                } /* LD   B,(IY+o)    */
+OP(fd,47) { illegal_1(); op_47();                                   } /* DB   FD          */
+
+OP(fd,48) { illegal_1(); op_48();                                   } /* DB   FD          */
+OP(fd,49) { illegal_1(); op_49();                                   } /* DB   FD          */
+OP(fd,4a) { illegal_1(); op_4a();                                   } /* DB   FD          */
+OP(fd,4b) { illegal_1(); op_4b();                                   } /* DB   FD          */
+OP(fd,4c) { m_R++; _C = _HY;                                        } /* LD   C,HY        */
+OP(fd,4d) { m_R++; _C = _LY;                                        } /* LD   C,LY        */
+OP(fd,4e) { m_R++; EAY(); _C = RM(m_ea);                                } /* LD   C,(IY+o)    */
+OP(fd,4f) { illegal_1(); op_4f();                                   } /* DB   FD          */
+
+OP(fd,50) { illegal_1(); op_50();                                   } /* DB   FD          */
+OP(fd,51) { illegal_1(); op_51();                                   } /* DB   FD          */
+OP(fd,52) { illegal_1(); op_52();                                   } /* DB   FD          */
+OP(fd,53) { illegal_1(); op_53();                                   } /* DB   FD          */
+OP(fd,54) { m_R++; _D = _HY;                                        } /* LD   D,HY        */
+OP(fd,55) { m_R++; _D = _LY;                                        } /* LD   D,LY        */
+OP(fd,56) { m_R++; EAY(); _D = RM(m_ea);                                } /* LD   D,(IY+o)    */
+OP(fd,57) { illegal_1(); op_57();                                   } /* DB   FD          */
+
+OP(fd,58) { illegal_1(); op_58();                                   } /* DB   FD          */
+OP(fd,59) { illegal_1(); op_59();                                   } /* DB   FD          */
+OP(fd,5a) { illegal_1(); op_5a();                                   } /* DB   FD          */
+OP(fd,5b) { illegal_1(); op_5b();                                   } /* DB   FD          */
+OP(fd,5c) { m_R++; _E = _HY;                                        } /* LD   E,HY        */
+OP(fd,5d) { m_R++; _E = _LY;                                        } /* LD   E,LY        */
+OP(fd,5e) { m_R++; EAY(); _E = RM(m_ea);                                } /* LD   E,(IY+o)    */
+OP(fd,5f) { illegal_1(); op_5f();                                   } /* DB   FD          */
+
+OP(fd,60) { m_R++; _HY = _B;                                        } /* LD   HY,B        */
+OP(fd,61) { m_R++; _HY = _C;                                        } /* LD   HY,C        */
+OP(fd,62) { m_R++; _HY = _D;                                        } /* LD   HY,D        */
+OP(fd,63) { m_R++; _HY = _E;                                        } /* LD   HY,E        */
+OP(fd,64) { m_R++;                                                  } /* LD   HY,HY       */
+OP(fd,65) { m_R++; _HY = _LY;                                       } /* LD   HY,LY       */
+OP(fd,66) { m_R++; EAY(); _H = RM(m_ea);                                } /* LD   H,(IY+o)    */
+OP(fd,67) { m_R++; _HY = _A;                                        } /* LD   HY,A        */
+
+OP(fd,68) { m_R++; _LY = _B;                                        } /* LD   LY,B        */
+OP(fd,69) { m_R++; _LY = _C;                                        } /* LD   LY,C        */
+OP(fd,6a) { m_R++; _LY = _D;                                        } /* LD   LY,D        */
+OP(fd,6b) { m_R++; _LY = _E;                                        } /* LD   LY,E        */
+OP(fd,6c) { m_R++; _LY = _HY;                                       } /* LD   LY,HY       */
+OP(fd,6d) { m_R++;                                                  } /* LD   LY,LY       */
+OP(fd,6e) { m_R++; EAY(); _L = RM(m_ea);                                } /* LD   L,(IY+o)    */
+OP(fd,6f) { m_R++; _LY = _A;                                        } /* LD   LY,A        */
+
+OP(fd,70) { m_R++; EAY(); WM( m_ea, _B );                               } /* LD   (IY+o),B    */
+OP(fd,71) { m_R++; EAY(); WM( m_ea, _C );                               } /* LD   (IY+o),C    */
+OP(fd,72) { m_R++; EAY(); WM( m_ea, _D );                               } /* LD   (IY+o),D    */
+OP(fd,73) { m_R++; EAY(); WM( m_ea, _E );                               } /* LD   (IY+o),E    */
+OP(fd,74) { m_R++; EAY(); WM( m_ea, _H );                               } /* LD   (IY+o),H    */
+OP(fd,75) { m_R++; EAY(); WM( m_ea, _L );                               } /* LD   (IY+o),L    */
+OP(fd,76) { illegal_1(); op_76();                                   }         /* DB   FD          */
+OP(fd,77) { m_R++; EAY(); WM( m_ea, _A );                               } /* LD   (IY+o),A    */
+
+OP(fd,78) { illegal_1(); op_78();                                   } /* DB   FD          */
+OP(fd,79) { illegal_1(); op_79();                                   } /* DB   FD          */
+OP(fd,7a) { illegal_1(); op_7a();                                   } /* DB   FD          */
+OP(fd,7b) { illegal_1(); op_7b();                                   } /* DB   FD          */
+OP(fd,7c) { m_R++; _A = _HY;                                        } /* LD   A,HY        */
+OP(fd,7d) { m_R++; _A = _LY;                                        } /* LD   A,LY        */
+OP(fd,7e) { m_R++; EAY(); _A = RM(m_ea);                                } /* LD   A,(IY+o)    */
+OP(fd,7f) { illegal_1(); op_7f();                                   } /* DB   FD          */
+
+OP(fd,80) { illegal_1(); op_80();                                   } /* DB   FD          */
+OP(fd,81) { illegal_1(); op_81();                                   } /* DB   FD          */
+OP(fd,82) { illegal_1(); op_82();                                   } /* DB   FD          */
+OP(fd,83) { illegal_1(); op_83();                                   } /* DB   FD          */
+OP(fd,84) { m_R++; ADD(_HY);                                      } /* ADD  A,HY        */
+OP(fd,85) { m_R++; ADD(_LY);                                      } /* ADD  A,LY        */
+OP(fd,86) { m_R++; EAY(); ADD(RM(m_ea));                              } /* ADD  A,(IY+o)    */
+OP(fd,87) { illegal_1(); op_87();                                   } /* DB   FD          */
+
+OP(fd,88) { illegal_1(); op_88();                                   } /* DB   FD          */
+OP(fd,89) { illegal_1(); op_89();                                   } /* DB   FD          */
+OP(fd,8a) { illegal_1(); op_8a();                                   } /* DB   FD          */
+OP(fd,8b) { illegal_1(); op_8b();                                   } /* DB   FD          */
+OP(fd,8c) { m_R++; ADC(_HY);                                      } /* ADC  A,HY        */
+OP(fd,8d) { m_R++; ADC(_LY);                                      } /* ADC  A,LY        */
+OP(fd,8e) { m_R++; EAY(); ADC(RM(m_ea));                              } /* ADC  A,(IY+o)    */
+OP(fd,8f) { illegal_1(); op_8f();                                   } /* DB   FD          */
+
+OP(fd,90) { illegal_1(); op_90();                                   } /* DB   FD          */
+OP(fd,91) { illegal_1(); op_91();                                   } /* DB   FD          */
+OP(fd,92) { illegal_1(); op_92();                                   } /* DB   FD          */
+OP(fd,93) { illegal_1(); op_93();                                   } /* DB   FD          */
+OP(fd,94) { m_R++; SUB(_HY);                                      } /* SUB  HY          */
+OP(fd,95) { m_R++; SUB(_LY);                                      } /* SUB  LY          */
+OP(fd,96) { m_R++; EAY(); SUB(RM(m_ea));                              } /* SUB  (IY+o)      */
+OP(fd,97) { illegal_1(); op_97();                                   } /* DB   FD          */
+
+OP(fd,98) { illegal_1(); op_98();                                   } /* DB   FD          */
+OP(fd,99) { illegal_1(); op_99();                                   } /* DB   FD          */
+OP(fd,9a) { illegal_1(); op_9a();                                   } /* DB   FD          */
+OP(fd,9b) { illegal_1(); op_9b();                                   } /* DB   FD          */
+OP(fd,9c) { m_R++; SBC(_HY);                                      } /* SBC  A,HY        */
+OP(fd,9d) { m_R++; SBC(_LY);                                      } /* SBC  A,LY        */
+OP(fd,9e) { m_R++; EAY(); SBC(RM(m_ea));                              } /* SBC  A,(IY+o)    */
+OP(fd,9f) { illegal_1(); op_9f();                                   } /* DB   FD          */
+
+OP(fd,a0) { illegal_1(); op_a0();                                   } /* DB   FD          */
+OP(fd,a1) { illegal_1(); op_a1();                                   } /* DB   FD          */
+OP(fd,a2) { illegal_1(); op_a2();                                   } /* DB   FD          */
+OP(fd,a3) { illegal_1(); op_a3();                                   } /* DB   FD          */
+OP(fd,a4) { m_R++; AND(_HY);                                      } /* AND  HY          */
+OP(fd,a5) { m_R++; AND(_LY);                                      } /* AND  LY          */
+OP(fd,a6) { m_R++; EAY(); AND(RM(m_ea));                              } /* AND  (IY+o)      */
+OP(fd,a7) { illegal_1(); op_a7();                                   } /* DB   FD          */
+
+OP(fd,a8) { illegal_1(); op_a8();                                   } /* DB   FD          */
+OP(fd,a9) { illegal_1(); op_a9();                                   } /* DB   FD          */
+OP(fd,aa) { illegal_1(); op_aa();                                   } /* DB   FD          */
+OP(fd,ab) { illegal_1(); op_ab();                                   } /* DB   FD          */
+OP(fd,ac) { m_R++; XOR(_HY);                                      } /* XOR  HY          */
+OP(fd,ad) { m_R++; XOR(_LY);                                      } /* XOR  LY          */
+OP(fd,ae) { m_R++; EAY(); XOR(RM(m_ea));                              } /* XOR  (IY+o)      */
+OP(fd,af) { illegal_1(); op_af();                                   } /* DB   FD          */
+
+OP(fd,b0) { illegal_1(); op_b0();                                   } /* DB   FD          */
+OP(fd,b1) { illegal_1(); op_b1();                                   } /* DB   FD          */
+OP(fd,b2) { illegal_1(); op_b2();                                   } /* DB   FD          */
+OP(fd,b3) { illegal_1(); op_b3();                                   } /* DB   FD          */
+OP(fd,b4) { m_R++; OR(_HY);                                           } /* OR   HY          */
+OP(fd,b5) { m_R++; OR(_LY);                                           } /* OR   LY          */
+OP(fd,b6) { m_R++; EAY(); OR(RM(m_ea));                                   } /* OR   (IY+o)      */
+OP(fd,b7) { illegal_1(); op_b7();                                   } /* DB   FD          */
+
+OP(fd,b8) { illegal_1(); op_b8();                                   } /* DB   FD          */
+OP(fd,b9) { illegal_1(); op_b9();                                   } /* DB   FD          */
+OP(fd,ba) { illegal_1(); op_ba();                                   } /* DB   FD          */
+OP(fd,bb) { illegal_1(); op_bb();                                   } /* DB   FD          */
+OP(fd,bc) { m_R++; CP(_HY);                                           } /* CP   HY          */
+OP(fd,bd) { m_R++; CP(_LY);                                           } /* CP   LY          */
+OP(fd,be) { m_R++; EAY(); CP(RM(m_ea));                                   } /* CP   (IY+o)      */
+OP(fd,bf) { illegal_1(); op_bf();                                   } /* DB   FD          */
+
+OP(fd,c0) { illegal_1(); op_c0();                                   } /* DB   FD          */
+OP(fd,c1) { illegal_1(); op_c1();                                   } /* DB   FD          */
+OP(fd,c2) { illegal_1(); op_c2();                                   } /* DB   FD          */
+OP(fd,c3) { illegal_1(); op_c3();                                   } /* DB   FD          */
+OP(fd,c4) { illegal_1(); op_c4();                                   } /* DB   FD          */
+OP(fd,c5) { illegal_1(); op_c5();                                   } /* DB   FD          */
+OP(fd,c6) { illegal_1(); op_c6();                                   } /* DB   FD          */
+OP(fd,c7) { illegal_1(); op_c7();                                   } /* DB   FD          */
+
+OP(fd,c8) { illegal_1(); op_c8();                                   } /* DB   FD          */
+OP(fd,c9) { illegal_1(); op_c9();                                   } /* DB   FD          */
+OP(fd,ca) { illegal_1(); op_ca();                                   } /* DB   FD          */
+OP(fd,cb) { m_R++; EAY(); m_extra_cycles += exec_xycb(ARG());                          } /* **   FD CB xx    */
+OP(fd,cc) { illegal_1(); op_cc();                                   } /* DB   FD          */
+OP(fd,cd) { illegal_1(); op_cd();                                   } /* DB   FD          */
+OP(fd,ce) { illegal_1(); op_ce();                                   } /* DB   FD          */
+OP(fd,cf) { illegal_1(); op_cf();                                   } /* DB   FD          */
+
+OP(fd,d0) { illegal_1(); op_d0();                                   } /* DB   FD          */
+OP(fd,d1) { illegal_1(); op_d1();                                   } /* DB   FD          */
+OP(fd,d2) { illegal_1(); op_d2();                                   } /* DB   FD          */
+OP(fd,d3) { illegal_1(); op_d3();                                   } /* DB   FD          */
+OP(fd,d4) { illegal_1(); op_d4();                                   } /* DB   FD          */
+OP(fd,d5) { illegal_1(); op_d5();                                   } /* DB   FD          */
+OP(fd,d6) { illegal_1(); op_d6();                                   } /* DB   FD          */
+OP(fd,d7) { illegal_1(); op_d7();                                   } /* DB   FD          */
+
+OP(fd,d8) { illegal_1(); op_d8();                                   } /* DB   FD          */
+OP(fd,d9) { illegal_1(); op_d9();                                   } /* DB   FD          */
+OP(fd,da) { illegal_1(); op_da();                                   } /* DB   FD          */
+OP(fd,db) { illegal_1(); op_db();                                   } /* DB   FD          */
+OP(fd,dc) { illegal_1(); op_dc();                                   } /* DB   FD          */
+OP(fd,dd) { illegal_1(); op_dd();                                   } /* DB   FD          */
+OP(fd,de) { illegal_1(); op_de();                                   } /* DB   FD          */
+OP(fd,df) { illegal_1(); op_df();                                   } /* DB   FD          */
+
+OP(fd,e0) { illegal_1(); op_e0();                                   } /* DB   FD          */
+OP(fd,e1) { m_R++; POP(IY);                                           } /* POP  IY          */
+OP(fd,e2) { illegal_1(); op_e2();                                   } /* DB   FD          */
+OP(fd,e3) { m_R++; EXSP(IY);                                        } /* EX   (SP),IY     */
+OP(fd,e4) { illegal_1(); op_e4();                                   } /* DB   FD          */
+OP(fd,e5) { m_R++; PUSH( IY );                                        } /* PUSH IY          */
+OP(fd,e6) { illegal_1(); op_e6();                                   } /* DB   FD          */
+OP(fd,e7) { illegal_1(); op_e7();                                   } /* DB   FD          */
+
+OP(fd,e8) { illegal_1(); op_e8();                                   } /* DB   FD          */
+OP(fd,e9) { m_R++; _PC = _IY;                                       } /* JP   (IY)        */
+OP(fd,ea) { illegal_1(); op_ea();                                   } /* DB   FD          */
+OP(fd,eb) { illegal_1(); op_eb();                                   } /* DB   FD          */
+OP(fd,ec) { illegal_1(); op_ec();                                   } /* DB   FD          */
+OP(fd,ed) { illegal_1(); op_ed();                                   } /* DB   FD          */
+OP(fd,ee) { illegal_1(); op_ee();                                   } /* DB   FD          */
+OP(fd,ef) { illegal_1(); op_ef();                                   } /* DB   FD          */
+
+OP(fd,f0) { illegal_1(); op_f0();                                   } /* DB   FD          */
+OP(fd,f1) { illegal_1(); op_f1();                                   } /* DB   FD          */
+OP(fd,f2) { illegal_1(); op_f2();                                   } /* DB   FD          */
+OP(fd,f3) { illegal_1(); op_f3();                                   } /* DB   FD          */
+OP(fd,f4) { illegal_1(); op_f4();                                   } /* DB   FD          */
+OP(fd,f5) { illegal_1(); op_f5();                                   } /* DB   FD          */
+OP(fd,f6) { illegal_1(); op_f6();                                   } /* DB   FD          */
+OP(fd,f7) { illegal_1(); op_f7();                                   } /* DB   FD          */
+
+OP(fd,f8) { illegal_1(); op_f8();                                   } /* DB   FD          */
+OP(fd,f9) { m_R++; _SP = _IY;                                       } /* LD   SP,IY       */
+OP(fd,fa) { illegal_1(); op_fa();                                   } /* DB   FD          */
+OP(fd,fb) { illegal_1(); op_fb();                                   } /* DB   FD          */
+OP(fd,fc) { illegal_1(); op_fc();                                   } /* DB   FD          */
+OP(fd,fd) { illegal_1(); op_fd();                                   } /* DB   FD          */
+OP(fd,fe) { illegal_1(); op_fe();                                   } /* DB   FD          */
+OP(fd,ff) { illegal_1(); op_ff();                                   } /* DB   FD          */
diff --git a/z180/z180op.hxx b/z180/z180op.hxx
new file mode 100644 (file)
index 0000000..e29d867
--- /dev/null
@@ -0,0 +1,375 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/**********************************************************
+ * main opcodes
+ **********************************************************/
+OP(op,00) {                                                         } /* NOP              */
+OP(op,01) { _BC = ARG16();                                            } /* LD   BC,w        */
+OP(op,02) { WM( _BC, _A );                                            } /* LD   (BC),A      */
+OP(op,03) { _BC++;                                                    } /* INC  BC          */
+OP(op,04) { _B = INC(_B);                                         } /* INC  B           */
+OP(op,05) { _B = DEC(_B);                                         } /* DEC  B           */
+OP(op,06) { _B = ARG();                                           } /* LD   B,n         */
+OP(op,07) { RLCA;                                                   } /* RLCA             */
+
+OP(op,08) { EX_AF;                                                  } /* EX   AF,AF'      */
+OP(op,09) { ADD16(HL,BC);                                           } /* ADD  HL,BC       */
+OP(op,0a) { _A = RM(_BC);                                         } /* LD   A,(BC)      */
+OP(op,0b) { _BC--;                                                    } /* DEC  BC          */
+OP(op,0c) { _C = INC(_C);                                         } /* INC  C           */
+OP(op,0d) { _C = DEC(_C);                                         } /* DEC  C           */
+OP(op,0e) { _C = ARG();                                           } /* LD   C,n         */
+OP(op,0f) { RRCA;                                                   } /* RRCA             */
+
+OP(op,10) { _B--; JR_COND( _B, 0x10 );                              } /* DJNZ o           */
+OP(op,11) { _DE = ARG16();                                            } /* LD   DE,w        */
+OP(op,12) { WM( _DE, _A );                                            } /* LD   (DE),A      */
+OP(op,13) { _DE++;                                                    } /* INC  DE          */
+OP(op,14) { _D = INC(_D);                                         } /* INC  D           */
+OP(op,15) { _D = DEC(_D);                                         } /* DEC  D           */
+OP(op,16) { _D = ARG();                                           } /* LD   D,n         */
+OP(op,17) { RLA;                                                    } /* RLA              */
+
+OP(op,18) { JR();                                                   } /* JR   o           */
+OP(op,19) { ADD16(HL,DE);                                           } /* ADD  HL,DE       */
+OP(op,1a) { _A = RM(_DE);                                         } /* LD   A,(DE)      */
+OP(op,1b) { _DE--;                ;                                   } /* DEC  DE          */
+OP(op,1c) { _E = INC(_E);                                         } /* INC  E           */
+OP(op,1d) { _E = DEC(_E);                                         } /* DEC  E           */
+OP(op,1e) { _E = ARG();                                           } /* LD   E,n         */
+OP(op,1f) { RRA;                                                    } /* RRA              */
+
+OP(op,20) { JR_COND( !(_F & ZF), 0x20 );                          } /* JR   NZ,o        */
+OP(op,21) { _HL = ARG16();                                            } /* LD   HL,w        */
+OP(op,22) { m_ea = ARG16(); WM16(m_ea, &m_HL );                   } /* LD   (w),HL      */
+OP(op,23) { _HL++;                                                    } /* INC  HL          */
+OP(op,24) { _H = INC(_H);                                         } /* INC  H           */
+OP(op,25) { _H = DEC(_H);                                         } /* DEC  H           */
+OP(op,26) { _H = ARG();                                           } /* LD   H,n         */
+OP(op,27) { DAA;                                                    } /* DAA              */
+
+OP(op,28) { JR_COND( _F & ZF, 0x28 );                             } /* JR   Z,o         */
+OP(op,29) { ADD16(HL,HL);                                           } /* ADD  HL,HL       */
+OP(op,2a) { m_ea = ARG16(); RM16(m_ea, &m_HL );                   } /* LD   HL,(w)      */
+OP(op,2b) { _HL--;                                                    } /* DEC  HL          */
+OP(op,2c) { _L = INC(_L);                                         } /* INC  L           */
+OP(op,2d) { _L = DEC(_L);                                         } /* DEC  L           */
+OP(op,2e) { _L = ARG();                                           } /* LD   L,n         */
+OP(op,2f) { _A ^= 0xff; _F = (_F&(SF|ZF|PF|CF))|HF|NF|(_A&(YF|XF)); } /* CPL              */
+
+OP(op,30) { JR_COND( !(_F & CF), 0x30 );                          } /* JR   NC,o        */
+OP(op,31) { _SP = ARG16();                                            } /* LD   SP,w        */
+OP(op,32) { m_ea = ARG16(); WM( m_ea, _A );                             } /* LD   (w),A       */
+OP(op,33) { _SP++;                                                    } /* INC  SP          */
+OP(op,34) { WM( _HL, INC(RM(_HL)) );                              } /* INC  (HL)        */
+OP(op,35) { WM( _HL, DEC(RM(_HL)) );                              } /* DEC  (HL)        */
+OP(op,36) { WM( _HL, ARG() );                                       } /* LD   (HL),n      */
+OP(op,37) { _F = (_F & (SF|ZF|PF)) | CF | (_A & (YF|XF));         } /* SCF              */
+
+OP(op,38) { JR_COND( _F & CF, 0x38 );                             } /* JR   C,o         */
+OP(op,39) { ADD16(HL,SP);                                           } /* ADD  HL,SP       */
+OP(op,3a) { m_ea = ARG16(); _A = RM( m_ea );                            } /* LD   A,(w)       */
+OP(op,3b) { _SP--;                                                    } /* DEC  SP          */
+OP(op,3c) { _A = INC(_A);                                         } /* INC  A           */
+OP(op,3d) { _A = DEC(_A);                                         } /* DEC  A           */
+OP(op,3e) { _A = ARG();                                           } /* LD   A,n         */
+OP(op,3f) { _F = ((_F&(SF|ZF|PF|CF))|((_F&CF)<<4)|(_A&(YF|XF)))^CF; } /* CCF              */
+//OP(op,3f) { _F = ((_F & ~(HF|NF)) | ((_F & CF)<<4)) ^ CF;           } /* CCF              */
+
+OP(op,40) {                                                         } /* LD   B,B         */
+OP(op,41) { _B = _C;                                                } /* LD   B,C         */
+OP(op,42) { _B = _D;                                                } /* LD   B,D         */
+OP(op,43) { _B = _E;                                                } /* LD   B,E         */
+OP(op,44) { _B = _H;                                                } /* LD   B,H         */
+OP(op,45) { _B = _L;                                                } /* LD   B,L         */
+OP(op,46) { _B = RM(_HL);                                         } /* LD   B,(HL)      */
+OP(op,47) { _B = _A;                                                } /* LD   B,A         */
+
+OP(op,48) { _C = _B;                                                } /* LD   C,B         */
+OP(op,49) {                                                         } /* LD   C,C         */
+OP(op,4a) { _C = _D;                                                } /* LD   C,D         */
+OP(op,4b) { _C = _E;                                                } /* LD   C,E         */
+OP(op,4c) { _C = _H;                                                } /* LD   C,H         */
+OP(op,4d) { _C = _L;                                                } /* LD   C,L         */
+OP(op,4e) { _C = RM(_HL);                                         } /* LD   C,(HL)      */
+OP(op,4f) { _C = _A;                                                } /* LD   C,A         */
+
+OP(op,50) { _D = _B;                                                } /* LD   D,B         */
+OP(op,51) { _D = _C;                                                } /* LD   D,C         */
+OP(op,52) {                                                         } /* LD   D,D         */
+OP(op,53) { _D = _E;                                                } /* LD   D,E         */
+OP(op,54) { _D = _H;                                                } /* LD   D,H         */
+OP(op,55) { _D = _L;                                                } /* LD   D,L         */
+OP(op,56) { _D = RM(_HL);                                         } /* LD   D,(HL)      */
+OP(op,57) { _D = _A;                                                } /* LD   D,A         */
+
+OP(op,58) { _E = _B;                                                } /* LD   E,B         */
+OP(op,59) { _E = _C;                                                } /* LD   E,C         */
+OP(op,5a) { _E = _D;                                                } /* LD   E,D         */
+OP(op,5b) {                                                         } /* LD   E,E         */
+OP(op,5c) { _E = _H;                                                } /* LD   E,H         */
+OP(op,5d) { _E = _L;                                                } /* LD   E,L         */
+OP(op,5e) { _E = RM(_HL);                                         } /* LD   E,(HL)      */
+OP(op,5f) { _E = _A;                                                } /* LD   E,A         */
+
+OP(op,60) { _H = _B;                                                } /* LD   H,B         */
+OP(op,61) { _H = _C;                                                } /* LD   H,C         */
+OP(op,62) { _H = _D;                                                } /* LD   H,D         */
+OP(op,63) { _H = _E;                                                } /* LD   H,E         */
+OP(op,64) {                                                         } /* LD   H,H         */
+OP(op,65) { _H = _L;                                                } /* LD   H,L         */
+OP(op,66) { _H = RM(_HL);                                         } /* LD   H,(HL)      */
+OP(op,67) { _H = _A;                                                } /* LD   H,A         */
+
+OP(op,68) { _L = _B;                                                } /* LD   L,B         */
+OP(op,69) { _L = _C;                                                } /* LD   L,C         */
+OP(op,6a) { _L = _D;                                                } /* LD   L,D         */
+OP(op,6b) { _L = _E;                                                } /* LD   L,E         */
+OP(op,6c) { _L = _H;                                                } /* LD   L,H         */
+OP(op,6d) {                                                         } /* LD   L,L         */
+OP(op,6e) { _L = RM(_HL);                                         } /* LD   L,(HL)      */
+OP(op,6f) { _L = _A;                                                } /* LD   L,A         */
+
+OP(op,70) { WM( _HL, _B );                                            } /* LD   (HL),B      */
+OP(op,71) { WM( _HL, _C );                                            } /* LD   (HL),C      */
+OP(op,72) { WM( _HL, _D );                                            } /* LD   (HL),D      */
+OP(op,73) { WM( _HL, _E );                                            } /* LD   (HL),E      */
+OP(op,74) { WM( _HL, _H );                                            } /* LD   (HL),H      */
+OP(op,75) { WM( _HL, _L );                                            } /* LD   (HL),L      */
+OP(op,76) { ENTER_HALT();                                           } /* HALT             */
+OP(op,77) { WM( _HL, _A );                                            } /* LD   (HL),A      */
+
+OP(op,78) { _A = _B;                                                } /* LD   A,B         */
+OP(op,79) { _A = _C;                                                } /* LD   A,C         */
+OP(op,7a) { _A = _D;                                                } /* LD   A,D         */
+OP(op,7b) { _A = _E;                                                } /* LD   A,E         */
+OP(op,7c) { _A = _H;                                                } /* LD   A,H         */
+OP(op,7d) { _A = _L;                                                } /* LD   A,L         */
+OP(op,7e) { _A = RM(_HL);                                         } /* LD   A,(HL)      */
+OP(op,7f) {                                                         } /* LD   A,A         */
+
+OP(op,80) { ADD(_B);                                              } /* ADD  A,B         */
+OP(op,81) { ADD(_C);                                              } /* ADD  A,C         */
+OP(op,82) { ADD(_D);                                              } /* ADD  A,D         */
+OP(op,83) { ADD(_E);                                              } /* ADD  A,E         */
+OP(op,84) { ADD(_H);                                              } /* ADD  A,H         */
+OP(op,85) { ADD(_L);                                              } /* ADD  A,L         */
+OP(op,86) { ADD(RM(_HL));                                           } /* ADD  A,(HL)      */
+OP(op,87) { ADD(_A);                                              } /* ADD  A,A         */
+
+OP(op,88) { ADC(_B);                                              } /* ADC  A,B         */
+OP(op,89) { ADC(_C);                                              } /* ADC  A,C         */
+OP(op,8a) { ADC(_D);                                              } /* ADC  A,D         */
+OP(op,8b) { ADC(_E);                                              } /* ADC  A,E         */
+OP(op,8c) { ADC(_H);                                              } /* ADC  A,H         */
+OP(op,8d) { ADC(_L);                                              } /* ADC  A,L         */
+OP(op,8e) { ADC(RM(_HL));                                           } /* ADC  A,(HL)      */
+OP(op,8f) { ADC(_A);                                              } /* ADC  A,A         */
+
+OP(op,90) { SUB(_B);                                              } /* SUB  B           */
+OP(op,91) { SUB(_C);                                              } /* SUB  C           */
+OP(op,92) { SUB(_D);                                              } /* SUB  D           */
+OP(op,93) { SUB(_E);                                              } /* SUB  E           */
+OP(op,94) { SUB(_H);                                              } /* SUB  H           */
+OP(op,95) { SUB(_L);                                              } /* SUB  L           */
+OP(op,96) { SUB(RM(_HL));                                           } /* SUB  (HL)        */
+OP(op,97) { SUB(_A);                                              } /* SUB  A           */
+
+OP(op,98) { SBC(_B);                                              } /* SBC  A,B         */
+OP(op,99) { SBC(_C);                                              } /* SBC  A,C         */
+OP(op,9a) { SBC(_D);                                              } /* SBC  A,D         */
+OP(op,9b) { SBC(_E);                                              } /* SBC  A,E         */
+OP(op,9c) { SBC(_H);                                              } /* SBC  A,H         */
+OP(op,9d) { SBC(_L);                                              } /* SBC  A,L         */
+OP(op,9e) { SBC(RM(_HL));                                           } /* SBC  A,(HL)      */
+OP(op,9f) { SBC(_A);                                              } /* SBC  A,A         */
+
+OP(op,a0) { AND(_B);                                              } /* AND  B           */
+OP(op,a1) { AND(_C);                                              } /* AND  C           */
+OP(op,a2) { AND(_D);                                              } /* AND  D           */
+OP(op,a3) { AND(_E);                                              } /* AND  E           */
+OP(op,a4) { AND(_H);                                              } /* AND  H           */
+OP(op,a5) { AND(_L);                                              } /* AND  L           */
+OP(op,a6) { AND(RM(_HL));                                           } /* AND  (HL)        */
+OP(op,a7) { AND(_A);                                              } /* AND  A           */
+
+OP(op,a8) { XOR(_B);                                              } /* XOR  B           */
+OP(op,a9) { XOR(_C);                                              } /* XOR  C           */
+OP(op,aa) { XOR(_D);                                              } /* XOR  D           */
+OP(op,ab) { XOR(_E);                                              } /* XOR  E           */
+OP(op,ac) { XOR(_H);                                              } /* XOR  H           */
+OP(op,ad) { XOR(_L);                                              } /* XOR  L           */
+OP(op,ae) { XOR(RM(_HL));                                           } /* XOR  (HL)        */
+OP(op,af) { XOR(_A);                                              } /* XOR  A           */
+
+OP(op,b0) { OR(_B);                                               } /* OR   B           */
+OP(op,b1) { OR(_C);                                               } /* OR   C           */
+OP(op,b2) { OR(_D);                                               } /* OR   D           */
+OP(op,b3) { OR(_E);                                               } /* OR   E           */
+OP(op,b4) { OR(_H);                                               } /* OR   H           */
+OP(op,b5) { OR(_L);                                               } /* OR   L           */
+OP(op,b6) { OR(RM(_HL));                                            } /* OR   (HL)        */
+OP(op,b7) { OR(_A);                                               } /* OR   A           */
+
+OP(op,b8) { CP(_B);                                               } /* CP   B           */
+OP(op,b9) { CP(_C);                                               } /* CP   C           */
+OP(op,ba) { CP(_D);                                               } /* CP   D           */
+OP(op,bb) { CP(_E);                                               } /* CP   E           */
+OP(op,bc) { CP(_H);                                               } /* CP   H           */
+OP(op,bd) { CP(_L);                                               } /* CP   L           */
+OP(op,be) { CP(RM(_HL));                                            } /* CP   (HL)        */
+OP(op,bf) { CP(_A);                                               } /* CP   A           */
+
+OP(op,c0) { RET_COND( !(_F & ZF), 0xc0 );                         } /* RET  NZ          */
+OP(op,c1) { POP(BC);                                              } /* POP  BC          */
+OP(op,c2) { JP_COND( !(_F & ZF) );                                    } /* JP   NZ,a        */
+OP(op,c3) { JP;                                                     } /* JP   a           */
+OP(op,c4) { CALL_COND( !(_F & ZF), 0xc4 );                            } /* CALL NZ,a        */
+OP(op,c5) { PUSH( BC );                                           } /* PUSH BC          */
+OP(op,c6) { ADD(ARG());                                             } /* ADD  A,n         */
+OP(op,c7) { RST(0x00);                                              } /* RST  0           */
+
+OP(op,c8) { RET_COND( _F & ZF, 0xc8 );                                } /* RET  Z           */
+OP(op,c9) { POP(PC);                                              } /* RET              */
+OP(op,ca) { JP_COND( _F & ZF );                                   } /* JP   Z,a         */
+OP(op,cb) { m_R++; m_extra_cycles += exec_cb(ROP());                                   } /* **** CB xx       */
+OP(op,cc) { CALL_COND( _F & ZF, 0xcc );                           } /* CALL Z,a         */
+OP(op,cd) { CALL();                                                 } /* CALL a           */
+OP(op,ce) { ADC(ARG());                                             } /* ADC  A,n         */
+OP(op,cf) { RST(0x08);                                              } /* RST  1           */
+
+OP(op,d0) { RET_COND( !(_F & CF), 0xd0 );                         } /* RET  NC          */
+OP(op,d1) { POP(DE);                                              } /* POP  DE          */
+OP(op,d2) { JP_COND( !(_F & CF) );                                    } /* JP   NC,a        */
+OP(op,d3) { unsigned n = ARG() | (_A << 8); OUT(n, _A );         } /* OUT  (n),A       */
+OP(op,d4) { CALL_COND( !(_F & CF), 0xd4 );                            } /* CALL NC,a        */
+OP(op,d5) { PUSH( DE );                                           } /* PUSH DE          */
+OP(op,d6) { SUB(ARG());                                             } /* SUB  n           */
+OP(op,d7) { RST(0x10);                                              } /* RST  2           */
+
+OP(op,d8) { RET_COND( _F & CF, 0xd8 );                                } /* RET  C           */
+OP(op,d9) { EXX;                                                    } /* EXX              */
+OP(op,da) { JP_COND( _F & CF );                                   } /* JP   C,a         */
+OP(op,db) { unsigned n = ARG() | (_A << 8); _A = IN(n );         } /* IN   A,(n)       */
+OP(op,dc) { CALL_COND( _F & CF, 0xdc );                           } /* CALL C,a         */
+OP(op,dd) { m_R++; m_extra_cycles += exec_dd(ROP());                                   } /* **** DD xx       */
+OP(op,de) { SBC(ARG());                                             } /* SBC  A,n         */
+OP(op,df) { RST(0x18);                                              } /* RST  3           */
+
+OP(op,e0) { RET_COND( !(_F & PF), 0xe0 );                         } /* RET  PO          */
+OP(op,e1) { POP(HL);                                              } /* POP  HL          */
+OP(op,e2) { JP_COND( !(_F & PF) );                                    } /* JP   PO,a        */
+OP(op,e3) { EXSP(HL);                                               } /* EX   HL,(SP)     */
+OP(op,e4) { CALL_COND( !(_F & PF), 0xe4 );                            } /* CALL PO,a        */
+OP(op,e5) { PUSH( HL );                                           } /* PUSH HL          */
+OP(op,e6) { AND(ARG());                                             } /* AND  n           */
+OP(op,e7) { RST(0x20);                                              } /* RST  4           */
+
+OP(op,e8) { RET_COND( _F & PF, 0xe8 );                                } /* RET  PE          */
+OP(op,e9) { _PC = _HL;                                              } /* JP   (HL)        */
+OP(op,ea) { JP_COND( _F & PF );                                   } /* JP   PE,a        */
+OP(op,eb) { EX_DE_HL;                                               } /* EX   DE,HL       */
+OP(op,ec) { CALL_COND( _F & PF, 0xec );                           } /* CALL PE,a        */
+OP(op,ed) { m_R++; m_extra_cycles += exec_ed(ROP());                                   } /* **** ED xx       */
+OP(op,ee) { XOR(ARG());                                             } /* XOR  n           */
+OP(op,ef) { RST(0x28);                                              } /* RST  5           */
+
+OP(op,f0) { RET_COND( !(_F & SF), 0xf0 );                         } /* RET  P           */
+OP(op,f1) { POP(AF);                                              } /* POP  AF          */
+OP(op,f2) { JP_COND( !(_F & SF) );                                    } /* JP   P,a         */
+OP(op,f3) { m_IFF1 = m_IFF2 = 0;                                        } /* DI               */
+OP(op,f4) { CALL_COND( !(_F & SF), 0xf4 );                            } /* CALL P,a         */
+OP(op,f5) { PUSH( AF );                                           } /* PUSH AF          */
+OP(op,f6) { OR(ARG());                                              } /* OR   n           */
+OP(op,f7) { RST(0x30);                                              } /* RST  6           */
+
+OP(op,f8) { RET_COND( _F & SF, 0xf8 );                                } /* RET  M           */
+OP(op,f9) { _SP = _HL;                                              } /* LD   SP,HL       */
+OP(op,fa) { JP_COND(_F & SF);                                     } /* JP   M,a         */
+OP(op,fb) { EI;                                                     } /* EI               */
+OP(op,fc) { CALL_COND( _F & SF, 0xfc );                           } /* CALL M,a         */
+OP(op,fd) { m_R++; m_extra_cycles += exec_fd(ROP());                                   } /* **** FD xx       */
+OP(op,fe) { CP(ARG());                                              } /* CP   n           */
+OP(op,ff) { RST(0x38);                                              } /* RST  7           */
+
+
+int z180_device::take_interrupt(int irq)
+{
+       int irq_vector;
+       int cycles = 0;
+
+       /* Check if processor was halted */
+       LEAVE_HALT();
+
+       /* Clear both interrupt flip flops */
+       m_IFF1 = m_IFF2 = 0;
+
+       if( irq == Z180_INT_IRQ0 )
+       {
+               // retrieve the IRQ vector from the daisy chain or CPU interface
+               device_z80daisy_interface *intf = daisy_get_irq_device();
+               irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback_member(*this, 0);
+
+               LOG("Z180 single int. irq_vector $%02x\n", irq_vector);
+
+               /* Interrupt mode 2. Call [m_I:databyte] */
+               if( m_IM == 2 )
+               {
+                       irq_vector = (irq_vector & 0xff) + (m_I << 8);
+                       PUSH( PC );
+                       RM16(irq_vector, &m_PC );
+                       LOG("Z180 IM2 [$%04x] = $%04x\n", irq_vector, _PCD);
+                       /* CALL opcode timing */
+                       cycles += m_cc[Z180_TABLE_op][0xcd];
+               }
+               else
+               /* Interrupt mode 1. RST 38h */
+               if( m_IM == 1 )
+               {
+                       LOG("Z180 IM1 $0038\n");
+                       PUSH( PC );
+                       _PCD = 0x0038;
+                       /* RST $38 + 'interrupt latency' cycles */
+                       cycles += m_cc[Z180_TABLE_op][0xff] - m_cc[Z180_TABLE_ex][0xff];
+               }
+               else
+               {
+                       /* Interrupt mode 0. We check for CALL and JP instructions, */
+                       /* if neither of these were found we assume a 1 byte opcode */
+                       /* was placed on the databus                                */
+                       LOG("Z180 IM0 $%04x\n", irq_vector);
+                       switch (irq_vector & 0xff0000)
+                       {
+                               case 0xcd0000:  /* call */
+                                       PUSH( PC );
+                                       _PCD = irq_vector & 0xffff;
+                                               /* CALL $xxxx + 'interrupt latency' cycles */
+                                       cycles += m_cc[Z180_TABLE_op][0xcd] - m_cc[Z180_TABLE_ex][0xff];
+                                       break;
+                               case 0xc30000:  /* jump */
+                                       _PCD = irq_vector & 0xffff;
+                                       /* JP $xxxx + 2 cycles */
+                                       cycles += m_cc[Z180_TABLE_op][0xc3] - m_cc[Z180_TABLE_ex][0xff];
+                                       break;
+                               default:        /* rst (or other opcodes?) */
+                                       PUSH( PC );
+                                       _PCD = irq_vector & 0x0038;
+                                       /* RST $xx + 2 cycles */
+                                       cycles += m_cc[Z180_TABLE_op][_PCD] - m_cc[Z180_TABLE_ex][_PCD];
+                                       break;
+                       }
+               }
+       }
+       else
+       {
+               irq_vector = (IO(Z180_IL) & Z180_IL_IL) + (irq - Z180_INT_IRQ1) * 2;
+               irq_vector = (m_I << 8) + (irq_vector & 0xff);
+               PUSH( PC );
+               RM16(irq_vector, &m_PC );
+               LOG("Z180 INT%d [$%04x] = $%04x\n", irq, irq_vector, _PCD);
+               /* CALL opcode timing */
+               cycles += m_cc[Z180_TABLE_op][0xcd];
+       }
+
+       return cycles;
+}
diff --git a/z180/z180ops.h b/z180/z180ops.h
new file mode 100644 (file)
index 0000000..320a66a
--- /dev/null
@@ -0,0 +1,957 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/***************************************************************
+ * Enter HALT state; write 1 to fake port on first execution
+ ***************************************************************/
+#define ENTER_HALT() {                                          \
+       _PC--;                                                      \
+       m_HALT = 1;                                                   \
+}
+
+/***************************************************************
+ * Leave HALT state; write 0 to fake port
+ ***************************************************************/
+#define LEAVE_HALT() {                                          \
+       if( m_HALT )                                                  \
+       {                                                           \
+               m_HALT = 0;                                               \
+               _PC++;                                                  \
+       }                                                           \
+}
+
+/***************************************************************
+ * Input a byte from given I/O port
+ ***************************************************************/
+inline u8 z180_device::IN(u16 port)
+{
+       if(((port ^ IO_IOCR) & 0xffc0) == 0)
+               return z180_readcontrol(port);
+       m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states
+       return m_iospace->read_byte(port);
+}
+
+/***************************************************************
+ * Output a byte to given I/O port
+ ***************************************************************/
+inline void z180_device::OUT(u16 port, u8 value)
+{
+       if (((port ^ IO_IOCR) & 0xffc0) == 0) {
+               z180_writecontrol(port,value);
+       } else
+       {
+               m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states
+               m_iospace->write_byte(port, value);
+       }
+}
+
+/***************************************************************
+ * MMU calculate the memory management lookup table
+ * bb and cb specify a 4K page
+ * If the 4 most significant bits of an 16 bit address are
+ * greater or equal to the bank base, the bank base register
+ * specifies the 4K offset into the 20 bit address space.
+ * If the 4 bits are also greater or equal to the common base,
+ * the common base register is used to specify the offset.
+ ***************************************************************/
+void z180_device::z180_mmu()
+{
+       offs_t addr, page, bb, cb;
+       bb = IO_CBAR & 15;
+       cb = IO_CBAR >> 4;
+       for( page = 0; page < 16; page++ )
+       {
+               addr = page << 12;
+               if (page >= bb)
+               {
+                       if (page >= cb)
+                               addr += (IO_CBR << 12);
+                       else
+                               addr += (IO_BBR << 12);
+               }
+               m_mmu[page] = (addr & 0xfffff);
+       }
+}
+
+
+#define MMU_REMAP_ADDR(addr) (m_mmu[((addr)>>12)&15]|((addr)&4095))
+
+/***************************************************************
+ * Read a byte from given memory location
+ ***************************************************************/
+inline u8 z180_device::RM(offs_t addr)
+{
+       m_extra_cycles += IO_DCNTL >> 6; // memory wait states
+       return m_program->read_byte(MMU_REMAP_ADDR(addr));
+}
+
+/***************************************************************
+ * Write a byte to given memory location
+ ***************************************************************/
+#define WM(addr,value) m_extra_cycles += IO_DCNTL >> 6; /* memory wait states */ m_program->write_byte(MMU_REMAP_ADDR(addr),value)
+
+/***************************************************************
+ * Read a word from given memory location
+ ***************************************************************/
+void z180_device::RM16( offs_t addr, PAIR *r )
+{
+       r->b.l = RM(addr);
+       r->b.h = RM(addr+1);
+}
+
+/***************************************************************
+ * Write a word to given memory location
+ ***************************************************************/
+void z180_device::WM16( offs_t addr, PAIR *r )
+{
+       WM(addr, r->b.l);
+       WM(addr+1, r->b.h);
+}
+
+/***************************************************************
+ * ROP() is identical to RM() except it is used for
+ * reading opcodes. In case of system with memory mapped I/O,
+ * this function can be used to greatly speed up emulation
+ ***************************************************************/
+uint8_t z180_device::ROP()
+{
+       offs_t addr = _PCD;
+       _PC++;
+       m_extra_cycles += IO_DCNTL >> 6; // memory wait states
+       return m_ocache->read_byte(MMU_REMAP_ADDR(addr));
+}
+
+/****************************************************************
+ * ARG() is identical to ROP() except it is used
+ * for reading opcode arguments. This difference can be used to
+ * support systems that use different encoding mechanisms for
+ * opcodes and opcode arguments
+ ***************************************************************/
+uint8_t z180_device::ARG()
+{
+       offs_t addr = _PCD;
+       _PC++;
+       m_extra_cycles += IO_DCNTL >> 6; // memory wait states
+       return m_cache->read_byte(MMU_REMAP_ADDR(addr));
+}
+
+uint32_t z180_device::ARG16()
+{
+       offs_t addr = _PCD;
+       _PC += 2;
+       m_extra_cycles += (IO_DCNTL >> 6) * 2; // memory wait states
+       return m_cache->read_byte(MMU_REMAP_ADDR(addr)) | (m_cache->read_byte(MMU_REMAP_ADDR(addr+1)) << 8);
+}
+
+/***************************************************************
+ * Calculate the effective address m_ea of an opcode using
+ * IX+offset resp. IY+offset addressing.
+ ***************************************************************/
+#define EAX() m_ea = (uint32_t)(uint16_t)(_IX + (int8_t)ARG())
+#define EAY() m_ea = (uint32_t)(uint16_t)(_IY + (int8_t)ARG())
+
+/***************************************************************
+ * POP
+ ***************************************************************/
+#define POP(DR) { RM16(_SPD, &m_##DR ); _SP += 2; }
+
+/***************************************************************
+ * PUSH
+ ***************************************************************/
+#define PUSH(SR) { _SP -= 2; WM16(_SPD, &m_##SR); }
+
+/***************************************************************
+ * JP
+ ***************************************************************/
+#define JP {                                                    \
+       _PCD = ARG16();                                           \
+}
+
+/***************************************************************
+ * JP_COND
+ ***************************************************************/
+
+#define JP_COND(cond)                                           \
+       if( cond )                                                  \
+       {                                                           \
+               _PCD = ARG16();                                       \
+       }                                                           \
+       else                                                        \
+       {                                                           \
+               _PC += 2;                                             \
+       }
+
+/***************************************************************
+ * JR
+ ***************************************************************/
+#define JR()                                                    \
+{                                                               \
+       int8_t arg = (int8_t)ARG(); /* ARG() also increments _PC */   \
+       _PC += arg;           /* so don't do _PC += ARG() */      \
+}
+
+/***************************************************************
+ * JR_COND
+ ***************************************************************/
+#define JR_COND(cond,opcode)                                    \
+       if( cond )                                                  \
+       {                                                           \
+               int8_t arg = (int8_t)ARG(); /* ARG() also increments _PC */ \
+               _PC += arg;           /* so don't do _PC += ARG() */  \
+               CC(ex,opcode);                                          \
+       }                                                           \
+       else _PC++;
+/***************************************************************
+ * CALL
+ ***************************************************************/
+#define CALL()                                                  \
+       m_ea = ARG16();                                             \
+       PUSH( PC );                                               \
+       _PCD = m_ea;
+
+/***************************************************************
+ * CALL_COND
+ ***************************************************************/
+#define CALL_COND(cond,opcode)                                  \
+       if( cond )                                                  \
+       {                                                           \
+               m_ea = ARG16();                                         \
+               PUSH( PC );                                           \
+               _PCD = m_ea;                                              \
+               CC(ex,opcode);                                          \
+       }                                                           \
+       else                                                        \
+       {                                                           \
+               _PC+=2;                                               \
+       }
+
+/***************************************************************
+ * RET_COND
+ ***************************************************************/
+#define RET_COND(cond,opcode)                                   \
+       if( cond )                                                  \
+       {                                                           \
+               POP(PC);                                                \
+               CC(ex,opcode);                                          \
+       }
+
+/***************************************************************
+ * RETN
+ ***************************************************************/
+#define RETN    {                                               \
+       LOG("Z180 RETN IFF1:%d IFF2:%d\n", m_IFF1, m_IFF2);         \
+       POP(PC);                                                    \
+       m_IFF1 = m_IFF2;                                            \
+}
+
+/***************************************************************
+ * RETI
+ ***************************************************************/
+#define RETI    {                                               \
+       POP(PC);                                                    \
+/* according to http://www.msxnet.org/tech/Z80/z80undoc.txt */  \
+/*  m_IFF1 = m_IFF2;  */                                        \
+       daisy_call_reti_device();                                   \
+}
+
+/***************************************************************
+ * LD   R,A
+ ***************************************************************/
+#define LD_R_A {                                                \
+       m_R = _A;                                                 \
+       m_R2 = _A & 0x80;             /* keep bit 7 of R */       \
+}
+
+/***************************************************************
+ * LD   A,R
+ ***************************************************************/
+#define LD_A_R {                                                \
+       _A = (m_R & 0x7f) | m_R2;                                     \
+       _F = (_F & CF) | SZ[_A] | ( m_IFF2 << 2 );                    \
+}
+
+/***************************************************************
+ * LD   I,A
+ ***************************************************************/
+#define LD_I_A {                                                \
+       m_I = _A;                                                 \
+}
+
+/***************************************************************
+ * LD   A,I
+ ***************************************************************/
+#define LD_A_I {                                                \
+       _A = m_I;                                                 \
+       _F = (_F & CF) | SZ[_A] | ( m_IFF2 << 2 );                    \
+}
+
+/***************************************************************
+ * RST
+ ***************************************************************/
+#define RST(addr)                                               \
+       PUSH( PC );                                               \
+       _PCD = addr;
+
+/***************************************************************
+ * INC  r8
+ ***************************************************************/
+uint8_t z180_device::INC(uint8_t value)
+{
+       uint8_t res = value + 1;
+       _F = (_F & CF) | SZHV_inc[res];
+       return (uint8_t)res;
+}
+
+/***************************************************************
+ * DEC  r8
+ ***************************************************************/
+uint8_t z180_device::DEC(uint8_t value)
+{
+       uint8_t res = value - 1;
+       _F = (_F & CF) | SZHV_dec[res];
+       return res;
+}
+
+/***************************************************************
+ * RLCA
+ ***************************************************************/
+#define RLCA                                                    \
+       _A = (_A << 1) | (_A >> 7);                               \
+       _F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF))
+
+/***************************************************************
+ * RRCA
+ ***************************************************************/
+#define RRCA                                                    \
+       _F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF));       \
+       _A = (_A >> 1) | (_A << 7)
+
+/***************************************************************
+ * RLA
+ ***************************************************************/
+#define RLA {                                                   \
+       uint8_t res = (_A << 1) | (_F & CF);                          \
+       uint8_t c = (_A & 0x80) ? CF : 0;                           \
+       _F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF));         \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * RRA
+ ***************************************************************/
+#define RRA {                                                   \
+       uint8_t res = (_A >> 1) | (_F << 7);                          \
+       uint8_t c = (_A & 0x01) ? CF : 0;                           \
+       _F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF));         \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * RRD
+ ***************************************************************/
+#define RRD {                                                   \
+       uint8_t n = RM(_HL);                                          \
+       WM( _HL, (n >> 4) | (_A << 4) );                          \
+       _A = (_A & 0xf0) | (n & 0x0f);                              \
+       _F = (_F & CF) | SZP[_A];                                 \
+}
+
+/***************************************************************
+ * RLD
+ ***************************************************************/
+#define RLD {                                                   \
+       uint8_t n = RM(_HL);                                          \
+       WM( _HL, (n << 4) | (_A & 0x0f) );                            \
+       _A = (_A & 0xf0) | (n >> 4);                                \
+       _F = (_F & CF) | SZP[_A];                                 \
+}
+
+/***************************************************************
+ * ADD  A,n
+ ***************************************************************/
+#define ADD(value)                                              \
+{                                                               \
+       uint32_t ah = _AFD & 0xff00;                                    \
+       uint32_t res = (uint8_t)((ah >> 8) + value);                    \
+       _F = SZHVC_add[ah | res];                                 \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * ADC  A,n
+ ***************************************************************/
+#define ADC(value)                                              \
+{                                                               \
+       uint32_t ah = _AFD & 0xff00, c = _AFD & 1;                    \
+       uint32_t res = (uint8_t)((ah >> 8) + value + c);                \
+       _F = SZHVC_add[(c << 16) | ah | res];                     \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * SUB  n
+ ***************************************************************/
+#define SUB(value)                                              \
+{                                                               \
+       uint32_t ah = _AFD & 0xff00;                                    \
+       uint32_t res = (uint8_t)((ah >> 8) - value);                    \
+       _F = SZHVC_sub[ah | res];                                 \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * SBC  A,n
+ ***************************************************************/
+#define SBC(value)                                              \
+{                                                               \
+       uint32_t ah = _AFD & 0xff00, c = _AFD & 1;                    \
+       uint32_t res = (uint8_t)((ah >> 8) - value - c);                \
+       _F = SZHVC_sub[(c<<16) | ah | res];                       \
+       _A = res;                                                 \
+}
+
+/***************************************************************
+ * NEG
+ ***************************************************************/
+#define NEG {                                                   \
+       uint8_t value = _A;                                         \
+       _A = 0;                                                   \
+       SUB(value);                                                 \
+}
+
+/***************************************************************
+ * DAA
+ ***************************************************************/
+#define DAA {                                                   \
+       uint8_t r = _A;                                         \
+       if (_F&NF) {                                          \
+               if ((_F&HF)|((_A&0xf)>9)) r-=6;                     \
+               if ((_F&CF)|(_A>0x99)) r-=0x60;                     \
+       }                                                   \
+       else {                                                  \
+               if ((_F&HF)|((_A&0xf)>9)) r+=6;                     \
+               if ((_F&CF)|(_A>0x99)) r+=0x60;                     \
+       }                                                   \
+       _F=(_F&3)|(_A>0x99)|((_A^r)&HF)|SZP[r];             \
+       _A=r;                                             \
+}
+
+/***************************************************************
+ * AND  n
+ ***************************************************************/
+#define AND(value)                                              \
+       _A &= value;                                              \
+       _F = SZP[_A] | HF
+
+/***************************************************************
+ * OR   n
+ ***************************************************************/
+#define OR(value)                                               \
+       _A |= value;                                              \
+       _F = SZP[_A]
+
+/***************************************************************
+ * XOR  n
+ ***************************************************************/
+#define XOR(value)                                              \
+       _A ^= value;                                              \
+       _F = SZP[_A]
+
+/***************************************************************
+ * CP   n
+ ***************************************************************/
+#define CP(value)                                               \
+{                                                               \
+       uint32_t ah = _AFD & 0xff00;                                    \
+       uint32_t res = (uint8_t)((ah >> 8) - value);                    \
+       _F = SZHVC_sub[ah | res];                                 \
+}
+
+/***************************************************************
+ * EX   AF,AF'
+ ***************************************************************/
+#define EX_AF {                                                 \
+       PAIR tmp;                                                   \
+       tmp = m_AF; m_AF = m_AF2; m_AF2 = tmp;          \
+}
+
+/***************************************************************
+ * EX   DE,HL
+ ***************************************************************/
+#define EX_DE_HL {                                              \
+       PAIR tmp;                                                   \
+       tmp = m_DE; m_DE = m_HL; m_HL = tmp;            \
+}
+
+/***************************************************************
+ * EXX
+ ***************************************************************/
+#define EXX {                                                   \
+       PAIR tmp;                                                   \
+       tmp = m_BC; m_BC = m_BC2; m_BC2 = tmp;          \
+       tmp = m_DE; m_DE = m_DE2; m_DE2 = tmp;          \
+       tmp = m_HL; m_HL = m_HL2; m_HL2 = tmp;          \
+}
+
+/***************************************************************
+ * EX   (SP),r16
+ ***************************************************************/
+#define EXSP(DR)                                                \
+{                                                               \
+       PAIR tmp = { { 0, 0, 0, 0 } };                              \
+       RM16( _SPD, &tmp );                                         \
+       WM16( _SPD, &m_##DR );                                    \
+       m_##DR = tmp;                                             \
+}
+
+
+/***************************************************************
+ * ADD16
+ ***************************************************************/
+#define ADD16(DR,SR)                                            \
+{                                                               \
+       uint32_t res = m_##DR.d + m_##SR.d;                       \
+       _F = (_F & (SF | ZF | VF)) |                                \
+               (((m_##DR.d ^ res ^ m_##SR.d) >> 8) & HF) |         \
+               ((res >> 16) & CF);                                     \
+       m_##DR.w.l = (uint16_t)res;                                 \
+}
+
+/***************************************************************
+ * ADC  r16,r16
+ ***************************************************************/
+#define ADC16(DR)                                               \
+{                                                               \
+       uint32_t res = _HLD + m_##DR.d + (_F & CF);                 \
+       _F = (((_HLD ^ res ^ m_##DR.d) >> 8) & HF) |              \
+               ((res >> 16) & CF) |                                    \
+               ((res >> 8) & SF) |                                     \
+               ((res & 0xffff) ? 0 : ZF) |                             \
+               (((m_##DR.d ^ _HLD ^ 0x8000) & (m_##DR.d ^ res) & 0x8000) >> 13); \
+       _HL = (uint16_t)res;                                            \
+}
+
+/***************************************************************
+ * SBC  r16,r16
+ ***************************************************************/
+#define SBC16(DR)                                               \
+{                                                               \
+       uint32_t res = _HLD - m_##DR.d - (_F & CF);                 \
+       _F = (((_HLD ^ res ^ m_##DR.d) >> 8) & HF) | NF |         \
+               ((res >> 16) & CF) |                                    \
+               ((res >> 8) & SF) |                                     \
+               ((res & 0xffff) ? 0 : ZF) |                             \
+               (((m_##DR.d ^ _HLD) & (_HLD ^ res) &0x8000) >> 13);   \
+       _HL = (uint16_t)res;                                            \
+}
+
+/***************************************************************
+ * RLC  r8
+ ***************************************************************/
+uint8_t z180_device::RLC(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x80) ? CF : 0;
+       res = ((res << 1) | (res >> 7)) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * RRC  r8
+ ***************************************************************/
+uint8_t z180_device::RRC(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x01) ? CF : 0;
+       res = ((res >> 1) | (res << 7)) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * RL   r8
+ ***************************************************************/
+uint8_t z180_device::RL(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x80) ? CF : 0;
+       res = ((res << 1) | (_F & CF)) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * RR   r8
+ ***************************************************************/
+uint8_t z180_device::RR(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x01) ? CF : 0;
+       res = ((res >> 1) | (_F << 7)) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * SLA  r8
+ ***************************************************************/
+uint8_t z180_device::SLA(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x80) ? CF : 0;
+       res = (res << 1) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * SRA  r8
+ ***************************************************************/
+uint8_t z180_device::SRA(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x01) ? CF : 0;
+       res = ((res >> 1) | (res & 0x80)) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * SLL  r8
+ ***************************************************************/
+uint8_t z180_device::SLL(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x80) ? CF : 0;
+       res = ((res << 1) | 0x01) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * SRL  r8
+ ***************************************************************/
+uint8_t z180_device::SRL(uint8_t value)
+{
+       unsigned res = value;
+       unsigned c = (res & 0x01) ? CF : 0;
+       res = (res >> 1) & 0xff;
+       _F = SZP[res] | c;
+       return res;
+}
+
+/***************************************************************
+ * BIT  bit,r8
+ ***************************************************************/
+#undef BIT
+#define BIT(bit,reg)                                            \
+       _F = (_F & CF) | HF | SZ_BIT[reg & (1<<bit)]
+
+/***************************************************************
+ * BIT  bit,(IX/Y+o)
+ ***************************************************************/
+#define BIT_XY(bit,reg)                                         \
+       _F = (_F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | ((m_ea>>8) & (YF|XF))
+
+/***************************************************************
+ * RES  bit,r8
+ ***************************************************************/
+uint8_t z180_device::RES(uint8_t bit, uint8_t value)
+{
+       return value & ~(1<<bit);
+}
+
+/***************************************************************
+ * SET  bit,r8
+ ***************************************************************/
+uint8_t z180_device::SET(uint8_t bit, uint8_t value)
+{
+       return value | (1<<bit);
+}
+
+/***************************************************************
+ * LDI
+ ***************************************************************/
+#define LDI {                                                   \
+       uint8_t io = RM(_HL);                                         \
+       WM( _DE, io );                                              \
+       _F &= SF | ZF | CF;                                       \
+       if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */      \
+       if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */      \
+       _HL++; _DE++; _BC--;                                      \
+       if( _BC ) _F |= VF;                                         \
+}
+
+/***************************************************************
+ * CPI
+ ***************************************************************/
+#define CPI {                                                   \
+       uint8_t val = RM(_HL);                                        \
+       uint8_t res = _A - val;                                     \
+       _HL++; _BC--;                                               \
+       _F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF;  \
+       if( _F & HF ) res -= 1;                                   \
+       if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */          \
+       if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */          \
+       if( _BC ) _F |= VF;                                         \
+}
+
+/***************************************************************
+ * INI
+ ***************************************************************/
+#define INI {                                                   \
+       uint8_t io = IN(_BC);                                         \
+       _B--;                                                     \
+       WM( _HL, io );                                              \
+       _HL++;                                                        \
+       _F = SZ[_B];                                                \
+       if( io & SF ) _F |= NF;                                   \
+       if( (_C + io + 1) & 0x100 ) _F |= HF | CF;                  \
+       if( (irep_tmp1[_C & 3][io & 3] ^                          \
+                       breg_tmp2[_B] ^                                       \
+                       (_C >> 2) ^                                           \
+                       (io >> 2)) & 1 )                                        \
+               _F |= PF;                                             \
+}
+
+/***************************************************************
+ * OUTI
+ ***************************************************************/
+#define OUTI {                                                  \
+       uint8_t io = RM(_HL);                                         \
+       _B--;                                                     \
+       OUT( _BC, io );                                             \
+       _HL++;                                                        \
+       _F = SZ[_B];                                                \
+       if( io & SF ) _F |= NF;                                   \
+       if( (_C + io + 1) & 0x100 ) _F |= HF | CF;                  \
+       if( (irep_tmp1[_C & 3][io & 3] ^                          \
+                       breg_tmp2[_B] ^                                       \
+                       (_C >> 2) ^                                           \
+                       (io >> 2)) & 1 )                                        \
+               _F |= PF;                                             \
+}
+
+/***************************************************************
+ * LDD
+ ***************************************************************/
+#define LDD {                                                   \
+       uint8_t io = RM(_HL);                                         \
+       WM( _DE, io );                                              \
+       _F &= SF | ZF | CF;                                       \
+       if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */      \
+       if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */      \
+       _HL--; _DE--; _BC--;                                      \
+       if( _BC ) _F |= VF;                                         \
+}
+
+/***************************************************************
+ * CPD
+ ***************************************************************/
+#define CPD {                                                   \
+       uint8_t val = RM(_HL);                                        \
+       uint8_t res = _A - val;                                     \
+       _HL--; _BC--;                                               \
+       _F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF;  \
+       if( _F & HF ) res -= 1;                                   \
+       if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */          \
+       if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */          \
+       if( _BC ) _F |= VF;                                         \
+}
+
+/***************************************************************
+ * IND
+ ***************************************************************/
+#define IND {                                                   \
+       uint8_t io = IN(_BC);                                         \
+       _B--;                                                     \
+       WM( _HL, io );                                              \
+       _HL--;                                                        \
+       _F = SZ[_B];                                                \
+       if( io & SF ) _F |= NF;                                   \
+       if( (_C + io - 1) & 0x100 ) _F |= HF | CF;                  \
+       if( (drep_tmp1[_C & 3][io & 3] ^                          \
+                       breg_tmp2[_B] ^                                       \
+                       (_C >> 2) ^                                           \
+                       (io >> 2)) & 1 )                                        \
+               _F |= PF;                                             \
+}
+
+/***************************************************************
+ * OUTD
+ ***************************************************************/
+#define OUTD {                                                  \
+       uint8_t io = RM(_HL);                                         \
+       _B--;                                                     \
+       OUT( _BC, io );                                             \
+       _HL--;                                                        \
+       _F = SZ[_B];                                                \
+       if( io & SF ) _F |= NF;                                   \
+       if( (_C + io - 1) & 0x100 ) _F |= HF | CF;                  \
+       if( (drep_tmp1[_C & 3][io & 3] ^                          \
+                       breg_tmp2[_B] ^                                       \
+                       (_C >> 2) ^                                           \
+                       (io >> 2)) & 1 )                                        \
+               _F |= PF;                                             \
+}
+
+/***************************************************************
+ * LDIR
+ ***************************************************************/
+#define LDIR                                                    \
+       LDI;                                                        \
+       if( _BC )                                                 \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb0);                                            \
+       }
+
+/***************************************************************
+ * CPIR
+ ***************************************************************/
+#define CPIR                                                    \
+       CPI;                                                        \
+       if( _BC && !(_F & ZF) )                                     \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb1);                                            \
+       }
+
+/***************************************************************
+ * INIR
+ ***************************************************************/
+#define INIR                                                    \
+       INI;                                                        \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb2);                                            \
+       }
+
+/***************************************************************
+ * OTIR
+ ***************************************************************/
+#define OTIR                                                    \
+       OUTI;                                                       \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb3);                                            \
+       }
+
+/***************************************************************
+ * LDDR
+ ***************************************************************/
+#define LDDR                                                    \
+       LDD;                                                        \
+       if( _BC )                                                 \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb8);                                            \
+       }
+
+/***************************************************************
+ * CPDR
+ ***************************************************************/
+#define CPDR                                                    \
+       CPD;                                                        \
+       if( _BC && !(_F & ZF) )                                     \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb9);                                            \
+       }
+
+/***************************************************************
+ * INDR
+ ***************************************************************/
+#define INDR                                                    \
+       IND;                                                        \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xba);                                            \
+       }
+
+/***************************************************************
+ * OTDR
+ ***************************************************************/
+#define OTDR                                                    \
+       OUTD;                                                       \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xbb);                                            \
+       }
+
+/***************************************************************
+ * EI
+ ***************************************************************/
+#define EI {                                                    \
+       m_IFF1 = m_IFF2 = 1;                                            \
+       m_after_EI = 1;                                         \
+}
+
+/***************************************************************
+ * TST  n
+ ***************************************************************/
+#define TST(value)                                              \
+       _F = SZP[_A & value] | HF
+
+/***************************************************************
+ * MLT  rr
+ ***************************************************************/
+#define MLT(DR) {                                               \
+       m_##DR.w.l = m_##DR.b.l * m_##DR.b.h;                 \
+}
+
+/***************************************************************
+ * OTIM
+ ***************************************************************/
+#define OTIM {                                                  \
+       _B--;                                                     \
+       OUT( _C, RM(_HL) );                                         \
+       _HL++;                                                        \
+       _C++;                                                     \
+       _F = (_B) ? NF : NF | ZF;                                   \
+}
+
+/***************************************************************
+ * OTDM
+ ***************************************************************/
+#define OTDM {                                                  \
+       _B--;                                                     \
+       OUT( _C, RM(_HL) );                                         \
+       _HL--;                                                        \
+       _C--;                                                     \
+       _F = (_B) ? NF : NF | ZF;                                   \
+}
+
+/***************************************************************
+ * OTIMR
+ ***************************************************************/
+#define OTIMR                                                   \
+       OTIM;                                                       \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb3);                                            \
+       }
+
+/***************************************************************
+ * OTDMR
+ ***************************************************************/
+#define OTDMR                                                   \
+       OTDM;                                                       \
+       if( _B )                                                  \
+       {                                                           \
+               _PC -= 2;                                             \
+               CC(ex,0xb3);                                            \
+       }
+
+/***************************************************************
+ * OTDMR
+ ***************************************************************/
+#define SLP {                                                   \
+       m_icount = 0;                                           \
+       m_HALT = 2;                                                 \
+}
diff --git a/z180/z180tbl.h b/z180/z180tbl.h
new file mode 100644 (file)
index 0000000..57d1bed
--- /dev/null
@@ -0,0 +1,232 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/* tmp1 value for ini/inir/outi/otir for [C.1-0][io.1-0] */
+static const uint8_t irep_tmp1[4][4] = {
+       {0,0,1,0},{0,1,0,1},{1,0,1,1},{0,1,1,0}
+};
+
+/* tmp1 value for ind/indr/outd/otdr for [C.1-0][io.1-0] */
+static const uint8_t drep_tmp1[4][4] = {
+       {0,1,0,0},{1,0,0,1},{0,0,1,0},{0,1,0,1}
+};
+
+/* tmp2 value for all in/out repeated opcodes for B.7-0 */
+static const uint8_t breg_tmp2[256] = {
+       0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,
+       0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,
+       1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1
+};
+
+static const uint8_t cc_op[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       3, 9, 7, 4, 4, 4, 6, 3, 4, 7, 6, 4, 4, 4, 6, 3,
+       7, 9, 7, 4, 4, 4, 6, 3, 8, 7, 6, 4, 4, 4, 6, 3,
+       6, 9,16, 4, 4, 4, 6, 4, 6, 7,15, 4, 4, 4, 6, 3,
+       6, 9,13, 4,10,10, 9, 3, 6, 7,12, 4, 4, 4, 6, 3,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       7, 7, 7, 7, 7, 7, 3, 7, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 4,
+       5, 9, 6, 9, 6,11, 6,11, 5, 9, 6, 0, 6,16, 6,11,
+       5, 9, 6,10, 6,11, 6,11, 5, 3, 6, 9, 6, 0, 6,11,
+       5, 9, 6,16, 6,11, 6,11, 5, 3, 6, 3, 6, 0, 6,11,
+       5, 9, 6, 3, 6,11, 6,11, 5, 4, 6, 3, 6, 0, 6,11
+};
+
+static const uint8_t cc_cb[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 9, 6,
+       6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 9, 6,
+       6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 9, 6,
+       6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 9, 6,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7,
+       7, 7, 7, 7, 7, 7,13, 7, 7, 7, 7, 7, 7, 7,13, 7
+};
+
+static const uint8_t cc_ed[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       12,13, 6, 6, 9, 6, 6, 6,12,13, 6, 6, 9, 6, 6, 6,
+       12,13, 6, 6, 9, 6, 6, 6,12,13, 6, 6, 9, 6, 6, 6,
+       12,13, 6, 6, 9, 6, 6, 6,12,13, 6, 6,10, 6, 6, 6,
+       12,13, 6, 6, 9, 6, 6, 6,12,13, 6, 6, 9, 6, 6, 6,
+       9,10,10,19, 6,12, 6, 6, 9,10,10,18,17,12, 6, 6,
+       9,10,10,19, 6,12, 6, 6, 9,10,10,18,17,12, 6, 6,
+       9,10,10,19, 6,12, 6,16, 9,10,10,18,17,12, 6,16,
+       9,10,10,19,12,12, 8, 6, 9,10,10,18,17,12, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+       12,12,12,12, 6, 6, 6, 6,12,12,12,12, 6, 6, 6, 6,
+       12,12,12,12, 6, 6, 6, 6,12,12,12,12, 6, 6, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
+};
+
+static const uint8_t cc_xy[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       4, 4, 4, 4, 4, 4, 4, 4, 4,10, 4, 4, 4, 4, 4, 4,
+       4, 4, 4, 4, 4, 4, 4, 4, 4,10, 4, 4, 4, 4, 4, 4,
+       4,12,19, 7, 9, 9,15, 4, 4,10,18, 7, 9, 9, 9, 4,
+       4, 4, 4, 4,18,18,15, 4, 4,10, 4, 4, 4, 4, 4, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       9, 9, 9, 9, 9, 9,14, 9, 9, 9, 9, 9, 9, 9,14, 9,
+       15,15,15,15,15,15, 4,15, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 9, 9,14, 4, 4, 4, 4, 4, 9, 9,14, 4,
+       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
+       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+       4,12, 4,19, 4,14, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4,
+       4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4
+};
+
+static const uint8_t cc_xycb[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+       15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+       15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+       15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+       19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19
+};
+
+/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
+static const uint8_t cc_ex[0x100] = {
+/*-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f */
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* DJNZ */
+       2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,   /* JR NZ/JR Z */
+       2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,   /* JR NC/JR C */
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0,   /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
+       5, 0, 3, 0,10, 0, 0, 2, 5, 0, 3, 0,10, 0, 0, 2,
+       5, 0, 3, 0,10, 0, 0, 2, 5, 0, 3, 0,10, 0, 0, 2,
+       5, 0, 3, 0,10, 0, 0, 2, 5, 0, 3, 0,10, 0, 0, 2,
+       5, 0, 3, 0,10, 0, 0, 2, 5, 0, 3, 0,10, 0, 0, 2
+};
+
+static const uint8_t *const cc_default[6] = { cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex };
+
+#define Z180_TABLE_dd    Z180_TABLE_xy
+#define Z180_TABLE_fd    Z180_TABLE_xy
+
+
+#define TABLE(prefix) {\
+       &z180_device::prefix##_00,&z180_device::prefix##_01,&z180_device::prefix##_02,&z180_device::prefix##_03,&z180_device::prefix##_04,&z180_device::prefix##_05,&z180_device::prefix##_06,&z180_device::prefix##_07, \
+       &z180_device::prefix##_08,&z180_device::prefix##_09,&z180_device::prefix##_0a,&z180_device::prefix##_0b,&z180_device::prefix##_0c,&z180_device::prefix##_0d,&z180_device::prefix##_0e,&z180_device::prefix##_0f, \
+       &z180_device::prefix##_10,&z180_device::prefix##_11,&z180_device::prefix##_12,&z180_device::prefix##_13,&z180_device::prefix##_14,&z180_device::prefix##_15,&z180_device::prefix##_16,&z180_device::prefix##_17, \
+       &z180_device::prefix##_18,&z180_device::prefix##_19,&z180_device::prefix##_1a,&z180_device::prefix##_1b,&z180_device::prefix##_1c,&z180_device::prefix##_1d,&z180_device::prefix##_1e,&z180_device::prefix##_1f, \
+       &z180_device::prefix##_20,&z180_device::prefix##_21,&z180_device::prefix##_22,&z180_device::prefix##_23,&z180_device::prefix##_24,&z180_device::prefix##_25,&z180_device::prefix##_26,&z180_device::prefix##_27, \
+       &z180_device::prefix##_28,&z180_device::prefix##_29,&z180_device::prefix##_2a,&z180_device::prefix##_2b,&z180_device::prefix##_2c,&z180_device::prefix##_2d,&z180_device::prefix##_2e,&z180_device::prefix##_2f, \
+       &z180_device::prefix##_30,&z180_device::prefix##_31,&z180_device::prefix##_32,&z180_device::prefix##_33,&z180_device::prefix##_34,&z180_device::prefix##_35,&z180_device::prefix##_36,&z180_device::prefix##_37, \
+       &z180_device::prefix##_38,&z180_device::prefix##_39,&z180_device::prefix##_3a,&z180_device::prefix##_3b,&z180_device::prefix##_3c,&z180_device::prefix##_3d,&z180_device::prefix##_3e,&z180_device::prefix##_3f, \
+       &z180_device::prefix##_40,&z180_device::prefix##_41,&z180_device::prefix##_42,&z180_device::prefix##_43,&z180_device::prefix##_44,&z180_device::prefix##_45,&z180_device::prefix##_46,&z180_device::prefix##_47, \
+       &z180_device::prefix##_48,&z180_device::prefix##_49,&z180_device::prefix##_4a,&z180_device::prefix##_4b,&z180_device::prefix##_4c,&z180_device::prefix##_4d,&z180_device::prefix##_4e,&z180_device::prefix##_4f, \
+       &z180_device::prefix##_50,&z180_device::prefix##_51,&z180_device::prefix##_52,&z180_device::prefix##_53,&z180_device::prefix##_54,&z180_device::prefix##_55,&z180_device::prefix##_56,&z180_device::prefix##_57, \
+       &z180_device::prefix##_58,&z180_device::prefix##_59,&z180_device::prefix##_5a,&z180_device::prefix##_5b,&z180_device::prefix##_5c,&z180_device::prefix##_5d,&z180_device::prefix##_5e,&z180_device::prefix##_5f, \
+       &z180_device::prefix##_60,&z180_device::prefix##_61,&z180_device::prefix##_62,&z180_device::prefix##_63,&z180_device::prefix##_64,&z180_device::prefix##_65,&z180_device::prefix##_66,&z180_device::prefix##_67, \
+       &z180_device::prefix##_68,&z180_device::prefix##_69,&z180_device::prefix##_6a,&z180_device::prefix##_6b,&z180_device::prefix##_6c,&z180_device::prefix##_6d,&z180_device::prefix##_6e,&z180_device::prefix##_6f, \
+       &z180_device::prefix##_70,&z180_device::prefix##_71,&z180_device::prefix##_72,&z180_device::prefix##_73,&z180_device::prefix##_74,&z180_device::prefix##_75,&z180_device::prefix##_76,&z180_device::prefix##_77, \
+       &z180_device::prefix##_78,&z180_device::prefix##_79,&z180_device::prefix##_7a,&z180_device::prefix##_7b,&z180_device::prefix##_7c,&z180_device::prefix##_7d,&z180_device::prefix##_7e,&z180_device::prefix##_7f, \
+       &z180_device::prefix##_80,&z180_device::prefix##_81,&z180_device::prefix##_82,&z180_device::prefix##_83,&z180_device::prefix##_84,&z180_device::prefix##_85,&z180_device::prefix##_86,&z180_device::prefix##_87, \
+       &z180_device::prefix##_88,&z180_device::prefix##_89,&z180_device::prefix##_8a,&z180_device::prefix##_8b,&z180_device::prefix##_8c,&z180_device::prefix##_8d,&z180_device::prefix##_8e,&z180_device::prefix##_8f, \
+       &z180_device::prefix##_90,&z180_device::prefix##_91,&z180_device::prefix##_92,&z180_device::prefix##_93,&z180_device::prefix##_94,&z180_device::prefix##_95,&z180_device::prefix##_96,&z180_device::prefix##_97, \
+       &z180_device::prefix##_98,&z180_device::prefix##_99,&z180_device::prefix##_9a,&z180_device::prefix##_9b,&z180_device::prefix##_9c,&z180_device::prefix##_9d,&z180_device::prefix##_9e,&z180_device::prefix##_9f, \
+       &z180_device::prefix##_a0,&z180_device::prefix##_a1,&z180_device::prefix##_a2,&z180_device::prefix##_a3,&z180_device::prefix##_a4,&z180_device::prefix##_a5,&z180_device::prefix##_a6,&z180_device::prefix##_a7, \
+       &z180_device::prefix##_a8,&z180_device::prefix##_a9,&z180_device::prefix##_aa,&z180_device::prefix##_ab,&z180_device::prefix##_ac,&z180_device::prefix##_ad,&z180_device::prefix##_ae,&z180_device::prefix##_af, \
+       &z180_device::prefix##_b0,&z180_device::prefix##_b1,&z180_device::prefix##_b2,&z180_device::prefix##_b3,&z180_device::prefix##_b4,&z180_device::prefix##_b5,&z180_device::prefix##_b6,&z180_device::prefix##_b7, \
+       &z180_device::prefix##_b8,&z180_device::prefix##_b9,&z180_device::prefix##_ba,&z180_device::prefix##_bb,&z180_device::prefix##_bc,&z180_device::prefix##_bd,&z180_device::prefix##_be,&z180_device::prefix##_bf, \
+       &z180_device::prefix##_c0,&z180_device::prefix##_c1,&z180_device::prefix##_c2,&z180_device::prefix##_c3,&z180_device::prefix##_c4,&z180_device::prefix##_c5,&z180_device::prefix##_c6,&z180_device::prefix##_c7, \
+       &z180_device::prefix##_c8,&z180_device::prefix##_c9,&z180_device::prefix##_ca,&z180_device::prefix##_cb,&z180_device::prefix##_cc,&z180_device::prefix##_cd,&z180_device::prefix##_ce,&z180_device::prefix##_cf, \
+       &z180_device::prefix##_d0,&z180_device::prefix##_d1,&z180_device::prefix##_d2,&z180_device::prefix##_d3,&z180_device::prefix##_d4,&z180_device::prefix##_d5,&z180_device::prefix##_d6,&z180_device::prefix##_d7, \
+       &z180_device::prefix##_d8,&z180_device::prefix##_d9,&z180_device::prefix##_da,&z180_device::prefix##_db,&z180_device::prefix##_dc,&z180_device::prefix##_dd,&z180_device::prefix##_de,&z180_device::prefix##_df, \
+       &z180_device::prefix##_e0,&z180_device::prefix##_e1,&z180_device::prefix##_e2,&z180_device::prefix##_e3,&z180_device::prefix##_e4,&z180_device::prefix##_e5,&z180_device::prefix##_e6,&z180_device::prefix##_e7, \
+       &z180_device::prefix##_e8,&z180_device::prefix##_e9,&z180_device::prefix##_ea,&z180_device::prefix##_eb,&z180_device::prefix##_ec,&z180_device::prefix##_ed,&z180_device::prefix##_ee,&z180_device::prefix##_ef, \
+       &z180_device::prefix##_f0,&z180_device::prefix##_f1,&z180_device::prefix##_f2,&z180_device::prefix##_f3,&z180_device::prefix##_f4,&z180_device::prefix##_f5,&z180_device::prefix##_f6,&z180_device::prefix##_f7, \
+       &z180_device::prefix##_f8,&z180_device::prefix##_f9,&z180_device::prefix##_fa,&z180_device::prefix##_fb,&z180_device::prefix##_fc,&z180_device::prefix##_fd,&z180_device::prefix##_fe,&z180_device::prefix##_ff  \
+}
+
+
+const z180_device::opcode_func z180_device::s_z180ops[Z180_PREFIX_COUNT][0x100] =
+{
+       TABLE(op),
+       TABLE(cb),
+       TABLE(dd),
+       TABLE(ed),
+       TABLE(fd),
+       TABLE(xycb)
+};
+
+/***************************************************************
+ * define an opcode function
+ ***************************************************************/
+#define OP(prefix,opcode)  void z180_device::prefix##_##opcode()
+
+/***************************************************************
+ * adjust cycle count by n T-states
+ ***************************************************************/
+#define CC(prefix,opcode) m_extra_cycles += m_cc[Z180_TABLE_##prefix][opcode]
+
+/***************************************************************
+ * execute an opcode
+ ***************************************************************/
+
+#define EXEC_PROTOTYPE(prefix) \
+int z180_device::exec##_##prefix(const uint8_t opcode)    \
+{                                                                       \
+       (this->*s_z180ops[Z180_PREFIX_##prefix][opcode])();                                     \
+       return m_cc[Z180_TABLE_##prefix][opcode];                   \
+}
+
+EXEC_PROTOTYPE(op)
+EXEC_PROTOTYPE(cb)
+EXEC_PROTOTYPE(dd)
+EXEC_PROTOTYPE(ed)
+EXEC_PROTOTYPE(fd)
+EXEC_PROTOTYPE(xycb)
diff --git a/z180/z180xy.hxx b/z180/z180xy.hxx
new file mode 100644 (file)
index 0000000..e897607
--- /dev/null
@@ -0,0 +1,293 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/**********************************************************
+* opcodes with DD/FD CB prefix
+* rotate, shift and bit operations with (IX+o)
+**********************************************************/
+OP(xycb,00) { _B = RLC(RM(m_ea) ); WM( m_ea,_B );                        } /* RLC  B=(XY+o)    */
+OP(xycb,01) { _C = RLC(RM(m_ea) ); WM( m_ea,_C );                        } /* RLC  C=(XY+o)    */
+OP(xycb,02) { _D = RLC(RM(m_ea) ); WM( m_ea,_D );                        } /* RLC  D=(XY+o)    */
+OP(xycb,03) { _E = RLC(RM(m_ea) ); WM( m_ea,_E );                        } /* RLC  E=(XY+o)    */
+OP(xycb,04) { _H = RLC(RM(m_ea) ); WM( m_ea,_H );                        } /* RLC  H=(XY+o)    */
+OP(xycb,05) { _L = RLC(RM(m_ea) ); WM( m_ea,_L );                        } /* RLC  L=(XY+o)    */
+OP(xycb,06) { WM( m_ea, RLC(RM(m_ea) ) );                                } /* RLC  (XY+o)      */
+OP(xycb,07) { _A = RLC(RM(m_ea) ); WM( m_ea,_A );                        } /* RLC  A=(XY+o)    */
+
+OP(xycb,08) { _B = RRC(RM(m_ea) ); WM( m_ea,_B );                        } /* RRC  B=(XY+o)    */
+OP(xycb,09) { _C = RRC(RM(m_ea) ); WM( m_ea,_C );                        } /* RRC  C=(XY+o)    */
+OP(xycb,0a) { _D = RRC(RM(m_ea) ); WM( m_ea,_D );                        } /* RRC  D=(XY+o)    */
+OP(xycb,0b) { _E = RRC(RM(m_ea) ); WM( m_ea,_E );                        } /* RRC  E=(XY+o)    */
+OP(xycb,0c) { _H = RRC(RM(m_ea) ); WM( m_ea,_H );                        } /* RRC  H=(XY+o)    */
+OP(xycb,0d) { _L = RRC(RM(m_ea) ); WM( m_ea,_L );                        } /* RRC  L=(XY+o)    */
+OP(xycb,0e) { WM( m_ea,RRC(RM(m_ea) ) );                             } /* RRC  (XY+o)      */
+OP(xycb,0f) { _A = RRC(RM(m_ea) ); WM( m_ea,_A );                        } /* RRC  A=(XY+o)    */
+
+OP(xycb,10) { _B = RL(RM(m_ea) ); WM( m_ea,_B );                     } /* RL   B=(XY+o)    */
+OP(xycb,11) { _C = RL(RM(m_ea) ); WM( m_ea,_C );                     } /* RL   C=(XY+o)    */
+OP(xycb,12) { _D = RL(RM(m_ea) ); WM( m_ea,_D );                     } /* RL   D=(XY+o)    */
+OP(xycb,13) { _E = RL(RM(m_ea) ); WM( m_ea,_E );                     } /* RL   E=(XY+o)    */
+OP(xycb,14) { _H = RL(RM(m_ea) ); WM( m_ea,_H );                     } /* RL   H=(XY+o)    */
+OP(xycb,15) { _L = RL(RM(m_ea) ); WM( m_ea,_L );                     } /* RL   L=(XY+o)    */
+OP(xycb,16) { WM( m_ea,RL(RM(m_ea) ) );                              } /* RL   (XY+o)      */
+OP(xycb,17) { _A = RL(RM(m_ea) ); WM( m_ea,_A );                     } /* RL   A=(XY+o)    */
+
+OP(xycb,18) { _B = RR(RM(m_ea) ); WM( m_ea,_B );                     } /* RR   B=(XY+o)    */
+OP(xycb,19) { _C = RR(RM(m_ea) ); WM( m_ea,_C );                     } /* RR   C=(XY+o)    */
+OP(xycb,1a) { _D = RR(RM(m_ea) ); WM( m_ea,_D );                     } /* RR   D=(XY+o)    */
+OP(xycb,1b) { _E = RR(RM(m_ea) ); WM( m_ea,_E );                     } /* RR   E=(XY+o)    */
+OP(xycb,1c) { _H = RR(RM(m_ea) ); WM( m_ea,_H );                     } /* RR   H=(XY+o)    */
+OP(xycb,1d) { _L = RR(RM(m_ea) ); WM( m_ea,_L );                     } /* RR   L=(XY+o)    */
+OP(xycb,1e) { WM( m_ea,RR(RM(m_ea) ) );                              } /* RR   (XY+o)      */
+OP(xycb,1f) { _A = RR(RM(m_ea) ); WM( m_ea,_A );                     } /* RR   A=(XY+o)    */
+
+OP(xycb,20) { _B = SLA(RM(m_ea) ); WM( m_ea,_B );                        } /* SLA  B=(XY+o)    */
+OP(xycb,21) { _C = SLA(RM(m_ea) ); WM( m_ea,_C );                        } /* SLA  C=(XY+o)    */
+OP(xycb,22) { _D = SLA(RM(m_ea) ); WM( m_ea,_D );                        } /* SLA  D=(XY+o)    */
+OP(xycb,23) { _E = SLA(RM(m_ea) ); WM( m_ea,_E );                        } /* SLA  E=(XY+o)    */
+OP(xycb,24) { _H = SLA(RM(m_ea) ); WM( m_ea,_H );                        } /* SLA  H=(XY+o)    */
+OP(xycb,25) { _L = SLA(RM(m_ea) ); WM( m_ea,_L );                        } /* SLA  L=(XY+o)    */
+OP(xycb,26) { WM( m_ea,SLA(RM(m_ea) ) );                             } /* SLA  (XY+o)      */
+OP(xycb,27) { _A = SLA(RM(m_ea) ); WM( m_ea,_A );                        } /* SLA  A=(XY+o)    */
+
+OP(xycb,28) { _B = SRA(RM(m_ea) ); WM( m_ea,_B );                        } /* SRA  B=(XY+o)    */
+OP(xycb,29) { _C = SRA(RM(m_ea) ); WM( m_ea,_C );                        } /* SRA  C=(XY+o)    */
+OP(xycb,2a) { _D = SRA(RM(m_ea) ); WM( m_ea,_D );                        } /* SRA  D=(XY+o)    */
+OP(xycb,2b) { _E = SRA(RM(m_ea) ); WM( m_ea,_E );                        } /* SRA  E=(XY+o)    */
+OP(xycb,2c) { _H = SRA(RM(m_ea) ); WM( m_ea,_H );                        } /* SRA  H=(XY+o)    */
+OP(xycb,2d) { _L = SRA(RM(m_ea) ); WM( m_ea,_L );                        } /* SRA  L=(XY+o)    */
+OP(xycb,2e) { WM( m_ea,SRA(RM(m_ea) ) );                             } /* SRA  (XY+o)      */
+OP(xycb,2f) { _A = SRA(RM(m_ea) ); WM( m_ea,_A );                        } /* SRA  A=(XY+o)    */
+
+OP(xycb,30) { _B = SLL(RM(m_ea) ); WM( m_ea,_B );                        } /* SLL  B=(XY+o)    */
+OP(xycb,31) { _C = SLL(RM(m_ea) ); WM( m_ea,_C );                        } /* SLL  C=(XY+o)    */
+OP(xycb,32) { _D = SLL(RM(m_ea) ); WM( m_ea,_D );                        } /* SLL  D=(XY+o)    */
+OP(xycb,33) { _E = SLL(RM(m_ea) ); WM( m_ea,_E );                        } /* SLL  E=(XY+o)    */
+OP(xycb,34) { _H = SLL(RM(m_ea) ); WM( m_ea,_H );                        } /* SLL  H=(XY+o)    */
+OP(xycb,35) { _L = SLL(RM(m_ea) ); WM( m_ea,_L );                        } /* SLL  L=(XY+o)    */
+OP(xycb,36) { WM( m_ea,SLL(RM(m_ea) ) );                             } /* SLL  (XY+o)      */
+OP(xycb,37) { _A = SLL(RM(m_ea) ); WM( m_ea,_A );                        } /* SLL  A=(XY+o)    */
+
+OP(xycb,38) { _B = SRL(RM(m_ea) ); WM( m_ea,_B );                        } /* SRL  B=(XY+o)    */
+OP(xycb,39) { _C = SRL(RM(m_ea) ); WM( m_ea,_C );                        } /* SRL  C=(XY+o)    */
+OP(xycb,3a) { _D = SRL(RM(m_ea) ); WM( m_ea,_D );                        } /* SRL  D=(XY+o)    */
+OP(xycb,3b) { _E = SRL(RM(m_ea) ); WM( m_ea,_E );                        } /* SRL  E=(XY+o)    */
+OP(xycb,3c) { _H = SRL(RM(m_ea) ); WM( m_ea,_H );                        } /* SRL  H=(XY+o)    */
+OP(xycb,3d) { _L = SRL(RM(m_ea) ); WM( m_ea,_L );                        } /* SRL  L=(XY+o)    */
+OP(xycb,3e) { WM( m_ea,SRL(RM(m_ea) ) );                             } /* SRL  (XY+o)      */
+OP(xycb,3f) { _A = SRL(RM(m_ea) ); WM( m_ea,_A );                        } /* SRL  A=(XY+o)    */
+
+OP(xycb,40) { xycb_46();                                            } /* BIT  0,B=(XY+o)  */
+OP(xycb,41) { xycb_46();                                                      } /* BIT  0,C=(XY+o)  */
+OP(xycb,42) { xycb_46();                                            } /* BIT  0,D=(XY+o)  */
+OP(xycb,43) { xycb_46();                                            } /* BIT  0,E=(XY+o)  */
+OP(xycb,44) { xycb_46();                                            } /* BIT  0,H=(XY+o)  */
+OP(xycb,45) { xycb_46();                                            } /* BIT  0,L=(XY+o)  */
+OP(xycb,46) { BIT_XY(0,RM(m_ea));                                     } /* BIT  0,(XY+o)    */
+OP(xycb,47) { xycb_46();                                            } /* BIT  0,A=(XY+o)  */
+
+OP(xycb,48) { xycb_4e();                                            } /* BIT  1,B=(XY+o)  */
+OP(xycb,49) { xycb_4e();                                                      } /* BIT  1,C=(XY+o)  */
+OP(xycb,4a) { xycb_4e();                                            } /* BIT  1,D=(XY+o)  */
+OP(xycb,4b) { xycb_4e();                                            } /* BIT  1,E=(XY+o)  */
+OP(xycb,4c) { xycb_4e();                                            } /* BIT  1,H=(XY+o)  */
+OP(xycb,4d) { xycb_4e();                                            } /* BIT  1,L=(XY+o)  */
+OP(xycb,4e) { BIT_XY(1,RM(m_ea));                                     } /* BIT  1,(XY+o)    */
+OP(xycb,4f) { xycb_4e();                                            } /* BIT  1,A=(XY+o)  */
+
+OP(xycb,50) { xycb_56();                                            } /* BIT  2,B=(XY+o)  */
+OP(xycb,51) { xycb_56();                                                      } /* BIT  2,C=(XY+o)  */
+OP(xycb,52) { xycb_56();                                            } /* BIT  2,D=(XY+o)  */
+OP(xycb,53) { xycb_56();                                            } /* BIT  2,E=(XY+o)  */
+OP(xycb,54) { xycb_56();                                            } /* BIT  2,H=(XY+o)  */
+OP(xycb,55) { xycb_56();                                            } /* BIT  2,L=(XY+o)  */
+OP(xycb,56) { BIT_XY(2,RM(m_ea));                                     } /* BIT  2,(XY+o)    */
+OP(xycb,57) { xycb_56();                                            } /* BIT  2,A=(XY+o)  */
+
+OP(xycb,58) { xycb_5e();                                            } /* BIT  3,B=(XY+o)  */
+OP(xycb,59) { xycb_5e();                                                      } /* BIT  3,C=(XY+o)  */
+OP(xycb,5a) { xycb_5e();                                            } /* BIT  3,D=(XY+o)  */
+OP(xycb,5b) { xycb_5e();                                            } /* BIT  3,E=(XY+o)  */
+OP(xycb,5c) { xycb_5e();                                            } /* BIT  3,H=(XY+o)  */
+OP(xycb,5d) { xycb_5e();                                            } /* BIT  3,L=(XY+o)  */
+OP(xycb,5e) { BIT_XY(3,RM(m_ea));                                     } /* BIT  3,(XY+o)    */
+OP(xycb,5f) { xycb_5e();                                            } /* BIT  3,A=(XY+o)  */
+
+OP(xycb,60) { xycb_66();                                            } /* BIT  4,B=(XY+o)  */
+OP(xycb,61) { xycb_66();                                                      } /* BIT  4,C=(XY+o)  */
+OP(xycb,62) { xycb_66();                                            } /* BIT  4,D=(XY+o)  */
+OP(xycb,63) { xycb_66();                                            } /* BIT  4,E=(XY+o)  */
+OP(xycb,64) { xycb_66();                                            } /* BIT  4,H=(XY+o)  */
+OP(xycb,65) { xycb_66();                                            } /* BIT  4,L=(XY+o)  */
+OP(xycb,66) { BIT_XY(4,RM(m_ea));                                     } /* BIT  4,(XY+o)    */
+OP(xycb,67) { xycb_66();                                            } /* BIT  4,A=(XY+o)  */
+
+OP(xycb,68) { xycb_6e();                                            } /* BIT  5,B=(XY+o)  */
+OP(xycb,69) { xycb_6e();                                                      } /* BIT  5,C=(XY+o)  */
+OP(xycb,6a) { xycb_6e();                                            } /* BIT  5,D=(XY+o)  */
+OP(xycb,6b) { xycb_6e();                                            } /* BIT  5,E=(XY+o)  */
+OP(xycb,6c) { xycb_6e();                                            } /* BIT  5,H=(XY+o)  */
+OP(xycb,6d) { xycb_6e();                                            } /* BIT  5,L=(XY+o)  */
+OP(xycb,6e) { BIT_XY(5,RM(m_ea));                                     } /* BIT  5,(XY+o)    */
+OP(xycb,6f) { xycb_6e();                                            } /* BIT  5,A=(XY+o)  */
+
+OP(xycb,70) { xycb_76();                                            } /* BIT  6,B=(XY+o)  */
+OP(xycb,71) { xycb_76();                                                      } /* BIT  6,C=(XY+o)  */
+OP(xycb,72) { xycb_76();                                            } /* BIT  6,D=(XY+o)  */
+OP(xycb,73) { xycb_76();                                            } /* BIT  6,E=(XY+o)  */
+OP(xycb,74) { xycb_76();                                            } /* BIT  6,H=(XY+o)  */
+OP(xycb,75) { xycb_76();                                            } /* BIT  6,L=(XY+o)  */
+OP(xycb,76) { BIT_XY(6,RM(m_ea));                                     } /* BIT  6,(XY+o)    */
+OP(xycb,77) { xycb_76();                                            } /* BIT  6,A=(XY+o)  */
+
+OP(xycb,78) { xycb_7e();                                            } /* BIT  7,B=(XY+o)  */
+OP(xycb,79) { xycb_7e();                                                      } /* BIT  7,C=(XY+o)  */
+OP(xycb,7a) { xycb_7e();                                            } /* BIT  7,D=(XY+o)  */
+OP(xycb,7b) { xycb_7e();                                            } /* BIT  7,E=(XY+o)  */
+OP(xycb,7c) { xycb_7e();                                            } /* BIT  7,H=(XY+o)  */
+OP(xycb,7d) { xycb_7e();                                            } /* BIT  7,L=(XY+o)  */
+OP(xycb,7e) { BIT_XY(7,RM(m_ea));                                     } /* BIT  7,(XY+o)    */
+OP(xycb,7f) { xycb_7e();                                            } /* BIT  7,A=(XY+o)  */
+
+OP(xycb,80) { _B = RES(0, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  0,B=(XY+o)  */
+OP(xycb,81) { _C = RES(0, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  0,C=(XY+o)  */
+OP(xycb,82) { _D = RES(0, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  0,D=(XY+o)  */
+OP(xycb,83) { _E = RES(0, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  0,E=(XY+o)  */
+OP(xycb,84) { _H = RES(0, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  0,H=(XY+o)  */
+OP(xycb,85) { _L = RES(0, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  0,L=(XY+o)  */
+OP(xycb,86) { WM( m_ea, RES(0,RM(m_ea)) );                              } /* RES  0,(XY+o)    */
+OP(xycb,87) { _A = RES(0, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  0,A=(XY+o)  */
+
+OP(xycb,88) { _B = RES(1, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  1,B=(XY+o)  */
+OP(xycb,89) { _C = RES(1, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  1,C=(XY+o)  */
+OP(xycb,8a) { _D = RES(1, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  1,D=(XY+o)  */
+OP(xycb,8b) { _E = RES(1, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  1,E=(XY+o)  */
+OP(xycb,8c) { _H = RES(1, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  1,H=(XY+o)  */
+OP(xycb,8d) { _L = RES(1, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  1,L=(XY+o)  */
+OP(xycb,8e) { WM( m_ea, RES(1,RM(m_ea)) );                              } /* RES  1,(XY+o)    */
+OP(xycb,8f) { _A = RES(1, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  1,A=(XY+o)  */
+
+OP(xycb,90) { _B = RES(2, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  2,B=(XY+o)  */
+OP(xycb,91) { _C = RES(2, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  2,C=(XY+o)  */
+OP(xycb,92) { _D = RES(2, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  2,D=(XY+o)  */
+OP(xycb,93) { _E = RES(2, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  2,E=(XY+o)  */
+OP(xycb,94) { _H = RES(2, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  2,H=(XY+o)  */
+OP(xycb,95) { _L = RES(2, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  2,L=(XY+o)  */
+OP(xycb,96) { WM( m_ea, RES(2,RM(m_ea)) );                              } /* RES  2,(XY+o)    */
+OP(xycb,97) { _A = RES(2, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  2,A=(XY+o)  */
+
+OP(xycb,98) { _B = RES(3, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  3,B=(XY+o)  */
+OP(xycb,99) { _C = RES(3, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  3,C=(XY+o)  */
+OP(xycb,9a) { _D = RES(3, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  3,D=(XY+o)  */
+OP(xycb,9b) { _E = RES(3, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  3,E=(XY+o)  */
+OP(xycb,9c) { _H = RES(3, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  3,H=(XY+o)  */
+OP(xycb,9d) { _L = RES(3, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  3,L=(XY+o)  */
+OP(xycb,9e) { WM( m_ea, RES(3,RM(m_ea)) );                              } /* RES  3,(XY+o)    */
+OP(xycb,9f) { _A = RES(3, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  3,A=(XY+o)  */
+
+OP(xycb,a0) { _B = RES(4, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  4,B=(XY+o)  */
+OP(xycb,a1) { _C = RES(4, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  4,C=(XY+o)  */
+OP(xycb,a2) { _D = RES(4, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  4,D=(XY+o)  */
+OP(xycb,a3) { _E = RES(4, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  4,E=(XY+o)  */
+OP(xycb,a4) { _H = RES(4, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  4,H=(XY+o)  */
+OP(xycb,a5) { _L = RES(4, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  4,L=(XY+o)  */
+OP(xycb,a6) { WM( m_ea, RES(4,RM(m_ea)) );                              } /* RES  4,(XY+o)    */
+OP(xycb,a7) { _A = RES(4, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  4,A=(XY+o)  */
+
+OP(xycb,a8) { _B = RES(5, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  5,B=(XY+o)  */
+OP(xycb,a9) { _C = RES(5, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  5,C=(XY+o)  */
+OP(xycb,aa) { _D = RES(5, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  5,D=(XY+o)  */
+OP(xycb,ab) { _E = RES(5, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  5,E=(XY+o)  */
+OP(xycb,ac) { _H = RES(5, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  5,H=(XY+o)  */
+OP(xycb,ad) { _L = RES(5, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  5,L=(XY+o)  */
+OP(xycb,ae) { WM( m_ea, RES(5,RM(m_ea)) );                              } /* RES  5,(XY+o)    */
+OP(xycb,af) { _A = RES(5, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  5,A=(XY+o)  */
+
+OP(xycb,b0) { _B = RES(6, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  6,B=(XY+o)  */
+OP(xycb,b1) { _C = RES(6, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  6,C=(XY+o)  */
+OP(xycb,b2) { _D = RES(6, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  6,D=(XY+o)  */
+OP(xycb,b3) { _E = RES(6, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  6,E=(XY+o)  */
+OP(xycb,b4) { _H = RES(6, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  6,H=(XY+o)  */
+OP(xycb,b5) { _L = RES(6, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  6,L=(XY+o)  */
+OP(xycb,b6) { WM( m_ea, RES(6,RM(m_ea)) );                              } /* RES  6,(XY+o)    */
+OP(xycb,b7) { _A = RES(6, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  6,A=(XY+o)  */
+
+OP(xycb,b8) { _B = RES(7, RM(m_ea) ); WM( m_ea,_B );                    } /* RES  7,B=(XY+o)  */
+OP(xycb,b9) { _C = RES(7, RM(m_ea) ); WM( m_ea,_C );                    } /* RES  7,C=(XY+o)  */
+OP(xycb,ba) { _D = RES(7, RM(m_ea) ); WM( m_ea,_D );                    } /* RES  7,D=(XY+o)  */
+OP(xycb,bb) { _E = RES(7, RM(m_ea) ); WM( m_ea,_E );                    } /* RES  7,E=(XY+o)  */
+OP(xycb,bc) { _H = RES(7, RM(m_ea) ); WM( m_ea,_H );                    } /* RES  7,H=(XY+o)  */
+OP(xycb,bd) { _L = RES(7, RM(m_ea) ); WM( m_ea,_L );                    } /* RES  7,L=(XY+o)  */
+OP(xycb,be) { WM( m_ea, RES(7,RM(m_ea)) );                              } /* RES  7,(XY+o)    */
+OP(xycb,bf) { _A = RES(7, RM(m_ea) ); WM( m_ea,_A );                    } /* RES  7,A=(XY+o)  */
+
+OP(xycb,c0) { _B = SET(0, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  0,B=(XY+o)  */
+OP(xycb,c1) { _C = SET(0, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  0,C=(XY+o)  */
+OP(xycb,c2) { _D = SET(0, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  0,D=(XY+o)  */
+OP(xycb,c3) { _E = SET(0, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  0,E=(XY+o)  */
+OP(xycb,c4) { _H = SET(0, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  0,H=(XY+o)  */
+OP(xycb,c5) { _L = SET(0, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  0,L=(XY+o)  */
+OP(xycb,c6) { WM( m_ea, SET(0,RM(m_ea)) );                              } /* SET  0,(XY+o)    */
+OP(xycb,c7) { _A = SET(0, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  0,A=(XY+o)  */
+
+OP(xycb,c8) { _B = SET(1, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  1,B=(XY+o)  */
+OP(xycb,c9) { _C = SET(1, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  1,C=(XY+o)  */
+OP(xycb,ca) { _D = SET(1, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  1,D=(XY+o)  */
+OP(xycb,cb) { _E = SET(1, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  1,E=(XY+o)  */
+OP(xycb,cc) { _H = SET(1, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  1,H=(XY+o)  */
+OP(xycb,cd) { _L = SET(1, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  1,L=(XY+o)  */
+OP(xycb,ce) { WM( m_ea, SET(1,RM(m_ea)) );                              } /* SET  1,(XY+o)    */
+OP(xycb,cf) { _A = SET(1, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  1,A=(XY+o)  */
+
+OP(xycb,d0) { _B = SET(2, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  2,B=(XY+o)  */
+OP(xycb,d1) { _C = SET(2, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  2,C=(XY+o)  */
+OP(xycb,d2) { _D = SET(2, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  2,D=(XY+o)  */
+OP(xycb,d3) { _E = SET(2, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  2,E=(XY+o)  */
+OP(xycb,d4) { _H = SET(2, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  2,H=(XY+o)  */
+OP(xycb,d5) { _L = SET(2, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  2,L=(XY+o)  */
+OP(xycb,d6) { WM( m_ea, SET(2,RM(m_ea)) );                              } /* SET  2,(XY+o)    */
+OP(xycb,d7) { _A = SET(2, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  2,A=(XY+o)  */
+
+OP(xycb,d8) { _B = SET(3, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  3,B=(XY+o)  */
+OP(xycb,d9) { _C = SET(3, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  3,C=(XY+o)  */
+OP(xycb,da) { _D = SET(3, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  3,D=(XY+o)  */
+OP(xycb,db) { _E = SET(3, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  3,E=(XY+o)  */
+OP(xycb,dc) { _H = SET(3, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  3,H=(XY+o)  */
+OP(xycb,dd) { _L = SET(3, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  3,L=(XY+o)  */
+OP(xycb,de) { WM( m_ea, SET(3,RM(m_ea)) );                              } /* SET  3,(XY+o)    */
+OP(xycb,df) { _A = SET(3, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  3,A=(XY+o)  */
+
+OP(xycb,e0) { _B = SET(4, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  4,B=(XY+o)  */
+OP(xycb,e1) { _C = SET(4, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  4,C=(XY+o)  */
+OP(xycb,e2) { _D = SET(4, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  4,D=(XY+o)  */
+OP(xycb,e3) { _E = SET(4, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  4,E=(XY+o)  */
+OP(xycb,e4) { _H = SET(4, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  4,H=(XY+o)  */
+OP(xycb,e5) { _L = SET(4, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  4,L=(XY+o)  */
+OP(xycb,e6) { WM( m_ea, SET(4,RM(m_ea)) );                              } /* SET  4,(XY+o)    */
+OP(xycb,e7) { _A = SET(4, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  4,A=(XY+o)  */
+
+OP(xycb,e8) { _B = SET(5, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  5,B=(XY+o)  */
+OP(xycb,e9) { _C = SET(5, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  5,C=(XY+o)  */
+OP(xycb,ea) { _D = SET(5, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  5,D=(XY+o)  */
+OP(xycb,eb) { _E = SET(5, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  5,E=(XY+o)  */
+OP(xycb,ec) { _H = SET(5, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  5,H=(XY+o)  */
+OP(xycb,ed) { _L = SET(5, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  5,L=(XY+o)  */
+OP(xycb,ee) { WM( m_ea, SET(5,RM(m_ea)) );                              } /* SET  5,(XY+o)    */
+OP(xycb,ef) { _A = SET(5, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  5,A=(XY+o)  */
+
+OP(xycb,f0) { _B = SET(6, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  6,B=(XY+o)  */
+OP(xycb,f1) { _C = SET(6, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  6,C=(XY+o)  */
+OP(xycb,f2) { _D = SET(6, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  6,D=(XY+o)  */
+OP(xycb,f3) { _E = SET(6, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  6,E=(XY+o)  */
+OP(xycb,f4) { _H = SET(6, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  6,H=(XY+o)  */
+OP(xycb,f5) { _L = SET(6, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  6,L=(XY+o)  */
+OP(xycb,f6) { WM( m_ea, SET(6,RM(m_ea)) );                              } /* SET  6,(XY+o)    */
+OP(xycb,f7) { _A = SET(6, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  6,A=(XY+o)  */
+
+OP(xycb,f8) { _B = SET(7, RM(m_ea) ); WM( m_ea,_B );                    } /* SET  7,B=(XY+o)  */
+OP(xycb,f9) { _C = SET(7, RM(m_ea) ); WM( m_ea,_C );                    } /* SET  7,C=(XY+o)  */
+OP(xycb,fa) { _D = SET(7, RM(m_ea) ); WM( m_ea,_D );                    } /* SET  7,D=(XY+o)  */
+OP(xycb,fb) { _E = SET(7, RM(m_ea) ); WM( m_ea,_E );                    } /* SET  7,E=(XY+o)  */
+OP(xycb,fc) { _H = SET(7, RM(m_ea) ); WM( m_ea,_H );                    } /* SET  7,H=(XY+o)  */
+OP(xycb,fd) { _L = SET(7, RM(m_ea) ); WM( m_ea,_L );                    } /* SET  7,L=(XY+o)  */
+OP(xycb,fe) { WM( m_ea, SET(7,RM(m_ea)) );                              } /* SET  7,(XY+o)    */
+OP(xycb,ff) { _A = SET(7, RM(m_ea) ); WM( m_ea,_A );                    } /* SET  7,A=(XY+o)  */