Initial import v0.0.1
authorHugo Villeneuve <hugo@hugovil.com>
Sat, 8 May 2004 02:56:47 +0000 (02:56 +0000)
committerHugo Villeneuve <hugo@hugovil.com>
Sun, 8 Sep 2013 14:49:17 +0000 (10:49 -0400)
46 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
config/debug.m4 [new file with mode: 0644]
config/gtk2.m4 [new file with mode: 0644]
configure.in [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/emu8051.man [new file with mode: 0644]
pixmaps/reset.xpm [new file with mode: 0644]
pixmaps/run.xpm [new file with mode: 0644]
pixmaps/step.xpm [new file with mode: 0644]
pixmaps/stop.xpm [new file with mode: 0644]
src/CPU8051.cpp [new file with mode: 0644]
src/CPU8051.hpp [new file with mode: 0644]
src/EmuConsole.cpp [new file with mode: 0644]
src/EmuConsole.hpp [new file with mode: 0644]
src/EmuGtk.cpp [new file with mode: 0644]
src/EmuGtk.hpp [new file with mode: 0644]
src/GtkSizes.hpp [new file with mode: 0644]
src/Inst_Def.hpp [new file with mode: 0644]
src/Inst_Imp.cpp [new file with mode: 0644]
src/Keyboard.hpp [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/MemWin.cpp [new file with mode: 0644]
src/MemWin.hpp [new file with mode: 0644]
src/Memory.cpp [new file with mode: 0644]
src/Memory.hpp [new file with mode: 0644]
src/Opcode2cpp.pl [new file with mode: 0755]
src/PgmWin.cpp [new file with mode: 0644]
src/PgmWin.hpp [new file with mode: 0644]
src/Reg8051.hpp [new file with mode: 0644]
src/RegWin.cpp [new file with mode: 0644]
src/RegWin.hpp [new file with mode: 0644]
src/disasm.hpp [new file with mode: 0644]
src/exceptions.hpp [new file with mode: 0644]
src/opcodes.lst [new file with mode: 0644]
test_files/siae1.hex [new file with mode: 0644]
test_files/test.hex [new file with mode: 0644]
test_files/timer.asm [new file with mode: 0644]
test_files/timer.hex [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  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 Library 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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+           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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..25aa334
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,492 @@
+------------------------------------------------------------------------------
+2002/11/12     Hugo Villeneuve         <hugovil@videotron.ca>
+       -Removed some warnings for GCC 3.2: replaced <fstream.h> by <fstream>
+        and <iostream.h> by <iostream>.
+       -Added "using namespace std;" in EmuGtk.hpp (for GCC 3.2)
+       -Removed all unused variables
+       -Corrected error in CPU8051.cpp, in function:
+               'void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )'
+        Modified this:
+               'sprintf( &Text[ TextLength ], ".%X", BitAddress );'
+        instead of:
+               'sprintf( &Text[ TextLength ], ".%X" );'
+       -In Opcode2cpp.pl (line 767), modified for GCC 3.2:
+               'print INST_IMP " funcptr[$i]=&CPU8051::$ifunc;\n";'
+        instead of:
+               'print INST_IMP " funcptr[$i]=&$ifunc;\n";'
+       -EmuGtk.cpp, added '#include <iostream>'
+       -Modified the return type of some functions to void to remove warnings.
+       -In function 'void RegWin::Show( CPU8051 *CPU )' (RegWin.cpp), removed all
+        the '\n' in 'gtk_clist_set_text' calls (to fix a display problem)
+------------------------------------------------------------------------------
+99/04/27       Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Ajoute les fonctions DumpInt dans EmuConsole.hpp ainsi que ReadInt
+         dans CPU8051.hpp. Corrige des bugs dans WriteInt et WriteExt.
+
+       - Corrige l'implementation des timers. Les 4 modes ont ete testes et
+         semblent bien fonctionner maintenant. LEs flags sont mis correctement
+         et les timers augmentent maintenant (au lieu d'etre decrementes).
+       - Ajoute un fichier timer.hex pour tester les timers.
+
+-----------------------------------------------------------------------------
+99/04/22       Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Ajoute les fonctions ME, MI et MP (voir definitions dans
+         EmuConsole.cpp). Ajoute les fonctions membres WriteExt et WriteInt
+         dans la classe CPU8051 afin de suivre la logique de l'espace
+         memoire du 8051. WriteExt permet de modifier la memoire externe
+         qui va de $00 a $FFFF (et non de $100 a $FFFF comme c'etait le cas
+         avant). De meme, WriteInt permet de modifier la memoire interne qui
+         va de $00 a $FF (incluant les SFR). Meme si la memoire externe
+         contient les adresses $00 a $FF, il n'y a pas de conflit avec la
+         memoire interne de $00 a $FF car la memoire externe est accedee avec
+         l'instruction MOVX alors que la memoire interne l'est avec les
+         instructions MOV (direct ou indirect).
+
+       - Renomme l'option DD du menu pour DE (dump External data memory).
+         Change la description de l'option DI du menu pour Dump External
+         Data Memory.
+
+       - Ajoute la fonction ReadExt dans la classe CPU8051, toujours pour
+         la logique de la memoire du 8051. Ajoute la fonction DumpExt dans la
+         classe EmuConsole pour dumper la memoire externe.
+       - Ces nouvelles fonctions ont ete testees et semblent bien fonctionner.
+------------------------------------------------------------------------------
+99/04/09       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Refait marche le RunningState avec les classes.
+       - Reconnecte les signaux aux boutons Trace, Run, Reset et Quit.
+       - Ajoute bouton Step qui ajoute un breakpoint a la ligne suivante
+       et passe en RunningState. Pratique lorsqu'arrive un CALL et qu'on ne
+       veut pas y entrer contrairement a Trace.
+------------------------------------------------------------------------------
+99/04/06       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Creation de EmuConsole.hpp et EmuConsole.cpp
+       - Cette nouvelle archive est presque rendue au meme niveau que
+       l'ancienne. Vous allez pouvoir commencer a laisser faire l'ancienne
+       et vous concentrer sur celle-ci.
+------------------------------------------------------------------------------
+(Les modifs annoncee se rapportent a l'ancienne archive mais elles ont ete
+ramenee dans celle-ci par Jonathan St-Andre)
+99/04/05       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Corrige qq malfonctions dans exec de mainconsole.cpp (nb d'inst.
+       peut etre l'infini, caractere est attendu au clavier seulement
+       si l'execution est arretee par une touche.
+       - Corrige probleme d'instructions sans operandes mal desassemblees
+       (il ne faut pas ecrire le caractere ' ' dans la chaine, il faut
+       utiliser sprintf avec " " a la place car sprintf termine la chaine
+       avec un 0 a la fin. La chaine n'etait pas terminee par un 0 et elle
+       affichait du garbage de la memoire)
+       - Corrige probleme dans disasm.cpp en rapport avec addr11 qui ne
+       prenait pas opcode mais memoire[opcode] (je devais etre chaud quand
+       j'ai ecrit ca).
+       - Bouton Run se change en Stop dans l'interface Gtk+ lorsque l'on
+       clique dessus et le cpu se met en mode execution. Les fonctions de
+       l'interface restent disponibles. N'importe quelle action dans
+       l'interface(excepte le fait de cliquer dans les fenetre memoire
+       et programme) cause l'arret de l'execution et la mise a jour
+       de l'affichage.
+       - Il est possible de placer des breakpoints pendant qu'il est
+       dans le "RunningState".
+       - Enleve les pixmaps sur les boutons dans l'interface Gtk+
+       - Ajoute verification de breakpoint deja existant dans
+       setbreakpoint.
+
+               Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       -Modifie l'affichage de disasm pour que les operandes soient alignees.
+       -Modifie la fonction DP pour qu'elle prenne l'adresse du PC par
+        defaut si aucune adresse n'est specifiee.
+
+       - Erreur avec l'instruction ACALL qui ne calculait pas l'adresse
+         correctement et qui ne poussait pas l'adresse de retour sur la pile.
+         Il est important que le PC soit incremente de 2 avant de calculer
+         addr11 et de pousser le PC sur la pile...
+         Il faut aussi modifier le dessassemblage de cette instruction qui
+         n'affiche que la deuxieme operande (adresse de 8 bits), alors que
+         l'adresse est sur 11 bits...
+       -Erreur avec l'instruction RET( fichier siae1.asm adresse 03A4) ,
+        affiche RET   @%K
+       -Ajoute la possibilite d'arreter l'execution du programme en pesant
+        sur n'importe quelle touche grace a la fonction kbhit().
+       -Ajoute les fonctions SB, RB et DB pour les breakpoints dans le
+        mode console. L'execution se fait jusqu'au breakpoint. Une fois
+        arrive au breakpoint, si on fait de nouveau EM, on peut continuer
+        l'execution du programme passe ce breakpoint. Autrement dit, EM
+        ne verifie pas si la premiere instruction qu'il execute est un
+        break point, ce qui est pratique pour continuer l'execution du prog
+        apres un breakpoint.
+------------------------------------------------------------------------------
+99/03/31-
+99/04/03       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Reecriture de TOUT les sources en imbriquant au maximum
+       dans des classes pour que ce soit plus lisible et reutilisable.
+       - Les classes sont CPU8051, Memory, EmuGtk, MemWin, RegWin, PgmWin
+       et les exceptions.
+       - Tout est en anglais pour rendre le programme disponible sur
+       internet.
+       - Je n'ai pas encore refais l'interface Console en classes donc
+       elle n'est pas incluse dans cette archive. Il faudrait vraiment
+       la refaire en tant que classe.
+       - Ajout fichiers TODO, CREDITS et COPYING (license GPL)
+------------------------------------------------------------------------------
+99/03/30       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Corrige bug lors du desassemblage dans l'interpretation des
+       adresses directes dans 0-7F. disasm.cpp
+       - Corrige bug dans l'opcode 0x85, ajoute conditions particulieres
+       pour cette instruction dans script Perl et dans desassemblage.
+       Les operandes de cette instruction sont inversees dans la memoire
+       programme. Ex.: MOV 50H,51H est ecrit 85 51 50 dans la memoire
+       programme.
+
+               Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Bug dans les instructions ayant un mode d'adressage direct qui
+       utilisent des adresses dans 0-7F. Le desassembleur interprete les
+       adresses comme etant des adresses de bit.
+       - Bug dans l'opcode 0x85 MOV direct,direct. La source et la
+       destination sont inverses dans le desassemblage et dans l'execution.
+------------------------------------------------------------------------------
+99/03/29       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Remplace string::erase pour string::replace partout, g++ a
+       l'universite ne connait pas encore string::erase, c'est trop recent.
+       - Ajoute "-w" pour disabler les warnings et "-fhandle-exceptions"
+       pour activer les exceptions a l'universite.
+
+               Pascal Fecteau          <fectea00@gel.ulaval.ca>
+
+       - Ajoute .h comme extension aux fichiers inclus, sinon ca ne
+       fonctionne pas a l'universite.
+
+               Pascal Fecteau          <fectea00@gel.ulaval.ca>
+               Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Corrige une erreur dans les instructions AJMP addr11
+------------------------------------------------------------------------------
+99/03/28       Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Modification de la presentation de "Dump Register" sur la console.
+       Beaucoup plus facile a lire maintenant.
+       - Correction d'un bug dans l'instruction DA (opcode 0xD4).
+------------------------------------------------------------------------------
+99/03/27       Hugo Villeneuve         <villen01@gel.ulaval.ca>
+
+       - Correction d'un probleme avec l'instruction CJNE.
+       - Correction de bugs dans LoadHexFile (voir 99/03/22)
+
+               Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Augmente la hauteur de la fenetre Internal RAM.
+       - Correction de probleme avec tous les XCH et XCHD, l'operande source
+       n'etait pas modifiee (Trouve par Hugo et suggestion de correction par
+       Hugo).
+       - Ajout de P0, P1, P2 et P3 dans la fenetre des registres.
+       (Suggestion d'Hugo).
+       - View -> Data Memory Dump et View -> Program Memory Dump sont
+       fonctionnels. On ne peut visionner que les 16384 premiers octets.
+       Il ne veut pas prendre 65536 lignes dans une scrolled window.
+       Probablement parce que 18colonnes x 65536lignes = 1179648 cellules
+       est beaucoup trop.
+       - J'ai remarque qu'avec Gtk, on peut facilement changer les raccoucis
+       dans les menus. Pour associer "View -> Program Memory Dump" au
+       raccourci "Alt-2" par exemple, il suffit d'aller dans le menu "View",
+       se placer au dessus de "Program Memory Dump" et appuyer "Alt-2".
+       Le menu se modifiera automatiquement pour afficher "Alt-2" au bout
+       de la ligne et desormais, lorsque vous appuierez "Alt-2", l'action
+       sera executee. Ca dure seulement durant la session presente.
+       - Reduit la taille de la fenetre principale en largeur de 120 pixels
+       et en hauteur de 20 pixels.
+------------------------------------------------------------------------------
+99/03/25       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Fenetre dump connais la position ou on clique dedans.
+       - Generalise dans une classe la fenetre memorydump, il sera plus
+       facile d'ajouter plusieurs fenetres memory dump a partir du menu
+       plus tard.
+       - Implemente Run jusqu'a un breakpoint (si aucun breakpoint,
+       loop sans fin -> il faut killer).
+       - Suffit de cliquer sur une ligne de programme dans Gtk pour placer
+       ou retirer un breakpoint. Les breakpoints apparaissent comme une
+       asterisque (*) a droite de l'adresse dans la fenetre program.
+       - Ajoute bouton Run dans interface Gtk
+       - Implemente quelques fonctions necessaires au breakpoints.
+       - Change un peu le layout
+       - Enleve image de fond (cause leger delai au chargement)
+       - Fait un peu de menage dans fichiers relatifs au Gtk
+------------------------------------------------------------------------------
+99/03/23       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Changement des champs GTK_TEXT des fenetres Registre, Program et
+       Internal RAM pour des champs GTK_CLIST. Plus beau, moins de
+       flickering quand on trace et plus pratique pour ce qui s'en vient.
+       - Integration des fichiers xpm dans l'executable. Mais c'est encore
+       trop long a charger lors de l'execution, va probablement falloir les
+       compresser ou laisser faire l'image de fond.
+       - Ajout de pixmaps sur les boutons Trace, Reset et Quit (Gtk)
+       - Ajout de pixmap comme fond (Gtk)
+------------------------------------------------------------------------------
+99/03/22        Hugo Villeneuve <villen01@gel.ulaval.ca>
+
+       - Corrige un bug dans la fonction LoadHexFile : Le checksum n'etait
+         pas calcule correctement, ce qui entrainait des erreurs a l'ouverture
+         de certains fichiers HEX. L'erreur venait du fait que le checksum se
+         calculait avec la valeur absolue du LoadOffset, au lieu d'utiliser
+         les caracteres composant le LoadOffset. Exemple : si LoadOffset =
+         0103, il faut additionner 01h+03h=4h au Checksum et non pas 0103h = 
+         259 en decimal.
+       - Deplace la fonction enleve_espaces de main_console vers mainemu
+         car elle est commune aux deux interfaces graphiques.
+       - Modifie la fonction majuscules pour qu'elle puisse convertir les
+         lettres de minuscule a majuscule meme si la chaine contient des
+         chiffres ou autres signes de ponctuation.
+       - Modifie la declaration des fonctions dans tous les fichiers .hpp:
+         enleve le nom des parametres car c'etait inutile.
+       - Stocke le nom des registres dans un fichier registres8051.hpp.
+         Ainsi, si on veut emuler un autre type de processeur, il suffira
+         de se creer un autre fichier registres8052xxx.hpp par exemple.
+       - Implemente l'affichage en francais ou en anglais dependant de
+         l'option passee sur la ligne de commande. L'interface est beaucoup
+         plus lisible de cette facon. Par defaut, l'affichage est en anglais.
+------------------------------------------------------------------------------
+99/03/21        Hugo Villeneuve <villen01@gel.ulaval.ca>
+
+       - Ajoute deux parametres qu'on peut passer par la ligne de commande:
+           /?  affiche les options disponibles sur la ligne de commande.
+           -f  force l'affichage en francais (pas encore implemente!!!)
+       - Ajoute le controle d'erreur pour le chargement d'un fichier HEX.
+         Les differentes erreurs sont controlees ( checksum, rectype,
+         fin de fichier, etc.).
+       - Modifie la fonction unasm pour qu'elle accepte 0,1 ou 2 parametres.
+         U (adresse) (nombre d'instructions)
+         Si adresse et nombre d'instructions non-specifies:
+           Adresse = PC et Nombre d'Instructions = 16
+         Si adresse specifie et nombre d'instructions non-specifie:
+           Adresse = adresse specifiee et Nombre d'Instructions = 16
+         Si adresse specifie et nombre d'instructions specifie:
+           Adresse = adresse specifiee et Nombre d'Instructions = nb specifie
+         A noter: on peut specifier une adresse comme etant un nombre
+         hexadecimal, ou tout simplement en entrant "PC" ou "pc".
+
+               Jonathan St-Andre       <standr00@gel.ulaval.ca
+
+       - Fait le menage dans la fonction main
+       - Modifie Makefile.console et Makefile.gtk
+       - Rearrangement des fichiers pour limiter les impacts sur
+       tout le projet lors de modifications dans une partie et
+       pour accelerer la compilation (en modules).
+       - Creation de mainconsole.hpp + mainconsole.cpp
+       - Creation de maingtk.cpp + maingtk.hpp
+       - Creation de mainemu.cpp + mainemu.hpp
+       - Elimine fonctions.cpp.
+       - Elimination du 2e parametre a unasm. Desassemble
+       de nouveau 16 instructions.
+       - Ajustement du menu pour qu'il rentre dans la largeur
+       d'un terminal 80x25.
+       
+               Jimmy Ringuette <ringue00@gel.ulaval.ca>
+
+       - Ajout des interruptions du port serie.
+       - Ajout du timer 2 (8052).
+------------------------------------------------------------------------------
+99/03/20        Hugo Villeneuve <villen01@gel.ulaval.ca>
+
+       - Separe le fichier main.cpp en deux: main.cpp et fonctions.cpp.
+         fonctions.cpp contient les fonctions necessaires a main.cpp.
+       - Ajoute un fichier exceptions.hpp qui permet de gerer les erreurs.
+       - Modifie le Makefile en consequence.
+       - On peut maintenant entrer les adresses < a quatre caracteres :
+         ex: adresse 0000h = 0 ou 00 ou 000 ou 0000.
+       - Enleve le include <stdlib.h>
+       - Remplace toutes les commandes printf du main par cout.
+       - Modifie l'apparence du menu.
+       - Le programme est maintenant plus robuste en ce qui concerne les
+         erreurs de syntaxe, les adresses invalides, etc (a tester...).
+       - Modifier l'operation et la syntaxe de certaines commandes
+         S (set register) devient MR (modify register) car set veut
+         plutot dire "mettre a 1", et on pourra aussi implementer
+         MM (modify Memory).
+         R devient DR (display Register), pour suivre la logique de
+         DP, DM et DI.
+       - Ajoute une commande Execute Memory: EM addr n
+       - La gestion des chaines de caracteres se fait maintenant
+         uniquement avec des variables de type STRING, selon le C++.
+       - Enleve variables i,j,k et inputcars dans le main.
+       - Modifie la fonction RESET pour quelle n'affiche pas les
+         registres au demarrage... ca faisait pas beau! Ajoute
+         cependant un message pour dire que le up est resette.
+       - Pour changer un registre, on doit entrer PC (et non p) ainsi
+         que SP (et non seulement s).
+       - Ajoute une fonction qui convertit une chaine de caracteres
+         en majuscules.
+------------------------------------------------------------------------------
+99/03/19       Jonathan St-Andre       <standr00@gel.ulaval.ca>
+
+       - Fonction reset51() ajoutee dans cpu8051.cpp, reset() ajoutee
+       dans main.cpp.
+       - Commande "Z" fait un reset du processeur sur la console et le
+       bouton Reset fonctionne dans le GUI.
+
+               Jimmy Ringuette <ringue00@gel.ulaval.ca>
+
+       - Les interruptions sont maintenant implementees. check_hardware() a
+       ete supprimee et Do_timers() est appelee directement de exec8051().
+------------------------------------------------------------------------------
+99/03/18        Hugo Villeneuve <villen01@gel.ulaval.ca>
+
+       - Modifie l'entree des commandes pour gerer un peu plus les erreurs
+         de syntaxe (je n'ai pas fini, il y a encore de la job a faire pour
+         mettre ca error proof).
+       - Simplifie l'entree des parametres pour chacune des fonctions.
+       - Re-modifie l'instruction trace pour avoir seulement deux modes:
+         trace a adresse et trace 1 instruction. Cela simplifie l'entree de
+         la commande (on n'a pas a faire TA, qui n'est pas une commande
+         standard dans les emulateurs). Si on veut faire tracer pour plusieurs
+         instructions, alors il suffira d'implementer la commande
+         EXECUTE Nombre_instructions, ce qui est beaucoup plus logique et 
+         c'est ce qu'on retrouve dans la plupart des emulateurs.
+       - Ajoute la description des commandes en francais (loi 101).
+------------------------------------------------------------------------------
+99/03/18       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Le bouton Trace dans la version Gtk+ fonctionne. On peut tracer
+       et les 3 fenetres(registres, memoire, programme) se mettent a jour.
+       - Ajout de 2 nouvelles fonctions trace : "tracenb()" et "traceat()"
+       Qui, respectivement, prenent un nombre d'instruction a executer ou
+       une adresse ou commencer l'execution. La fonction trace() a ete
+       resimplifiee.
+       - Dans les instructions RET, RETI, LCALL, PUSH et POP la pile prend
+       la iram seulement pour les adresses sous 0x80, la data RAM est
+       utilisee autrement. Avant, les SFR se faisaient ecraser!
+       - Modes d'addressage addr16, reladdr, #data16 modifies!
+       En tenant compte de ce que Hugo avait fait remarquer ce matin :
+       ex.: si PC++ apparait 2 fois sur une ligne, les 2 fois il repartira
+       de la meme valeur de PC et suite a cette ligne, on se trouve avec
+       un PC incremente 1 fois au lieu de 2.
+       - Menu accepte maj/minuscules
+       - Corrige bug dans "setreg", les registres peuvent vraiment
+       etre donnes en maj/minuscules maintenant.
+------------------------------------------------------------------------------
+99/03/17       Hugo Villeneuve <villen01@gel.ulaval.ca
+
+        - Corrige les instructions LJMP et LCALL qui ne calculaient pas la
+          bonne adresse pour le PC. Toutes les autres instructions de
+          branchement sont probablement a revoir pour le meme probleme. Le
+          probleme etait cause par la syntaxe dans le fichier instructions.hpp
+          (lignes ou on retrouve addr16 = (pgm_mem[PC++] << 8)+pgm_mem[PC++] a
+          remplacer par addr16 = (pgm_mem[PC+1] << 8) + pgm_mem[PC+2] )
+       - Modifie la commande TRACE pour qu'on puisse lui passer une adresse
+          de depart comme parametre (main.cpp lignes 406-409) et modifie
+          en consequence ascii2hex pour qu'il ignore les espaces avant
+          l'adresse. (main.cpp ligne 133).
+------------------------------------------------------------------------------
+99/03/14       Pascal Fecteau <fectea00@gel.ulaval.ca>
+
+       - Correction de bugs relatifs a la compilation sur VC5.
+       Dont ajout de #include <string.h>.
+------------------------------------------------------------------------------
+99/03/13       Jimmy Ringuette <ringue00@gel.ulaval.ca>
+
+       - Ajout des timers dans cpu8051.cpp. Il faudrait tester a fond.
+------------------------------------------------------------------------------
+99/03/12       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Je crois qu'il sera plus interessant si on garde le memory
+       dump normal dans une fenetre exterieur et dont on pourra en ouvrir
+       plusieurs pour monitorer differents endroits de la memoire, c'est
+       pourquoi je n'ai place que "Internal RAM" comme memory dump dans
+       la fenetre principale.
+       - Au demarrage, effectue un premier memory dump dans la fenetre
+       "Internal RAM", un unasm dans "Program" et un show register dans
+       "Registers".
+       - Bouton Quit, menus "File -> Quit" et "Help -> About" reagissent.
+       - Comporte maintenant 2 Makefile : Makefile.console(fonctionne sur
+       toutes les plateformes) et Makefile.gtk(teste seulement sous Linux).
+       - DEBUT d'interface graphique Gtk+ (ne fait qu'afficher une fenetre
+       avec un layout tres simple), presentement je cours apres des sources
+       de documentations.(le manuel n'est pas encore complet)
+------------------------------------------------------------------------------
+99/03/09       Jimmy Ringuette <ringue00@gel.ulaval.ca>
+
+        - Regle le bug avec mul (probleme avec les bits 15-8 du resultat
+       ne se ramenaient pas dans les bits 7-0 du registre B)
+        - La conversion chaine->hexadecimal accepte les minuscules
+        - Il n'est plus obligatoire d'ecrire les 4 caracteres lorsqu'il faut
+       entrer une valeur hexadecimale.
+------------------------------------------------------------------------------
+99/03/05       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Corrige un warning de compilation sous Solaris.
+------------------------------------------------------------------------------
+99/03/04       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Ca execute! (presque) 
+       - Phase de corrections des bugs dans les instructions, une premiere
+       implementation est faite pour toutes les instructions. 
+       - Ajout fonction "trace" et "dump internal memory" 
+       - Les modes d'adressage sont pratiquement termines dans
+       les instructions. 
+       - Certaines instructions ont un debut d'implementation. 
+       - Desassembleur, bit addressable segment 00-7F -> 20.0-2F.7 
+------------------------------------------------------------------------------
+99/03/03       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Ajout automatique de certaines lignes de codes concernant
+       l'adressage dans les fonctions d'instructions tres brouillon 
+       - Ajout de stub pour write_mem et read_mem, modifs dans exec8051 
+       - Ajout de la fonction showregister() et de la commande 'r'. 
+       - Correction d'une erreur iram_mem doit etre unsigned char et non int
+       - Note : Il y a des references a certaines parties du 8052 mais
+       elles ne seront pas implementees. Ce n'est qu'a titre d'informations.
+       - Ajout de #define pour faire correspondre les registres SFR avec
+       leur adresse dans la iram. 
+       - Renomme instructions.cpp a instructions.hpp et ajout du tableau
+       de pointeurs sur les fonctions 
+       - Ajout de la ram interne 00-FF et valeurs initiale au reset
+       dans cpu8051.cpp avec le registre : unsigned int PC. 
+       - Ajout de cpu8051.cpp contenant exec8051() 
+------------------------------------------------------------------------------
+99/03/02       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Ajout de remarques dans le source 
+       - Il faudrait maintenant tester avec plusieurs programmes pour
+       reperer les bugs. 
+       - Le desassembleur reconnait maintenant les registres du SFR
+       (ex.: 88H est remplace par TCON, F0 par B, etc...) 
+       - Changement au desassembleur (instructions peuvent avoir jusqu'a 3
+       arguments ex.: CJNE R0,#data,reladdr) 
+       - La vrai instruction CJNE comporte 3 arguments il faut changer 
+       radicalement le desassembleur 
+------------------------------------------------------------------------------
+99/03/01       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Probleme dans opcodes.lst au niveau de l'instruction CJNE (mauvaise
+        definition) 
+       - Tous les types d'adressages semblent fonctionner 
+       - Le desassembleur peut lire les arguments et les afficher 
+       (ex.: MOV A,#data peut devenir plus concret MOV A,#20) 
+       - Desassembleur (instructions ont 2 arguments : instleftarg et 
+       instrightarg) 
+------------------------------------------------------------------------------
+99/02/28       Jonathan St-Andre <standr00@gel.ulaval.ca>
+
+       - Charge un fichier .hex donne en parametre (format Intel Hexadecimal 
+       produit par ASM51) 
+       - Effectue le dump program memory et dump data memory 
+       - On peut quitter (YEAH!) 
+       - Affiche le menu 
+       - Creation de opcodes.lst et script Perl pour l'interpreter 
+       - Debut
+
+
+
+
+
+
+
+
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..a4b3414
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,229 @@
+Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..db1bf04
--- /dev/null
@@ -0,0 +1,25 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = gnu
+
+SUBDIRS = src doc
+
+EXTRA_DIST = bootstrap \
+             $(ac_aux_dir)/debug.m4 \
+             $(ac_aux_dir)/gtk2.m4 \
+             pixmaps/*.xpm \
+             test_files/*
+
+ACLOCAL = aclocal -I $(ac_aux_dir)
+
+CLEANFILES = *~
+
+DISTCLEANFILES = .deps/*.P
+
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in stamp-h.in \
+                       $(ac_aux_dir)/depcomp $(ac_aux_dir)/install-sh $(ac_aux_dir)/missing \
+                       $(ac_aux_dir)/mkinstalldirs $(ac_aux_dir)/config.guess \
+                       $(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh
+
+
+
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..4896be3
--- /dev/null
+++ b/TODO
@@ -0,0 +1,15 @@
+       THINGS TO DO
+       ------------
+
+-Compile only one program for both graphical and console modes, or
+ support only the graphical mode.
+- Some fine tuning around the classes
+- Make MemWin, RegWin be able to make a standalone
+  window if parentwin=0.
+- Connect File->Open, View->... and Help->License menus.
+- Make the RegWin and MemWin react when mouse clicked. (modify register or
+  memory)
+- Enlever les fonctions ReadI, WriteI, dumpI etc... et plutot utiliser les
+  fonctions ReadInt, WriteInt, DumpInt, DumpExt, etc.
+- Lors d'un DumpInt, verifier a ne pas afficher plus haut que la taille
+  reelle de la memoire interne. (Detail)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..3cbbe7d
--- /dev/null
@@ -0,0 +1,28 @@
+#! /bin/sh
+# bootstrap -- Use this script to create generated files from the CVS dist
+# Copyright (C) 2000 Gary V. Vaughan
+#
+# 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+## @start 1
+#! /bin/sh
+
+set -x
+aclocal -I config
+##libtoolize --force --copy
+autoheader
+automake --add-missing --copy
+autoconf
+## @end 1
diff --git a/config/debug.m4 b/config/debug.m4
new file mode 100644 (file)
index 0000000..f8fc330
--- /dev/null
@@ -0,0 +1,18 @@
+dnl
+dnl Macro for adding an option to 'configure' for enabling debugging messages
+dnl
+AC_DEFUN([HV_CHECK_FOR_DEBUG],[
+AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
+                                    [enable debugging messages on console
+                                     (default is NO)]),[
+  if test x"${enableval}" = xyes; then
+    debug_messages=1
+    AC_DEFINE([DEBUG],1,[Set to 1 to enable debugging messages.])
+  elif test x"${enableval}" = xno; then
+    debug_messages=0
+  else
+    AC_MSG_ERROR(bad value for --enable-debug option)
+  fi
+], debug_messages=0 )
+])
+
diff --git a/config/gtk2.m4 b/config/gtk2.m4
new file mode 100644 (file)
index 0000000..46f02a7
--- /dev/null
@@ -0,0 +1,17 @@
+dnl
+dnl Macro for adding an option to 'configure' for choosing GTK+-2 instead of the
+dnl GTK+-1 default
+dnl
+AC_DEFUN([HV_CHECK_FOR_GTK2],[dnl
+AC_ARG_WITH(gtk2, AC_HELP_STRING([--with-gtk2], [use GTK2 (default is GTK1)]),[dnl
+  if test x"${withval}" = xyes; then
+    use_gtk2=1
+    AC_DEFINE([USE_GTK2],1,[Set to 1 to use the Gtk+-2 library.])
+  elif test x"${withval}" = xno; then
+    use_gtk2=0
+  else
+    AC_MSG_ERROR(bad value for --with-gtk2 option)
+  fi
+], use_gtk2=0 )
+])
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..d033b20
--- /dev/null
@@ -0,0 +1,89 @@
+# configure.in -- Process this file with autoconf to produce configure
+
+dnl Initialization stuff.
+AC_INIT(emu8051, 0.1.0)
+AC_CONFIG_AUX_DIR(config)
+AC_CONFIG_SRCDIR(src/CPU8051.cpp)
+AM_CONFIG_HEADER(config.h:config-h.in)
+dnl Checking if the NEWS file has been updated to reflect the current version.
+AM_INIT_AUTOMAKE(check-news)
+
+dnl Tests the C compiler
+AC_PROG_CC
+AC_LANG_C
+
+dnl Checking for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(strings.h unistd.h)
+
+dnl Checking for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+
+dnl Basic CFLAGS values
+CFLAGS="-Wall"
+
+dnl Checks for '--enable-debug' option
+HV_CHECK_FOR_DEBUG
+
+if test x"${debug_messages}" = x1; then
+dnl -g is for GDB debugging
+  CFLAGS="${CFLAGS} -g -gdwarf-2 -g3"
+fi
+
+dnl Checks for '--with-gtk2' option
+HV_CHECK_FOR_GTK2
+
+if test x"${use_gtk2}" = x0; then
+  dnl Checks for Gtk+-1.2.0
+  AM_PATH_GTK(1.2.0, CFLAGS="${CFLAGS} ${GTK_CFLAGS}" LIBS="${LIBS} ${GTK_LIBS}",
+  AC_MSG_ERROR(GTK+ not found!))dnl
+else
+  dnl Checks for Gtk+-2.0
+  PKG_CHECK_MODULES(GTK,gtk+-2.0 >= 2.0.5, CFLAGS="${CFLAGS} ${GTK_CFLAGS}" \
+  LIBS="${LIBS} ${GTK_LIBS}",AC_MSG_ERROR(GTK+-2.0 not found!))dnl
+fi
+
+dnl Tests the C++ compiler
+AC_PROG_CXX
+AC_LANG_CPLUSPLUS
+
+CXXFLAGS="${CFLAGS}"
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(LIBS)
+AC_SUBST(ac_aux_dir)
+
+dnl Creating output file(s)
+AC_OUTPUT(Makefile src/Makefile doc/Makefile)
+
+echo \
+"---------------------------------------------------------------------------
+Configuration:
+
+  Install path:        ${prefix}
+  Compiler:            ${CC}
+  Compiler flags:      ${CFLAGS}
+  Linker flags:        ${LIBS}"
+
+echo -n "  GTK base version:    "
+if test x"${use_gtk2}" = x1; then
+  echo "2"
+else
+  echo "1"
+fi
+
+echo -n "  Debugging messages:  "
+if test x"${debug_messages}" = x1; then
+  echo "yes"
+else
+  echo "no"
+fi
+
+echo \
+"
+  See config.h for further configuration information.
+---------------------------------------------------------------------------"
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..edc4c8a
--- /dev/null
@@ -0,0 +1,9 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+
+man1_MANS = emu8051.man
+
+EXTRA_DIST = $(man1_MANS)
+
+CLEANFILES = *~
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/doc/emu8051.man b/doc/emu8051.man
new file mode 100644 (file)
index 0000000..aa9cef6
--- /dev/null
@@ -0,0 +1,123 @@
+.TH WMNOTIFY 1 "March 2003" "wmnotify" "User's Manual"
+
+.SH NAME
+wmnotify \- Dockable E-mail notification program for single POP3 account
+
+.SH SYNOPSIS
+.B wmnotify
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+\fBwmnotify\fR is a dockable application (DockApp) for the WindowMaker window
+manager to periodically check a POP3 E-mail account for new messages. If there
+are new messages in the mailbox, a simple animation is started to notify the
+user. An optional beep or sound can also be produced if desired.
+
+The interface is kept very simple. To immediately check for new messages,
+single-click on the mailbox image. To start your favorite email program, 
+double-click on the mailbox image.
+
+When you double-click on the mailbox image to start your email program,
+the new messages animation is stopped, assuming that you will read your new
+messages. If you don't, the wmnotify program will simply continue it's
+periodic checking of your email account and will restart the new messages
+animation after the usual delay if new messages are unread.
+
+By default, the interval between checks is 1 minute, and this can be changed in
+the configuration file. You can also enable audio notification as well as
+specify an optional audio sound file (WAV or AU). If audio notification is
+enabled but no audio sound file is specified, a beep will be produced. There is
+an option in the configuration file to adjust the volume of the sound file.
+
+.SH "OPTIONS"
+.TP
+.BI "\-\^c " config-file
+.B wmnotify
+reads your POP3 account settings and preferences from the specified
+configuration file. This option overrides the use of the default config file,
+.IR "$HOME/.wmnotifyrc".
+
+.TP
+.BI \-display " host" : display
+Specifies the host and screen to be used by \fBwmnotify\fR. By default this
+is obtained from the environment variable
+.SB DISPLAY.
+
+.TP
+.BI \-geometry " geometry"
+.RB ( *geometry )
+Specifies the initial geometry of the window.
+
+.TP
+\fB\-h\fR
+display usage and exit
+.TP
+\fB\-v\fR
+output version information and exit
+
+.SH "CONFIGURATION FILE"
+.IR $HOME/.wmnotifyrc
+
+The first time the program is run, it will check for the presence of the
+configuration file in the user's home directory. If this file is not found,
+wmnotify will automatically create a new one, and exit. Then the user must
+enter it's POP3 account settings and preferences in the configuration file
+before restarting wmnotify.
+
+.TP
+.BI "server " <pop3-servername>
+POP3 server name.
+
+.TP
+.BI "port " <pop3-portnumber>
+POP3 port number (optional, default value is 110).
+
+.TP
+.BI "username " <pop3-username>
+POP3 username.
+
+.TP
+.BI "password " <pop3-password>
+POP3 password.
+
+.TP
+.BI "mailcheckdelay " <delay-in-minutes>
+Mail check interval, in minutes (optional, default value is 1).
+
+.TP
+.BI "mailclient " <program>
+The program to start when double-clicking on the mailbox image (optional).
+
+.TP
+.BI "enablebeep " <value>
+This option controls the audio notification enabling/disabling. If this option
+is enabled and the "audiofile" option below contains a valid audio file, it
+will be played whenever new message(s) are detected. If "audiofile" is
+commented, the console beep will be used to produce the audio notification. The
+value may be set to "0" to disable or to "1" to enable (optional, default value is 0, disabled).
+
+.TP
+.BI "audiofile " <path-to-audiofile>
+Path and filename of the WAV or AU audio sound file to play when new message(s)
+are detected (optional).
+
+.TP
+.BI "volume " <value>
+Volume value, in percent, when playing an audio file (optional, default value is
+100%). This volume value is relative to the values you have set in your sound
+card mixer settings. If you find the audio notification sound to be too loud,
+just reduce the volume value. On the other hand, if you want to increase the
+audio notification sound amplitude, just increase the volume. If you increase
+the volume value to 100% and you find that it is not sufficient, then you would
+have to increase the volume using your favorite sound card mixer program
+(ex: with alsamixer, increase the PCM or master value).
+
+.SH CREDITS
+\fBwmnotify\fR was written by Hugo Villeneuve <hugovil@videotron.ca>, based on
+the WMPop3 program by Scott Holden <scotth@thezone.net>.
+
+.SH COPYRIGHT
+\fBwmnotify\fR is free; anyone may redistribute it to anyone under the terms
+stated in the GNU General Public License. A copy of the license is included in
+the \fBwmnotify\fR distribution. You can also browse it online at
+.I http://www.gnu.org/copyleft/gpl.html
diff --git a/pixmaps/reset.xpm b/pixmaps/reset.xpm
new file mode 100644 (file)
index 0000000..a7df6bd
--- /dev/null
@@ -0,0 +1,54 @@
+/* XPM */
+static char * reset_xpm[] = {
+"48 48 3 1",
+"      c None",
+".     c #005A9C",
+"+     c #FFFFFF",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"..+++++++..++++++++..+++++++.++++++++.++++++++..",
+"..++++++++.++++++++.++++++++.++++++++.++++++++..",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.+++++++..+++++++..+++++++.....++.....",
+"..+++++++..+++++++...+++++++.+++++++.....++.....",
+"..+++++++..++.............++.++..........++.....",
+"..++....++.++.............++.++..........++.....",
+"..++....++.++.............++.++..........++.....",
+"..++....++.++++++++.++++++++.++++++++....++.....",
+"..++....++.++++++++.+++++++..++++++++....++.....",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................"};
diff --git a/pixmaps/run.xpm b/pixmaps/run.xpm
new file mode 100644 (file)
index 0000000..d456e74
--- /dev/null
@@ -0,0 +1,55 @@
+/* XPM */
+static char * run_xpm[] = {
+"48 48 4 1",
+"      c None",
+".     c #000000",
+"+     c #008C6B",
+"@     c #FFFFFF",
+"                  ...........                   ",
+"              ...................               ",
+"            ........+++++++........             ",
+"          ......+++++++++++++++......           ",
+"         .....+++++++++++++++++++.....          ",
+"       .....+++++++++++++++++++++++.....        ",
+"      .....+++++++++++++++++++++++++.....       ",
+"     ....+++++++++++++++++++++++++++++....      ",
+"     ...+++++++++++++++++++++++++++++++...      ",
+"    ...+++++++++++++++++++++++++++++++++...     ",
+"   ....+++++++++++++++++++++++++++++++++....    ",
+"   ...+++++++++++++++++++++++++++++++++++...    ",
+"  ...+++++++++++++++++++++++++++++++++++++...   ",
+"  ...+++++++++++++++++++++++++++++++++++++...   ",
+" ...+++++++++++++++++++++++++++++++++++++++...  ",
+" ...+++++++++++++++++++++++++++++++++++++++...  ",
+" ..+++++++++++++++++++++++++++++++++++++++++..  ",
+" ..++++++++@@@@@@@++@@++++@@+@@++++@@+++++++..  ",
+"...++++++++@@@@@@@@+@@++++@@+@@@+++@@+++++++... ",
+"...++++++++@@++++@@+@@++++@@+@@@+++@@+++++++... ",
+"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@+@@+@@++++++++.. ",
+"..+++++++++@@@@@@@++@@++++@@+@@+@@+@@++++++++.. ",
+"..+++++++++@@@@@@@++@@++++@@+@@++@@@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@++@@@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@+++@@@++++++++.. ",
+"...++++++++@@++++@@+@@@@@@@@+@@+++@@@+++++++... ",
+"...++++++++@@++++@@++@@@@@@++@@++++@@+++++++... ",
+" ..+++++++++++++++++++++++++++++++++++++++++..  ",
+" ..+++++++++++++++++++++++++++++++++++++++++..  ",
+" ...+++++++++++++++++++++++++++++++++++++++...  ",
+" ...+++++++++++++++++++++++++++++++++++++++...  ",
+"  ...+++++++++++++++++++++++++++++++++++++...   ",
+"  ...+++++++++++++++++++++++++++++++++++++...   ",
+"   ...+++++++++++++++++++++++++++++++++++...    ",
+"   ....+++++++++++++++++++++++++++++++++....    ",
+"    ...+++++++++++++++++++++++++++++++++...     ",
+"     ...+++++++++++++++++++++++++++++++...      ",
+"     ....+++++++++++++++++++++++++++++....      ",
+"      .....+++++++++++++++++++++++++.....       ",
+"       .....+++++++++++++++++++++++.....        ",
+"         .....+++++++++++++++++++.....          ",
+"          ......+++++++++++++++......           ",
+"            ........+++++++........             ",
+"              ...................               ",
+"                  ...........                   ",
+"                                                "};
diff --git a/pixmaps/step.xpm b/pixmaps/step.xpm
new file mode 100644 (file)
index 0000000..167cac3
--- /dev/null
@@ -0,0 +1,56 @@
+/* XPM */
+static char * step_xpm[] = {
+"48 48 5 1",
+"      c None",
+".     c #FFDE08",
+"+     c #000000",
+"@     c #FFFFFF",
+"#     c #080800",
+"..........++++++++++++............++++++++++++..",
+"...........++++++++++++............++++++++++++.",
+"............++++++++++++............++++++++++++",
+"+............++++++++++++............+++++++++++",
+"++............++++++++++++............++++++++++",
+"+++............++++++++++++............+++++++++",
+"++++............++++++++++++............++++++++",
+"+++++............++++++++++++............+++++++",
+"++++++............++++++++++++............++++++",
+"+++++++............++++++++++++............+++++",
+"++++++++............++++++++++++............++++",
+"+++++++++............++++++++++++............+++",
+"++++++++++............++++++++++++............++",
+"+++++++++++............++++++++++++............+",
+"++++++++++++............++++++++++++............",
+".++++++++++++++++++++++++++++++++++++++++++++...",
+"..+++++++++++++++++++++++++++++++++++++++++++...",
+"...++++++++++++++++++++++++++++++++++++++++++...",
+"....++++@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@++++...",
+"....+++@@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@@@@@@+++++@@++++@@@@@@@++@@++++@@+++...",
+"....++++@@@@@@@++++@@++++@@@@@@@++@@@@@@@@++++..",
+"....+++++++++@@++++@@++++@@+++++++@@@@@@@++++++.",
+"....+++++++++@@++++@@++++@@+++++++@@++++++++++++",
+"+...+++++++++@@++++@@++++@@+++++++@@++++++++++++",
+"++..+++@@@@@@@@++++@@++++@@@@@@@@+@@++++++++++++",
+"+++.+++@@@@@@@+++++@@++++@@@@@@@@+@@++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"+++++++............++++++++++++............+++++",
+"++++++++............++++++++++++............++++",
+"+++++++++............+#++++++++++............+++",
+"++++++++++............++++++++++++............++",
+"#++++++++++............++++++++++++............+",
+"++++++++++++............++++++++++++............",
+".+#++++++++++............+#++++++++++...........",
+"..++++++++++++............+#++++++++++..........",
+"...++++++++++++............++++++++++++.........",
+"....++++++++++++............++++++++++++........",
+".....+#++++++++++............+#++++++++++.......",
+"......++++++++++++............++++++++++++......",
+".......++++++++++++............++++++++++++.....",
+"........+#++++++++++............++++++++++++....",
+".........++++++++++++............+#++++++++++..."};
diff --git a/pixmaps/stop.xpm b/pixmaps/stop.xpm
new file mode 100644 (file)
index 0000000..e8d3d85
--- /dev/null
@@ -0,0 +1,55 @@
+/* XPM */
+static char * stop_xpm[] = {
+"48 48 4 1",
+"      c None",
+".     c #000000",
+"+     c #C60021",
+"@     c #FFFFFF",
+"              ....................              ",
+"             .++++++++++++++++++++.             ",
+"            .++@@@@@@@@@@@@@@@@@@++.            ",
+"           .++@@++++++++++++++++@@++.           ",
+"          .++@@++++++++++++++++++@@++.          ",
+"         .++@@++++++++++++++++++++@@++.         ",
+"        .++@@++++++++++++++++++++++@@++.        ",
+"       .++@@++++++++++++++++++++++++@@++.       ",
+"      .++@@++++++++++++++++++++++++++@@++.      ",
+"     .++@@++++++++++++++++++++++++++++@@++.     ",
+"    .++@@++++++++++++++++++++++++++++++@@++.    ",
+"   .++@@++++++++++++++++++++++++++++++++@@++.   ",
+"  .++@@++++++++++++++++++++++++++++++++++@@++.  ",
+" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
+".++@@++++++++++++++++++++++++++++++++++++++@@++.",
+".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@+++++@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@++++@+.",
+".+@++++@@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@@+++@+.",
+".+@++++@@++++++++++@@++++@@@++@@@+@@++++@@+++@+.",
+".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@++++@@@@@@@+++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@+++++@@@@@@@++++@@++++@@++++@@+@@@@@@@@+++@+.",
+".+@++++++++++@@++++@@++++@@++++@@+@@@@@@@++++@+.",
+".+@++++++++++@@++++@@++++@@++++@@+@@+++++++++@+.",
+".+@++++++++++@@++++@@++++@@@++@@@+@@+++++++++@+.",
+".+@++++@@@@@@@@++++@@+++++@@@@@@++@@+++++++++@+.",
+".+@++++@@@@@@@+++++@@+++++@@@@@@++@@+++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
+".++@@++++++++++++++++++++++++++++++++++++++@@++.",
+" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
+"  .++@@++++++++++++++++++++++++++++++++++@@++.  ",
+"   .++@@++++++++++++++++++++++++++++++++@@++.   ",
+"    .++@@++++++++++++++++++++++++++++++@@++.    ",
+"     .++@@++++++++++++++++++++++++++++@@++.     ",
+"      .++@@++++++++++++++++++++++++++@@++.      ",
+"       .++@@++++++++++++++++++++++++@@++.       ",
+"        .++@@++++++++++++++++++++++@@++.        ",
+"         .++@@++++++++++++++++++++@@++.         ",
+"          .++@@++++++++++++++++++@@++.          ",
+"           .++@@++++++++++++++++@@++.           ",
+"            .++@@@@@@@@@@@@@@@@@@@+.            ",
+"             .++++++++++++++++++++.             ",
+"              ....................              "};
diff --git a/src/CPU8051.cpp b/src/CPU8051.cpp
new file mode 100644 (file)
index 0000000..b0a45de
--- /dev/null
@@ -0,0 +1,644 @@
+// CPU8051.cpp
+
+#include <stdio.h>
+#include <iostream>
+#include "CPU8051.hpp"
+#include "disasm.hpp"
+
+//////////////////////////////////////////////////////////////////////////////
+// CPU8051::CPU8051( )
+// CPU8051 constructor
+//////////////////////////////////////////////////////////////////////////////
+CPU8051::CPU8051( )
+{
+  InitFuncPtr( );
+  // Cree les objets Memory
+  SFRMem = new Memory( 128 );
+  PGMMem = new Memory( 65536 );
+  IntMem = new Memory( 128 );
+  ExtMem = new Memory( 65536 );
+  PC = 0; CLOCK = 0; ActivePriority = -1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// CPU8051::~CPU8051( )
+// CPU8051 destructor
+//////////////////////////////////////////////////////////////////////////////
+CPU8051::~CPU8051( )
+{
+  // Detruit les objets Memory
+  delete SFRMem;
+  delete PGMMem;
+  delete IntMem;
+  delete ExtMem;
+
+  SFRMem = 0;
+  PGMMem = 0;
+  IntMem = 0;
+  ExtMem = 0;
+  PC = 0;
+  CLOCK = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::Exec( )
+// Execute at address PC from PGMMem
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::Exec( )
+{
+int i;
+unsigned char opcode = PGMMem->Read8( PC++ );
+int insttiming = ( this->*funcptr[ opcode ] )();
+
+for ( i = 0; i < insttiming; i++)
+  {
+    CheckInterrupts();
+    DoTimers();
+    CLOCK++;    
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned int CPU8051::GetNextAddress( )
+// Return PC + size in bytes of current instruction
+//////////////////////////////////////////////////////////////////////////////
+unsigned int CPU8051::GetNextAddress( )
+{
+return ( PC + InstSizesTbl[ PGMMem->Read8( PC ) ] );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::Reset( )
+// Reset the registers and CPU state
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::Reset( )
+{
+  PC = 0; CLOCK = 0; ActivePriority = -1;
+  // Reinitialisation des registres
+  int i;
+  for ( i = 0; i < 128; i++ )
+    {
+      SFRMem->Write8( i, 0 );
+      IntMem->Write8( i, 0 );
+    }
+  SFRMem->Write8( _P0_ - 0x80, 0xFF );
+  SFRMem->Write8( _P1_ - 0x80, 0xFF );
+  SFRMem->Write8( _P2_ - 0x80, 0xFF );
+  SFRMem->Write8( _P3_ - 0x80, 0xFF );
+  SFRMem->Write8( _SP_ - 0x80, 0x07 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned int CPU8051::GetPC( )
+// Return the value of PC register
+//////////////////////////////////////////////////////////////////////////////
+unsigned int CPU8051::GetPC( )
+{
+  return PC;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::SetPC( unsigned int NewPC )
+// Set the new value of PC register
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::SetPC( unsigned int NewPC )
+{
+  PC = NewPC;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WriteD( unsigned int Address, unsigned char Value )
+// Write with a direct addressing mode at Address the new Value
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WriteD( unsigned int Address, unsigned char Value )
+{
+  if ( Address > 0x7F ) { SFRMem->Write8( Address - 0x80, Value ); return; }
+  IntMem->Write8( Address, Value );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WriteExt( unsigned int Address, unsigned char Value )
+// Ecriture d'une valeur dans la memoire externe ( Address = $00 a $FFFF )
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WriteExt( unsigned int Address, unsigned char Value )
+{
+  ExtMem->Write8( Address, Value );
+  return;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WriteInt( unsigned int Address, unsigned char Value )
+// Ecriture d'une valeur dans la memoire interne ( Address = $00 a $FF )
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WriteInt( unsigned int Address, unsigned char Value )
+{
+  if ( Address > 0x7F )
+    SFRMem->Write8( Address - 0x80, Value );
+  else
+    IntMem->Write8( Address, Value );
+  return;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WriteI( unsigned int Address, unsigned char Value )
+// Write with an indirect addressing mode at Address the new Value
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WriteI( unsigned int Address, unsigned char Value )
+{
+  if ( Address > 0x7F ) { ExtMem->Write8( Address, Value ); return; }
+  IntMem->Write8( Address, Value );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WritePGM( unsigned int Address, unsigned char Value )
+// Write at Address the new Value in PGMMem
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WritePGM( unsigned int Address, unsigned char Value )
+{
+  PGMMem->Write8( Address, Value );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadD( unsigned int Address )
+// Read with a direct addressing mode at Address
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadD( unsigned int Address )
+{
+  if ( Address > 0xFF ) return ExtMem->Read8( Address );
+  if ( Address > 0x7F ) return SFRMem->Read8( Address - 0x80 );
+  return IntMem->Read8( Address );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadInt( unsigned int Address )
+// Read Internal data memory at Address
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadInt( unsigned int Address )
+{
+  if ( Address > 0x7F )
+    return SFRMem->Read8( Address - 0x80 );
+  return IntMem->Read8( Address );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadExt( unsigned int Address )
+// Lecture du contenu de la memoire externe
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadExt( unsigned int Address )
+{
+  return ExtMem->Read8( Address );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadI( unsigned int Address )
+// Read with a indirect addressing mode at Address
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadI( unsigned int Address )
+{
+  if ( Address > 0x7F ) return ExtMem->Read8( Address );
+  return IntMem->Read8( Address );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadPGM( unsigned int Address )
+// Read at Address from PGMMem
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadPGM( unsigned int Address )
+{
+  return PGMMem->Read8( Address );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::WriteB( unsigned int BitAddress, unsigned char Value )
+// Write with a bit addressing mode at BitAddress the new Value
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::WriteB( unsigned int BitAddress, unsigned char Value )
+{
+unsigned int ByteAddress, BitNumber;
+unsigned char ByteValue, ByteMask;
+  if ( BitAddress > 0x7F ) {
+    // SFR 80-FF
+    ByteAddress = BitAddress & 0xF8;
+    BitNumber = BitAddress & 0x07;
+  }
+  else {
+    // 20-2F
+    ByteAddress = ( BitAddress >> 3 ) + 0x20;
+    BitNumber = BitAddress & 0x07;
+  }
+  ByteMask = ( ( 1 << BitNumber ) ^ 0xFF );
+  ByteValue = ReadD( ByteAddress ) & ByteMask;
+  ByteValue += Value << BitNumber;
+  WriteD( ByteAddress, ByteValue );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char CPU8051::ReadB( unsigned int BitAddress )
+// Read with a bit addressing mode at BitAddress
+//////////////////////////////////////////////////////////////////////////////
+unsigned char CPU8051::ReadB( unsigned int BitAddress )
+{
+unsigned int ByteAddress, BitNumber;
+unsigned char BitValue;
+  if ( BitAddress > 0x7F ) {
+    // SFR 80-FF
+    ByteAddress = BitAddress & 0xF8;
+    BitNumber = BitAddress & 0x07;
+  }
+  else {
+    // 20-2F
+    ByteAddress = ( BitAddress >> 3 ) + 0x20;
+    BitNumber = BitAddress & 0x07;
+  }
+  BitValue = ( ReadD( ByteAddress ) >> BitNumber );
+  BitValue &= 1;
+  return BitValue;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::CheckInterrupts()
+// Check interrupts state and process them as needed
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::CheckInterrupts()
+{
+unsigned char SP;
+
+  if ( ReadD( _IE_ ) & 0x80 ) {
+    for ( int i = 1; i >= 0; i-- )
+      if ( ActivePriority < i ) {
+//-------------------------  External interrupt 0 ----------------------------     
+//        if ( ( ReadD( _IE_ ) & 0x01 ) && ( ( ReadD( _IP_ ) & 0x01 ) ? i : !i ) && pin0 )
+//-------------------------- Interrupt timer 0 -------------------------------
+          if ( ( ReadD( _IE_ ) & 0x02 ) && ( ( ReadD( _IP_ & 0x02 ) ? i : !i ) && ( ReadD( _TCON_ ) & 0x20 ) ) ){
+              WriteD( _TCON_, ReadD( _TCON_ ) & 0xDF );
+             SP = ReadD( _SP_ );
+             WriteI( ++SP, ( PC & 0xFF ) );
+             WriteI( ++SP, ( PC >> 8 ) );
+             WriteD( _SP_, SP );
+              PC = 0x0B;  
+              ActivePriority = i;
+              return;          
+          }
+//-------------------------- External interrupt 1 ----------------------------     
+//        if ( ( ReadD( _IE_ ) & 0x04 ) && ( ( ReadD( _IP_ ) & 0x04 ) ? i : !i ) && pin1 )
+//-------------------------- Interrupt timer 1 -------------------------------      
+          if ( ( ReadD( _IE_ ) & 0x08 ) && ( ( ReadD( _IP_ ) & 0x08 ) ? i : !i ) && ( ReadD( _TCON_ ) & 0x80 ) ) {
+              WriteD( _TCON_, ReadD( _TCON_ ) & 0x7F );
+             SP = ReadD( _SP_ );
+             WriteI( ++SP, ( PC & 0xFF ) );
+             WriteI( ++SP, ( PC >> 8 ) );
+             WriteD( _SP_, SP );
+             PC = 0x1B;
+              ActivePriority = i;
+              return;
+          }
+//-------------------------- Serial Interrupts -------------------------------
+          if ( ( ReadD( _IE_ ) & 0x10 ) && ( ( ReadD( _IP_ ) & 0x10 ) ? i : !i ) && ( ReadD( _SCON_ ) & 0x03 ) ) {
+             SP = ReadD( _SP_ );
+             WriteI( ++SP, ( PC & 0xFF ) );
+             WriteI( ++SP, ( PC >> 8 ) );
+             WriteD( _SP_, SP );
+              PC = 0x23;
+              ActivePriority = i;
+              return;
+          }
+//-------------------------- Interrupt timer 2 -------------------------------
+          if ( ( ReadD( _IE_ ) & 0x20 ) && ( ( ReadD( _IP_ ) & 0x20 ) ? i : !i ) && ( ReadD( _T2CON_ ) & 0x80 ) ) {          
+             SP = ReadD( _SP_ );
+             WriteI( ++SP, ( PC & 0xFF ) );
+             WriteI( ++SP, ( PC >> 8 ) );
+             WriteD( _SP_, SP );
+              PC = 0x2B;
+              ActivePriority = i;
+              return;
+          }
+      }
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::DoTimers( )
+// Execute les timers
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::DoTimers( )
+{
+  unsigned int tmp;
+  unsigned int TR;
+  unsigned int MODE;
+  unsigned int GATE;
+  unsigned int TimerCounter;
+
+  // ----- Timer 0
+  TR = ReadD( _TCON_ ) & 0x10;
+  MODE = ReadD( _TMOD_ ) & 0x03;
+  GATE = ReadD( _TMOD_ ) & 0x08;
+  TimerCounter = ReadD( _TMOD_ ) & 0x04;
+  
+  if ( ( TR && !GATE && !TimerCounter ) || ( MODE == 3 ) )
+    switch( MODE ) {
+      // Mode 0, compteur de 13 bits.
+    case 0 :
+      tmp = ReadD( _TH0_ ) * 0x100 + ReadD( _TL0_ );
+      ++tmp &= 0x1FFF;   // On ne garde que 13 bits.
+      if ( tmp == 0 )    // If overflow set TF0
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
+      WriteD( _TH0_, tmp / 0x100 );
+      WriteD( _TL0_, tmp & 0xFF  );
+      break;
+      
+      // Mode 1, compteur de 16 bits.
+    case 1 :
+      tmp = ReadD( _TH0_ ) * 0x100 + ReadD( _TL0_ );
+      ++tmp &= 0xFFFF;   // On ne garde que 16 bits.
+      if ( tmp == 0 )   // If overflow set TF0
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
+      WriteD( _TH0_, ( tmp / 0x100 ) );
+      WriteD( _TL0_, ( tmp & 0xFF ) );
+      break;
+      
+      // Mode 2, Compteur de 8 bits avec Auto-Reload
+    case 2 :
+      tmp = ReadD( _TL0_ );
+      ++tmp &= 0xFF;
+      if ( tmp == 0 ) {    // If overflow -> reload et set TF0
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
+       WriteD( _TL0_, ReadD( _TH0_ ) );
+      }
+      else
+       WriteD( _TL0_, tmp );
+      break;
+    
+    // Mode 3 : TL0 et TH0 sont 2 Timers independants de 8 bits chacuns.
+    case 3 :
+      if ( TR && !GATE && !TimerCounter ) {
+       tmp = ReadD( _TL0_ );
+       ++tmp &= 0xFF;
+       if ( tmp == 0 )  // If TL0 overflow set TF0
+         WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
+       WriteD( _TL0_, tmp );
+      }  // TH0 utilise TR1 et TF1.
+      TR = ReadD( _TCON_ ) & 0x40;
+      if ( TR ) {
+       tmp = ReadD( _TH0_ );
+       ++tmp &= 0xFF;
+       if ( tmp == 0 )  // If TH0 overflow set TF1
+         WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );  // TF1 = 1.
+       WriteD( _TH0_, tmp );
+      }
+      break;
+    };
+  
+
+  // ----- Timer 1
+  TR = ReadD( _TCON_ ) & 0x40;
+  MODE = ( ReadD( _TMOD_ ) & 0x30 ) >> 4 ;
+  GATE = ReadD( _TMOD_ ) & 0x80;
+  TimerCounter = ReadD( _TMOD_ ) & 0x40;
+  
+  if ( TR && !GATE && !TimerCounter )
+    switch( MODE ) {
+      // Mode 0, compteur de 13 bits.
+    case 0 :
+      tmp = ReadD( _TH1_ ) * 0x100 + ReadD( _TL1_ );
+      ++tmp &= 0x1FFF;   // On ne garde que 13 bits.
+      if ( tmp == 0 )    // If overflow set TF1
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
+      WriteD( _TH1_, tmp / 0x100 );
+      WriteD( _TL1_, tmp & 0xFF  );
+      break;
+      
+      // Mode 1, compteur de 16 bits.
+    case 1 :
+      tmp = ReadD( _TH1_ ) * 0x100 + ReadD( _TL1_ );
+      ++tmp &= 0xFFFF;   // On ne garde que 16 bits.
+      if ( tmp == 0 )   // If overflow set TF1
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
+      WriteD( _TH1_, ( tmp / 0x100 ) );
+      WriteD( _TL1_, ( tmp & 0xFF ) );
+      break;
+      
+      // Mode 2, Compteur de 8 bits avec Auto-Reload
+    case 2 :
+      tmp = ReadD( _TL1_ );
+      ++tmp &= 0xFF;
+      if ( tmp == 0 ) {    // If overflow -> reload et set TF1
+       WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
+       WriteD( _TL1_, ReadD( _TH1_ ) );
+      }
+      else
+       WriteD( _TL1_, tmp );
+      break;
+      
+      // Mode 3 : mode inactif: retient la valeur de TH1 et TL1.
+      // Equivalent a TR1 = 0.
+    case 3 :
+      break;
+      
+    };
+}
+
+
+
+// Addressing modes defined in the order as they appear in disasm.hpp
+// from table argstext[]
+#define ADDR11 0
+#define ADDR16 1
+#define DIRECT 3
+#define BITADDR 14
+#define RELADDR 15
+#define DATAIMM 16
+#define DATA16 22
+#define CBITADDR 23
+
+// SFR Memory map [80h - FFh]
+// ---------------------------------------------------------------
+// F8 |      |      |      |      |      |      |      |      | FF
+// F0 |   B  |      |      |      |      |      |      |      | F7
+// E8 |      |      |      |      |      |      |      |      | EF
+// E0 |  ACC |      |      |      |      |      |      |      | E7
+// D8 |      |      |      |      |      |      |      |      | DF
+// D0 |  PSW |      |      |      |      |      |      |      | D7
+// C8 | T2CON|      |RCAP2L|RCAP2H|  TL2 |  TH2 |      |      | CF
+// C0 |      |      |      |      |      |      |      |      | C7
+// B8 |  IP  |      |      |      |      |      |      |      | BF
+// B0 |  P3  |      |      |      |      |      |      |      | B7
+// A8 |  IE  |      |      |      |      |      |      |      | AF
+// A0 |  P2  |      |      |      |      |      |      |      | A7
+// 98 | SCON | SBUF |      |      |      |      |      |      | 9F
+// 90 |  P1  |      |      |      |      |      |      |      | 97
+// 88 | TCON | TMOD |  TL0 |  TL1 |  TH0 |  TH1 |      |      | 8F
+// 80 |  P0  |  SP  |  DPL |  DPH |      |      |      | PCON | 87
+// ---------------------------------------------------------------
+
+//////////////////////////////////////////////////////////////////////////////
+// int CPU8051::SFRMemInfo( unsigned int Address, char *Text )
+// Return as Text the name of the SFR register at Address if any
+//////////////////////////////////////////////////////////////////////////////
+    int CPU8051::SFRMemInfo( unsigned int Address, char *Text )
+  {
+    switch( Address ) {
+  case 0x80 : return sprintf( Text, "P0" );
+  case 0x81 : return sprintf( Text, "SP" );
+  case 0x82 : return sprintf( Text, "DPL" );
+  case 0x83 : return sprintf( Text, "DPH" );
+  case 0x87 : return sprintf( Text, "PCON" );
+  case 0x88 : return sprintf( Text, "TCON" );
+  case 0x89 : return sprintf( Text, "TMOD" );
+  case 0x8A : return sprintf( Text, "TL0" );
+  case 0x8B : return sprintf( Text, "TL1" );
+  case 0x8C : return sprintf( Text, "TH0" );
+  case 0x8D : return sprintf( Text, "TH1" );
+  case 0x90 : return sprintf( Text, "P1" );
+  case 0x98 : return sprintf( Text, "SCON" );
+  case 0x99 : return sprintf( Text, "SBUF" );
+  case 0xA0 : return sprintf( Text, "P2" );
+  case 0xA8 : return sprintf( Text, "IE" );
+  case 0xB0 : return sprintf( Text, "P3" );
+  case 0xB8 : return sprintf( Text, "IP" );
+  case 0xC8 : return sprintf( Text, "T2CON" );
+  case 0xCA : return sprintf( Text, "RCAP2L" );
+  case 0xCB : return sprintf( Text, "RCAP2H" );
+  case 0xCC : return sprintf( Text, "TL2" );
+  case 0xCD : return sprintf( Text, "TH2" );
+  case 0xD0 : return sprintf( Text, "PSW" );
+  case 0xE0 : return sprintf( Text, "ACC" );
+  case 0xF0 : return sprintf( Text, "B" );
+  default : return sprintf( Text, "%.2XH", Address );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )
+// Return as Text the decoded BitAddress
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )
+{
+unsigned int ByteAddress, BitNumber;
+int TextLength;
+  if ( BitAddress > 0x7F ) {
+    // SFR 80-FF
+    ByteAddress = BitAddress & 0xF8;
+    BitNumber = BitAddress & 0x07;
+  }
+  else {
+    // 20-2F
+    ByteAddress = ( BitAddress >> 3 ) + 0x20;
+    BitNumber = BitAddress & 0x07;
+  }
+
+  TextLength = SFRMemInfo( ByteAddress, Text );
+  // sprintf( &Text[ TextLength ], ".%X" );
+  // Modified by Hugo Villeneuve to remove compilation warning
+  sprintf( &Text[ TextLength ], ".%X", BitAddress );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// int CPU8051::Disasm( unsigned int Address, char *Text )
+// Disasm one instruction at Address into a Text string
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::Disasm( unsigned int Address, char *Text )
+{
+int TextLength=0;
+char TextTmp[20];
+unsigned char OpCode;
+int ArgTblOfs;
+int InstSize;
+int i;
+
+OpCode = PGMMem->Read8( Address );
+InstSize = InstSizesTbl[ OpCode ];
+//printf("%.4X\n", Address);
+
+TextLength += sprintf( Text, " %.4X ", Address );
+
+for (i = 0; i < InstSize; i++ )
+  TextLength += sprintf( &Text[TextLength], " %.2X", PGMMem->Read8( Address + i ) );
+
+Address++;
+
+for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " );
+
+TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] );
+ArgTblOfs = OpCode << 2;
+
+for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " );
+
+ // MOV direct, direct (OpCode 85h) is peculiar, the operands are inverted
+ if ( OpCode == 0x85 ) {
+   SFRMemInfo( PGMMem->Read8( Address + 1 ), TextTmp );
+   TextLength += sprintf( &Text[ TextLength ], "%s,", TextTmp );
+   SFRMemInfo( PGMMem->Read8( Address ), TextTmp );
+   TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp );
+   Address += 2;
+   return InstSize;
+ }
+
+ for ( i = 1; i <= InstArgTbl[ ArgTblOfs ]; i++ ) {
+   switch( InstArgTbl[ ArgTblOfs + i ] ) {
+   case ADDR11  : {
+     TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( OpCode << 3) & 0xF00 ) + ( PGMMem->Read8( Address ) ) );
+     Address++;
+     break;
+   }
+   case ADDR16  : {
+     TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( PGMMem->Read8( Address ) << 8 ) + PGMMem->Read8( Address + 1 ) ) );
+     Address += 2;
+     break;
+   }
+   case DIRECT  : {
+     SFRMemInfo( PGMMem->Read8( Address ), TextTmp );
+     TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp );
+     Address++;
+     break;
+   }
+   case BITADDR : {
+     IntMemBitInfo( ( PGMMem->Read8( Address ) & 0xF8 ), TextTmp );
+     TextLength += sprintf( &Text[ TextLength ], "%s.%X" , TextTmp, ( PGMMem->Read8( Address ) & 7 ) );
+     Address++;
+     break;
+   }
+   case RELADDR : {
+     Address++;
+     TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( Address & 0xFF00 ) + ( ( ( Address & 0xFF ) + PGMMem->Read8( Address - 1 ) ) & 0xFF ) );
+     break;
+   }
+   case DATAIMM : {
+     TextLength += sprintf( &Text[ TextLength ], "#%.2XH", PGMMem->Read8( Address ) );
+     Address++;
+     break;
+   }
+   case DATA16  : {
+     TextLength += sprintf( &Text[ TextLength ],"#%.4XH", ( ( PGMMem->Read8( Address ) << 8 ) + PGMMem->Read8( Address+1 ) ) );
+     Address += 2;
+     break;
+   }
+   case CBITADDR : {
+     IntMemBitInfo( ( PGMMem->Read8( Address ) & 0xF8 ), TextTmp );
+     TextLength += sprintf( &Text[ TextLength ], "/%s.%X", TextTmp, ( PGMMem->Read8( Address ) & 7 ) );
+     Address++;
+     break;
+   }
+   default : {
+     TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] );
+   }
+   }
+   if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); }
+ }
+
+return InstSize;
+}
+
+
+#include "Inst_Imp.cpp"
+
+
+
+
+
+
diff --git a/src/CPU8051.hpp b/src/CPU8051.hpp
new file mode 100644 (file)
index 0000000..d51d8aa
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef _CPU8051_HPP_
+#define _CPU8051_HPP_
+
+#include "Memory.hpp"
+#include "Reg8051.hpp"
+
+#define BANKPSW ( ReadD( _PSW_ ) & 0x18 )
+
+//////////////////////////////////////////////////////////////////////////////
+// CPU8051
+// Implements the 8051 CPU Object
+//////////////////////////////////////////////////////////////////////////////
+class CPU8051 {
+public:
+  CPU8051( );
+  ~CPU8051( );
+
+  void Exec( );
+  void Reset( );
+  unsigned int GetPC( );
+  void SetPC( unsigned int NewPC );
+  void WriteD( unsigned int Address, unsigned char Value );
+  void WriteExt( unsigned int Address, unsigned char Value );
+  void WriteInt( unsigned int Address, unsigned char Value );
+  void WriteI( unsigned int Address, unsigned char Value );
+  void WritePGM( unsigned int Address, unsigned char Value );
+  unsigned char ReadD( unsigned int Address );
+  unsigned char ReadInt( unsigned int Address );
+  unsigned char ReadExt( unsigned int Address );
+  unsigned char ReadI( unsigned int Address );
+  unsigned char ReadPGM( unsigned int Address );
+  unsigned int GetNextAddress( );
+
+  void WriteB( unsigned int BitAddress, unsigned char Value );
+  unsigned char ReadB( unsigned int BitAddress );
+
+  void CheckInterrupts( );
+  void DoTimers( );
+
+  int SFRMemInfo( unsigned int Address, char *Text );
+  void IntMemBitInfo( unsigned int BitAddress, char *Text );
+  int Disasm( unsigned int Address, char *Text );
+
+private:
+  Memory *SFRMem;
+  Memory *PGMMem;
+  Memory *IntMem;
+  Memory *ExtMem;
+  unsigned int PC;
+  unsigned long CLOCK;
+  int ActivePriority;
+  int (CPU8051::*funcptr[256])();
+
+  #include "Inst_Def.hpp"
+
+};
+
+
+
+
+#endif
+
diff --git a/src/EmuConsole.cpp b/src/EmuConsole.cpp
new file mode 100644 (file)
index 0000000..0a0fe66
--- /dev/null
@@ -0,0 +1,737 @@
+// EmuConsole.cpp
+
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "config.h"
+#include "EmuConsole.hpp"
+#include "CPU8051.hpp"
+#include "Reg8051.hpp"
+#include "Keyboard.hpp"
+
+
+int main( int argc, char **argv )
+{
+  CPU8051 *maincpu = new CPU8051;
+  
+  EmuConsole *emuUI = new EmuConsole( argc, argv, maincpu );
+  
+  emuUI->Main();
+  printf( "End of program.\n" );
+  
+  delete emuUI;
+  delete maincpu;
+  
+  return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
+// EmuConsole constructor
+//////////////////////////////////////////////////////////////////////////////
+EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
+{
+  CPU = mCPU;
+  CPU->Reset( );
+  NbBreakpoints = 0;
+  if ( argc > 1 ) LoadHexFile( argv[ 1 ] );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuConsole::~EmuConsole( )
+// EmuConsole destructor
+//////////////////////////////////////////////////////////////////////////////
+EmuConsole::~EmuConsole( )
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Main( )
+// EmuConsole main loop
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Main( )
+{
+  /*int ASCII_Code;*/
+  unsigned int Index;
+  
+  string InputString;
+  string Command;
+  string Parameter1;
+  string Parameter2;
+  char prompt[] = "-> ";
+
+  char *Title[] = { "      *******************",
+                   "      *  8051 Emulator  *",
+                   "      *******************",
+                   "", 0 };
+  
+  char *Menu[] = {
+      "      Available commands, [ ] = options",
+      "",
+      "  Set Breakpoint.............. SB [address]",
+      "  Remove Breakpoint........... RB [address]",
+      "  Display Breakpoint(s)....... DB",
+      "  Dump External Data Memory... DE [address]",
+      "  Dump Internal Data Memory... DI [address]",
+      "  Dump Program Memory......... DP [address]",
+      "  Display Registers content... DR",
+      "  Execute..................... EM [address [number of instructions]]",
+      "  Help........................ H",
+      "  Modify External Data Memory. ME address value",
+      "  Modify Internal Data Memory. MI address value",
+      "  Modify Program Memory....... MP address value",
+      "  Modify Register............. MR register value",
+      "  Quit Emulator............... Q",
+      "  Trace mode.................. T [address]",
+      "  Unassemble.................. U [address [numberof instructions]]",
+      "  Reset processor............. Z", 0 };
+
+  
+  Index = 0;
+  while ( Title[ Index ] != 0 ) printf( "%s%s", Title[ Index++ ], ENDLINE );
+  Index = 0;
+  while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE );
+  
+  Reset( );
+  int QuitRequest = 0;
+  
+  while( !QuitRequest ) {
+    try {
+      
+      printf( prompt );
+      getline ( cin, InputString, '\n' );
+      Capitalize( &InputString );          
+      RemoveSpaces( &InputString );
+
+      for ( Index = 0; Index < InputString.size( ); Index++ ) {
+       if ( InputString[ Index ] < 'A' || InputString[ Index ] > 'z' )
+         break;
+      }
+
+      Command = InputString;
+      // Keep only the Command part from the input line
+      Command.replace( Index, Command.size( ), 0, ( char )0 );
+      // Keep only the arguments
+      InputString.replace( 0, Index, 0, ( char )0 );
+      
+      RemoveSpaces ( &InputString );
+      Index = 0;
+      while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++;
+      Parameter1 = InputString;
+      Parameter1.replace( Index, Parameter1.size( ), 0, ( char )0 );
+      InputString.replace( 0, Index, 0, ( char )0 );
+      
+      RemoveSpaces ( &InputString );
+      Index = 0;
+      while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++;
+      Parameter2 = InputString;
+      Parameter2.replace( Index, Parameter2.size( ), 0, ( char )0 );
+      InputString.replace( 0, Index, 0, ( char )0 );
+
+      RemoveSpaces ( &InputString );
+      if ( !InputString.empty( ) )
+       throw SyntaxError( );
+      
+      if ( Command.empty( ) && !Parameter1.empty( ) )
+       throw SyntaxError( );
+      
+      if ( ( Parameter1.size( ) > 4 ) || ( Parameter2.size( ) > 4 ) )
+       throw InvalidParameter( );
+      
+      if ( !Command.empty( ) ) {
+       switch ( Command [ 0 ] ) {
+
+       case 'D' :
+         if ( Parameter2.empty( ) ) {
+           if ( Command == "DB" && Parameter1.empty( ) )
+              ShowBreakpoints( );       
+           else if ( Command == "DE" )
+             DumpExt( Parameter1 );
+           else if ( Command == "DI" )
+             DumpInt( Parameter1 );
+           else if ( Command == "DP" ) {
+             if ( Parameter1.empty( ) )
+               Parameter1 = "PC";
+             DumpPGM( Parameter1 );    
+           }
+           else if ( Command == "DR" && Parameter1.empty( ) )
+             ShowRegisters( );
+           else
+             throw SyntaxError( );
+         }
+         else
+           throw SyntaxError( );
+         break;
+         
+       case 'E' :
+         if ( Command == "EM" )
+           Exec( Parameter1, Parameter2 );
+         else
+           throw SyntaxError( );
+         break;
+       case 'H' :
+         if ( Command == "H" && Parameter1.empty( ) && Parameter2.empty( ) )
+           {
+             Index = 0;
+             while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE );
+           }
+         else
+           throw SyntaxError( );
+         break;
+       case 'M' :
+         if ( Parameter1.empty() || Parameter2.empty() )
+           throw MissingParameter();
+         else if ( Command == "ME" ) {
+           unsigned int adresse = Ascii2Hex( Parameter1, 4 );
+           unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+           CPU->WriteExt( adresse, valeur );
+         }
+         else if ( Command == "MI" ) {
+           unsigned char adresse = Ascii2Hex( Parameter1, 2 );
+           unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+           CPU->WriteInt( adresse, valeur );
+         }
+         else if ( Command == "MP" ) {
+           unsigned int adresse = Ascii2Hex( Parameter1, 4 );
+           unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+           CPU->WritePGM( adresse, valeur );
+         }
+         else if ( Command == "MR" )
+           SetRegister( Parameter1, Parameter2 );  
+         else
+           throw SyntaxError();
+         break;
+       case 'Q' :
+         if ( Command == "Q" && Parameter1.empty( ) && Parameter2.empty( ) )
+           QuitRequest = 1;
+         else
+           throw SyntaxError( );
+         break;      
+       case 'R' :
+         if ( !Parameter2.empty( ) )
+           throw TooMuchParameters( );
+         if ( Command == "RB" ) {
+           if ( Parameter1.empty( ) )
+             ClearBreakpoint( CPU->GetPC( ) );
+           else
+             ClearBreakpoint( Ascii2Hex( Parameter1, 4 ) );
+         }
+         else
+           throw SyntaxError( );
+         break;
+       case 'S' :
+         if ( !Parameter2.empty( ) )
+           throw TooMuchParameters( );
+         if ( Command == "SB" ) {
+           if ( Parameter1.empty( ) )
+             SetBreakpoint( CPU->GetPC( ) );
+           else
+             SetBreakpoint( Ascii2Hex( Parameter1, 4 ) );
+         }
+         else
+           throw SyntaxError( );
+         break;
+       case 'T' :
+         if ( !Parameter2.empty( ) )
+           throw TooMuchParameters( );
+         if ( Command == "T" )
+           Trace( Parameter1 );
+         else
+           throw SyntaxError( );
+         break;
+       case 'U' :
+         if ( Command == "U" )
+           Disasm( Parameter1, Parameter2 );
+         else
+           throw SyntaxError( );
+         break;
+       case 'Z' :
+         if ( Command == "Z" && Parameter1.empty( ) && Parameter2.empty( ) )
+           Reset( );
+         else
+           throw SyntaxError( );
+         break;
+       case '\n' :
+         break;
+       default :
+         throw SyntaxError( );
+       }
+      }
+    }
+    catch ( SyntaxError ) {
+      printf( "Syntax Error!%s", ENDLINE );
+    }
+    catch ( MissingParameter ) {
+      printf( "Missing Parameter!%s", ENDLINE );
+    }
+    catch ( InvalidParameter ) {
+      printf( "Invalid Parameter Format!%s", ENDLINE );
+    }
+    catch ( TooMuchParameters ) {
+      printf( "Wrong Number of Parameters!%s", ENDLINE );
+    }
+    catch ( ResetRequest ) {
+      printf( "Resetting Microcontroler...%s", ENDLINE );
+    }
+    catch ( InvalidRegister ) {
+      printf( "%sInvalid register name!%s", ENDLINE, ENDLINE );
+      printf( "Valid registers are A, B, PC and SP.%s", ENDLINE );
+      }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Reset( )
+// CPU reset and Console UI update
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Reset( )
+{
+  printf( "Resetting... " );
+  CPU->Reset( );
+  printf( "Done.%s", ENDLINE );
+  ShowRegisters( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Trace( string Address )
+// CPU trace and Console UI update
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Trace( string Address )
+{
+  if ( !Address.empty( ) ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
+  CPU->Exec( );
+  ShowRegisters( );
+  DisasmN( CPU->GetPC( ), 1 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Exec( string Address, string NumberInst )
+// CPU exec and Console UI update
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Exec( string Address, string NumberInst )
+{
+  char dummy;
+  int NbInst = -1;     // -1 is infinity
+  if ( !Address.empty( ) ) {
+    Capitalize( &Address );
+    if ( Address != "PC" ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
+  }
+
+  if ( !NumberInst.empty( ) ) NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
+
+  InitUnixKB( );
+
+  printf( "Program executing...%s", ENDLINE );
+
+  do {
+    CPU->Exec( );
+    if ( NbInst > 0 ) NbInst--;
+  } while ( !IsBreakpoint( CPU->GetPC( ) ) && ( NbInst != 0 ) && !kbhit( ) );
+  if ( kbhit( ) ) {
+    dummy = getch( );   // flush key
+    printf( "Caught break signal!%s", ENDLINE );
+  }
+  if ( NbInst == 0 ) printf( "Number of instructions reached! Stopping!%s", ENDLINE );
+  if ( IsBreakpoint( CPU->GetPC( ) ) ) printf( "Breakpoint hit at %.4X! Stopping!%s", CPU->GetPC( ), ENDLINE );
+
+  ResetUnixKB( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::ShowBreakpoints( )
+// Show Breakpoints list
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::ShowBreakpoints( )
+{
+  for ( int Index = 0; Index < NbBreakpoints ; Index++ )
+    printf( "Breakpoint at Address = %.4X%s", Breakpoints[ Index ], ENDLINE );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::ClearBreakpoint( unsigned int Address )
+// Clear Breakpoint at Address from list
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::ClearBreakpoint( unsigned int Address )
+{
+  int Index = 0;
+  while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
+  if ( Breakpoints[ Index ] != Address ) return;
+  Breakpoints[ Index ] = Breakpoints[ NbBreakpoints - 1 ];
+  NbBreakpoints--;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::SetBreakpoint( unsigned int Address )
+// Set Breakpoint at Address from list
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::SetBreakpoint( unsigned int Address )
+{
+  if ( IsBreakpoint( Address ) ) return;
+  if ( NbBreakpoints < MAXBP ) Breakpoints[ NbBreakpoints++ ] = Address;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// int EmuConsole::IsBreakpoint( unsigned int Address )
+// Is the a breakpoint at Address
+//////////////////////////////////////////////////////////////////////////////
+int EmuConsole::IsBreakpoint( unsigned int Address )
+{
+  int Index = 0;
+  while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
+  return ( Breakpoints[ Index ] == Address && Index < NbBreakpoints );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Disasm( string Address, string NumberInst )
+// Disassemble 16 instructions at Address
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Disasm( string Address, string NumberInst )
+{
+  unsigned int MemAddress, NbInst;
+  Capitalize( &Address );
+  if ( Address.empty( ) || ( Address == "PC" ) ) MemAddress = CPU->GetPC( );
+  else MemAddress = Ascii2Hex( Address, Address.size( ) );
+  if ( NumberInst.empty( ) ) NumberInst = "10";
+  NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
+  DisasmN( MemAddress, NbInst );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DisasmN( unsigned int Address, int NumberInst )
+// Disassemble NumberInst instructions at Address
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DisasmN( unsigned int Address, int NumberInst )
+{
+char TextTmp[255];
+int Row;
+ for ( Row = 0; Row < NumberInst ; Row++ ) {
+   Address += CPU->Disasm( Address, TextTmp );
+   printf( "%s%s", TextTmp, ENDLINE );
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DumpPGM( string Address )
+// Dump Program memory
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DumpPGM( string Address )
+{
+  unsigned int MemAddress = 0;
+  int Offset, Column;
+  unsigned char Byte;
+  if ( !Address.empty( ) ) {
+    Capitalize( &Address );
+    if ( Address == "PC" )
+      MemAddress = CPU->GetPC( );
+    else
+      MemAddress = Ascii2Hex( Address, Address.size( ) );
+  }
+  for ( Offset = 0; Offset < 256; Offset += 16 ) {
+    printf( "%.4X ", MemAddress + Offset );
+    for ( Column = 0; Column < 16; Column++ ) 
+      printf( " %.2X", ( int )CPU->ReadPGM( MemAddress + Offset + Column ) );
+    printf( "  " );
+    for ( Column = 0; Column < 16; Column++ ) {
+      Byte = CPU->ReadPGM( MemAddress + Offset + Column );
+      if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
+       printf( "%c", Byte );
+      else printf( "." );
+    }
+    printf( "%s", ENDLINE );
+  }
+
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DumpI( string Address )
+// Dump using Indirect read access
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DumpI( string Address )
+{
+  unsigned int MemAddress = 0;
+  int Offset, Column;
+  unsigned char Byte;
+  if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
+  for ( Offset = 0; Offset < 256; Offset += 16 ) {
+    printf( "%.4X ", MemAddress + Offset );
+    for ( Column = 0; Column < 16; Column++ ) 
+      printf( " %.2X", ( int )CPU->ReadI( MemAddress + Offset + Column ) );
+    printf( "  " );
+    for ( Column = 0; Column < 16; Column++ ) {
+      Byte = CPU->ReadI( MemAddress + Offset + Column );
+      if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
+       printf( "%c", Byte );
+      else printf( "." );
+    }
+    printf( "%s", ENDLINE );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DumpInt( string Address )
+// Dump internal Data memory
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DumpInt( string Address )
+{
+  unsigned int MemAddress = 0;
+  int Offset, Column;
+  unsigned char Byte;
+  if ( !Address.empty( ) )
+    MemAddress = Ascii2Hex( Address, 4 );
+  for ( Offset = 0; Offset < 256; Offset += 16 ) {
+    printf( "%.4X ", MemAddress + Offset );
+    for ( Column = 0; Column < 16; Column++ ) 
+      printf( " %.2X", ( int )CPU->ReadInt( MemAddress + Offset + Column ) );
+    printf( "  " );
+    for ( Column = 0; Column < 16; Column++ ) {
+      Byte = CPU->ReadInt( MemAddress + Offset + Column );
+      if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
+       printf( "%c", Byte );
+      else printf( "." );
+    }
+    printf( "%s", ENDLINE );
+  }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DumpExt( string Address )
+// Dump de la memoire externe ( $00 a $FFFF)
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DumpExt( string Address )
+{
+  unsigned int MemAddress = 0;
+  int Offset, Column;
+  unsigned char Byte;
+  if ( !Address.empty( ) )
+    MemAddress = Ascii2Hex( Address, 4 );
+  for ( Offset = 0; Offset < 256; Offset += 16 ) {
+    printf( "%.4X ", MemAddress + Offset );
+    for ( Column = 0; Column < 16; Column++ ) 
+      printf( " %.2X", ( int )CPU->ReadExt( MemAddress + Offset + Column ) );
+    printf( "  " );
+    for ( Column = 0; Column < 16; Column++ ) {
+      Byte = CPU->ReadExt( MemAddress + Offset + Column );
+      if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
+       printf( "%c", Byte );
+      else printf( "." );
+    }
+    printf( "%s", ENDLINE );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::DumpD( string Address )
+// Dump using Direct read access
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::DumpD( string Address )
+{
+  unsigned int MemAddress = 0;
+  int Offset, Column;
+  unsigned char Byte;
+  if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
+  for ( Offset = 0; Offset < 256; Offset += 16 ) {
+    printf( "%.4X ", MemAddress + Offset );
+    for ( Column = 0; Column < 16; Column++ ) 
+      printf( " %.2X", ( int )CPU->ReadD( MemAddress + Offset + Column ) );
+    printf( "  " );
+    for ( Column = 0; Column < 16; Column++ ) {
+      Byte = CPU->ReadD( MemAddress + Offset + Column );
+      if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
+       printf( "%c", Byte );
+      else printf( "." );
+    }
+    printf( "%s", ENDLINE );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::SetRegister( string Register, string NewValue )
+// Set NewValue to Register
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::SetRegister( string Register, string NewValue )
+{
+  Capitalize( &Register );
+  if ( Register == "PC" ) CPU->SetPC( Ascii2Hex( NewValue, 4 ) );
+  else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex( NewValue, 2 ) );
+  else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex( NewValue, 2 ) );
+  else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex( NewValue, 2 ) );
+  else throw InvalidRegister( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::Capitalize( string *InputString )
+// Capitalize all letters in InputString
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::Capitalize( string *InputString )
+{
+  for (unsigned int Index = 0; Index < InputString->size( ); Index++ ) {
+    {
+      if ( ( ( *InputString )[ Index ] >= 'a' ) && ( ( *InputString )[ Index ] <= 'z' ) )
+       ( *InputString )[ Index ] -= ( ( int )'a'- ( int )'A' );
+    }
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::RemoveSpaces( string *InputString )
+// Remove spaces from InputString
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::RemoveSpaces( string *InputString )
+{
+  unsigned int Index = 0;
+
+  while ( ( Index < ( *InputString ).size( ) ) && ( *InputString )[ Index ] == ' ' ) {
+    Index++;
+  }
+  ( *InputString ).replace( 0, Index, 0, ( char )0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::ShowRegisters( )
+// Show CPU registers
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::ShowRegisters( )
+{
+  unsigned char PSW = CPU->ReadD( _PSW_ );
+  int BankSelect = ( PSW & 0x18 );
+
+  printf( "----------------------------------------------------------------------%s", ENDLINE );
+  printf( "|  PC  | SP | DPTR | ACC |  B | PSW:  CY  AC  F0 RS1 RS0  OV   -   P |%s", ENDLINE );
+  printf( "| %.4X | %.2X | %.4X |  %.2X | %.2X |", CPU->GetPC( ), CPU->ReadD( _SP_ ), ( CPU->ReadD( _DPTRHIGH_ ) << 8 ) + CPU->ReadD( _DPTRLOW_ ), CPU->ReadD( _ACC_ ), CPU->ReadD( _B_ ) );
+  printf( "        %d   %d   %d   %d   %d   %d   %d   %d |",  ( PSW >> 7 ) & 1, ( PSW >> 6 ) & 1, ( PSW >> 5 ) & 1, ( PSW >> 4 ) & 1, ( PSW >> 3 ) & 1, ( PSW >> 2 ) & 1, ( PSW >> 1 ) & 1, PSW & 1 );
+  printf( "%s", ENDLINE );
+  printf( "----------------------------------------------------------------------%s", ENDLINE );
+  
+  printf( "| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 |    |%s", ENDLINE );
+  printf( "|   %.2X |   %.2X | %.2X | %.2X ", CPU->ReadD( _TCON_ ), CPU->ReadD( _TMOD_ ), CPU->ReadD( _IE_ ), CPU->ReadD( _IP_ ) );
+  printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R0_ ), CPU->ReadD( BankSelect + _R1_ ), CPU->ReadD( BankSelect + _R2_ ), CPU->ReadD( BankSelect + _R3_ ) );
+  printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R4_ ), CPU->ReadD( BankSelect + _R5_ ), CPU->ReadD( BankSelect + _R6_ ), CPU->ReadD( BankSelect + _R7_ ) );
+  printf( "|    |%s", ENDLINE );
+
+  printf( "----------------------------------------------------------------------%s", ENDLINE );
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuConsole::LoadHexFile( string Filename )
+// 
+//////////////////////////////////////////////////////////////////////////////
+void EmuConsole::LoadHexFile( string Filename )
+{
+
+  printf("LoadHex\n");
+  int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
+  char Line[ 250 ];
+
+  ifstream HexFile( Filename.c_str() );
+  try { 
+    if ( ! HexFile )
+      throw ErrorOpeningFile();
+    
+    while( ! HexFile.eof() ) {
+      i = 0;
+      Checksum = 0;
+      HexFile.getline( Line, 250, '\n' );  
+
+      if ( Line[ i++ ] != ':' )
+       throw ErrorHexFileFormat();
+      
+      RecLength = Ascii2Hex( &Line[ i ], 2 );
+      i += 2;
+      Checksum += RecLength;
+      
+      LoadOffset = Ascii2Hex( &Line[i], 4 );
+      Checksum += LoadOffset / 256;
+      Checksum += LoadOffset % 256;
+      i += 4;
+
+      RecType = Ascii2Hex( &Line[i],2);
+      i += 2;
+      Checksum += RecType;
+
+      if ( RecType == 1 ) {
+       Checksum += Ascii2Hex( &Line[ i ], 2 );
+       if ( Checksum &= 0x000000FF )
+         throw ErrorHexFileFormat();
+       throw FinishedLoading();
+      }   
+      if ( RecType )
+       throw ErrorHexFileFormat();
+      
+      for ( j = 0; j < RecLength; j++ ) {
+       Data = Ascii2Hex( &Line[ i ], 2 );
+       CPU->WritePGM( (unsigned int)(LoadOffset + j), (unsigned char)Data );
+       i += 2;
+       Checksum += Data;
+      }
+      RecType = Ascii2Hex( &Line[ i ], 2 );
+      Checksum += RecType;      
+
+      if ( Checksum &= 0x000000FF )
+       throw ErrorHexFileFormat();
+    }
+    throw ErrorHexFileFormat();
+  }
+  catch ( ErrorOpeningFile ) {
+    cout << "Error opening file " << Filename << endl;
+  }
+  catch ( ErrorHexFileFormat ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( SyntaxError ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( MissingParameter ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( FinishedLoading ) {
+    cout << "Using file " << Filename << " as input program." << endl;  
+  }
+  HexFile.close();  
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned int EmuConsole::Ascii2Hex( string istring, int length )
+//
+//////////////////////////////////////////////////////////////////////////////
+unsigned int EmuConsole::Ascii2Hex( string istring, unsigned int length )
+{
+  if ( !length || ( length > istring.size() ) )
+    length = istring.size();
+
+  if ( istring.empty() )
+    throw MissingParameter();
+
+  unsigned int result = 0;
+  unsigned int i, ascii_code;
+  for ( i = 0; i < length; i++ ) {
+    ascii_code = istring[ i ];
+    if ( ascii_code > 0x39 )
+      ascii_code &= 0xDF;
+    if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
+      ascii_code -= 0x30;
+      if ( ascii_code > 9 )
+       ascii_code -= 7;
+      result <<= 4;
+      result += ascii_code;
+    }
+    else {
+      throw SyntaxError();
+    }
+  }
+  return result;
+}
+
+
+
+
+
+
+
diff --git a/src/EmuConsole.hpp b/src/EmuConsole.hpp
new file mode 100644 (file)
index 0000000..0c2c094
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _EMUCONSOLE_HPP_
+#define _EMUCONSOLE_HPP_
+
+#include "CPU8051.hpp"
+#include <string>
+#include "exceptions.hpp"
+
+using namespace std;
+
+// Maximum number of BreakPoints
+#define MAXBP 32
+
+#define ENDLINE "\n"
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuConsole
+// Implements the Console User Interface as an Object
+//////////////////////////////////////////////////////////////////////////////
+class EmuConsole {
+public:
+
+  EmuConsole( int argc, char **argv, CPU8051 *mCPU );
+  ~EmuConsole( );
+
+  void Main( );
+
+  void Reset( );
+  void Trace( string Address );
+  void Exec( string Address, string NumberInst );
+  void ShowBreakpoints( );
+  void SetBreakpoint( unsigned int Address );
+  void ClearBreakpoint( unsigned int Address );
+  int IsBreakpoint( unsigned int Address );
+  void Disasm( string Address, string NumberInst );
+  void DisasmN( unsigned int Address, int NumberInst );
+  void DumpPGM( string Address );
+  void DumpD( string Address );
+  void DumpInt( string Address );
+  void DumpExt( string Address );
+  void DumpI( string Address );
+  void ShowRegisters( );
+  void SetRegister( string Register, string NewValue );
+  
+
+
+private:
+  CPU8051 *CPU;
+  int NbBreakpoints;
+  unsigned int Breakpoints[ MAXBP ];
+
+  void LoadHexFile( string Filename );
+  unsigned int Ascii2Hex( string istring, unsigned int length );
+  void Capitalize( string *InputString );
+  void RemoveSpaces( string *InputString );
+
+};
+
+
+
+#endif
+
+
+
diff --git a/src/EmuGtk.cpp b/src/EmuGtk.cpp
new file mode 100644 (file)
index 0000000..ee91146
--- /dev/null
@@ -0,0 +1,735 @@
+// EmuGtk.cpp
+
+#include <iostream>
+#include <stdio.h>
+#include "config.h"
+#include "CPU8051.hpp"
+#include "EmuGtk.hpp"
+#include "exceptions.hpp"
+#include "pixmaps/reset.xpm"
+#include "pixmaps/run.xpm"
+#include "pixmaps/stop.xpm"
+#include "pixmaps/step.xpm"
+
+
+int EmuGtkNumber = 0;
+int NbSignals = 0;
+int SignalsData[ 32 ];
+EmuGtk *EmuGtkPtr;
+
+
+enum
+{
+  DestroySignal=0,
+  DeleteSignal,
+  OpenISignal,
+  QuitISignal,
+  AboutISignal,
+  ResetBSignal,
+  RunBSignal,
+  StopBSignal,
+  StepBSignal
+};
+
+
+int main( int argc, char **argv )
+{
+  CPU8051 *maincpu = new CPU8051;
+  EmuGtk *emuUI = new EmuGtk( argc, argv, maincpu );
+  
+  emuUI->Main();
+  printf( "End of program.\n" );
+  
+  delete emuUI;
+  delete maincpu;
+  
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuGtk::EmuGtk(  )
+// EmuGtk constructor
+//////////////////////////////////////////////////////////////////////////////
+EmuGtk::EmuGtk( int argc, char **argv, CPU8051 *mCPU )
+{
+  CPU = mCPU;
+  RunningState = 0;
+
+  g_print( "\n" );
+
+  gtk_init( &argc, &argv );
+
+  emuwin = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  gtk_window_set_title( GTK_WINDOW( emuwin ), "emu8051" );
+  gtk_container_set_border_width( GTK_CONTAINER( emuwin ), 0 );
+  gtk_widget_show( emuwin );
+
+  emufixed = gtk_fixed_new();
+  gtk_widget_set_usize( GTK_WIDGET( emufixed ), MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT );
+  gtk_container_add( GTK_CONTAINER( emuwin ), emufixed );
+  gtk_widget_show( emufixed );
+
+  //  EmuMenuBar( );
+
+  // Main window
+  emumainfixed = gtk_fixed_new();
+  gtk_widget_set_usize( GTK_WIDGET( emumainfixed ), MAIN_WIN_WIDTH, REG_WIN_HEIGHT + MEM_WIN_HEIGHT + BUTTONS_BAR_HEIGHT + 10 );
+  gtk_fixed_put( GTK_FIXED( emufixed ), emumainfixed, 0, 25 );
+  gtk_widget_show( emumainfixed );
+
+  ShowMenu();
+
+  AddButtons();
+  
+  // Registers frame
+  regfrm = gtk_frame_new( 0 );
+  gtk_frame_set_shadow_type( GTK_FRAME( regfrm ), GTK_SHADOW_ETCHED_OUT );
+  gtk_widget_set_usize( GTK_WIDGET( regfrm ), REG_WIN_WIDTH, REG_WIN_HEIGHT );
+  gtk_fixed_put( GTK_FIXED( emumainfixed ), regfrm, 0, BUTTONS_BAR_HEIGHT );
+  regwin = new RegWin( regfrm );
+  gtk_widget_show( regfrm );
+
+  // Program disassembly frame
+  pgmfrm = gtk_frame_new( 0 );
+  gtk_frame_set_shadow_type( GTK_FRAME( pgmfrm ), GTK_SHADOW_ETCHED_OUT );
+  gtk_widget_set_usize( GTK_WIDGET( pgmfrm ), PGM_WIN_WIDTH, PGM_WIN_HEIGHT );
+  gtk_fixed_put( GTK_FIXED( emumainfixed ), pgmfrm, REG_WIN_WIDTH + 10, BUTTONS_BAR_HEIGHT );
+  pgmwin = new PgmWin( pgmfrm, CPU );
+  gtk_widget_show( pgmfrm );
+
+  // Memory dump frame
+  memfrm = gtk_frame_new( 0 );
+  gtk_frame_set_shadow_type( GTK_FRAME( memfrm ), GTK_SHADOW_ETCHED_OUT );
+  gtk_widget_set_usize( GTK_WIDGET( memfrm ), MEM_WIN_WIDTH, MEM_WIN_HEIGHT );
+  gtk_fixed_put( GTK_FIXED( emumainfixed ), memfrm, 0, REG_WIN_HEIGHT + BUTTONS_BAR_HEIGHT );
+  memwin = new MemWin( memfrm );
+  gtk_widget_show( memfrm );
+
+  
+  if ( EmuGtkNumber >= 1 )
+    g_print( "WARNING! Signal too much EmuGtk Objects to handle signals!\n");
+  else
+    {
+      EmuGtkPtr = this;
+      NbSignals = 0;
+
+      // Window DESTROY signal
+      SignalsData[ NbSignals ] = DestroySignal;
+      gtk_signal_connect( GTK_OBJECT( emuwin ), "destroy", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+      
+      // Window DELETE event
+      SignalsData[ NbSignals ] = DeleteSignal;
+      gtk_signal_connect( GTK_OBJECT( emuwin ), "delete_event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+
+      // File->Open
+      SignalsData[ NbSignals ] = OpenISignal;
+      gtk_signal_connect( GTK_OBJECT( OpenItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+
+      // File->Quit
+      SignalsData[ NbSignals ] = QuitISignal;
+      gtk_signal_connect( GTK_OBJECT( QuitItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+
+      // Help->About
+      SignalsData[ NbSignals ] = AboutISignal;
+      gtk_signal_connect( GTK_OBJECT( AboutItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+
+      // RESET button
+      SignalsData[ NbSignals ] = ResetBSignal;
+      gtk_signal_connect( GTK_OBJECT( ButtonReset ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+      
+      // RUN button
+      SignalsData[ NbSignals ] = RunBSignal;
+      gtk_signal_connect( GTK_OBJECT( ButtonRun ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+
+      // STOP button
+      SignalsData[ NbSignals ] = StopBSignal;
+      gtk_signal_connect( GTK_OBJECT( ButtonStop ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
+      NbSignals++;      
+
+      // STEP button
+      SignalsData[ NbSignals ] = StepBSignal;
+      gtk_signal_connect( GTK_OBJECT( ButtonStep ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
+      NbSignals++;
+      
+      EmuGtkNumber++;
+    }
+
+  if ( argc > 1 )
+    LoadHexFile( argv[1] );
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void AddButtons()
+// Create and show the Reset, Run, Stop, Trace and Step buttons
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::AddButtons( void )
+{
+  //GtkStyle *Style = gtk_widget_get_style( GTK_WIDGET( emuwin ) );
+
+  RESET_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
+                                                     gtk_widget_get_default_colormap(),
+                                                     &RESET_mask,
+                                                     NULL,
+                                                     ( gchar ** ) reset_xpm );
+  RESET_widget = gtk_pixmap_new( RESET_pixmap, RESET_mask );
+
+  RUN_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
+                                                     gtk_widget_get_default_colormap(),
+                                                     &RUN_mask,
+                                                     NULL,
+                                                     ( gchar ** ) run_xpm );
+  RUN_widget = gtk_pixmap_new( RUN_pixmap, RUN_mask );
+
+  STOP_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
+                                                      gtk_widget_get_default_colormap(),
+                                                      &STOP_mask,
+                                                      NULL,
+                                                      ( gchar ** ) stop_xpm );
+  STOP_widget = gtk_pixmap_new( STOP_pixmap, STOP_mask );
+
+  STEP_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
+                                                      gtk_widget_get_default_colormap(),
+                                                      &STEP_mask,
+                                                      NULL,
+                                                      ( gchar ** ) step_xpm );
+  STEP_widget = gtk_pixmap_new( STEP_pixmap, STEP_mask );
+  
+  ButtonTable = gtk_table_new( 1, 4, TRUE );
+  gtk_widget_set_usize( GTK_WIDGET( ButtonTable ), BUTTONS_BAR_WIDTH, BUTTONS_BAR_HEIGHT );
+  gtk_fixed_put( GTK_FIXED( emumainfixed ), ButtonTable, 0, 0 );
+  
+  ButtonReset = gtk_button_new();
+  ButtonRun   = gtk_button_new();
+  ButtonStop  = gtk_button_new();
+  ButtonStep  = gtk_button_new();
+
+  gtk_container_add( GTK_CONTAINER( ButtonReset ), RESET_widget );
+  gtk_container_add( GTK_CONTAINER( ButtonRun ), RUN_widget );
+  gtk_container_add( GTK_CONTAINER( ButtonStop ), STOP_widget );
+  gtk_container_add( GTK_CONTAINER( ButtonStep ), STEP_widget );
+
+
+  gtk_widget_set_usize( GTK_WIDGET( ButtonReset ), BUTTON_WIDTH, BUTTON_HEIGHT );
+  gtk_widget_set_usize( GTK_WIDGET( ButtonRun ),   BUTTON_WIDTH, BUTTON_HEIGHT );
+  gtk_widget_set_usize( GTK_WIDGET( ButtonStop ),  BUTTON_WIDTH, BUTTON_HEIGHT );
+  gtk_widget_set_usize( GTK_WIDGET( ButtonStep ),  BUTTON_WIDTH, BUTTON_HEIGHT );
+
+  gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonReset, 0, 1, 0, 1);
+  gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonRun,   1, 2, 0, 1);
+  gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStop,  2, 3, 0, 1);
+  gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStep,  3, 4, 0, 1);
+
+  gtk_widget_show( GTK_WIDGET( ButtonReset ) );
+  gtk_widget_show( GTK_WIDGET( ButtonRun ) );
+  gtk_widget_show( GTK_WIDGET( ButtonStop ) );  
+  gtk_widget_show( GTK_WIDGET( ButtonStep ) );  
+
+  gtk_widget_show_all( GTK_WIDGET( ButtonTable ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuGtk::~EmuGtk( )
+// EmuGtk destructor
+//////////////////////////////////////////////////////////////////////////////
+EmuGtk::~EmuGtk( )
+{
+  g_print( "EmuGtk::~EmuGtk( )\n" );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::Reset( )
+// CPU reset and Gtk UI update
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::Reset( )
+{
+  CPU->Reset( );
+  regwin->Show( CPU );
+  pgmwin->Disasm( );
+  memwin->DumpD( CPU, 0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::Step( )
+// CPU Step and Gtk UI update
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::Step( )
+{
+  CPU->Exec( );
+  regwin->Show( CPU );
+  pgmwin->Disasm( );
+  memwin->DumpD( CPU, 0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::Main( )
+// Gtk UI Main function
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::Main( )
+{
+  Reset( );
+  gtk_main();
+  g_print( "End of EmuGtk::Main( )\n" );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::ShowMenu( )
+// Show the menu
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::ShowMenu( )
+{
+  FileMenu = gtk_menu_new( );
+  OpenItem = gtk_menu_item_new_with_label( "Open" );
+  QuitItem = gtk_menu_item_new_with_label( "Quit" );
+  gtk_menu_append( GTK_MENU( FileMenu ), GTK_WIDGET( OpenItem ) );
+  gtk_menu_append( GTK_MENU( FileMenu ), GTK_WIDGET( QuitItem ) );
+  gtk_widget_show( GTK_WIDGET( OpenItem ) );
+  gtk_widget_show( GTK_WIDGET( QuitItem ) );
+  
+  ViewMenu = gtk_menu_new( );
+  ExtMemItem = gtk_menu_item_new_with_label( "External Memory Dump" );
+  IntMemItem = gtk_menu_item_new_with_label( "Internal Memory Dump" );
+  //PgmMemItem = gtk_menu_item_new_with_label( "Program Memory Dump" );
+  gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( ExtMemItem ) );
+  gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( IntMemItem ) );
+  //gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( PgmMemItem ) );
+  gtk_widget_show( GTK_WIDGET( ExtMemItem ) );
+  gtk_widget_show( GTK_WIDGET( IntMemItem ) );
+  //gtk_widget_show( GTK_WIDGET( PgmMemItem ) );
+  
+  HelpMenu = gtk_menu_new( );
+  AboutItem = gtk_menu_item_new_with_label( "About" );
+  gtk_menu_append( GTK_MENU( HelpMenu ), GTK_WIDGET( AboutItem ) );
+  gtk_widget_show( GTK_WIDGET( AboutItem ) );
+  
+  MenuBar = gtk_menu_bar_new( );
+  gtk_fixed_put( GTK_FIXED( emufixed ), MenuBar, 0, 0 );
+  gtk_widget_show( GTK_WIDGET( MenuBar ) );
+  
+  FileItem = gtk_menu_item_new_with_label( "File" );
+  ViewItem = gtk_menu_item_new_with_label( "View" );
+  HelpItem = gtk_menu_item_new_with_label( "Help" );
+  gtk_widget_show( GTK_WIDGET( FileItem ) );
+  gtk_widget_show( GTK_WIDGET( ViewItem ) );
+  gtk_widget_show( GTK_WIDGET( HelpItem ) );
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM( FileItem ), FileMenu );
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM( ViewItem ), ViewMenu );
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM( HelpItem ), HelpMenu );
+  gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), FileItem );
+  gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), ViewItem );
+  gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), HelpItem );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal DeleteEvent
+//////////////////////////////////////////////////////////////////////////////
+gboolean EmuGtk::DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  g_print( "EmuGtk::DeleteEvent(...)\n" );
+  StopRunning( );
+  return FALSE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::DestroyEvent( GtkWidget *widget, gpointer data )
+// Signal DestroyEvent
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::DestroyEvent( GtkWidget *widget, gpointer data )
+{
+  g_print( "EmuGtk::DestroyEvent(...)\n" );
+  gtk_main_quit();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::AboutEvent( GtkWidget *widget, gpointer data )
+// Signal AboutEvent ( Help->About in menu )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::AboutEvent( GtkWidget *widget, gpointer data )
+{
+  char about_string[256];
+  GtkWidget *about_window;
+  GtkWidget *text_window;
+
+  sprintf( about_string, "%s\n\nversion %s\n\n\nAuthors:\nHugo Villeneuve\nJonathan St-André\n", PACKAGE, VERSION );
+  
+  about_window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  gtk_window_set_title( GTK_WINDOW( about_window ), "About" );
+  gtk_container_set_border_width( GTK_CONTAINER( about_window ), 20 );
+  
+  text_window = gtk_label_new( about_string );
+  gtk_container_add( GTK_CONTAINER( about_window ), text_window );
+  
+  gtk_widget_show_all( GTK_WIDGET( about_window ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::OpenEvent( GtkWidget *widget, gpointer data )
+// Signal OpenEvent ( File->Open in menu )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::OpenEvent( GtkWidget *widget, gpointer data )
+{
+  GtkWidget *FileOpendialog;
+
+  // g_print( "EmuGtk::OpenEvent(...)\n" );
+
+  FileOpendialog = gtk_file_selection_new( "Open Intel Hex file" );
+
+  // Connect the file dialog's OK button up to a handler.
+  gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION ( FileOpendialog ) -> ok_button ),
+                     "clicked",
+                     GTK_SIGNAL_FUNC( FileOpenDialog_OK ),
+                     FileOpendialog );
+
+  // Connect the file dialog's CANCEL button up to a handler.
+  gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION ( FileOpendialog ) -> cancel_button ),
+                     "clicked",
+                     GTK_SIGNAL_FUNC( FileOpenDialog_CANCEL ),
+                     FileOpendialog );
+
+  // Set the 'File Open dialog' to show only Intel HEX files (.hex).
+  // gtk_file_selection_complete( GTK_FILE_SELECTION( FileOpendialog ), "*.hex" );
+  
+  // Show the dialog
+  gtk_widget_show( GTK_WIDGET( FileOpendialog ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void FileOpenDialog_OK( GtkButton *button, gpointer data )
+{
+  g_print( "EmuGtk::FileOpenDialog_OK Event(...)\n" );
+
+  const gchar *SelectedFile;
+
+  SelectedFile = gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( data ) );
+  
+  g_print( "EmuGtk::File = %s\n", SelectedFile );
+  
+  EmuGtkPtr->StopRunning( );
+
+  EmuGtkPtr->LoadHexFile( SelectedFile );
+
+  gtk_widget_destroy( GTK_WIDGET( data ) );
+
+  EmuGtkPtr->Reset( );
+  EmuGtkPtr->UpdateDisplay();
+}
+
+
+void EmuGtk::UpdateDisplay( void )
+{
+  regwin->Show( CPU );
+  pgmwin->Disasm( );
+  memwin->DumpD( CPU, 0 );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void FileOpenDialog_CANCEL( GtkButton *button, gpointer data )
+{
+  g_print( "EmuGtk::FileOpenDialog_CANCEL Event(...)\n" );
+
+  gtk_widget_destroy( GTK_WIDGET( data ) );
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::QuitEvent( GtkWidget *widget, gpointer data )
+// Signal QuitEvent ( File->Quit in menu )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::QuitEvent( GtkWidget *widget, gpointer data )
+{
+  g_print( "EmuGtk::QuitEvent(...)\n" );
+  StopRunning( );
+  gtk_main_quit( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::ResetEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal ResetEvent ( ResetButton )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::ResetEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  g_print( "EmuGtk::ResetEvent(...)\n" );
+  StopRunning( );
+  Reset( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::RunEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal RunEvent ( RunButton )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::RunEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  g_print( "EmuGtk::RunEvent(...)\n" );
+  if ( RunningState ) {
+    //   g_print( "Getting out of RunningState! \n" );
+    StopRunning( );
+  }
+  else {
+    //   g_print( "Going In RunningState! \n" );
+    StartRunning( );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::StopEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal StopEvent ( StopButton )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::StopEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  g_print( "EmuGtk::StopEvent(...)\n" );
+  StopRunning( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtk::StepEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal StepEvent ( StepButton )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::StepEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  g_print( "EmuGtk::StepEvent(...)\n" );
+  StopRunning( );
+  Step( );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned int EmuGtk::Ascii2Hex( string istring, int length = 0 )
+// Convert an ascii string to an hexadecimal number
+//////////////////////////////////////////////////////////////////////////////
+unsigned int EmuGtk::Ascii2Hex( string istring, int length = 0 )
+{
+  if ( !length || ( length > (int) istring.size() ) )
+    length = istring.size();
+  
+  if ( istring.empty() )
+    throw MissingParameter();
+  
+  unsigned int result = 0;
+  int i, ascii_code;
+  for ( i = 0; i < length; i++ ) {
+    ascii_code = istring[ i ];
+    if ( ascii_code > 0x39 )
+      ascii_code &= 0xDF;
+    if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
+      ascii_code -= 0x30;
+      if ( ascii_code > 9 )
+       ascii_code -= 7;
+      result <<= 4;
+      result += ascii_code;
+    }
+    else {
+      throw SyntaxError();
+    }
+  }
+  return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::LoadHexFile( string Filename )
+// Load an HEX file into program memory
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::LoadHexFile( string Filename )
+{
+  printf("LoadHex\n");
+  int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
+  char Line[ 250 ];
+
+  ifstream HexFile( Filename.c_str() );
+  try { 
+    if ( ! HexFile )
+      throw ErrorOpeningFile();
+    
+    while( ! HexFile.eof() ) {
+      i = 0;
+      Checksum = 0;
+      HexFile.getline( Line, 250, '\n' );  
+
+      if ( Line[ i++ ] != ':' )
+       throw ErrorHexFileFormat();
+      
+      RecLength = Ascii2Hex( &Line[ i ], 2 );
+      i += 2;
+      Checksum += RecLength;
+      
+      LoadOffset = Ascii2Hex( &Line[i], 4 );
+      Checksum += LoadOffset / 256;
+      Checksum += LoadOffset % 256;
+      i += 4;
+
+      RecType = Ascii2Hex( &Line[i],2);
+      i += 2;
+      Checksum += RecType;
+
+      if ( RecType == 1 ) {
+       Checksum += Ascii2Hex( &Line[ i ], 2 );
+       if ( Checksum &= 0x000000FF )
+         throw ErrorHexFileFormat();
+       throw FinishedLoading();
+      }   
+      if ( RecType )
+       throw ErrorHexFileFormat();
+      
+      for ( j = 0; j < RecLength; j++ ) {
+       Data = Ascii2Hex( &Line[ i ], 2 );
+       CPU->WritePGM( (unsigned int)(LoadOffset + j), (unsigned char)Data );
+       i += 2;
+       Checksum += Data;
+      }
+      RecType = Ascii2Hex( &Line[ i ], 2 );
+      Checksum += RecType;      
+
+      if ( Checksum &= 0x000000FF )
+       throw ErrorHexFileFormat();
+    }
+    throw ErrorHexFileFormat();
+  }
+  catch ( ErrorOpeningFile ) {
+    cout << "Error opening file " << Filename << endl;
+  }
+  catch ( ErrorHexFileFormat ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( SyntaxError ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( MissingParameter ) {
+    cout << "Invalid format for " << Filename << " file..." << endl;
+  }
+  catch ( FinishedLoading ) {
+    cout << "Using file " << Filename << " as input program." << endl;  
+  }
+  HexFile.close();  
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtkSignalStub2( GtkWidget *widget, gpointer data )
+// Signal Stub with 2 parameters
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtkSignalStub2( GtkWidget *widget, gpointer data )
+{
+  //g_print( "EmuGtkSignalStub2(...)\n");
+  int SigNumber = (* ( static_cast< int * >( data ) ) );
+  
+  switch( SigNumber )
+    {
+    case DestroySignal:
+      EmuGtkPtr->DestroyEvent( widget, 0 );
+      break;
+    case AboutISignal:
+      EmuGtkPtr->AboutEvent( widget, 0 );
+      break;
+    case OpenISignal:
+      EmuGtkPtr->OpenEvent( widget, 0 );
+      break;
+    case QuitISignal:
+      EmuGtkPtr->QuitEvent( widget, 0 );
+      break;
+    default:
+      g_print( "*** error: EmuGtkSignalStub2: default case reached\n" );
+      break;
+    };
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// gint EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal Stub with 3 parameters
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  //g_print( "EmuGtkSignalStub3(...)\n");
+  int SigNumber = (* ( static_cast< int * >( data ) ) );
+  
+  switch( SigNumber )
+    {
+    case DeleteSignal:
+      EmuGtkPtr->DeleteEvent( widget, event, 0 );
+      break;
+    case ResetBSignal:
+      EmuGtkPtr->ResetEvent( widget, event, 0 );
+      break;
+    case RunBSignal:
+      EmuGtkPtr->RunEvent( widget, event, 0 );
+      break;
+    case StopBSignal:
+      EmuGtkPtr->StopEvent( widget, event, 0 );
+      break;
+    case StepBSignal:
+      EmuGtkPtr->StepEvent( widget, event, 0 );
+      break;
+    default:
+      g_print( "*** error: EmuGtkSignalStub3: default case reached\n" );
+      break;
+    };
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::Running( )
+// Running called by RunningFunction( )
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::Running( )
+{
+  CPU->Exec( );
+  if ( pgmwin->IsBreakpoint( CPU->GetPC( ) ) ) {
+    g_print( "Breakpoint Hit, stopping!\n" );
+    StopRunning( );
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint RunningFunction( )
+// RunningFunction called when idle from gtk_main
+//////////////////////////////////////////////////////////////////////////////
+gint RunningFunction( )
+{
+  EmuGtkPtr->Running( );
+  return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::StartRunning( )
+// Get in the RunningState
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::StartRunning( )
+{
+  if ( !RunningState ) {
+    printf( "EmuGtk::StartRunning( )\n" );
+    RunFuncTag = gtk_idle_add( GtkFunction( RunningFunction ),0 );
+    RunningState = 1;
+    // gtk_widget_hide( GTK_WIDGET( ButtonRun ) );
+    // gtk_widget_show_now( GTK_WIDGET( ButtonStop ) );
+    // gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStop, 3, 4, 0, 1);
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void EmuGtk::StopRunning( )
+// Step out of RunningState
+//////////////////////////////////////////////////////////////////////////////
+void EmuGtk::StopRunning( )
+{
+  if (RunningState) {
+    printf( "EmuGtk::StopRunning( )\n" );
+    gtk_idle_remove( RunFuncTag );
+    RunningState = 0;
+    //gtk_widget_hide( GTK_WIDGET( ButtonStop ) );
+    //gtk_widget_show( GTK_WIDGET( ButtonRun ) );
+    //    gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonRun, 3, 4, 0, 1);
+    regwin->Show( CPU );
+    pgmwin->Disasm( );
+    memwin->DumpD( CPU, 0 );
+  }
+}
diff --git a/src/EmuGtk.hpp b/src/EmuGtk.hpp
new file mode 100644 (file)
index 0000000..8fe4713
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef _EMUGTK_HPP_
+#define _EMUGTK_HPP_
+
+#include <gtk/gtk.h>
+#include <string>
+#include <fstream>
+#include "CPU8051.hpp"
+#include "MemWin.hpp"
+#include "PgmWin.hpp"
+#include "RegWin.hpp"
+#include "GtkSizes.hpp"
+#include "exceptions.hpp"
+
+using namespace std;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// EmuGtk
+// Implements the Gtk+ Graphical User Interface as an Object
+//////////////////////////////////////////////////////////////////////////////
+class EmuGtk {
+public:
+  EmuGtk( int argc , char **argv, CPU8051 *mCPU );
+  ~EmuGtk( );
+  
+  void Main( );
+
+  void Reset( );
+  void Step( );
+  //  void Step( );
+  //  void Exec( );
+
+  void AddButtons( );
+  void ShowMenu( );
+
+  gboolean DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+  void DestroyEvent( GtkWidget *widget, gpointer data );
+
+  void OpenEvent( GtkWidget *widget, gpointer data );
+  void QuitEvent( GtkWidget *widget, gpointer data );
+  void AboutEvent( GtkWidget *widget, gpointer data );
+
+  void ResetEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+  void RunEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+  void StopEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+  void StepEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+
+  void StartRunning( );
+  void StopRunning( );
+  void Running( );
+
+  void LoadHexFile( string Filename );
+  void UpdateDisplay();
+
+private:
+  int     EmuGtkID;
+  CPU8051 *CPU;
+  int     RunningState;
+  int     RunFuncTag;
+  MemWin  *memwin;
+  PgmWin  *pgmwin;
+  RegWin  *regwin;
+  GtkWidget *emuwin, *emufixed, *emumainfixed;
+  GtkWidget *regfrm, *pgmfrm, *memfrm;
+  GtkWidget *ButtonTable;
+  
+  //  GdkPixmap *PixMapT, *PixMapRun, *PixMapR, *PixMapQ;
+  //  GtkWidget *PixMapWidT, *PixMapWidRun, *PixMapWidR, *PixMapWidQ;
+  //  GdkBitmap *mask;
+  GtkWidget *FileMenu, *OpenItem, *QuitItem, *FileItem;
+  GtkWidget *ViewMenu, *ExtMemItem, *IntMemItem, *ViewItem;
+  //  GtkWidget *ViewMenu, *ExtMemItem, *IntMemItem, *PgmMemItem, *ViewItem;
+  GtkWidget *HelpMenu, *AboutItem, *LicenseItem, *HelpItem;
+  GtkWidget *MenuBar;
+
+  // RESET button
+  GdkBitmap *RESET_mask;
+  GdkPixmap *RESET_pixmap;
+  GtkWidget *RESET_widget;
+  GtkWidget *ButtonReset;
+
+  // RUN button
+  GdkBitmap *RUN_mask;
+  GdkPixmap *RUN_pixmap;
+  GtkWidget *RUN_widget;
+  GtkWidget *ButtonRun;
+
+  // STOP button
+  GdkBitmap *STOP_mask;
+  GdkPixmap *STOP_pixmap;
+  GtkWidget *STOP_widget;
+  GtkWidget *ButtonStop;
+
+  // STEP button
+  GdkBitmap *STEP_mask;
+  GdkPixmap *STEP_pixmap;
+  GtkWidget *STEP_widget;
+  GtkWidget *ButtonStep;
+  unsigned int Ascii2Hex( string istring, int length );
+};
+
+void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data );
+void EmuGtkSignalStub2( GtkWidget *widget, gpointer data );
+void FileOpenDialog_OK( GtkButton *button, gpointer data );
+void FileOpenDialog_CANCEL( GtkButton *button, gpointer data );
+
+gint RunningFunction( );
+
+
+#endif
diff --git a/src/GtkSizes.hpp b/src/GtkSizes.hpp
new file mode 100644 (file)
index 0000000..9bffe25
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _GTKSIZES_HPP_
+#define _GTKSIZES_HPP_
+
+#define NUMBER_OF_BUTTONS  5
+#define BUTTON_WIDTH       60
+#define BUTTON_HEIGHT      60
+#define BUTTONS_BAR_WIDTH  (NUMBER_OF_BUTTONS * BUTTON_WIDTH)
+#define BUTTONS_BAR_HEIGHT BUTTON_HEIGHT
+
+#define REG_WIN_WIDTH      100
+#define REG_WIN_HEIGHT     390
+
+#define PGM_WIN_WIDTH      480
+#define PGM_WIN_HEIGHT     390
+
+#define MEM_WIN_WIDTH      590
+#define MEM_WIN_HEIGHT     280
+
+#define MENU_BAR_HEIGHT    0
+
+#define MAIN_WIN_WIDTH     (REG_WIN_WIDTH + PGM_WIN_WIDTH)
+#define MAIN_WIN_HEIGHT    (BUTTONS_BAR_HEIGHT + REG_WIN_HEIGHT + MEM_WIN_HEIGHT)
+
+#endif
diff --git a/src/Inst_Def.hpp b/src/Inst_Def.hpp
new file mode 100644 (file)
index 0000000..2ef66da
--- /dev/null
@@ -0,0 +1,266 @@
+#ifndef __INST_DEF_HPP_
+#define __INST_DEF_HPP_
+// Do not modify this file directly, it was created by Opcode2cpp.pl
+// Any modification made directly on this file will be lost
+
+
+int OP_00( );
+int OP_01( );
+int OP_02( );
+int OP_03( );
+int OP_04( );
+int OP_05( );
+int OP_06( );
+int OP_07( );
+int OP_08( );
+int OP_09( );
+int OP_0A( );
+int OP_0B( );
+int OP_0C( );
+int OP_0D( );
+int OP_0E( );
+int OP_0F( );
+int OP_10( );
+int OP_11( );
+int OP_12( );
+int OP_13( );
+int OP_14( );
+int OP_15( );
+int OP_16( );
+int OP_17( );
+int OP_18( );
+int OP_19( );
+int OP_1A( );
+int OP_1B( );
+int OP_1C( );
+int OP_1D( );
+int OP_1E( );
+int OP_1F( );
+int OP_20( );
+int OP_21( );
+int OP_22( );
+int OP_23( );
+int OP_24( );
+int OP_25( );
+int OP_26( );
+int OP_27( );
+int OP_28( );
+int OP_29( );
+int OP_2A( );
+int OP_2B( );
+int OP_2C( );
+int OP_2D( );
+int OP_2E( );
+int OP_2F( );
+int OP_30( );
+int OP_31( );
+int OP_32( );
+int OP_33( );
+int OP_34( );
+int OP_35( );
+int OP_36( );
+int OP_37( );
+int OP_38( );
+int OP_39( );
+int OP_3A( );
+int OP_3B( );
+int OP_3C( );
+int OP_3D( );
+int OP_3E( );
+int OP_3F( );
+int OP_40( );
+int OP_41( );
+int OP_42( );
+int OP_43( );
+int OP_44( );
+int OP_45( );
+int OP_46( );
+int OP_47( );
+int OP_48( );
+int OP_49( );
+int OP_4A( );
+int OP_4B( );
+int OP_4C( );
+int OP_4D( );
+int OP_4E( );
+int OP_4F( );
+int OP_50( );
+int OP_51( );
+int OP_52( );
+int OP_53( );
+int OP_54( );
+int OP_55( );
+int OP_56( );
+int OP_57( );
+int OP_58( );
+int OP_59( );
+int OP_5A( );
+int OP_5B( );
+int OP_5C( );
+int OP_5D( );
+int OP_5E( );
+int OP_5F( );
+int OP_60( );
+int OP_61( );
+int OP_62( );
+int OP_63( );
+int OP_64( );
+int OP_65( );
+int OP_66( );
+int OP_67( );
+int OP_68( );
+int OP_69( );
+int OP_6A( );
+int OP_6B( );
+int OP_6C( );
+int OP_6D( );
+int OP_6E( );
+int OP_6F( );
+int OP_70( );
+int OP_71( );
+int OP_72( );
+int OP_73( );
+int OP_74( );
+int OP_75( );
+int OP_76( );
+int OP_77( );
+int OP_78( );
+int OP_79( );
+int OP_7A( );
+int OP_7B( );
+int OP_7C( );
+int OP_7D( );
+int OP_7E( );
+int OP_7F( );
+int OP_80( );
+int OP_81( );
+int OP_82( );
+int OP_83( );
+int OP_84( );
+int OP_85( );
+int OP_86( );
+int OP_87( );
+int OP_88( );
+int OP_89( );
+int OP_8A( );
+int OP_8B( );
+int OP_8C( );
+int OP_8D( );
+int OP_8E( );
+int OP_8F( );
+int OP_90( );
+int OP_91( );
+int OP_92( );
+int OP_93( );
+int OP_94( );
+int OP_95( );
+int OP_96( );
+int OP_97( );
+int OP_98( );
+int OP_99( );
+int OP_9A( );
+int OP_9B( );
+int OP_9C( );
+int OP_9D( );
+int OP_9E( );
+int OP_9F( );
+int OP_A0( );
+int OP_A1( );
+int OP_A2( );
+int OP_A3( );
+int OP_A4( );
+int OP_A5( );
+int OP_A6( );
+int OP_A7( );
+int OP_A8( );
+int OP_A9( );
+int OP_AA( );
+int OP_AB( );
+int OP_AC( );
+int OP_AD( );
+int OP_AE( );
+int OP_AF( );
+int OP_B0( );
+int OP_B1( );
+int OP_B2( );
+int OP_B3( );
+int OP_B4( );
+int OP_B5( );
+int OP_B6( );
+int OP_B7( );
+int OP_B8( );
+int OP_B9( );
+int OP_BA( );
+int OP_BB( );
+int OP_BC( );
+int OP_BD( );
+int OP_BE( );
+int OP_BF( );
+int OP_C0( );
+int OP_C1( );
+int OP_C2( );
+int OP_C3( );
+int OP_C4( );
+int OP_C5( );
+int OP_C6( );
+int OP_C7( );
+int OP_C8( );
+int OP_C9( );
+int OP_CA( );
+int OP_CB( );
+int OP_CC( );
+int OP_CD( );
+int OP_CE( );
+int OP_CF( );
+int OP_D0( );
+int OP_D1( );
+int OP_D2( );
+int OP_D3( );
+int OP_D4( );
+int OP_D5( );
+int OP_D6( );
+int OP_D7( );
+int OP_D8( );
+int OP_D9( );
+int OP_DA( );
+int OP_DB( );
+int OP_DC( );
+int OP_DD( );
+int OP_DE( );
+int OP_DF( );
+int OP_E0( );
+int OP_E1( );
+int OP_E2( );
+int OP_E3( );
+int OP_E4( );
+int OP_E5( );
+int OP_E6( );
+int OP_E7( );
+int OP_E8( );
+int OP_E9( );
+int OP_EA( );
+int OP_EB( );
+int OP_EC( );
+int OP_ED( );
+int OP_EE( );
+int OP_EF( );
+int OP_F0( );
+int OP_F1( );
+int OP_F2( );
+int OP_F3( );
+int OP_F4( );
+int OP_F5( );
+int OP_F6( );
+int OP_F7( );
+int OP_F8( );
+int OP_F9( );
+int OP_FA( );
+int OP_FB( );
+int OP_FC( );
+int OP_FD( );
+int OP_FE( );
+int OP_FF( );
+void InitFuncPtr( );
+
+
+#endif
diff --git a/src/Inst_Imp.cpp b/src/Inst_Imp.cpp
new file mode 100644 (file)
index 0000000..b8998ab
--- /dev/null
@@ -0,0 +1,4208 @@
+#ifndef __INST_IMP_HPP_
+#define __INST_IMP_HPP_
+
+//#include "CPU8051.hpp"
+
+// Do not modify this file directly, it was created by Opcode2cpp.pl
+// Any modification made directly on this file will be lost
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_00( )
+// Instruction "NOP" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_00( )
+{
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_01( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_01( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_02( )
+// Instruction "LJMP addr16" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_02( )
+{
+unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );
+addr16 += PGMMem->Read8( PC++ );
+PC = addr16;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_03( )
+// Instruction "RR A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_03( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination = ( destination >> 1 ) | ( destination << 7 );
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_04( )
+// Instruction "INC A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_04( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination++;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_05( )
+// Instruction "INC direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_05( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+destination++;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_06( )
+// Instruction "INC @R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_06( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination++;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_07( )
+// Instruction "INC @R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_07( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination++;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_08( )
+// Instruction "INC R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_08( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+destination++;
+WriteD( BANKPSW + _R0_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_09( )
+// Instruction "INC R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_09( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+destination++;
+WriteD( BANKPSW + _R1_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0A( )
+// Instruction "INC R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0A( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+destination++;
+WriteD( BANKPSW + _R2_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0B( )
+// Instruction "INC R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0B( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+destination++;
+WriteD( BANKPSW + _R3_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0C( )
+// Instruction "INC R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0C( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+destination++;
+WriteD( BANKPSW + _R4_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0D( )
+// Instruction "INC R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0D( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+destination++;
+WriteD( BANKPSW + _R5_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0E( )
+// Instruction "INC R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0E( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+destination++;
+WriteD( BANKPSW + _R6_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_0F( )
+// Instruction "INC R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_0F( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+destination++;
+WriteD( BANKPSW + _R7_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_10( )
+// Instruction "JBC bitaddr,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_10( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( destination == 1 ) { PC = source; destination = 0; }
+WriteB( dstbitaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_11( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_11( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_12( )
+// Instruction "LCALL addr16" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_12( )
+{
+unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );
+addr16 += PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = addr16;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_13( )
+// Instruction "RRC A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_13( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char tmpval = destination;
+destination = ( destination >> 1 ) | ( ReadD( _PSW_ ) & 0x80 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval << 7 ) );
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_14( )
+// Instruction "DEC A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_14( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination--;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_15( )
+// Instruction "DEC direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_15( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+destination--;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_16( )
+// Instruction "DEC @R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_16( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination--;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_17( )
+// Instruction "DEC @R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_17( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination--;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_18( )
+// Instruction "DEC R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_18( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+destination--;
+WriteD( BANKPSW + _R0_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_19( )
+// Instruction "DEC R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_19( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+destination--;
+WriteD( BANKPSW + _R1_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1A( )
+// Instruction "DEC R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1A( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+destination--;
+WriteD( BANKPSW + _R2_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1B( )
+// Instruction "DEC R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1B( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+destination--;
+WriteD( BANKPSW + _R3_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1C( )
+// Instruction "DEC R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1C( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+destination--;
+WriteD( BANKPSW + _R4_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1D( )
+// Instruction "DEC R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1D( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+destination--;
+WriteD( BANKPSW + _R5_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1E( )
+// Instruction "DEC R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1E( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+destination--;
+WriteD( BANKPSW + _R6_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_1F( )
+// Instruction "DEC R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_1F( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+destination--;
+WriteD( BANKPSW + _R7_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_20( )
+// Instruction "JB bitaddr,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_20( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( destination == 1 ) { PC = source; }
+WriteB( dstbitaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_21( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_21( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_22( )
+// Instruction "RET" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_22( )
+{
+unsigned char SP = ReadD( _SP_ );
+PC = ( ReadI( SP-- ) << 8 );
+PC += ReadI ( SP-- );
+WriteD( _SP_, SP );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_23( )
+// Instruction "RL A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_23( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination = ( destination << 1 ) | ( destination >> 7 );
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_24( )
+// Instruction "ADD A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_24( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_25( )
+// Instruction "ADD A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_25( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_26( )
+// Instruction "ADD A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_26( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_27( )
+// Instruction "ADD A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_27( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_28( )
+// Instruction "ADD A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_28( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_29( )
+// Instruction "ADD A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_29( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2A( )
+// Instruction "ADD A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2B( )
+// Instruction "ADD A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2C( )
+// Instruction "ADD A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2D( )
+// Instruction "ADD A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2E( )
+// Instruction "ADD A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_2F( )
+// Instruction "ADD A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_2F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_30( )
+// Instruction "JNB bitaddr,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_30( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( destination == 0 ) { PC = source; }
+WriteB( dstbitaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_31( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_31( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_32( )
+// Instruction "RETI" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_32( )
+{
+ActivePriority = -1;
+unsigned char SP = ReadD( _SP_ );
+PC = ( ReadI( SP-- ) << 8 );
+PC += ReadI( SP-- );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_33( )
+// Instruction "RLC A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_33( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char tmpval = destination;
+destination = ( destination << 1 ) | ( ( ReadD( _PSW_ ) & 0x80 ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval & 0x80 ) );
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_34( )
+// Instruction "ADDC A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_34( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_35( )
+// Instruction "ADDC A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_35( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_36( )
+// Instruction "ADDC A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_36( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_37( )
+// Instruction "ADDC A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_37( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_38( )
+// Instruction "ADDC A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_38( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_39( )
+// Instruction "ADDC A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_39( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3A( )
+// Instruction "ADDC A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3B( )
+// Instruction "ADDC A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3C( )
+// Instruction "ADDC A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3D( )
+// Instruction "ADDC A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3E( )
+// Instruction "ADDC A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_3F( )
+// Instruction "ADDC A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_3F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination + source + carryflag > 0xFF ) {
+   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination += source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_40( )
+// Instruction "JC reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_40( )
+{
+PC++;
+unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( ReadD( _PSW_ ) > 0x7F) { PC = destination; }
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_41( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_41( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_42( )
+// Instruction "ORL direct,A" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_42( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( _ACC_ );
+destination |= source;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_43( )
+// Instruction "ORL direct,#data" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_43( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = PGMMem->Read8( PC++ );
+destination |= source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_44( )
+// Instruction "ORL A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_44( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_45( )
+// Instruction "ORL A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_45( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_46( )
+// Instruction "ORL A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_46( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_47( )
+// Instruction "ORL A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_47( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_48( )
+// Instruction "ORL A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_48( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_49( )
+// Instruction "ORL A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_49( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4A( )
+// Instruction "ORL A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4B( )
+// Instruction "ORL A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4C( )
+// Instruction "ORL A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4D( )
+// Instruction "ORL A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4E( )
+// Instruction "ORL A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_4F( )
+// Instruction "ORL A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_4F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+destination |= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_50( )
+// Instruction "JNC reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_50( )
+{
+PC++;
+unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( ReadD( _PSW_ ) < 0x80 ) { PC = destination; }
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_51( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_51( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_52( )
+// Instruction "ANL direct,A" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_52( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( _ACC_ );
+destination &= source;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_53( )
+// Instruction "ANL direct,#data" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_53( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = PGMMem->Read8( PC++ );
+destination &= source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_54( )
+// Instruction "ANL A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_54( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_55( )
+// Instruction "ANL A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_55( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_56( )
+// Instruction "ANL A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_56( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_57( )
+// Instruction "ANL A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_57( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_58( )
+// Instruction "ANL A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_58( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_59( )
+// Instruction "ANL A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_59( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5A( )
+// Instruction "ANL A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5B( )
+// Instruction "ANL A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5C( )
+// Instruction "ANL A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5D( )
+// Instruction "ANL A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5E( )
+// Instruction "ANL A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_5F( )
+// Instruction "ANL A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_5F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+destination &= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_60( )
+// Instruction "JZ reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_60( )
+{
+PC++;
+unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( ReadD( _ACC_ ) == 0 ) { PC = destination; }
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_61( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_61( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_62( )
+// Instruction "XRL direct,A" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_62( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( _ACC_ );
+destination ^= source;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_63( )
+// Instruction "XRL direct,#data" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_63( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = PGMMem->Read8( PC++ );
+destination ^= source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_64( )
+// Instruction "XRL A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_64( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_65( )
+// Instruction "XRL A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_65( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_66( )
+// Instruction "XRL A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_66( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_67( )
+// Instruction "XRL A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_67( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_68( )
+// Instruction "XRL A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_68( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_69( )
+// Instruction "XRL A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_69( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6A( )
+// Instruction "XRL A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6B( )
+// Instruction "XRL A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6C( )
+// Instruction "XRL A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6D( )
+// Instruction "XRL A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6E( )
+// Instruction "XRL A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_6F( )
+// Instruction "XRL A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_6F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+destination ^= source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_70( )
+// Instruction "JNZ reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_70( )
+{
+PC++;
+unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+if ( ReadD( _ACC_ ) != 0 ) { PC = destination; }
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_71( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_71( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_72( )
+// Instruction "ORL C,bitaddr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_72( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );
+source = ReadB( srcbitaddr );
+WriteD( _PSW_ , ( ( destination | source ) << 7 ) );
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_73( )
+// Instruction "JMP @A+DPTR" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_73( )
+{
+unsigned int destination = ReadI( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );
+PC = destination;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_74( )
+// Instruction "MOV A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_74( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_75( )
+// Instruction "MOV direct,#data" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_75( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_76( )
+// Instruction "MOV @R0,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_76( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_77( )
+// Instruction "MOV @R1,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_77( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_78( )
+// Instruction "MOV R0,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_78( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R0_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_79( )
+// Instruction "MOV R1,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_79( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R1_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7A( )
+// Instruction "MOV R2,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7A( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R2_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7B( )
+// Instruction "MOV R3,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7B( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R3_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7C( )
+// Instruction "MOV R4,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7C( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R4_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7D( )
+// Instruction "MOV R5,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7D( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R5_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7E( )
+// Instruction "MOV R6,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7E( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R6_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_7F( )
+// Instruction "MOV R7,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_7F( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+unsigned char source = PGMMem->Read8( PC++ );
+destination = source;
+WriteD( BANKPSW + _R7_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_80( )
+// Instruction "SJMP reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_80( )
+{
+PC++;
+unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+PC = destination;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_81( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_81( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_82( )
+// Instruction "ANL C,bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_82( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );
+source = ReadB( srcbitaddr );
+WriteD( _PSW_, ( ( destination & source) << 7 ) );
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_83( )
+// Instruction "MOVC A,@A+PC" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_83( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ( ++PC ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_84( )
+// Instruction "DIV AB" takes 4 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_84( )
+{
+unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );
+if ( B != 0 ) {
+WriteD( _ACC_, A/B ); WriteD( _B_, A%B );
+} else WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+return 4;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_85( )
+// Instruction "MOV direct,direct" takes 1 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_85( )
+{
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+destination = source;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_86( )
+// Instruction "MOV direct,@R0" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_86( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_87( )
+// Instruction "MOV direct,@R1" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_87( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_88( )
+// Instruction "MOV direct,R0" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_88( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_89( )
+// Instruction "MOV direct,R1" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_89( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8A( )
+// Instruction "MOV direct,R2" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8A( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8B( )
+// Instruction "MOV direct,R3" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8B( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8C( )
+// Instruction "MOV direct,R4" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8C( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8D( )
+// Instruction "MOV direct,R5" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8D( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8E( )
+// Instruction "MOV direct,R6" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8E( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_8F( )
+// Instruction "MOV direct,R7" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_8F( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+destination = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_90( )
+// Instruction "MOV DPTR,#data16" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_90( )
+{
+unsigned int destination = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );
+unsigned char source = ( PGMMem->Read8( PC++ ) << 8 );
+source += PGMMem->Read8( PC++ );
+destination = source;
+WriteD( _DPTRHIGH_, ( destination >> 8 ) );
+WriteD( _DPTRLOW_, ( destination & 0xFF ) );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_91( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_91( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_92( )
+// Instruction "MOV bitaddr,C" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_92( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+unsigned char source = ( ReadD( _PSW_ ) >> 7 );
+destination = source;
+WriteB( dstbitaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_93( )
+// Instruction "MOVC A,@A+DPTR" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_93( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_94( )
+// Instruction "SUBB A,#data" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_94( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_95( )
+// Instruction "SUBB A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_95( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_96( )
+// Instruction "SUBB A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_96( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_97( )
+// Instruction "SUBB A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_97( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_98( )
+// Instruction "SUBB A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_98( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_99( )
+// Instruction "SUBB A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_99( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9A( )
+// Instruction "SUBB A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9A( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9B( )
+// Instruction "SUBB A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9B( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9C( )
+// Instruction "SUBB A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9C( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9D( )
+// Instruction "SUBB A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9D( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9E( )
+// Instruction "SUBB A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9E( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_9F( )
+// Instruction "SUBB A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_9F( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+unsigned char carryflag = ReadD( _PSW_ ) >> 7;
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );
+if ( destination < ( source + carryflag ) ) {
+  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );
+destination -= source + carryflag;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A0( )
+// Instruction "ORL C,/bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A0( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );
+source = ( ReadB( srcbitaddr ) ^ 1 );
+WriteD( _PSW_ , ( ( destination | source ) << 7 ) );
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A1( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A2( )
+// Instruction "MOV C,bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A2( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );
+source = ReadB( srcbitaddr );
+destination = source;
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A3( )
+// Instruction "INC DPTR" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A3( )
+{
+unsigned int destination = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );
+destination++;
+WriteD( _DPTRHIGH_, ( destination >> 8 ) );
+WriteD( _DPTRLOW_, ( destination & 0xFF ) );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A4( )
+// Instruction "MUL AB" takes 4 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A4( )
+{
+unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );
+WriteD( _ACC_ , ( ( A * B ) & 0x00FF ) ); WriteD( _B_, ( A * B ) / 0x100 );
+if ( ReadD( _B_ ) > 0) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );
+return 4;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A5( )
+// Instruction "INVALID" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A5( )
+{
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A6( )
+// Instruction "MOV @R0,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A6( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A7( )
+// Instruction "MOV @R1,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A7( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A8( )
+// Instruction "MOV R0,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A8( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R0_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_A9( )
+// Instruction "MOV R1,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_A9( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R1_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AA( )
+// Instruction "MOV R2,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AA( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R2_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AB( )
+// Instruction "MOV R3,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AB( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R3_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AC( )
+// Instruction "MOV R4,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AC( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R4_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AD( )
+// Instruction "MOV R5,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AD( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R5_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AE( )
+// Instruction "MOV R6,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AE( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R6_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_AF( )
+// Instruction "MOV R7,direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_AF( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( BANKPSW + _R7_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B0( )
+// Instruction "ANL C,/bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B0( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );
+source = ( ReadB( srcbitaddr ) ^ 1 );
+WriteD( _PSW_, ( ( destination & source) << 7 ) );
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B1( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B2( )
+// Instruction "CPL bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B2( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+destination ^= 0x01;
+WriteB( dstbitaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B3( )
+// Instruction "CPL C" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B3( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+destination ^= 0x01;
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B4( )
+// Instruction "CJNE A,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B4( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B5( )
+// Instruction "CJNE A,direct,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B5( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B6( )
+// Instruction "CJNE @R0,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B6( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B7( )
+// Instruction "CJNE @R1,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B7( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B8( )
+// Instruction "CJNE R0,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B8( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R0_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_B9( )
+// Instruction "CJNE R1,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_B9( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R1_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BA( )
+// Instruction "CJNE R2,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BA( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R2_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BB( )
+// Instruction "CJNE R3,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BB( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R3_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BC( )
+// Instruction "CJNE R4,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BC( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R4_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BD( )
+// Instruction "CJNE R5,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BD( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R5_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BE( )
+// Instruction "CJNE R6,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BE( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R6_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_BF( )
+// Instruction "CJNE R7,#data,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_BF( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+unsigned char source = PGMMem->Read8( PC++ );
+unsigned int reladdr = ( ( PGMMem->Read8( PC++ ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );
+WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );
+if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+if ( destination != source ) PC = reladdr;
+WriteD( BANKPSW + _R7_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C0( )
+// Instruction "PUSH direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C0( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, destination );
+WriteD( _SP_, SP );
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C1( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C2( )
+// Instruction "CLR bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C2( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+destination = 0;
+WriteB( dstbitaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C3( )
+// Instruction "CLR C" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C3( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+destination = 0;
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C4( )
+// Instruction "SWAP A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C4( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination = ( destination << 4 ) + ( destination >> 4 );
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C5( )
+// Instruction "XCH A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C5( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( srcaddr, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C6( )
+// Instruction "XCH A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C6( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteI( ReadD( BANKPSW + _R0_ ), source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C7( )
+// Instruction "XCH A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C7( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteI( ReadD( BANKPSW + _R1_ ), source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C8( )
+// Instruction "XCH A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C8( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R0_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_C9( )
+// Instruction "XCH A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_C9( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R1_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CA( )
+// Instruction "XCH A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CA( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R2_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CB( )
+// Instruction "XCH A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CB( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R3_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CC( )
+// Instruction "XCH A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CC( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R4_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CD( )
+// Instruction "XCH A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CD( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R5_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CE( )
+// Instruction "XCH A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CE( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R6_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_CF( )
+// Instruction "XCH A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_CF( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+unsigned char tmpval = destination;
+destination = source; source = tmpval;
+WriteD( _ACC_, destination );
+WriteD( BANKPSW + _R7_, source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D0( )
+// Instruction "POP direct" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D0( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char SP = ReadD( _SP_ );
+destination = ReadI( SP-- );
+WriteD( _SP_, SP );
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D1( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D2( )
+// Instruction "SETB bitaddr" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D2( )
+{
+unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );
+destination = ReadB( dstbitaddr );
+destination = 1;
+WriteB( dstbitaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D3( )
+// Instruction "SETB C" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D3( )
+{
+unsigned char destination = ( ReadD( _PSW_ ) >> 7 );
+destination = 1;
+WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D4( )
+// Instruction "DA A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D4( )
+{
+unsigned char destination = ReadD( _ACC_ );
+if ( ( ( destination & 0x0F ) > 9) || ( ReadD( _PSW_ ) | 0x40)) {
+   if ( ( destination + 6 ) > 0xFF)  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   destination += 6;
+}
+if ( ( ReadD( _PSW_ ) & 0x80) || ( ( destination & 0xF0 ) > 0x90 ) ) {
+   if ( ( destination + 0x60 ) > 0xFF ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );
+   destination += 0x60;
+}
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D5( )
+// Instruction "DJNZ direct,reladdr" takes 2 cycle(s) and 3 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D5( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( destaddr, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D6( )
+// Instruction "XCHD A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D6( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char tmpval = ( destination & 0x0F );
+destination = ( destination & 0xF0 ) + ( source & 0x0F );
+source = ( source & 0xF0 ) + tmpval;
+WriteD( _ACC_, destination );
+WriteI( ReadD( BANKPSW + _R0_ ), source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D7( )
+// Instruction "XCHD A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D7( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char tmpval = ( destination & 0x0F );
+destination = ( destination & 0xF0 ) + ( source & 0x0F );
+source = ( source & 0xF0 ) + tmpval;
+WriteD( _ACC_, destination );
+WriteI( ReadD( BANKPSW + _R1_ ), source );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D8( )
+// Instruction "DJNZ R0,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D8( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R0_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_D9( )
+// Instruction "DJNZ R1,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_D9( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R1_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DA( )
+// Instruction "DJNZ R2,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DA( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R2_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DB( )
+// Instruction "DJNZ R3,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DB( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R3_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DC( )
+// Instruction "DJNZ R4,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DC( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R4_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DD( )
+// Instruction "DJNZ R5,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DD( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R5_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DE( )
+// Instruction "DJNZ R6,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DE( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R6_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_DF( )
+// Instruction "DJNZ R7,reladdr" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_DF( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+PC++;
+unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );
+destination--;
+if ( destination != 0 ) PC = source;
+WriteD( BANKPSW + _R7_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E0( )
+// Instruction "MOVX A,@DPTR" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E0( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );
+destination = source;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E1( )
+// Instruction "AJMP addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E2( )
+// Instruction "MOVX A,@R0" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E2( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E3( )
+// Instruction "MOVX A,@R1" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E3( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E4( )
+// Instruction "CLR A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E4( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination = 0;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E5( )
+// Instruction "MOV A,direct" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E5( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char srcaddr = PGMMem->Read8( PC++ );
+unsigned char source = ReadD( srcaddr );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E6( )
+// Instruction "MOV A,@R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E6( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E7( )
+// Instruction "MOV A,@R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E7( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E8( )
+// Instruction "MOV A,R0" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E8( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R0_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_E9( )
+// Instruction "MOV A,R1" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_E9( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R1_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_EA( )
+// Instruction "MOV A,R2" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_EA( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R2_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_EB( )
+// Instruction "MOV A,R3" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_EB( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R3_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_EC( )
+// Instruction "MOV A,R4" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_EC( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R4_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_ED( )
+// Instruction "MOV A,R5" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_ED( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R5_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_EE( )
+// Instruction "MOV A,R6" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_EE( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R6_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_EF( )
+// Instruction "MOV A,R7" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_EF( )
+{
+unsigned char destination = ReadD( _ACC_ );
+unsigned char source = ReadD( BANKPSW + _R7_ );
+destination = source;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F0( )
+// Instruction "MOVX @DPTR,A" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F0( )
+{
+unsigned char destination = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F1( )
+// Instruction "ACALL addr11" takes 2 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F1( )
+{
+unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );
+unsigned char SP = ReadD( _SP_ );
+WriteI( ++SP, ( PC & 0x00FF ) );
+WriteI( ++SP, ( PC >> 8 ) );
+WriteD( _SP_, SP );
+PC = ( PC & 0xF800 ) | addr11;
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F2( )
+// Instruction "MOVX @R0,A" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F2( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F3( )
+// Instruction "MOVX @R1,A" takes 2 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F3( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 2;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F4( )
+// Instruction "CPL A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F4( )
+{
+unsigned char destination = ReadD( _ACC_ );
+destination ^= 0xFF;
+WriteD( _ACC_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F5( )
+// Instruction "MOV direct,A" takes 1 cycle(s) and 2 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F5( )
+{
+unsigned char destaddr = PGMMem->Read8( PC++ );
+unsigned char destination = ReadD( destaddr );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( destaddr, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F6( )
+// Instruction "MOV @R0,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F6( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R0_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F7( )
+// Instruction "MOV @R1,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F7( )
+{
+unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteI( ReadD( BANKPSW + _R1_ ), destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F8( )
+// Instruction "MOV R0,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F8( )
+{
+unsigned char destination = ReadD( BANKPSW + _R0_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R0_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_F9( )
+// Instruction "MOV R1,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_F9( )
+{
+unsigned char destination = ReadD( BANKPSW + _R1_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R1_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FA( )
+// Instruction "MOV R2,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FA( )
+{
+unsigned char destination = ReadD( BANKPSW + _R2_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R2_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FB( )
+// Instruction "MOV R3,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FB( )
+{
+unsigned char destination = ReadD( BANKPSW + _R3_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R3_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FC( )
+// Instruction "MOV R4,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FC( )
+{
+unsigned char destination = ReadD( BANKPSW + _R4_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R4_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FD( )
+// Instruction "MOV R5,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FD( )
+{
+unsigned char destination = ReadD( BANKPSW + _R5_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R5_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FE( )
+// Instruction "MOV R6,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FE( )
+{
+unsigned char destination = ReadD( BANKPSW + _R6_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R6_, destination );
+return 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::OP_FF( )
+// Instruction "MOV R7,A" takes 1 cycle(s) and 1 byte(s)
+//////////////////////////////////////////////////////////////////////////////
+int CPU8051::OP_FF( )
+{
+unsigned char destination = ReadD( BANKPSW + _R7_ );
+unsigned char source = ReadD( _ACC_ );
+destination = source;
+WriteD( BANKPSW + _R7_, destination );
+return 1;
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void CPU8051::InitFuncPtr( )
+// Initialize Functions Pointers
+//////////////////////////////////////////////////////////////////////////////
+void CPU8051::InitFuncPtr( )
+{
+ funcptr[0]=&CPU8051::OP_00;
+ funcptr[1]=&CPU8051::OP_01;
+ funcptr[2]=&CPU8051::OP_02;
+ funcptr[3]=&CPU8051::OP_03;
+ funcptr[4]=&CPU8051::OP_04;
+ funcptr[5]=&CPU8051::OP_05;
+ funcptr[6]=&CPU8051::OP_06;
+ funcptr[7]=&CPU8051::OP_07;
+ funcptr[8]=&CPU8051::OP_08;
+ funcptr[9]=&CPU8051::OP_09;
+ funcptr[10]=&CPU8051::OP_0A;
+ funcptr[11]=&CPU8051::OP_0B;
+ funcptr[12]=&CPU8051::OP_0C;
+ funcptr[13]=&CPU8051::OP_0D;
+ funcptr[14]=&CPU8051::OP_0E;
+ funcptr[15]=&CPU8051::OP_0F;
+ funcptr[16]=&CPU8051::OP_10;
+ funcptr[17]=&CPU8051::OP_11;
+ funcptr[18]=&CPU8051::OP_12;
+ funcptr[19]=&CPU8051::OP_13;
+ funcptr[20]=&CPU8051::OP_14;
+ funcptr[21]=&CPU8051::OP_15;
+ funcptr[22]=&CPU8051::OP_16;
+ funcptr[23]=&CPU8051::OP_17;
+ funcptr[24]=&CPU8051::OP_18;
+ funcptr[25]=&CPU8051::OP_19;
+ funcptr[26]=&CPU8051::OP_1A;
+ funcptr[27]=&CPU8051::OP_1B;
+ funcptr[28]=&CPU8051::OP_1C;
+ funcptr[29]=&CPU8051::OP_1D;
+ funcptr[30]=&CPU8051::OP_1E;
+ funcptr[31]=&CPU8051::OP_1F;
+ funcptr[32]=&CPU8051::OP_20;
+ funcptr[33]=&CPU8051::OP_21;
+ funcptr[34]=&CPU8051::OP_22;
+ funcptr[35]=&CPU8051::OP_23;
+ funcptr[36]=&CPU8051::OP_24;
+ funcptr[37]=&CPU8051::OP_25;
+ funcptr[38]=&CPU8051::OP_26;
+ funcptr[39]=&CPU8051::OP_27;
+ funcptr[40]=&CPU8051::OP_28;
+ funcptr[41]=&CPU8051::OP_29;
+ funcptr[42]=&CPU8051::OP_2A;
+ funcptr[43]=&CPU8051::OP_2B;
+ funcptr[44]=&CPU8051::OP_2C;
+ funcptr[45]=&CPU8051::OP_2D;
+ funcptr[46]=&CPU8051::OP_2E;
+ funcptr[47]=&CPU8051::OP_2F;
+ funcptr[48]=&CPU8051::OP_30;
+ funcptr[49]=&CPU8051::OP_31;
+ funcptr[50]=&CPU8051::OP_32;
+ funcptr[51]=&CPU8051::OP_33;
+ funcptr[52]=&CPU8051::OP_34;
+ funcptr[53]=&CPU8051::OP_35;
+ funcptr[54]=&CPU8051::OP_36;
+ funcptr[55]=&CPU8051::OP_37;
+ funcptr[56]=&CPU8051::OP_38;
+ funcptr[57]=&CPU8051::OP_39;
+ funcptr[58]=&CPU8051::OP_3A;
+ funcptr[59]=&CPU8051::OP_3B;
+ funcptr[60]=&CPU8051::OP_3C;
+ funcptr[61]=&CPU8051::OP_3D;
+ funcptr[62]=&CPU8051::OP_3E;
+ funcptr[63]=&CPU8051::OP_3F;
+ funcptr[64]=&CPU8051::OP_40;
+ funcptr[65]=&CPU8051::OP_41;
+ funcptr[66]=&CPU8051::OP_42;
+ funcptr[67]=&CPU8051::OP_43;
+ funcptr[68]=&CPU8051::OP_44;
+ funcptr[69]=&CPU8051::OP_45;
+ funcptr[70]=&CPU8051::OP_46;
+ funcptr[71]=&CPU8051::OP_47;
+ funcptr[72]=&CPU8051::OP_48;
+ funcptr[73]=&CPU8051::OP_49;
+ funcptr[74]=&CPU8051::OP_4A;
+ funcptr[75]=&CPU8051::OP_4B;
+ funcptr[76]=&CPU8051::OP_4C;
+ funcptr[77]=&CPU8051::OP_4D;
+ funcptr[78]=&CPU8051::OP_4E;
+ funcptr[79]=&CPU8051::OP_4F;
+ funcptr[80]=&CPU8051::OP_50;
+ funcptr[81]=&CPU8051::OP_51;
+ funcptr[82]=&CPU8051::OP_52;
+ funcptr[83]=&CPU8051::OP_53;
+ funcptr[84]=&CPU8051::OP_54;
+ funcptr[85]=&CPU8051::OP_55;
+ funcptr[86]=&CPU8051::OP_56;
+ funcptr[87]=&CPU8051::OP_57;
+ funcptr[88]=&CPU8051::OP_58;
+ funcptr[89]=&CPU8051::OP_59;
+ funcptr[90]=&CPU8051::OP_5A;
+ funcptr[91]=&CPU8051::OP_5B;
+ funcptr[92]=&CPU8051::OP_5C;
+ funcptr[93]=&CPU8051::OP_5D;
+ funcptr[94]=&CPU8051::OP_5E;
+ funcptr[95]=&CPU8051::OP_5F;
+ funcptr[96]=&CPU8051::OP_60;
+ funcptr[97]=&CPU8051::OP_61;
+ funcptr[98]=&CPU8051::OP_62;
+ funcptr[99]=&CPU8051::OP_63;
+ funcptr[100]=&CPU8051::OP_64;
+ funcptr[101]=&CPU8051::OP_65;
+ funcptr[102]=&CPU8051::OP_66;
+ funcptr[103]=&CPU8051::OP_67;
+ funcptr[104]=&CPU8051::OP_68;
+ funcptr[105]=&CPU8051::OP_69;
+ funcptr[106]=&CPU8051::OP_6A;
+ funcptr[107]=&CPU8051::OP_6B;
+ funcptr[108]=&CPU8051::OP_6C;
+ funcptr[109]=&CPU8051::OP_6D;
+ funcptr[110]=&CPU8051::OP_6E;
+ funcptr[111]=&CPU8051::OP_6F;
+ funcptr[112]=&CPU8051::OP_70;
+ funcptr[113]=&CPU8051::OP_71;
+ funcptr[114]=&CPU8051::OP_72;
+ funcptr[115]=&CPU8051::OP_73;
+ funcptr[116]=&CPU8051::OP_74;
+ funcptr[117]=&CPU8051::OP_75;
+ funcptr[118]=&CPU8051::OP_76;
+ funcptr[119]=&CPU8051::OP_77;
+ funcptr[120]=&CPU8051::OP_78;
+ funcptr[121]=&CPU8051::OP_79;
+ funcptr[122]=&CPU8051::OP_7A;
+ funcptr[123]=&CPU8051::OP_7B;
+ funcptr[124]=&CPU8051::OP_7C;
+ funcptr[125]=&CPU8051::OP_7D;
+ funcptr[126]=&CPU8051::OP_7E;
+ funcptr[127]=&CPU8051::OP_7F;
+ funcptr[128]=&CPU8051::OP_80;
+ funcptr[129]=&CPU8051::OP_81;
+ funcptr[130]=&CPU8051::OP_82;
+ funcptr[131]=&CPU8051::OP_83;
+ funcptr[132]=&CPU8051::OP_84;
+ funcptr[133]=&CPU8051::OP_85;
+ funcptr[134]=&CPU8051::OP_86;
+ funcptr[135]=&CPU8051::OP_87;
+ funcptr[136]=&CPU8051::OP_88;
+ funcptr[137]=&CPU8051::OP_89;
+ funcptr[138]=&CPU8051::OP_8A;
+ funcptr[139]=&CPU8051::OP_8B;
+ funcptr[140]=&CPU8051::OP_8C;
+ funcptr[141]=&CPU8051::OP_8D;
+ funcptr[142]=&CPU8051::OP_8E;
+ funcptr[143]=&CPU8051::OP_8F;
+ funcptr[144]=&CPU8051::OP_90;
+ funcptr[145]=&CPU8051::OP_91;
+ funcptr[146]=&CPU8051::OP_92;
+ funcptr[147]=&CPU8051::OP_93;
+ funcptr[148]=&CPU8051::OP_94;
+ funcptr[149]=&CPU8051::OP_95;
+ funcptr[150]=&CPU8051::OP_96;
+ funcptr[151]=&CPU8051::OP_97;
+ funcptr[152]=&CPU8051::OP_98;
+ funcptr[153]=&CPU8051::OP_99;
+ funcptr[154]=&CPU8051::OP_9A;
+ funcptr[155]=&CPU8051::OP_9B;
+ funcptr[156]=&CPU8051::OP_9C;
+ funcptr[157]=&CPU8051::OP_9D;
+ funcptr[158]=&CPU8051::OP_9E;
+ funcptr[159]=&CPU8051::OP_9F;
+ funcptr[160]=&CPU8051::OP_A0;
+ funcptr[161]=&CPU8051::OP_A1;
+ funcptr[162]=&CPU8051::OP_A2;
+ funcptr[163]=&CPU8051::OP_A3;
+ funcptr[164]=&CPU8051::OP_A4;
+ funcptr[165]=&CPU8051::OP_A5;
+ funcptr[166]=&CPU8051::OP_A6;
+ funcptr[167]=&CPU8051::OP_A7;
+ funcptr[168]=&CPU8051::OP_A8;
+ funcptr[169]=&CPU8051::OP_A9;
+ funcptr[170]=&CPU8051::OP_AA;
+ funcptr[171]=&CPU8051::OP_AB;
+ funcptr[172]=&CPU8051::OP_AC;
+ funcptr[173]=&CPU8051::OP_AD;
+ funcptr[174]=&CPU8051::OP_AE;
+ funcptr[175]=&CPU8051::OP_AF;
+ funcptr[176]=&CPU8051::OP_B0;
+ funcptr[177]=&CPU8051::OP_B1;
+ funcptr[178]=&CPU8051::OP_B2;
+ funcptr[179]=&CPU8051::OP_B3;
+ funcptr[180]=&CPU8051::OP_B4;
+ funcptr[181]=&CPU8051::OP_B5;
+ funcptr[182]=&CPU8051::OP_B6;
+ funcptr[183]=&CPU8051::OP_B7;
+ funcptr[184]=&CPU8051::OP_B8;
+ funcptr[185]=&CPU8051::OP_B9;
+ funcptr[186]=&CPU8051::OP_BA;
+ funcptr[187]=&CPU8051::OP_BB;
+ funcptr[188]=&CPU8051::OP_BC;
+ funcptr[189]=&CPU8051::OP_BD;
+ funcptr[190]=&CPU8051::OP_BE;
+ funcptr[191]=&CPU8051::OP_BF;
+ funcptr[192]=&CPU8051::OP_C0;
+ funcptr[193]=&CPU8051::OP_C1;
+ funcptr[194]=&CPU8051::OP_C2;
+ funcptr[195]=&CPU8051::OP_C3;
+ funcptr[196]=&CPU8051::OP_C4;
+ funcptr[197]=&CPU8051::OP_C5;
+ funcptr[198]=&CPU8051::OP_C6;
+ funcptr[199]=&CPU8051::OP_C7;
+ funcptr[200]=&CPU8051::OP_C8;
+ funcptr[201]=&CPU8051::OP_C9;
+ funcptr[202]=&CPU8051::OP_CA;
+ funcptr[203]=&CPU8051::OP_CB;
+ funcptr[204]=&CPU8051::OP_CC;
+ funcptr[205]=&CPU8051::OP_CD;
+ funcptr[206]=&CPU8051::OP_CE;
+ funcptr[207]=&CPU8051::OP_CF;
+ funcptr[208]=&CPU8051::OP_D0;
+ funcptr[209]=&CPU8051::OP_D1;
+ funcptr[210]=&CPU8051::OP_D2;
+ funcptr[211]=&CPU8051::OP_D3;
+ funcptr[212]=&CPU8051::OP_D4;
+ funcptr[213]=&CPU8051::OP_D5;
+ funcptr[214]=&CPU8051::OP_D6;
+ funcptr[215]=&CPU8051::OP_D7;
+ funcptr[216]=&CPU8051::OP_D8;
+ funcptr[217]=&CPU8051::OP_D9;
+ funcptr[218]=&CPU8051::OP_DA;
+ funcptr[219]=&CPU8051::OP_DB;
+ funcptr[220]=&CPU8051::OP_DC;
+ funcptr[221]=&CPU8051::OP_DD;
+ funcptr[222]=&CPU8051::OP_DE;
+ funcptr[223]=&CPU8051::OP_DF;
+ funcptr[224]=&CPU8051::OP_E0;
+ funcptr[225]=&CPU8051::OP_E1;
+ funcptr[226]=&CPU8051::OP_E2;
+ funcptr[227]=&CPU8051::OP_E3;
+ funcptr[228]=&CPU8051::OP_E4;
+ funcptr[229]=&CPU8051::OP_E5;
+ funcptr[230]=&CPU8051::OP_E6;
+ funcptr[231]=&CPU8051::OP_E7;
+ funcptr[232]=&CPU8051::OP_E8;
+ funcptr[233]=&CPU8051::OP_E9;
+ funcptr[234]=&CPU8051::OP_EA;
+ funcptr[235]=&CPU8051::OP_EB;
+ funcptr[236]=&CPU8051::OP_EC;
+ funcptr[237]=&CPU8051::OP_ED;
+ funcptr[238]=&CPU8051::OP_EE;
+ funcptr[239]=&CPU8051::OP_EF;
+ funcptr[240]=&CPU8051::OP_F0;
+ funcptr[241]=&CPU8051::OP_F1;
+ funcptr[242]=&CPU8051::OP_F2;
+ funcptr[243]=&CPU8051::OP_F3;
+ funcptr[244]=&CPU8051::OP_F4;
+ funcptr[245]=&CPU8051::OP_F5;
+ funcptr[246]=&CPU8051::OP_F6;
+ funcptr[247]=&CPU8051::OP_F7;
+ funcptr[248]=&CPU8051::OP_F8;
+ funcptr[249]=&CPU8051::OP_F9;
+ funcptr[250]=&CPU8051::OP_FA;
+ funcptr[251]=&CPU8051::OP_FB;
+ funcptr[252]=&CPU8051::OP_FC;
+ funcptr[253]=&CPU8051::OP_FD;
+ funcptr[254]=&CPU8051::OP_FE;
+ funcptr[255]=&CPU8051::OP_FF;
+
+}
+
+
+#endif
diff --git a/src/Keyboard.hpp b/src/Keyboard.hpp
new file mode 100644 (file)
index 0000000..35b0f14
--- /dev/null
@@ -0,0 +1,59 @@
+// Keyboard.hpp
+
+#ifndef _KEYBOARD_HPP_
+#define _KEYBOARD_HPP_
+
+#include <termios.h>
+#include <unistd.h>
+
+static struct termios orig, newtio;
+static int peek = -1;
+
+int kbhit()
+{
+  char ch;
+  int nread;
+  if(peek != -1) return 1;
+  newtio.c_cc[VMIN]=0;
+  tcsetattr(0, TCSANOW, &newtio);
+  nread = read(0,&ch,1);
+  newtio.c_cc[VMIN]=1;
+  tcsetattr(0, TCSANOW, &newtio);
+  if(nread == 1) {
+   peek = ch;
+   return 1;
+  }
+  return 0;
+}
+
+int getch()
+{
+  char ch;
+  if(peek != -1) {
+    ch = peek;
+    peek = -1;
+    return ch;
+  }
+  read(0,&ch,1);
+  return ch;
+}
+
+void InitUnixKB( )
+{
+  tcgetattr(0, &orig);
+  newtio = orig;
+  newtio.c_lflag &= ~ICANON;
+  newtio.c_lflag &= ~ECHO;
+  newtio.c_lflag &= ~ISIG;
+  newtio.c_cc[VMIN] = 1;
+  newtio.c_cc[VTIME] = 0;
+  tcsetattr(0, TCSANOW, &newtio);
+}
+
+void ResetUnixKB( )
+{
+  tcsetattr(0,TCSANOW, &orig);
+}
+
+#endif
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..f17fac9
--- /dev/null
@@ -0,0 +1,37 @@
+# This file is processed by GNU automake to generate Makefile.in
+
+INCLUDES = -I$(top_srcdir)/pixmaps
+
+bin_PROGRAMS = emu8051 emu8051_console
+
+emu8051_SOURCES = EmuGtk.hpp EmuGtk.cpp CPU8051.hpp CPU8051.cpp Memory.hpp Memory.cpp \
+                  MemWin.hpp MemWin.cpp PgmWin.hpp PgmWin.cpp RegWin.hpp RegWin.cpp
+
+emu8051_console_SOURCES = EmuConsole.hpp EmuConsole.cpp CPU8051.hpp CPU8051.cpp Memory.hpp \
+                          Memory.cpp Keyboard.hpp
+
+# These headers will be included in the distribution tarball, but will not be
+# installed by 'make install'
+noinst_HEADERS = Inst_Def.hpp EmuConsole.hpp Keyboard.hpp Reg8051.hpp GtkSizes.hpp disasm.hpp \
+                 exceptions.hpp
+
+CLEANFILES     = *~
+
+DISTCLEANFILES = .deps/*.P
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = Opcode2cpp.pl opcodes.lst Inst_Imp.cpp
+
+# This rule is used to bypass the default rule which is generated by Automake, in order
+# to get rid of all the cluttered informations that are displayed by Make before
+# calling the compiler like in the following example:
+#    source='programming.c' object='programming.o' libtool=no \
+#    depfile='.deps/programming.Po' tmpdepfile='.deps/programming.TPo' \
+#    depmode=gcc3 /bin/sh ../config/depcomp \
+#    gcc -DHAVE_CONFIG_H -I. -I. -I.. -c `test -f 'main.c' || echo './'`main.c
+.c.o:
+       $(COMPILE) -c $<
+
+.cpp.o:
+       $(CXXCOMPILE) -c $<
diff --git a/src/MemWin.cpp b/src/MemWin.cpp
new file mode 100644 (file)
index 0000000..26bd464
--- /dev/null
@@ -0,0 +1,128 @@
+/* memwin.cpp */
+
+
+#if HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "MemWin.hpp"
+#include <stdio.h>
+
+
+//////////////////////////////////////////////////////////////////////////////
+// MemWin::MemWin( GtkWidget *parentwin )
+// MemWin constructor
+//////////////////////////////////////////////////////////////////////////////
+MemWin::MemWin( GtkWidget *parentwin )
+{
+  int i;
+  GtkStyle *style;
+  GdkFont *fixedfont;
+  fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
+
+  memclist = gtk_clist_new( 18 );
+  gtk_clist_set_selection_mode( GTK_CLIST( memclist ), GTK_SELECTION_SINGLE );
+  gtk_widget_set_usize( GTK_WIDGET( memclist ), 620, 250 );
+
+  for ( i = 0; i < 18; i++ ) gtk_clist_set_column_justification( GTK_CLIST( memclist ), i, GTK_JUSTIFY_LEFT );
+  gtk_clist_set_column_width( GTK_CLIST( memclist ), 0, 5*8 );
+  for ( i = 1; i < 17; i++ ) gtk_clist_set_column_width( GTK_CLIST( memclist ), i, 2*8 );
+  gtk_clist_set_column_width( GTK_CLIST( memclist ), 17, 16*8 );
+
+  style = gtk_widget_get_style( GTK_WIDGET( memclist ) );
+
+#ifdef USE_GTK2
+  gtk_style_set_font( style, fixedfont );
+#else
+  style->font = fixedfont;
+#endif
+
+  gtk_widget_set_style( GTK_WIDGET( memclist ), style );
+
+  char *memdummy[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+  for ( i = 0; i < 16; i++ ) gtk_clist_append( GTK_CLIST( memclist ), memdummy );
+
+  gtk_container_add( GTK_CONTAINER( parentwin ), memclist );
+
+  gtk_widget_show( memclist );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// MemWin::~MemWin( )
+// MemWin destructor
+//////////////////////////////////////////////////////////////////////////////
+MemWin::~MemWin( )
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void MemWin::DumpD( CPU8051 *mCPU, unsigned int Address )
+// Dump 16 rows of 16 bytes from Address in Memory (direct addressing)
+//////////////////////////////////////////////////////////////////////////////
+void MemWin::DumpD( CPU8051 *mCPU, unsigned int Address)
+{
+char TextTmp[255];
+int row, column, TextLength;
+
+gtk_clist_freeze( GTK_CLIST( memclist ) );
+ for ( row = 0; row < 16; row++ ) {
+   sprintf( TextTmp, "%.4X", Address );
+   gtk_clist_set_text( GTK_CLIST( memclist ), row, 0, TextTmp );
+
+   for ( column = 0; column < 16; column++ ) {
+     sprintf( TextTmp, "%.2X", ( int ) mCPU->ReadD( Address + column ) );
+     gtk_clist_set_text( GTK_CLIST( memclist ), row, column + 1, TextTmp );
+   }
+
+   TextLength = 0;
+   for ( column = 0; column < 16; column++ ) {
+     if ( ( ( int ) mCPU->ReadD( Address + column ) >= 32 ) && ( ( int ) mCPU->ReadD( Address + column ) <= 126 ) )
+       TextLength += sprintf( &TextTmp[ TextLength ], "%c", mCPU->ReadD( Address + column ) );
+     else TextLength += sprintf( &TextTmp[ TextLength ], "." );
+   }
+   gtk_clist_set_text( GTK_CLIST( memclist ), row, 17, TextTmp );
+
+   Address += 16;
+ }
+
+gtk_clist_select_row( GTK_CLIST( memclist ), 0, 0 );
+gtk_clist_thaw( GTK_CLIST( memclist ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void MemWin::DumpI( CPU8051 *mCPU, unsigned int Address )
+// Dump 16 rows of 16 bytes from Address in Memory (indirect addressing)
+//////////////////////////////////////////////////////////////////////////////
+void MemWin::DumpI( CPU8051 *mCPU, unsigned int Address)
+{
+char TextTmp[255];
+int row, column, TextLength;
+
+gtk_clist_freeze( GTK_CLIST( memclist ) );
+ for ( row = 0; row < 16; row++ ) {
+   sprintf( TextTmp, "%.4X", Address );
+   gtk_clist_set_text( GTK_CLIST( memclist ), row, 0, TextTmp );
+
+   for ( column = 0; column < 16; column++ ) {
+     sprintf( TextTmp, "%.2X", ( int ) mCPU->ReadI( Address + column ) );
+     gtk_clist_set_text( GTK_CLIST( memclist ), row, column + 1, TextTmp );
+   }
+
+   TextLength = 0;
+   for ( column = 0; column < 16; column++ ) {
+     if ( ( ( int ) mCPU->ReadI( Address + column ) >= 32 ) && ( ( int ) mCPU->ReadI( Address + column ) <= 126 ) )
+       TextLength += sprintf( &TextTmp[ TextLength ], "%c", mCPU->ReadI( Address + column ) );
+     else TextLength += sprintf( &TextTmp[ TextLength ], "." );
+   }
+   gtk_clist_set_text( GTK_CLIST( memclist ), row, 17, TextTmp );
+
+   Address += 16;
+ }
+gtk_clist_thaw( GTK_CLIST( memclist ) );
+}
+
+
+
+
diff --git a/src/MemWin.hpp b/src/MemWin.hpp
new file mode 100644 (file)
index 0000000..0a610d0
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _MEMWIN_HPP_
+#define _MEMWIN_HPP_
+
+#include <gtk/gtk.h>
+#include "CPU8051.hpp"
+
+//////////////////////////////////////////////////////////////////////////////
+// MemWin
+// Implements a memory Window in Gtk+ as an Object
+//////////////////////////////////////////////////////////////////////////////
+class MemWin {
+public:
+  MemWin( GtkWidget *parentwin );
+  ~MemWin( );
+
+  void DumpD( CPU8051 *mCPU, unsigned int Address );
+  void DumpI( CPU8051 *mCPU, unsigned int Address );
+
+private:
+  GtkWidget *memwin;
+  GtkWidget *memclist;
+
+
+};
+
+
+
+
+#endif
diff --git a/src/Memory.cpp b/src/Memory.cpp
new file mode 100644 (file)
index 0000000..8570264
--- /dev/null
@@ -0,0 +1,51 @@
+#include "Memory.hpp"
+
+//////////////////////////////////////////////////////////////////////////////
+// Memory::Memory( unsigned long MemSize )
+// Memory object constructor
+//////////////////////////////////////////////////////////////////////////////
+Memory::Memory( unsigned long MemSize )
+{
+  memsize = MemSize;
+  memarray = new unsigned char[memsize];
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Memory::~Memory( )
+// Memory object destructor
+//////////////////////////////////////////////////////////////////////////////
+Memory::~Memory( )
+{
+  delete[] memarray;
+  memarray = 0;
+  memsize = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned long Memory::GetSize( )
+// Get Memory size
+//////////////////////////////////////////////////////////////////////////////
+unsigned long Memory::GetSize( )
+{
+  return memsize;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void Memory::Write8( unsigned long Address, unsigned char Value )
+// Write 8-bit Value at Address into Memory
+//////////////////////////////////////////////////////////////////////////////
+void Memory::Write8( unsigned long Address, unsigned char Value )
+{
+  if (Address >= memsize) return;
+  memarray[Address] = Value;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// unsigned char Memory::Read8( unsigned long Address )
+// Read 8-bit value at Address in Memory
+//////////////////////////////////////////////////////////////////////////////
+unsigned char Memory::Read8( unsigned long Address )
+{
+  if (Address < memsize) { return memarray[Address]; }
+  return 0;
+}
diff --git a/src/Memory.hpp b/src/Memory.hpp
new file mode 100644 (file)
index 0000000..a4aaba8
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _MEMORY_HPP_
+#define _MEMORY_HPP_
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Memory
+// Implements a Memory array to be used by the CPU8051 as an Object
+//////////////////////////////////////////////////////////////////////////////
+class Memory {
+public:
+  Memory( unsigned long MemSize );
+  ~Memory( );
+
+  unsigned long GetSize( );
+
+  void Write8( unsigned long Address, unsigned char Value );
+  unsigned char Read8( unsigned long Address );
+
+  unsigned char *memarray;
+  unsigned long memsize;
+};
+
+
+#endif
diff --git a/src/Opcode2cpp.pl b/src/Opcode2cpp.pl
new file mode 100755 (executable)
index 0000000..66ab1c2
--- /dev/null
@@ -0,0 +1,785 @@
+#!/usr/bin/perl
+
+open INST_DEF,">Inst_Def.hpp" or die "Erreur ouverture Inst_Def.hpp : $!\n";
+open INST_IMP,">Inst_Imp.cpp" or die "Erreur ouverture Inst_Imp.hpp : $!\n";
+open OPCODELST,"opcodes.lst" or die "Erreur ouverture opcodes.lst : $!\n";
+open DISASM_HPP,">disasm.hpp" or die "Erreur ouverture disasm.hpp : $!\n";
+
+print INST_IMP "#ifndef __INST_IMP_HPP_\n";
+print INST_IMP "#define __INST_IMP_HPP_\n\n";
+print INST_IMP "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
+print INST_IMP "// Any modification made directly on this file will be lost\n\n\n";
+
+
+print INST_DEF "#ifndef __INST_DEF_HPP_\n";
+print INST_DEF "#define __INST_DEF_HPP_\n";
+print INST_DEF "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
+print INST_DEF "// Any modification made directly on this file will be lost\n\n\n";
+
+print DISASM_HPP "#ifndef __DISASM_HPP_\n";
+print DISASM_HPP "#define __DISASM_HPP_\n";
+print DISASM_HPP "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
+print DISASM_HPP "// Any modification made directly on this file will be lost\n\n\n";
+
+$nbinst=0;
+$nbaddr=0;
+$nbargs=0;
+$instnumb=0;
+
+$ligne=<OPCODELST>;
+$ligne=<OPCODELST>;
+while($ligne=<OPCODELST>) {
+    chop $ligne;
+    if (length $ligne < 2) {next;}
+    @wordlist=split ' ',$ligne;
+    $nbword=@wordlist;
+    $instruction=$wordlist[2];
+    for($i=3;$i<($nbword-2);$i++) {$instruction="$instruction $wordlist[$i]";}
+
+    $a_instruction[$instnumb]=$instruction;
+    $a_bytes[$instnumb]=$wordlist[$nbword-2];
+    $a_cycles[$instnumb]=$wordlist[$nbword-1];
+    $a_opcodehex[$instnumb]=$wordlist[1];
+    $a_opcodebin[$instnumb]=$wordlist[0];
+
+    
+    $instfunction[$instnumb]="CPU8051::OP_$wordlist[1]";
+
+    $instargs[$instnumb << 2]=$instargs[($instnumb << 2) + 1]=$instargs[($instnumb << 2) + 2]=$instargs[($instnumb << 2) + 3]=0;
+    if ($nbword > 5) {
+       @argslist=split /\,/,$wordlist[3];
+       $argslistsize=@argslist;
+       $instargs[$instnumb << 2]=$argslistsize;
+       for ($i=0;$i<$argslistsize;$i++) {
+           if (not exists $argstypes{$argslist[$i]}) {
+               $argstypes[$nbargs]=$argslist[$i];
+               $argstypes{$argslist[$i]}=$nbargs++;
+           }
+           $instargs[($instnumb << 2) + $i + 1]=$argstypes{$argslist[$i]};
+       }
+    }
+       
+    if (not exists $insttext{$wordlist[2]}) {
+       $insttext[$nbinst]=$wordlist[2];
+       $insttext{$wordlist[2]}=$nbinst++;
+    }
+
+    $insttype[$instnumb]=$insttext{$wordlist[2]};
+
+    if ( not exists $addrmode{$wordlist[3]}) {
+       $addrmode[$nbaddr]=$wordlist[3];
+       $addrmode{$wordlist[3]}=$nbaddr++;
+    }
+
+    $nbbytes[$instnumb]=$wordlist[$nbword-2];
+
+    $instaddr[$instnumb]=$addrmode{$wordlist[3]};
+
+    $instnumb++;
+}
+# ------------------------------------------------------------------------------
+print DISASM_HPP "// For all 256 opcodes, the value in this table gives the instruction type\n";
+print DISASM_HPP "// ex.: MOV, INC, CLR, CPL,...\n";
+print DISASM_HPP "// To know what is the instruction type, use the number as an offset in the InstTextTbl[]\n";
+print DISASM_HPP "static int InstTypesTbl[] = {\n";
+for($i=0;$i<256;$i++) {
+    print DISASM_HPP " $insttype[$i]";
+    ($i != 255) and print DISASM_HPP ",";
+    if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
+}
+print DISASM_HPP "};\n";
+print DISASM_HPP "\n\n";
+# ------------------------------------------------------------------------------
+print DISASM_HPP "// Size(in bytes) of each instruction (offset in table is instruction opcode)\n";
+print DISASM_HPP "static int InstSizesTbl[] = {\n";
+for($i=0;$i<256;$i++) {
+    print DISASM_HPP " $nbbytes[$i]";
+    ($i != 255) and print DISASM_HPP ",";
+    if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
+}
+print DISASM_HPP "};\n";
+print DISASM_HPP "\n\n";
+# ------------------------------------------------------------------------------
+print DISASM_HPP "// List of instructions types referenced by InstTypesTbl[]\n";
+$nbelement=@insttext;
+print DISASM_HPP "\#define InstTextTblLength $nbelement\n";
+$elementnb=0;
+print DISASM_HPP "static char *InstTextTbl[] = {\n";
+foreach $instruc (@insttext) {
+    print DISASM_HPP " \"$instruc\"";
+    ($elementnb++ < $nbelement-1) and print DISASM_HPP ",";
+    print DISASM_HPP "\n";
+}
+print DISASM_HPP "};\n";
+print DISASM_HPP "\n\n";
+# ------------------------------------------------------------------------------
+print DISASM_HPP "// Table describing all arguments types of an instruction\n";
+print DISASM_HPP "// The table is indexed InstArgTbl[ opcode * 4]\n";
+print DISASM_HPP "// InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
+print DISASM_HPP "// InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
+print DISASM_HPP "// for most instructions, the 3rd argument isn't used\n";
+print DISASM_HPP "// the argument type is referecing to ArgsTextTbl[]\n";
+print DISASM_HPP "\#define InstArgTblLength 256\n";
+print DISASM_HPP "static int InstArgTbl[] = {\n";
+for($i=0;$i<1024;$i++) {
+    print DISASM_HPP " $instargs[$i]";
+    ($i != 1023) and print DISASM_HPP ",";
+    if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
+}
+print DISASM_HPP "};\n";
+print DISASM_HPP "\n\n";
+# ------------------------------------------------------------------------------
+print DISASM_HPP "// List all types of arguments available to instructions\n";
+print DISASM_HPP "// Referenced by InstArgsTbl[]\n";
+$nbelement=@argstypes;
+print DISASM_HPP "\#define ArgsTextTblLength $nbelement\n";
+$elementnb=0;
+print DISASM_HPP "static char *ArgsTextTbl[] = {\n";
+foreach $args (@argstypes) {
+    print DISASM_HPP " \"$args\"";
+    ($elementnb++ < $nbelement-1) and print DISASM_HPP ",";
+    print DISASM_HPP "\n";
+}
+print DISASM_HPP "};\n";
+print DISASM_HPP "\n\n";
+# ------------------------------------------------------------------------------
+for ($i=0 ; $i< 256; $i++) {
+    print INST_IMP "/"x78,"\n";
+    print INST_IMP "// void CPU8051::OP_$a_opcodehex[$i]( )\n";
+    print INST_IMP "// Instruction \"$a_instruction[$i]\" takes $a_cycles[$i] cycle(s) and $a_bytes[$i] byte(s)\n";
+    print INST_IMP "/"x78,"\n";
+    print INST_IMP "int CPU8051::OP_$a_opcodehex[$i]( )\n";
+    print INST_DEF "int OP_$a_opcodehex[$i]( );\n";
+    print INST_IMP "{\n";
+
+    if ($i == 0x85) {
+       # Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
+        print INST_IMP "unsigned char srcaddr = PGMMem->Read8( PC++ );\n";
+       print INST_IMP "unsigned char source = ReadD( srcaddr );\n";
+       print INST_IMP "unsigned char destaddr = PGMMem->Read8( PC++ );\n";
+       print INST_IMP "unsigned char destination = ReadD( destaddr );\n";
+       print INST_IMP "destination = source;\n";
+       print INST_IMP "WriteD( destaddr, destination );\n";
+    } else {
+       
+if ($instargs[$i*4] > 0) {
+       $op_destination=$instargs[$i*4+1];
+       if ($op_destination == 0) { # addr11
+           print INST_IMP "unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_destination == 1) { # addr16
+           print INST_IMP "unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );\n";
+            print INST_IMP "addr16 += PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_destination == 2) { # A
+           print INST_IMP "unsigned char destination = ReadD( _ACC_ );\n";
+       }
+       if ($op_destination == 3) { # direct
+           print INST_IMP "unsigned char destaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "unsigned char destination = ReadD( destaddr );\n";
+       }
+       if ($op_destination == 4) { # @R0
+           print INST_IMP "unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );\n";
+       }
+       if ($op_destination == 5) { # @R1
+           print INST_IMP "unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );\n";
+       }
+
+       if ($op_destination == 6) { # R0
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R0_ );\n";
+       }
+       if ($op_destination == 7) { # R1
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R1_ );\n";
+       }
+       if ($op_destination == 8) { # R2
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R2_ );\n";
+       }
+       if ($op_destination == 9) { # R3
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R3_ );\n";
+       }
+       if ($op_destination == 10) { # R4
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R4_ );\n";
+       }
+       if ($op_destination == 11) { # R5
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R5_ );\n";
+       }
+       if ($op_destination == 12) { # R6
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R6_ );\n";
+       }
+       if ($op_destination == 13) { # R7
+           print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R7_ );\n";
+       }
+       if ($op_destination == 14) { # bitaddr
+           print INST_IMP "unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "destination = ReadB( dstbitaddr );\n";
+       }
+       if ($op_destination == 15) { # reladdr
+           print INST_IMP "PC++;\n";
+           print INST_IMP "unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );\n";
+       }
+       if ($op_destination == 16) { # #data
+           print INST_IMP "unsigned char destination = PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_destination == 17) { # C
+           print INST_IMP "unsigned char destination = ( ReadD( _PSW_ ) >> 7 );\n";
+       }
+       if ($op_destination == 18) { # @A+DPTR
+           print INST_IMP "unsigned int destination = ReadI( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );\n";
+       }
+# Mis en commentaire car donnait un warning (destination et source unused variables...)
+#      if ($op_destination == 20) { # AB
+#          print INST_IMP "unsigned char destination = ReadD( _ACC_ );\n";
+#          print INST_IMP "unsigned char source = ReadD( _B_ );\n";
+#      }
+       if ($op_destination == 21) { # DPTR
+           print INST_IMP "unsigned int destination = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );\n";
+       }
+       if ($op_destination == 22) { # #data16
+           print INST_IMP "unsigned char destination = ( PGMMem->Read8( PC++ ) << 8 );\n";
+           print INST_IMP "destination += PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_destination == 23) { # /bitaddr
+           print INST_IMP "unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "destination = ( ReadB( dstbitaddr ) ^ 1 );\n";
+       }
+       if ($op_destination == 24) { # @DPTR
+           print INST_IMP "unsigned char destination = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );\n";
+       }
+    }
+
+    if ($instargs[$i*4] > 1) {
+       $op_source=$instargs[$i*4+2];
+       if ($op_source == 0) { # addr11
+           print INST_IMP "unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_source == 1) { # addr16
+           print INST_IMP "unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );\n";
+            print INST_IMP "addr16 += PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_source == 2) { # A
+           print INST_IMP "unsigned char source = ReadD( _ACC_ );\n";
+       }
+       if ($op_source == 3) { # direct
+           print INST_IMP "unsigned char srcaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "unsigned char source = ReadD( srcaddr );\n";
+       }
+       if ($op_source == 4) { # @R0
+           print INST_IMP "unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );\n";
+       }
+       if ($op_source == 5) { # @R1
+           print INST_IMP "unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );\n";
+       }
+       if ($op_source == 6) { # R0
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R0_ );\n";
+       }
+       if ($op_source == 7) { # R1
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R1_ );\n";
+       }
+       if ($op_source == 8) { # R2
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R2_ );\n";
+       }
+       if ($op_source == 9) { # R3
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R3_ );\n";
+       }
+       if ($op_source == 10) { # R4
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R4_ );\n";
+       }
+       if ($op_source == 11) { # R5
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R5_ );\n";
+       }
+       if ($op_source == 12) { # R6
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R6_ );\n";
+       }
+       if ($op_source == 13) { # R7
+           print INST_IMP "unsigned char source = ReadD( BANKPSW + _R7_ );\n";
+       }
+
+       if ($op_source == 14) { # bitaddr
+           print INST_IMP "unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "source = ReadB( srcbitaddr );\n";
+       }
+       if ($op_source == 15) { # reladdr
+           print INST_IMP "PC++;\n";
+           print INST_IMP "unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );\n";
+       }
+       if ($op_source == 16) { # #data
+           print INST_IMP "unsigned char source = PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_source == 17) { # C
+           print INST_IMP "unsigned char source = ( ReadD( _PSW_ ) >> 7 );\n";
+       }
+       if ($op_source == 18) { # @A+DPTR
+           print INST_IMP "unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );\n";
+       }
+       if ($op_source == 19) { # @A+PC
+           print INST_IMP "unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ( ++PC ) );\n";
+       }
+       if ($op_source == 21) { # DPTR
+           print INST_IMP "unsigned int source = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );\n";
+       }
+       if ($op_source == 22) { # #data16
+           print INST_IMP "unsigned char source = ( PGMMem->Read8( PC++ ) << 8 );\n";
+           print INST_IMP "source += PGMMem->Read8( PC++ );\n";
+       }
+       if ($op_source == 23) { # /bitaddr
+           print INST_IMP "unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );\n";
+           print INST_IMP "source = ( ReadB( srcbitaddr ) ^ 1 );\n";
+       }
+       if ($op_source == 24) { # @DPTR
+           print INST_IMP "unsigned char source = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );\n";
+       }
+    }
+
+##############################################################################
+    $modifysrc=0;
+#    print INST_IMP "\n// Inserer le code ici\n\n";
+
+    # RR
+    if ($insttype[$i] == 3) {
+       print INST_IMP "destination = ( destination >> 1 ) | ( destination << 7 );\n";
+    }
+
+    # INC
+    if ($insttype[$i] == 4) {
+       print INST_IMP "destination++;\n";
+    }
+
+    # JBC
+    if ($insttype[$i] == 5) {
+       print INST_IMP "if ( destination == 1 ) { PC = source; destination = 0; }\n";
+    }
+
+    # ACALL
+    if ($insttype[$i] == 6) {
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "WriteI( ++SP, ( PC & 0x00FF ) );\n";
+       print INST_IMP "WriteI( ++SP, ( PC >> 8 ) );\n";
+       print INST_IMP "WriteD( _SP_, SP );\n";
+   }
+
+    # LCALL
+    if ($insttype[$i] == 7) {
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "WriteI( ++SP, ( PC & 0x00FF ) );\n";
+       print INST_IMP "WriteI( ++SP, ( PC >> 8 ) );\n";
+       print INST_IMP "WriteD( _SP_, SP );\n";
+   }
+
+    # RRC
+    if ($insttype[$i] == 8) {
+       print INST_IMP "unsigned char tmpval = destination;\n";
+               print INST_IMP "destination = ( destination >> 1 ) | ( ReadD( _PSW_ ) & 0x80 );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval << 7 ) );\n";
+    }
+
+    # DEC
+    if ($insttype[$i] == 9) {
+       print INST_IMP "destination--;\n";
+    }
+
+    # JB
+    if ($insttype[$i] == 10) {
+       print INST_IMP "if ( destination == 1 ) { PC = source; }\n";
+    }
+
+    # RET
+    if ($insttype[$i] == 11) {
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "PC = ( ReadI( SP-- ) << 8 );\n";
+       print INST_IMP "PC += ReadI ( SP-- );\n";
+       print INST_IMP "WriteD( _SP_, SP );\n";
+    }
+
+    # RL
+    if ($insttype[$i] == 12) {
+       print INST_IMP "destination = ( destination << 1 ) | ( destination >> 7 );\n";
+    }
+
+    # ADD
+    if ($insttype[$i] == 13) {
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
+       print INST_IMP "if ( destination + source > 0xFF ) {\n";
+       print INST_IMP "   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "   if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "destination += source;\n";
+    }
+
+    # JNB
+    if ($insttype[$i] == 14) {
+       print INST_IMP "if ( destination == 0 ) { PC = source; }\n";
+    }
+
+    # RETI
+    if ($insttype[$i] == 15) {
+       print INST_IMP "ActivePriority = -1;\n";
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "PC = ( ReadI( SP-- ) << 8 );\n";
+       print INST_IMP "PC += ReadI( SP-- );\n";
+    }
+
+    # RLC
+    if ($insttype[$i] == 16) {
+       print INST_IMP "unsigned char tmpval = destination;\n";
+               print INST_IMP "destination = ( destination << 1 ) | ( ( ReadD( _PSW_ ) & 0x80 ) >> 7 );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval & 0x80 ) );\n";
+    }
+
+    # ADDC
+    if ($insttype[$i] == 17) {
+       print INST_IMP "unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
+       print INST_IMP "if ( destination + source + carryflag > 0xFF ) {\n";
+       print INST_IMP "   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "   if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );\n";
+       print INST_IMP "destination += source;\n";
+    }
+
+    # JC
+    if ($insttype[$i] == 18) {
+       print INST_IMP "if ( ReadD( _PSW_ ) > 0x7F) { PC = destination; }\n";
+    }
+
+    # ORL
+    if ($insttype[$i] == 19) {
+       if ($instargs[$i*4+1] == 17) {
+           # sur des bits
+           print INST_IMP "WriteD( _PSW_ , ( ( destination | source ) << 7 ) );\n";
+       } else {
+           # sur des bytes
+           print INST_IMP "destination |= source;\n";
+       }
+    }
+
+    # JNC
+    if ($insttype[$i] == 20) {
+       print INST_IMP "if ( ReadD( _PSW_ ) < 0x80 ) { PC = destination; }\n";
+    }
+
+    # ANL
+    if ($insttype[$i] == 21) {
+       if ($instargs[$i*4+1] == 17) {
+           # sur des bits
+           print INST_IMP "WriteD( _PSW_, ( ( destination & source) << 7 ) );\n";
+       } else {
+           # sur des bytes
+           print INST_IMP "destination &= source;\n";
+       }
+    }
+
+    # JZ
+    if ($insttype[$i] == 22) {
+       print INST_IMP "if ( ReadD( _ACC_ ) == 0 ) { PC = destination; }\n";
+    }
+
+    # XRL
+    if ($insttype[$i] == 23) {
+           print INST_IMP "destination ^= source;\n";
+    }
+
+    # JNZ
+    if ($insttype[$i] == 24) {
+       print INST_IMP "if ( ReadD( _ACC_ ) != 0 ) { PC = destination; }\n";
+    }
+
+    # JMP
+    if ($insttype[$i] == 25) {
+       print INST_IMP "PC = destination;\n";
+    }
+
+    # MOV
+    if ($insttype[$i] == 26) {
+       print INST_IMP "destination = source;\n";
+    }
+
+    # SJMP
+    if ($insttype[$i] == 27) {
+       print INST_IMP "PC = destination;\n";
+    }
+
+    # MOVC
+    if ($insttype[$i] == 28) {
+       print INST_IMP "destination = source;\n";
+    }
+
+    # DIV
+    if ($insttype[$i] == 29) {
+       print INST_IMP "unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );\n";
+       print INST_IMP "if ( B != 0 ) {\n";
+       print INST_IMP "WriteD( _ACC_, A/B ); WriteD( _B_, A%B );\n";
+       print INST_IMP "} else WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+    }
+
+    # SUBB
+    if ($insttype[$i] == 30) {
+       print INST_IMP "unsigned char carryflag = ReadD( _PSW_ ) >> 7;\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
+       print INST_IMP "if ( destination < ( source + carryflag ) ) {\n";
+       print INST_IMP "  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "  if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) )  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+       print INST_IMP "if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) )   WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );\n";
+       print INST_IMP "destination -= source + carryflag;\n";
+    }
+
+    # MUL
+    if ($insttype[$i] == 31) {
+       print INST_IMP "unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );\n";
+       print INST_IMP "WriteD( _ACC_ , ( ( A * B ) & 0x00FF ) ); WriteD( _B_, ( A * B ) / 0x100 );\n";
+       print INST_IMP "if ( ReadD( _B_ ) > 0) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
+    }
+
+    # CPL
+    if ($insttype[$i] == 33) {
+       if ($instargs[$i*4+1] == 2) { print INST_IMP "destination ^= 0xFF;\n"; }
+       else { print INST_IMP "destination ^= 0x01;\n"; }
+    }
+
+    # CJNE
+    if ($insttype[$i] == 34) {
+       print INST_IMP "unsigned int reladdr = ( ( PGMMem->Read8( PC ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );\n";
+       print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );\n";
+       print INST_IMP "if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "if ( destination != source ) PC = reladdr;\n";
+    }
+
+    # PUSH
+    if ($insttype[$i] == 35) {
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "WriteI( ++SP, destination );\n";
+       print INST_IMP "WriteD( _SP_, SP );\n";
+    }
+
+    # CLR
+    if ($insttype[$i] == 36) {
+       print INST_IMP "destination = 0;\n";
+    }
+
+    # SWAP
+    if ($insttype[$i] == 37) {
+       print INST_IMP "destination = ( destination << 4 ) + ( destination >> 4 );\n";
+    }
+
+    # XCH
+    if ($insttype[$i] == 38) {
+       print INST_IMP "unsigned char tmpval = destination;\n";
+       print INST_IMP "destination = source; source = tmpval;\n";
+       $modifysrc=1;
+    }
+
+    # POP
+    if ($insttype[$i] == 39) {
+       print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
+       print INST_IMP "destination = ReadI( SP-- );\n";
+       print INST_IMP "WriteD( _SP_, SP );\n";
+    }
+
+    # SETB
+    if ($insttype[$i] == 40) {
+       print INST_IMP "destination = 1;\n";
+    }
+
+    # DA
+    if ($insttype[$i] == 41) {
+       print INST_IMP "if ( ( ( destination & 0x0F ) > 9) || ( ReadD( _PSW_ ) | 0x40)) {\n";
+       print INST_IMP "   if ( ( destination + 6 ) > 0xFF)  WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "   destination += 6;\n";
+       print INST_IMP "}\n";
+       print INST_IMP "if ( ( ReadD( _PSW_ ) & 0x80) || ( ( destination & 0xF0 ) > 0x90 ) ) {\n";
+       print INST_IMP "   if ( ( destination + 0x60 ) > 0xFF ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
+       print INST_IMP "   destination += 0x60;\n";
+       print INST_IMP "}\n";
+    }
+
+    # DJNZ
+    if ($insttype[$i] == 42) {
+       print INST_IMP "destination--;\n";
+       print INST_IMP "if ( destination != 0 ) PC = source;\n";
+    }
+
+    # XCHD
+    if ($insttype[$i] == 43) {
+       print INST_IMP "unsigned char tmpval = ( destination & 0x0F );\n";
+       print INST_IMP "destination = ( destination & 0xF0 ) + ( source & 0x0F );\n";
+       print INST_IMP "source = ( source & 0xF0 ) + tmpval;\n";
+       $modifysrc=1;
+    }
+
+    # MOVX
+    if ($insttype[$i] == 44) {
+       print INST_IMP "destination = source;\n";
+    }
+
+
+
+##############################################################################
+
+
+    if ($instargs[$i*4] > 0) {
+       $op_destination=$instargs[$i*4+1];
+       if ($op_destination == 0) { # addr11
+           print INST_IMP "PC = ( PC & 0xF800 ) | addr11;\n";
+       }
+       if ($op_destination == 1) { # addr16
+           print INST_IMP "PC = addr16;\n";
+       }
+       if ($op_destination == 2) { # A
+           print INST_IMP "WriteD( _ACC_, destination );\n";
+       }
+       if ($op_destination == 3) { # direct
+           print INST_IMP "WriteD( destaddr, destination );\n";
+       }
+       if ($op_destination == 4) { # @R0
+           print INST_IMP "WriteI( ReadD( BANKPSW + _R0_ ), destination );\n";
+       }
+       if ($op_destination == 5) { # @R1
+           print INST_IMP "WriteI( ReadD( BANKPSW + _R1_ ), destination );\n";
+       }
+       if ($op_destination == 6) { # R0
+           print INST_IMP "WriteD( BANKPSW + _R0_, destination );\n";
+       }
+       if ($op_destination == 7) { # R1
+           print INST_IMP "WriteD( BANKPSW + _R1_, destination );\n";
+       }
+       if ($op_destination == 8) { # R2
+           print INST_IMP "WriteD( BANKPSW + _R2_, destination );\n";
+       }
+       if ($op_destination == 9) { # R3
+           print INST_IMP "WriteD( BANKPSW + _R3_, destination );\n";
+       }
+       if ($op_destination == 10) { # R4
+           print INST_IMP "WriteD( BANKPSW + _R4_, destination );\n";
+       }
+       if ($op_destination == 11) { # R5
+           print INST_IMP "WriteD( BANKPSW + _R5_, destination );\n";
+       }
+       if ($op_destination == 12) { # R6
+           print INST_IMP "WriteD( BANKPSW + _R6_, destination );\n";
+       }
+       if ($op_destination == 13) { # R7
+           print INST_IMP "WriteD( BANKPSW + _R7_, destination );\n";
+       }
+
+       if ($op_destination == 14) { # bitaddr
+           print INST_IMP "WriteB( dstbitaddr, destination );\n";
+       }
+       if ($op_destination == 17) { # C
+           print INST_IMP "WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );\n";
+       }
+       if ($op_destination == 21) { # DPTR
+           print INST_IMP "WriteD( _DPTRHIGH_, ( destination >> 8 ) );\n";
+           print INST_IMP "WriteD( _DPTRLOW_, ( destination & 0xFF ) );\n";
+       }
+       if ($op_destination == 23) { # /bitaddr
+           print INST_IMP "WriteB( dstbitaddr, destination );\n";
+       }
+       if ($op_destination == 24) { # @DPTR
+           print INST_IMP "WriteI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ ), destination );\n";
+       }
+    }
+
+    if ($modifysrc == 1) {
+    if ($instargs[$i*4] > 1) {
+       $op_source=$instargs[$i*4+2];
+       if ($op_source == 0) { # addr11
+           print INST_IMP "PC = ( PC & 0xF800 ) | addr11;\n";
+       }
+       if ($op_source == 1) { # addr16
+           print INST_IMP "PC = addr16;\n";
+       }
+       if ($op_source == 2) { # A
+           print INST_IMP "WriteD( _ACC_, source );\n";
+       }
+       if ($op_source == 3) { # direct
+           print INST_IMP "WriteD( srcaddr, source );\n";
+       }
+       if ($op_source == 4) { # @R0
+           print INST_IMP "WriteI( ReadD( BANKPSW + _R0_ ), source );\n";
+       }
+       if ($op_source == 5) { # @R1
+           print INST_IMP "WriteI( ReadD( BANKPSW + _R1_ ), source );\n";
+       }
+       if ($op_source == 6) { # R0
+           print INST_IMP "WriteD( BANKPSW + _R0_, source );\n";
+       }
+       if ($op_source == 7) { # R1
+           print INST_IMP "WriteD( BANKPSW + _R1_, source );\n";
+       }
+       if ($op_source == 8) { # R2
+           print INST_IMP "WriteD( BANKPSW + _R2_, source );\n";
+       }
+       if ($op_source == 9) { # R3
+           print INST_IMP "WriteD( BANKPSW + _R3_, source );\n";
+       }
+       if ($op_source == 10) { # R4
+           print INST_IMP "WriteD( BANKPSW + _R4_, source );\n";
+       }
+       if ($op_source == 11) { # R5
+           print INST_IMP "WriteD( BANKPSW + _R5_, source );\n";
+       }
+       if ($op_source == 12) { # R6
+           print INST_IMP "WriteD( BANKPSW + _R6_, source );\n";
+       }
+       if ($op_source == 13) { # R7
+           print INST_IMP "WriteD( BANKPSW + _R7_, source );\n";
+       }
+       if ($op_source == 14) { # bitaddr
+           print INST_IMP "WriteB( srcbitaddr, source );\n";
+       }
+       if ($op_source == 17) { # C
+           print INST_IMP "WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( source << 7 ) ) );\n";
+       }
+       if ($op_source == 21) { # DPTR
+           print INST_IMP "WriteD( _DPTRHIGH_, ( source >> 8 ) );\n";
+           print INST_IMP "WriteD( _DPTRLOW_, ( source & 0xFF ) );\n";
+       }
+       if ($op_source == 23) { # /bitaddr
+           print INST_IMP "WriteB( srcbitaddr, source );\n";
+       }
+       if ($op_source == 24) { # @DPTR
+           print INST_IMP "WriteI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ ), source );\n";
+       }
+    }
+}
+}
+    print INST_IMP "return $a_cycles[$i];\n";
+    print INST_IMP "}\n";
+    print INST_IMP "\n\n";
+}
+# ------------------------------------------------------------------------------
+print INST_IMP "\n\n";
+
+    print INST_IMP "/"x78,"\n";
+    print INST_IMP "// void CPU8051::InitFuncPtr( )\n";
+    print INST_IMP "// Initialize Functions Pointers\n";
+    print INST_IMP "/"x78,"\n";
+    print INST_IMP "void CPU8051::InitFuncPtr( )\n";
+    print INST_DEF "void InitFuncPtr( );\n";
+    print INST_IMP "{\n";
+
+
+#print INST_IMP "static int (*instfnc[])() = {\n";
+for ($i=0;$i<256;$i++) {
+    $ifunc=substr($instfunction[$i], 9);
+    print INST_IMP " funcptr[$i]=&CPU8051::$ifunc;\n";
+#    ($i < 255) and print INST_IMP ",\n";
+#    (($i+1) % 4 == 0) and print INST_IMP "\n";
+}
+print INST_IMP "\n}\n";
+
+print INST_IMP "\n\n#endif\n";
+print INST_DEF "\n\n#endif\n";
+print DISASM_HPP "\n\n#endif\n";
+
+close DISASM_HPP;
+close OPCODELST;
+close INST_DEF;
+close INST_IMP;
+
+
diff --git a/src/PgmWin.cpp b/src/PgmWin.cpp
new file mode 100644 (file)
index 0000000..b362709
--- /dev/null
@@ -0,0 +1,186 @@
+/* pgmwin.cpp */
+
+
+#if HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "PgmWin.hpp"
+#include <stdio.h>
+
+int PgmWinNumber = 0;
+int PgmWinNumbers[ 1 ];
+PgmWin *PgmWinPtrs[ 1 ];
+
+//////////////////////////////////////////////////////////////////////////////
+// PgmWin::PgmWin( GtkWidget *parentwin, CPU8051 *mCPU )
+// PgmWin constructor
+//////////////////////////////////////////////////////////////////////////////
+PgmWin::PgmWin( GtkWidget *parentwin, CPU8051 *mCPU )
+{
+  CPU = mCPU;
+  int i;
+  GtkStyle *style;
+  GdkFont *fixedfont;
+  fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
+
+  pgmclist = gtk_clist_new( 1 );
+  gtk_clist_set_selection_mode( GTK_CLIST( pgmclist ), GTK_SELECTION_SINGLE );
+  gtk_widget_set_usize( GTK_WIDGET( pgmclist ), PGM_WIN_WIDTH, PGM_WIN_HEIGHT );
+  gtk_clist_set_column_justification( GTK_CLIST( pgmclist ), 0, GTK_JUSTIFY_LEFT );
+  gtk_clist_set_column_width( GTK_CLIST( pgmclist ), 0, PGM_WIN_WIDTH-10 );
+
+  style = gtk_widget_get_style( GTK_WIDGET( pgmclist ) );
+
+#ifdef USE_GTK2
+  gtk_style_set_font( style, fixedfont );
+#else
+  style->font = fixedfont;
+#endif
+
+  gtk_widget_set_style( GTK_WIDGET( pgmclist ), style );
+
+  char *pgmdummy[] = { 0 };
+  for ( i = 0; i < 24; i++ ) gtk_clist_append( GTK_CLIST( pgmclist ), pgmdummy );
+
+  gtk_container_add( GTK_CONTAINER( parentwin ), pgmclist );
+
+  gtk_widget_show( pgmclist );
+
+  NbBreakpoints = 0;
+
+  if ( PgmWinNumber >= 1 ) g_print( "WARNING! Too many PgmWin objects to handle signals!\n");
+  else {
+    PgmWinPtrs[ PgmWinNumber ] = this;
+    PgmWinNumbers[ PgmWinNumber ] = PgmWinNumber;
+    gtk_signal_connect( GTK_OBJECT( pgmclist ), "button-press-event", GTK_SIGNAL_FUNC( PgmWinButtonPress ), &PgmWinNumbers[ PgmWinNumber++ ] );
+  }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// PgmWin::~PgmWin( )
+// PgmWin destructor
+//////////////////////////////////////////////////////////////////////////////
+PgmWin::~PgmWin( )
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void PgmWin::Disasm( )
+// Disasm 24 lines from CPU
+//////////////////////////////////////////////////////////////////////////////
+void PgmWin::Disasm( )
+{
+char TextTmp[255];
+int row;
+//int TextLength;
+int InstSize;
+unsigned int Address;
+Address = CPU->GetPC( );
+
+gtk_clist_freeze( GTK_CLIST( pgmclist ) );
+ for ( row = 0; row < 24; row++ ) {
+   InstSize = CPU->Disasm( Address, TextTmp );
+   if ( IsBreakpoint( Address ) ) TextTmp[0] = '*';
+   gtk_clist_set_text( GTK_CLIST( pgmclist ), row, 0, TextTmp );
+   DisasmAddresses[ row ] = Address;
+   Address += InstSize;
+ }
+gtk_clist_select_row( GTK_CLIST( pgmclist ), 0, 0 );
+gtk_clist_thaw( GTK_CLIST( pgmclist ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint PgmWin::ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Mouse button pressed in the window
+//////////////////////////////////////////////////////////////////////////////
+gint PgmWin::ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+  gint row, column;
+  char TextTmp[ 255 ];
+  //g_print( "PgmWin::ButtonPressEvent(...)\n" );
+  gtk_clist_get_selection_info( GTK_CLIST( pgmclist ), ( int )event->button.x ,( int )event->button.y, &row, &column );
+  if (row >= 24 || row < 0)
+    return TRUE;
+  if (column >= 1 || column < 0)
+    return TRUE;
+  sprintf( TextTmp, "PgmWin::ButtonPressEvent( ) at %d,%d\n", column, row );
+  g_print( TextTmp );
+  ToggleBreakpoint( DisasmAddresses[ row ] );
+  Disasm( );
+  return FALSE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// gint PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data )
+// Signal Stub with 3 parameters
+//////////////////////////////////////////////////////////////////////////////
+void PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+int PWNumber = (* ( static_cast< int * >( data ) ) );
+PgmWinPtrs[ PWNumber ]->ButtonPressEvent( widget, event, 0 );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// void PgmWin::ShowBreakpoints( )
+// Show Breakpoints list
+//////////////////////////////////////////////////////////////////////////////
+void PgmWin::ShowBreakpoints( )
+{
+  for ( int Index = 0; Index < NbBreakpoints ; Index++ )
+    printf( "Breakpoint at Address = %.4X\n", Breakpoints[ Index ] );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void PgmWin::ClearBreakpoint( unsigned int Address )
+// Clear Breakpoint at Address from list
+//////////////////////////////////////////////////////////////////////////////
+void PgmWin::ClearBreakpoint( unsigned int Address )
+{
+  int Index = 0;
+  while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
+  if ( Breakpoints[ Index ] != Address ) return;
+  Breakpoints[ Index ] = Breakpoints[ NbBreakpoints - 1 ];
+  NbBreakpoints--;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void PgmWin::SetBreakpoint( unsigned int Address )
+// Set Breakpoint at Address from list
+//////////////////////////////////////////////////////////////////////////////
+void PgmWin::SetBreakpoint( unsigned int Address )
+{
+  if ( IsBreakpoint( Address ) ) return;
+  if ( NbBreakpoints < MAXBP ) Breakpoints[ NbBreakpoints++ ] = Address;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// int PgmWin::IsBreakpoint( unsigned int Address )
+// Is the a breakpoint at Address
+//////////////////////////////////////////////////////////////////////////////
+int PgmWin::IsBreakpoint( unsigned int Address )
+{
+  int Index = 0;
+  while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
+  return ( Breakpoints[ Index ] == Address && Index < NbBreakpoints );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void PgmWin::ToggleBreakpoint( unsigned int Address )
+// Toggle the breakpoint at Address
+//////////////////////////////////////////////////////////////////////////////
+void PgmWin::ToggleBreakpoint( unsigned int Address )
+{
+  if ( IsBreakpoint( Address ) ) ClearBreakpoint( Address );
+  else SetBreakpoint( Address );
+}
+
+
+
+
+
+
+
diff --git a/src/PgmWin.hpp b/src/PgmWin.hpp
new file mode 100644 (file)
index 0000000..0bf5820
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _PGMWIN_HPP_
+#define _PGMWIN_HPP_
+
+#include <gtk/gtk.h>
+#include "CPU8051.hpp"
+#include "GtkSizes.hpp"
+
+#define MAXBP 32
+
+//////////////////////////////////////////////////////////////////////////////
+// PgmWin
+// Implements a Program Window in Gtk+ as an Object
+//////////////////////////////////////////////////////////////////////////////
+class PgmWin {
+public:
+  PgmWin( GtkWidget *parentwin, CPU8051 *mCPU );
+  ~PgmWin( );
+
+  void Disasm( );
+  gint ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
+
+  void ShowBreakpoints( );
+  void SetBreakpoint( unsigned int Address );
+  void ClearBreakpoint( unsigned int Address );
+  int IsBreakpoint( unsigned int Address );
+  void ToggleBreakpoint( unsigned int Address );
+
+private:
+  CPU8051 *CPU;
+  GtkWidget *pgmwin;
+  GtkWidget *pgmclist;
+  int NbBreakpoints;
+  unsigned int Breakpoints[ MAXBP ];
+  unsigned int DisasmAddresses[ 24 ];
+
+};
+
+void PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data );
+
+
+#endif
diff --git a/src/Reg8051.hpp b/src/Reg8051.hpp
new file mode 100644 (file)
index 0000000..1e6a65e
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __REGISTRES8051_HPP_
+#define __REGISTRES8051_HPP_
+
+// SFR Registers ( $80 - $FF )
+#define    _ACC_       0xE0
+#define    _B_         0xF0
+#define    _PSW_       0xD0
+#define    _SP_        0x81
+#define    _DPTRLOW_   _DPL_
+#define    _DPTRHIGH_  _DPH_
+#define    _DPL_       0x82
+#define    _DPH_       0x83
+#define    _P0_        0x80
+#define    _P1_        0x90
+#define    _P2_        0xA0
+#define    _P3_        0xB0
+#define    _IP_        0xB8
+#define    _IE_        0xA8
+#define    _TMOD_      0x89
+#define    _TCON_      0x88
+#define    _TH0_       0x8C
+#define    _TL0_       0x8A
+#define    _TH1_       0x8D
+#define    _TL1_       0x8B
+#define    _SCON_      0x98
+#define    _SBUF_      0x99
+#define    _PCON_      0x87
+#define    _T2CON_     0xC8
+
+#define    _R0_        0x00
+#define    _R1_        0x01
+#define    _R2_        0x02
+#define    _R3_        0x03
+#define    _R4_        0x04
+#define    _R5_        0x05
+#define    _R6_        0x06
+#define    _R7_        0x07
+
+#define    _BANK0_     0x00
+#define    _BANK1_     0x08
+#define    _BANK2_     0x10
+#define    _BANK3_     0x18
+
+#endif
diff --git a/src/RegWin.cpp b/src/RegWin.cpp
new file mode 100644 (file)
index 0000000..0047ec5
--- /dev/null
@@ -0,0 +1,131 @@
+/* regwin.cpp */
+
+
+#if HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdio.h>
+#include "RegWin.hpp"
+
+
+//////////////////////////////////////////////////////////////////////////////
+// RegWin::RegWin( GtkWidget *parentwin )
+// RegWin constructor
+//////////////////////////////////////////////////////////////////////////////
+RegWin::RegWin( GtkWidget *parentwin )
+{
+  int i;
+  GtkStyle *style;
+  GdkFont *fixedfont;
+  fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
+  
+  regclist = gtk_clist_new( 1 );
+  gtk_clist_set_selection_mode( GTK_CLIST( regclist ), GTK_SELECTION_SINGLE );
+  gtk_widget_set_usize( GTK_WIDGET( regclist ), REG_WIN_WIDTH, REG_WIN_HEIGHT );
+  gtk_clist_set_column_justification( GTK_CLIST( regclist ), 0, GTK_JUSTIFY_LEFT );
+  gtk_clist_set_column_width( GTK_CLIST( regclist ), 0, REG_WIN_WIDTH );
+
+  style = gtk_widget_get_style( GTK_WIDGET( regclist ) );
+
+#ifdef USE_GTK2
+  gtk_style_set_font( style, fixedfont );
+#else
+  style->font = fixedfont;
+#endif
+
+  gtk_widget_set_style( GTK_WIDGET( regclist ), style );
+
+  char *regdummy[] = { 0 };
+  for ( i = 0; i < 24; i++ )
+    gtk_clist_append( GTK_CLIST( regclist ), regdummy );
+  
+  gtk_container_add( GTK_CONTAINER( parentwin ), regclist );
+
+  gtk_widget_show( regclist );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// RegWin::~RegWin( )
+// RegWin destructor
+//////////////////////////////////////////////////////////////////////////////
+RegWin::~RegWin( )
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// void RegWin::Show( CPU8051 *CPU )
+// Show registers
+//////////////////////////////////////////////////////////////////////////////
+void RegWin::Show( CPU8051 *CPU )
+{
+  char TextTmp[255];
+  int row = 0;
+  unsigned char PSW = CPU->ReadD( _PSW_ );
+  unsigned char Rbank;
+  
+  gtk_clist_freeze( GTK_CLIST( regclist ) );
+  
+  // Main registers
+  sprintf( TextTmp , "PC   = %.4X", CPU->GetPC( ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "SP   =   %.2X", CPU->ReadD( _SP_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "A    =   %.2X", CPU->ReadD( _ACC_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "B    =   %.2X", CPU->ReadD( _B_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "DPTR = %.4X", ( CPU->ReadD( _DPTRHIGH_ )  << 8 ) +  CPU->ReadD( _DPTRLOW_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  
+  // Program Status Word
+  sprintf( TextTmp , "PSW  =   %.2X",PSW);
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+
+  // Ports registers
+  sprintf( TextTmp , "P0 =     %.2X", CPU->ReadD( _P0_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "P1 =     %.2X", CPU->ReadD( _P1_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "P2 =     %.2X", CPU->ReadD( _P2_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "P3 =     %.2X", CPU->ReadD( _P3_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+
+  // Misc Registers
+  sprintf( TextTmp , "TCON =   %.2X", CPU->ReadD( _TCON_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "TMOD =   %.2X", CPU->ReadD( _TMOD_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "SCON =   %.2X", CPU->ReadD( _SCON_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "IE   =   %.2X", CPU->ReadD( _IE_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "IP   =   %.2X", CPU->ReadD( _IP_ ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+
+  // R0-R7 Registers in current Bank
+  Rbank = CPU->ReadD( _PSW_ ) & 0x18;
+  sprintf( TextTmp , "Bank =   %.2X", Rbank);
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R0   =   %.2X", CPU->ReadD( _R0_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R1   =   %.2X", CPU->ReadD( _R1_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R2   =   %.2X", CPU->ReadD( _R2_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R3   =   %.2X", CPU->ReadD( _R3_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R4   =   %.2X", CPU->ReadD( _R4_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R5   =   %.2X", CPU->ReadD( _R5_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R6   =   %.2X", CPU->ReadD( _R6_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  sprintf( TextTmp , "R7   =   %.2X", CPU->ReadD( _R7_ + Rbank ) );
+  gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
+  
+  gtk_clist_select_row(GTK_CLIST(regclist),0,0);
+  gtk_clist_thaw( GTK_CLIST( regclist ) );
+}
diff --git a/src/RegWin.hpp b/src/RegWin.hpp
new file mode 100644 (file)
index 0000000..cd43721
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _REGWIN_HPP_
+#define _REGWIN_HPP_
+
+#include <gtk/gtk.h>
+#include "CPU8051.hpp"
+#include "GtkSizes.hpp"
+
+//////////////////////////////////////////////////////////////////////////////
+// RegWin
+// Implements a Registers Window in Gtk+ as an Object
+//////////////////////////////////////////////////////////////////////////////
+class RegWin {
+public:
+  RegWin( GtkWidget *parentwin );
+  ~RegWin( );
+
+  void Show( CPU8051 *CPU );
+
+private:
+  GtkWidget *regwin;
+  GtkWidget *regclist;
+
+
+};
+
+#endif
diff --git a/src/disasm.hpp b/src/disasm.hpp
new file mode 100644 (file)
index 0000000..bd4460f
--- /dev/null
@@ -0,0 +1,211 @@
+#ifndef __DISASM_HPP_
+#define __DISASM_HPP_
+// Do not modify this file directly, it was created by Opcode2cpp.pl
+// Any modification made directly on this file will be lost
+
+
+// For all 256 opcodes, the value in this table gives the instruction type
+// ex.: MOV, INC, CLR, CPL,...
+// To know what is the instruction type, use the number as an offset in the InstTextTbl[]
+static int InstTypesTbl[] = {
+ 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10, 1, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 14, 6, 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 18, 1, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 20, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 22, 1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 24, 6, 19, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 27, 1, 21, 28, 29, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 6, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 19, 1, 26, 4, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 21, 6, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 35, 1, 36, 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 39, 6, 40, 40, 41, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 42,
+ 44, 1, 44, 44, 36, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 44, 6, 44, 44, 33, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
+};
+
+
+// Size(in bytes) of each instruction (offset in table is instruction opcode)
+static int InstSizesTbl[] = {
+ 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+
+// List of instructions types referenced by InstTypesTbl[]
+#define InstTextTblLength 45
+static char *InstTextTbl[] = {
+ "NOP",
+ "AJMP",
+ "LJMP",
+ "RR",
+ "INC",
+ "JBC",
+ "ACALL",
+ "LCALL",
+ "RRC",
+ "DEC",
+ "JB",
+ "RET",
+ "RL",
+ "ADD",
+ "JNB",
+ "RETI",
+ "RLC",
+ "ADDC",
+ "JC",
+ "ORL",
+ "JNC",
+ "ANL",
+ "JZ",
+ "XRL",
+ "JNZ",
+ "JMP",
+ "MOV",
+ "SJMP",
+ "MOVC",
+ "DIV",
+ "SUBB",
+ "MUL",
+ "INVALID",
+ "CPL",
+ "CJNE",
+ "PUSH",
+ "CLR",
+ "SWAP",
+ "XCH",
+ "POP",
+ "SETB",
+ "DA",
+ "DJNZ",
+ "XCHD",
+ "MOVX"
+};
+
+
+// Table describing all arguments types of an instruction
+// The table is indexed InstArgTbl[ opcode * 4]
+// InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has
+// InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument
+// for most instructions, the 3rd argument isn't used
+// the argument type is referecing to ArgsTextTbl[]
+#define InstArgTblLength 256
+static int InstArgTbl[] = {
+ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0,
+ 1, 2, 0, 0, 1, 3, 0, 0, 1, 4, 0, 0, 1, 5, 0, 0,
+ 1, 6, 0, 0, 1, 7, 0, 0, 1, 8, 0, 0, 1, 9, 0, 0,
+ 1, 10, 0, 0, 1, 11, 0, 0, 1, 12, 0, 0, 1, 13, 0, 0,
+ 2, 14, 15, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0,
+ 1, 2, 0, 0, 1, 3, 0, 0, 1, 4, 0, 0, 1, 5, 0, 0,
+ 1, 6, 0, 0, 1, 7, 0, 0, 1, 8, 0, 0, 1, 9, 0, 0,
+ 1, 10, 0, 0, 1, 11, 0, 0, 1, 12, 0, 0, 1, 13, 0, 0,
+ 2, 14, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 2, 14, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 1, 15, 0, 0, 1, 0, 0, 0, 2, 17, 14, 0, 1, 18, 0, 0,
+ 2, 2, 16, 0, 2, 3, 16, 0, 2, 4, 16, 0, 2, 5, 16, 0,
+ 2, 6, 16, 0, 2, 7, 16, 0, 2, 8, 16, 0, 2, 9, 16, 0,
+ 2, 10, 16, 0, 2, 11, 16, 0, 2, 12, 16, 0, 2, 13, 16, 0,
+ 1, 15, 0, 0, 1, 0, 0, 0, 2, 17, 14, 0, 2, 2, 19, 0,
+ 1, 20, 0, 0, 2, 3, 3, 0, 2, 3, 4, 0, 2, 3, 5, 0,
+ 2, 3, 6, 0, 2, 3, 7, 0, 2, 3, 8, 0, 2, 3, 9, 0,
+ 2, 3, 10, 0, 2, 3, 11, 0, 2, 3, 12, 0, 2, 3, 13, 0,
+ 2, 21, 22, 0, 1, 0, 0, 0, 2, 14, 17, 0, 2, 2, 18, 0,
+ 2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 2, 17, 23, 0, 1, 0, 0, 0, 2, 17, 14, 0, 1, 21, 0, 0,
+ 1, 20, 0, 0, 0, 0, 0, 0, 2, 4, 3, 0, 2, 5, 3, 0,
+ 2, 6, 3, 0, 2, 7, 3, 0, 2, 8, 3, 0, 2, 9, 3, 0,
+ 2, 10, 3, 0, 2, 11, 3, 0, 2, 12, 3, 0, 2, 13, 3, 0,
+ 2, 17, 23, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
+ 3, 2, 16, 15, 3, 2, 3, 15, 3, 4, 16, 15, 3, 5, 16, 15,
+ 3, 6, 16, 15, 3, 7, 16, 15, 3, 8, 16, 15, 3, 9, 16, 15,
+ 3, 10, 16, 15, 3, 11, 16, 15, 3, 12, 16, 15, 3, 13, 16, 15,
+ 1, 3, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
+ 1, 2, 0, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 1, 3, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
+ 1, 2, 0, 0, 2, 3, 15, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 6, 15, 0, 2, 7, 15, 0, 2, 8, 15, 0, 2, 9, 15, 0,
+ 2, 10, 15, 0, 2, 11, 15, 0, 2, 12, 15, 0, 2, 13, 15, 0,
+ 2, 2, 24, 0, 1, 0, 0, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 1, 2, 0, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
+ 2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
+ 2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
+ 2, 24, 2, 0, 1, 0, 0, 0, 2, 4, 2, 0, 2, 5, 2, 0,
+ 1, 2, 0, 0, 2, 3, 2, 0, 2, 4, 2, 0, 2, 5, 2, 0,
+ 2, 6, 2, 0, 2, 7, 2, 0, 2, 8, 2, 0, 2, 9, 2, 0,
+ 2, 10, 2, 0, 2, 11, 2, 0, 2, 12, 2, 0, 2, 13, 2, 0
+};
+
+
+// List all types of arguments available to instructions
+// Referenced by InstArgsTbl[]
+#define ArgsTextTblLength 25
+static char *ArgsTextTbl[] = {
+ "addr11",
+ "addr16",
+ "A",
+ "direct",
+ "@R0",
+ "@R1",
+ "R0",
+ "R1",
+ "R2",
+ "R3",
+ "R4",
+ "R5",
+ "R6",
+ "R7",
+ "bitaddr",
+ "reladdr",
+ "#data",
+ "C",
+ "@A+DPTR",
+ "@A+PC",
+ "AB",
+ "DPTR",
+ "#data16",
+ "/bitaddr",
+ "@DPTR"
+};
+
+
+
+
+#endif
diff --git a/src/exceptions.hpp b/src/exceptions.hpp
new file mode 100644 (file)
index 0000000..5aa1af7
--- /dev/null
@@ -0,0 +1,19 @@
+// Exceptions.hpp
+// Gestion des erreurs pour le programme d'emulation du 8051.
+
+#ifndef _EXCEPTION_HPP_
+#define _EXCEPTION_HPP_
+
+class ShowOptions { /* ... */ };
+class FinishedLoading { /* ... */ };
+class ErrorOpeningFile { /* ... */ };
+class ErrorHexFileFormat { /* ... */ };
+class SyntaxError { /* ... */ };
+class InvalidAddress { /* ... */ };
+class MissingParameter { /* ... */ };
+class InvalidParameter { /* ... */ };
+class InvalidRegister { /* ... */ };
+class TooMuchParameters { /* ... */ };
+class ResetRequest { /* ... */ };
+
+#endif
diff --git a/src/opcodes.lst b/src/opcodes.lst
new file mode 100644 (file)
index 0000000..1494258
--- /dev/null
@@ -0,0 +1,258 @@
+Opcode(bin)    Opcode  Instruction             Bytes   Cycles
+--------------------------------------------------------------
+00000000       00      NOP                     1       1
+00000001       01      AJMP addr11             2       2
+00000010       02      LJMP addr16             3       2
+00000011       03      RR A                    1       1
+00000100       04      INC A                   1       1
+00000101       05      INC direct              2       1
+00000110       06      INC @R0                 1       1
+00000111       07      INC @R1                 1       1
+00001000       08      INC R0                  1       1
+00001001       09      INC R1                  1       1
+00001010       0A      INC R2                  1       1
+00001011       0B      INC R3                  1       1
+00001100       0C      INC R4                  1       1
+00001101       0D      INC R5                  1       1
+00001110       0E      INC R6                  1       1
+00001111       0F      INC R7                  1       1
+00010000       10      JBC bitaddr,reladdr     3       2
+00010001       11      ACALL addr11            2       2
+00010010       12      LCALL addr16            3       2
+00010011       13      RRC A                   1       1
+00010100       14      DEC A                   1       1
+00010101       15      DEC direct              2       1
+00010110       16      DEC @R0                 1       1
+00010111       17      DEC @R1                 1       1
+00011000       18      DEC R0                  1       1
+00011001       19      DEC R1                  1       1
+00011010       1A      DEC R2                  1       1
+00011011       1B      DEC R3                  1       1
+00011100       1C      DEC R4                  1       1
+00011101       1D      DEC R5                  1       1
+00011110       1E      DEC R6                  1       1
+00011111       1F      DEC R7                  1       1
+00100000       20      JB bitaddr,reladdr      3       2
+00100001       21      AJMP addr11             2       2       
+00100010       22      RET                     1       2
+00100011       23      RL A                    1       1
+00100100       24      ADD A,#data             2       1
+00100101       25      ADD A,direct            2       1
+00100110       26      ADD A,@R0               1       1
+00100111       27      ADD A,@R1               1       1
+00101000       28      ADD A,R0                1       1
+00101001       29      ADD A,R1                1       1
+00101010       2A      ADD A,R2                1       1
+00101011       2B      ADD A,R3                1       1
+00101100       2C      ADD A,R4                1       1
+00101101       2D      ADD A,R5                1       1
+00101110       2E      ADD A,R6                1       1
+00101111       2F      ADD A,R7                1       1
+00110000       30      JNB bitaddr,reladdr     3       2
+00110001       31      ACALL addr11            2       2
+00110010       32      RETI                    1       2
+00110011       33      RLC A                   1       1
+00110100       34      ADDC A,#data            2       1
+00110101       35      ADDC A,direct           2       1
+00110110       36      ADDC A,@R0              1       1
+00110111       37      ADDC A,@R1              1       1
+00111000       38      ADDC A,R0               1       1
+00111001       39      ADDC A,R1               1       1
+00111010       3A      ADDC A,R2               1       1
+00111011       3B      ADDC A,R3               1       1
+00111100       3C      ADDC A,R4               1       1
+00111101       3D      ADDC A,R5               1       1
+00111110       3E      ADDC A,R6               1       1
+00111111       3F      ADDC A,R7               1       1
+01000000       40      JC reladdr              2       2
+01000001       41      AJMP addr11             2       2       
+01000010       42      ORL direct,A            2       1
+01000011       43      ORL direct,#data        3       2
+01000100       44      ORL A,#data             2       1
+01000101       45      ORL A,direct            2       1
+01000110       46      ORL A,@R0               1       1
+01000111       47      ORL A,@R1               1       1
+01001000       48      ORL A,R0                1       1
+01001001       49      ORL A,R1                1       1
+01001010       4A      ORL A,R2                1       1
+01001011       4B      ORL A,R3                1       1
+01001100       4C      ORL A,R4                1       1
+01001101       4D      ORL A,R5                1       1
+01001110       4E      ORL A,R6                1       1
+01001111       4F      ORL A,R7                1       1
+01010000       50      JNC reladdr             2       2
+01010001       51      ACALL addr11            2       2
+01010010       52      ANL direct,A            2       1
+01010011       53      ANL direct,#data        3       2
+01010100       54      ANL A,#data             2       1
+01010101       55      ANL A,direct            2       1
+01010110       56      ANL A,@R0               1       1
+01010111       57      ANL A,@R1               1       1
+01011000       58      ANL A,R0                1       1
+01011001       59      ANL A,R1                1       1
+01011010       5A      ANL A,R2                1       1
+01011011       5B      ANL A,R3                1       1
+01011100       5C      ANL A,R4                1       1
+01011101       5D      ANL A,R5                1       1
+01011110       5E      ANL A,R6                1       1
+01011111       5F      ANL A,R7                1       1
+01100000       60      JZ reladdr              2       2
+01100001       61      AJMP addr11             2       2       
+01100010       62      XRL direct,A            2       1
+01100011       63      XRL direct,#data        3       2
+01100100       64      XRL A,#data             2       1
+01100101       65      XRL A,direct            2       1
+01100110       66      XRL A,@R0               1       1
+01100111       67      XRL A,@R1               1       1
+01101000       68      XRL A,R0                1       1
+01101001       69      XRL A,R1                1       1
+01101010       6A      XRL A,R2                1       1
+01101011       6B      XRL A,R3                1       1
+01101100       6C      XRL A,R4                1       1
+01101101       6D      XRL A,R5                1       1
+01101110       6E      XRL A,R6                1       1
+01101111       6F      XRL A,R7                1       1
+01110000       70      JNZ reladdr             2       2
+01110001       71      ACALL addr11            2       2
+01110010       72      ORL C,bitaddr           2       2
+01110011       73      JMP @A+DPTR             1       2
+01110100       74      MOV A,#data             2       1
+01110101       75      MOV direct,#data        3       2
+01110110       76      MOV @R0,#data           2       1
+01110111       77      MOV @R1,#data           2       1
+01111000       78      MOV R0,#data            2       1
+01111001       79      MOV R1,#data            2       1
+01111010       7A      MOV R2,#data            2       1
+01111011       7B      MOV R3,#data            2       1
+01111100       7C      MOV R4,#data            2       1
+01111101       7D      MOV R5,#data            2       1
+01111110       7E      MOV R6,#data            2       1
+01111111       7F      MOV R7,#data            2       1
+10000000       80      SJMP reladdr            2       2
+10000001       81      AJMP addr11             2       2
+10000010       82      ANL C,bitaddr           2       1
+10000011       83      MOVC A,@A+PC            1       1
+10000100       84      DIV AB                  1       4
+10000101       85      MOV direct,direct       3       1
+10000110       86      MOV direct,@R0          2       2
+10000111       87      MOV direct,@R1          2       2
+10001000       88      MOV direct,R0           2       2
+10001001       89      MOV direct,R1           2       2
+10001010       8A      MOV direct,R2           2       2
+10001011       8B      MOV direct,R3           2       2
+10001100       8C      MOV direct,R4           2       2
+10001101       8D      MOV direct,R5           2       2
+10001110       8E      MOV direct,R6           2       2
+10001111       8F      MOV direct,R7           2       2
+10010000       90      MOV DPTR,#data16        3       2
+10010001       91      ACALL addr11            2       2
+10010010       92      MOV bitaddr,C           2       2
+10010011       93      MOVC A,@A+DPTR          1       2
+10010100       94      SUBB A,#data            2       1
+10010101       95      SUBB A,direct           2       1
+10010110       96      SUBB A,@R0              1       1
+10010111       97      SUBB A,@R1              1       1
+10011000       98      SUBB A,R0               1       1
+10011001       99      SUBB A,R1               1       1
+10011010       9A      SUBB A,R2               1       1
+10011011       9B      SUBB A,R3               1       1
+10011100       9C      SUBB A,R4               1       1
+10011101       9D      SUBB A,R5               1       1
+10011110       9E      SUBB A,R6               1       1
+10011111       9F      SUBB A,R7               1       1
+10100000       A0      ORL C,/bitaddr          2       1
+10100001       A1      AJMP addr11             2       2
+10100010       A2      MOV C,bitaddr           2       1
+10100011       A3      INC DPTR                1       2
+10100100       A4      MUL AB                  1       4
+10100101       A5      INVALID                 1       1
+10100110       A6      MOV @R0,direct          2       2
+10100111       A7      MOV @R1,direct          2       2
+10101000       A8      MOV R0,direct           2       2
+10101001       A9      MOV R1,direct           2       2
+10101010       AA      MOV R2,direct           2       2
+10101011       AB      MOV R3,direct           2       2
+10101100       AC      MOV R4,direct           2       2
+10101101       AD      MOV R5,direct           2       2
+10101110       AE      MOV R6,direct           2       2
+10101111       AF      MOV R7,direct           2       2
+10110000       B0      ANL C,/bitaddr          2       1
+10110001       B1      ACALL addr11            2       2
+10110010       B2      CPL bitaddr             2       1
+10110011       B3      CPL C                   1       1
+10110100       B4      CJNE A,#data,reladdr    3       2
+10110101       B5      CJNE A,direct,reladdr   3       2
+10110110       B6      CJNE @R0,#data,reladdr  3       2
+10110111       B7      CJNE @R1,#data,reladdr  3       2
+10111000       B8      CJNE R0,#data,reladdr   3       2
+10111001       B9      CJNE R1,#data,reladdr   3       2
+10111010       BA      CJNE R2,#data,reladdr   3       2
+10111011       BB      CJNE R3,#data,reladdr   3       2
+10111100       BC      CJNE R4,#data,reladdr   3       2
+10111101       BD      CJNE R5,#data,reladdr   3       2
+10111110       BE      CJNE R6,#data,reladdr   3       2
+10111111       BF      CJNE R7,#data,reladdr   3       2
+11000000       C0      PUSH direct             2       2
+11000001       C1      AJMP addr11             2       2       
+11000010       C2      CLR bitaddr             2       1
+11000011       C3      CLR C                   1       1
+11000100       C4      SWAP A                  1       1
+11000101       C5      XCH A,direct            2       1
+11000110       C6      XCH A,@R0               1       1
+11000111       C7      XCH A,@R1               1       1
+11001000       C8      XCH A,R0                1       1
+11001001       C9      XCH A,R1                1       1
+11001010       CA      XCH A,R2                1       1
+11001011       CB      XCH A,R3                1       1
+11001100       CC      XCH A,R4                1       1
+11001101       CD      XCH A,R5                1       1
+11001110       CE      XCH A,R6                1       1
+11001111       CF      XCH A,R7                1       1
+11010000       D0      POP direct              2       2
+11010001       D1      ACALL addr11            2       2
+11010010       D2      SETB bitaddr            2       1
+11010011       D3      SETB C                  1       1
+11010100       D4      DA A                    1       1
+11010101       D5      DJNZ direct,reladdr     3       2
+11010110       D6      XCHD A,@R0              1       1
+11010111       D7      XCHD A,@R1              1       1
+11011000       D8      DJNZ R0,reladdr         2       2
+11011001       D9      DJNZ R1,reladdr         2       2
+11011010       DA      DJNZ R2,reladdr         2       2
+11011011       DB      DJNZ R3,reladdr         2       2
+11011100       DC      DJNZ R4,reladdr         2       2
+11011101       DD      DJNZ R5,reladdr         2       2
+11011110       DE      DJNZ R6,reladdr         2       2
+11011111       DF      DJNZ R7,reladdr         2       2
+11100000       E0      MOVX A,@DPTR            1       2
+11100001       E1      AJMP addr11             2       2       
+11100010       E2      MOVX A,@R0              1       2
+11100011       E3      MOVX A,@R1              1       2
+11100100       E4      CLR A                   1       1
+11100101       E5      MOV A,direct            2       1
+11100110       E6      MOV A,@R0               1       1
+11100111       E7      MOV A,@R1               1       1
+11101000       E8      MOV A,R0                1       1
+11101001       E9      MOV A,R1                1       1
+11101010       EA      MOV A,R2                1       1
+11101011       EB      MOV A,R3                1       1
+11101100       EC      MOV A,R4                1       1
+11101101       ED      MOV A,R5                1       1
+11101110       EE      MOV A,R6                1       1
+11101111       EF      MOV A,R7                1       1
+11110000       F0      MOVX @DPTR,A            1       2
+11110001       F1      ACALL addr11            2       2
+11110010       F2      MOVX @R0,A              1       2
+11110011       F3      MOVX @R1,A              1       2
+11110100       F4      CPL A                   1       1
+11110101       F5      MOV direct,A            2       1
+11110110       F6      MOV @R0,A               1       1
+11110111       F7      MOV @R1,A               1       1
+11111000       F8      MOV R0,A                1       1
+11111001       F9      MOV R1,A                1       1
+11111010       FA      MOV R2,A                1       1
+11111011       FB      MOV R3,A                1       1
+11111100       FC      MOV R4,A                1       1
+11111101       FD      MOV R5,A                1       1
+11111110       FE      MOV R6,A                1       1
+11111111       FF      MOV R7,A                1       1
diff --git a/test_files/siae1.hex b/test_files/siae1.hex
new file mode 100644 (file)
index 0000000..7324c56
--- /dev/null
@@ -0,0 +1,115 @@
+:0600000002003302003390
+:03000B00020033BD
+:03001300020033B5
+:03001B00020033AD
+:03002300020033A5
+:03002B000200339D
+:100033007581801202D312024375540075550085F1
+:100043004356854457755BC61204C8120493740360
+:100053002557F543855A56855B57755B0A1204C8C5
+:10006300120493E5574430F55E75F000E543120240
+:10007300DC85514F85525085535175522E855E5301
+:1000830074501203067404120306E54F120306E5C7
+:1000930050120306E551120306E552120306E55317
+:1000A300120306745A12030675300075315D7532FA
+:1000B300C01204E78534F0E5351202DC74501203F4
+:1000C300067401120306E54F120306E550120306F8
+:1000D300E551120306E552120306E55312030674B3
+:1000E3005A12030675F000E5361202DC745012034F
+:1000F300067405120306E551120306E552120306C0
+:10010300E553120306745A12030675F000E537121D
+:1001130002DC74501203067406120306E55112033F
+:1001230006E552120306E553120306745A12030638
+:10013300E53875F00584C5F0C3334430F55FC5F089
+:1001430075F0001202DC85525085535175522E858D
+:100153005F5374501203067408120306E55012032A
+:1001630006E551120306E552120306E55312030690
+:10017300745A12030675540075550085415685421D
+:1001830057755B641204C87554001204938556F0C6
+:10019300E5571202DC74501203067402120306E5DB
+:1001A30051120306E552120306E553120306745A6D
+:1001B300120306755400755500853B56853C5775EB
+:1001C3005B0F1204C812049385575C855A56855BEE
+:1001D30057755B641204C81204938556F0E55712F1
+:1001E30002DC85525D85535E75F000E55C1202DC2E
+:1001F30085524F85535075512E855D52855E5374DC
+:10020300501203067407120306E54F120306E55066
+:10021300120306E551120306E552120306E55312D3
+:100223000306745A12030674201203060139756219
+:1002330016740075F000D5F0FDD5E0F7D562F22213
+:10024300783B7900E9120255A64E08A64D0809B974
+:1002530008F2D2B3C2B1C2B300D2B3C2B6C2B300C2
+:10026300D2B3F580C2B300D2B3D2B6C2B300D2B315
+:10027300D2B1C2B31202CA7580FFD2B3C2B1C2B344
+:1002830000D2B3C2B7C2B30085804DD2B3D2B7C2D6
+:10029300B300D2B3D2B1C2B300D2B3D2B2C2B300AD
+:1002A300D2B3C2B1C2B300D2B3C2B7C2B300858066
+:1002B3004E00D2B3D2B7C2B300D2B3D2B1C2B300ED
+:1002C300D2B3C2B2C2B322D2B300C2B330B0F822A7
+:1002D30075D54475B0F3513122C00078537554007D
+:1002E30075550085F056F557755800755900755AC0
+:1002F30000755B0A120314E55B4430F618B84EE848
+:10030300D00022F586B290E5AA53E08060F9E58635
+:1003130022C004C003C002C001C0007504207503DD
+:100323000075020075010075000012038F1203A50A
+:100333004022C3E5039558403A7019C3E502955925
+:1003430040317010C3E501955A40287007C3E5009A
+:10035300955B401FC3E500955BF500E501955AF5F4
+:1003630001E5029559F502E5039558F503E557D2E2
+:10037300E0F557DCB585035885025985015A850098
+:100383005BD000D001D002D003D00422C3E55733A1
+:10039300F557E55633F556E55533F555E55433F53D
+:1003A3005422E50033F500E50133F501E50233F5A9
+:1003B30002E50333F50322C002C001C00075021B2E
+:1003C30075010075000012040312041D4010C3E5FB
+:1003D30001955A401C7007C3E500955B4013C3E5C4
+:1003E30000955BF500E501955AF501E557D2E0F577
+:1003F30057DAD385015A85005BD000D001D00222A1
+:10040300C3E55733F557E55633F556E55533F555FB
+:10041300E5543392E35407F55422E50033F500E540
+:100423000133F50122C002C001C000750216750137
+:10043300007500001204711204844010C3E5019595
+:100443005A401C7007C3E500955B4013C3E5009554
+:100453005BF500E501955AF501E557D2E0F557DA6A
+:10046300D385015A85005BD000D001D00222C3E5B9
+:100473005733F557E55633F556E55533F55592E6BB
+:1004830022E50033F500E5013392E6543FF50122FE
+:1004930085575B85565A535A0F1204B81204B81283
+:1004A30004B81204B853540F8556578555568554CE
+:1004B3005575540022E55413F554E55513F555E5E8
+:1004C3005613F55622E556855BF0A4F55685F0558F
+:1004D300E557855BF0A4F557C5F02556F556E43589
+:1004E30055F555221205751205981205B5E53654D2
+:1004F300F0C4C5F0E53754F025F0F5F01205DAF84D
+:10050300E5F0240130D605E8F90205131205DAF9FE
+:10051300E5F024105007E8FAE9FB020536F5F0127E
+:1005230005DAFAE5F0240130D605EAFB02053612B6
+:1005330005DAFB88F0E9AC36120553F88AF0EBAC28
+:1005430036120553FA88F0EAAC37120553F5382210
+:10055300C0F0C223C395F05005F42401D223F5F073
+:10056300EC540FA454F0C4302303F42401D0F02539
+:10057300F02275540775552775560E755700E530EB
+:10058300B4000B85315A85325B71BA0205918556E9
+:100593003485573522C3E5359490F556E5349401F7
+:1005A300F555755700C3755A25755B809128855796
+:1005B3003622755400755500C3E54394285001E471
+:1005C300F556755700755800755900755A00755BD7
+:1005D300A071148557372224E8F58274053400F599
+:1005E3008374009322111123465F5F666666666615
+:1005F3006666585858111123465F5F6666666666DD
+:100603006666585858111123465F5F6666666666CC
+:100613006666585858111123465F5F6666666666BC
+:100623006666585858111123465F5F6666666666AC
+:100633006666585858111123465F5F66666666669C
+:100643006666585858111123465F5F66666666668C
+:100653006666585858111123465B5B626262626298
+:1006630062625454541111234651515858585858E2
+:100673005858585858111123464A4A51515151510B
+:10068300515151515111111C3846464A4A4A4A4A5E
+:100693004A4A4A4A4A11111C343F3F4343434343A6
+:1006A300434343434311111C3438383C3C3C3C3CEA
+:1006B3003C3C3C3C3C11111C2A2D2D313131313154
+:1006C300313131313111111C3438383C3C3C3C3C24
+:1006D3003C3C3C3C3C11111C2A2D2D313131313134
+:0506E30031313131311D
+:00000001FF
diff --git a/test_files/test.hex b/test_files/test.hex
new file mode 100644 (file)
index 0000000..7a42308
--- /dev/null
@@ -0,0 +1,13 @@
+:03000000020033C8
+:1000330075818075D54475A000C290E4F500E50094
+:1000430012007DF586D29005A07400D5E0FDC29024
+:10005300E5AA53E08060F9E5861200690500C3E56F
+:1000630000945040D92222752005740075F000D504
+:10007300F0FDD5E0F7D520F20022248BF582740041
+:100083003400F5837400932252504D3A31303234A8
+:1000930035204D41503A313033204D41543A3131BE
+:1000A30030204241543A31322E3420202020202067
+:1000B3000D0A0A45474F3A31342E36202054505307
+:1000C3003A31303020414E473A33302020434C54AC
+:0B00D3003A313038202020202020206F
+:00000001FF
diff --git a/test_files/timer.asm b/test_files/timer.asm
new file mode 100644 (file)
index 0000000..aac4885
--- /dev/null
@@ -0,0 +1,179 @@
+;*******************************************************************************
+;*                Système d'Injection et d'Allumage Électronique               *
+;*                Version     : 01                                             *
+;*                Auteur      : Hugo Villeneuve                                *
+;*                                                                             *
+;*                10 mars 1999                                                 *
+;*******************************************************************************
+
+        $MOD52                  ; Micro-contrôleur Atmel AT89S8252
+
+
+;*******************************************************************************
+;*      Définition des constantes                                              *
+;*******************************************************************************
+
+TOS             EQU     60h     ; Adresse du dessus de la pile.
+CR              EQU     0Dh    ; Code ASCII pour un retour de chariot.
+LF              EQU     0Ah    ; Code ASCII pour un changement de ligne
+
+
+;*******************************************************************************
+;*      Définition des variables                                               *
+;*******************************************************************************
+                BSEG
+                ORG     20h
+C_FLAG:         DBIT    1
+Z_FLAG:         DBIT    2
+N_FLAG:                DBIT    3       ; Utilisé par la sous-routine MULT8_16
+SIGNE:         DBIT    4       ; Utilisé pour l'interpolation.
+
+                DSEG
+                ORG     30h
+PERIODE2:      DS      1       ; Période pour une rotation du vilebrequin, sur 24 bits.
+PERIODE1:       DS      1
+PERIODE0:       DS      1
+POSITION_VILB: DS      1       ; Renseignement sur la position actuelle du vilebrequin (zones 0,1 ou 2).
+VITESSE_RPM:   DS      2       ; Vitesse de rotation du moteur en RPM.
+INDEX_RPM:     DS      1       ; Index de 8 bits pour l'adressage des colonnes de la table d'allumage.
+INDEX_MAP:     DS      1       ; Index de 8 bits pour l'adressage des lignes de la table d'allumage.
+ANGLE:         DS      1       ; Angle d'allumage calculé à partir de la table.
+BAT:            DS      2       ; Voltage de la batterie.
+MAT:            DS      2       ; Manifold Air Temperature.
+CLT:            DS      2       ; Coolant Temperature.
+TPS:            DS      2       ; Throttle Position Sensor.
+MAP:            DS      2       ; Manifold Absolute Pressure.
+EGO:            DS      2       ; Exhaust Gas-Oxygen Sensor.
+CAN6:           DS      2       ; Canal #6 du convertisseur AN.
+CAN7:           DS      2       ; Canal #7 du convertisseur AN.
+GAMMA:          DS      2       ; Rapport Air/Carburant.
+LSB_CAN:        DS      1       ; Octet de poids faible de la conversion Analogique-Numérique.
+MSB_CAN:        DS      1       ; Octet de poids fort de la conversion Analogique-Numérique.
+NOMBRE4:        DS      1       ; Stockage des codes ASCII pour les conversions.
+NOMBRE3:        DS      1
+NOMBRE2:        DS      1
+NOMBRE1:        DS      1
+NOMBRE0:        DS      1
+C3:             DS      1       ; Accumulateur C de 32 bits pour les calculs mathématiques.
+C2:             DS      1
+C1:             DS      1
+C0:             DS      1
+D3:            DS      1       ; Accumulateur D de 32 bits pour les calculs mathématiques.
+D2:            DS      1
+D1:             DS      1
+D0:             DS      1
+TMP6:           DS      1       ; Variables temporaires utilisées pour les calculs mathématiques.
+TMP5:           DS      1      ; FAIRE LE MÉNAGE VARIABLES NON UTILISEES!!!
+TMP4:           DS      1
+TMP3:           DS      1
+TMP2:           DS      1
+TMP1:           DS      1
+TMP0:           DS      1
+VAR0:          DS      1
+VAR1:          DS      1
+VAR2:          DS      1
+
+
+;*******************************************************************************
+;*      Définition des régistres spécifiques au AT89S8252                      *
+;*******************************************************************************
+SPCR            DATA    0D5h            ; SPCR - SPI Control Register
+SPSR            DATA    0AAh            ; SPSR - SPI Status Register
+SPIF            EQU     10000000b       ; Masque pour le drapeau SPI.
+WCOL            EQU     01000000b       ; Masque pour le drapeau Write Collision.
+SPDR            DATA    086h            ; SPDR - SPI Data Register
+
+
+;*******************************************************************************
+;*      Vecteurs d'interruptions                                               *
+;*******************************************************************************
+        CSEG
+
+        ORG     0000h   ; Vecteur d'interruption du RESET.
+        JMP     DEBUT
+
+        ORG     0003h   ; Vecteur pour l'interruption EXTERNE 0.
+        JMP     VILEBREQUIN
+
+        ORG     000Bh   ; Vecteur pour l'interruption du TIMER 0.
+        JMP     DEBUT
+
+        ORG     0013h   ; Vecteur pour l'interruption EXTERNE 1.
+        JMP     DEBUT
+
+        ORG     001Bh   ; Vecteur pour l'interruption du TIMER 1.
+        JMP     DEBUT
+
+        ORG     0023h   ; Vecteur pour l'interruption du Port série.
+        JMP     DEBUT
+
+        ORG     002Bh   ; Vecteur pour l'interruption du TIMER 2.
+        JMP     DEBUT
+
+
+;*******************************************************************************
+;*      Début du programme principal                                           *
+;*******************************************************************************
+        ORG     0033h
+
+DEBUT:
+        MOV     SP,#TOS         ; Initialisation de la pile.
+        CALL    INITIALISATION
+        ; il ne faut pas modifier la valeur de P1.0!!!
+
+ICI:
+       NOP
+       NOP
+       NOP
+       NOP     
+
+        JMP     ICI
+
+
+;*******************************************************************************
+;*      Délai                                                                  *
+;*******************************************************************************
+DELAI:          MOV     TMP0,#016h      ; Délai de 1/2 seconde.
+B3:            MOV     A,#0    
+B2:            MOV     B,#0
+B1:            DJNZ    B,B1
+               DJNZ    ACC,B2  
+                DJNZ    TMP0,B3  
+                RET
+
+
+
+;*******************************************************************************
+;*      INTERRUPTION                                                           *
+;*******************************************************************************
+VILEBREQUIN:
+       RETI
+
+
+;*******************************************************************************
+;*      Initialisation                                                         *
+;*******************************************************************************
+INITIALISATION: MOV     SPCR,#01000100b ; Interruption SPI désactivée;
+                                       ; Activation du port SPI;
+                                       ; Ordre des transferts : MSB en premier;
+                                       ; Opération en mode escalve (SLAVE);
+                                        ; Polarité de l'horloge : niveau bas si inactif.
+                                       ; Phase de l'horloge : transfert sur front montant.
+       MOV     TH0,#2
+       MOV     TL0,#55h
+       SETB    TCON.4          ; Timer 0 ON.
+       SETB    TCON.6          ; Timer 1 ON.
+       MOV     TMOD,#00010001B ; Initialisation des timers 0 et 1 en timers de
+                               ; 16 bits, incrémentés par l'horloge interne
+                               ; Chaque timer est incrémenté tant que le bit correspondant de
+                               ; TCON est à 1 (TCON.4 et TCON.6).
+       RET
+
+
+
+        END
+
+
+
+
+
diff --git a/test_files/timer.hex b/test_files/timer.hex
new file mode 100644 (file)
index 0000000..3fadd1b
--- /dev/null
@@ -0,0 +1,10 @@
+:0600000002003302005172
+:03000B00020033BD
+:03001300020033B5
+:03001B00020033AD
+:03002300020033A5
+:03002B000200339D
+:100033007581601200520000000080FA756016742A
+:100043000075F000D5F0FDD5E0F7D560F2223275EA
+:10005300D544758C02758A55D28CD28E758911223E
+:00000001FF