--- /dev/null
+ 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.
--- /dev/null
+------------------------------------------------------------------------------
+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
+
+
+
+
+
+
+
+
--- /dev/null
+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.
+
--- /dev/null
+## 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
+
+
+
--- /dev/null
+ 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)
--- /dev/null
+#! /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
--- /dev/null
+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 )
+])
+
--- /dev/null
+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 )
+])
+
--- /dev/null
+# 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.
+---------------------------------------------------------------------------"
--- /dev/null
+## Makefile.am -- Process this file with automake to produce Makefile.in
+
+man1_MANS = emu8051.man
+
+EXTRA_DIST = $(man1_MANS)
+
+CLEANFILES = *~
+
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+.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
--- /dev/null
+/* XPM */
+static char * reset_xpm[] = {
+"48 48 3 1",
+" c None",
+". c #005A9C",
+"+ c #FFFFFF",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"..+++++++..++++++++..+++++++.++++++++.++++++++..",
+"..++++++++.++++++++.++++++++.++++++++.++++++++..",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.++.......++.......++..........++.....",
+"..++....++.+++++++..+++++++..+++++++.....++.....",
+"..+++++++..+++++++...+++++++.+++++++.....++.....",
+"..+++++++..++.............++.++..........++.....",
+"..++....++.++.............++.++..........++.....",
+"..++....++.++.............++.++..........++.....",
+"..++....++.++++++++.++++++++.++++++++....++.....",
+"..++....++.++++++++.+++++++..++++++++....++.....",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................",
+"................................................"};
--- /dev/null
+/* XPM */
+static char * run_xpm[] = {
+"48 48 4 1",
+" c None",
+". c #000000",
+"+ c #008C6B",
+"@ c #FFFFFF",
+" ........... ",
+" ................... ",
+" ........+++++++........ ",
+" ......+++++++++++++++...... ",
+" .....+++++++++++++++++++..... ",
+" .....+++++++++++++++++++++++..... ",
+" .....+++++++++++++++++++++++++..... ",
+" ....+++++++++++++++++++++++++++++.... ",
+" ...+++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++... ",
+" ....+++++++++++++++++++++++++++++++++.... ",
+" ...+++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++++... ",
+" ..+++++++++++++++++++++++++++++++++++++++++.. ",
+" ..++++++++@@@@@@@++@@++++@@+@@++++@@+++++++.. ",
+"...++++++++@@@@@@@@+@@++++@@+@@@+++@@+++++++... ",
+"...++++++++@@++++@@+@@++++@@+@@@+++@@+++++++... ",
+"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@+@@+@@++++++++.. ",
+"..+++++++++@@@@@@@++@@++++@@+@@+@@+@@++++++++.. ",
+"..+++++++++@@@@@@@++@@++++@@+@@++@@@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@++@@@@++++++++.. ",
+"..+++++++++@@++++@@+@@++++@@+@@+++@@@++++++++.. ",
+"...++++++++@@++++@@+@@@@@@@@+@@+++@@@+++++++... ",
+"...++++++++@@++++@@++@@@@@@++@@++++@@+++++++... ",
+" ..+++++++++++++++++++++++++++++++++++++++++.. ",
+" ..+++++++++++++++++++++++++++++++++++++++++.. ",
+" ...+++++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++++++... ",
+" ....+++++++++++++++++++++++++++++++++.... ",
+" ...+++++++++++++++++++++++++++++++++... ",
+" ...+++++++++++++++++++++++++++++++... ",
+" ....+++++++++++++++++++++++++++++.... ",
+" .....+++++++++++++++++++++++++..... ",
+" .....+++++++++++++++++++++++..... ",
+" .....+++++++++++++++++++..... ",
+" ......+++++++++++++++...... ",
+" ........+++++++........ ",
+" ................... ",
+" ........... ",
+" "};
--- /dev/null
+/* XPM */
+static char * step_xpm[] = {
+"48 48 5 1",
+" c None",
+". c #FFDE08",
+"+ c #000000",
+"@ c #FFFFFF",
+"# c #080800",
+"..........++++++++++++............++++++++++++..",
+"...........++++++++++++............++++++++++++.",
+"............++++++++++++............++++++++++++",
+"+............++++++++++++............+++++++++++",
+"++............++++++++++++............++++++++++",
+"+++............++++++++++++............+++++++++",
+"++++............++++++++++++............++++++++",
+"+++++............++++++++++++............+++++++",
+"++++++............++++++++++++............++++++",
+"+++++++............++++++++++++............+++++",
+"++++++++............++++++++++++............++++",
+"+++++++++............++++++++++++............+++",
+"++++++++++............++++++++++++............++",
+"+++++++++++............++++++++++++............+",
+"++++++++++++............++++++++++++............",
+".++++++++++++++++++++++++++++++++++++++++++++...",
+"..+++++++++++++++++++++++++++++++++++++++++++...",
+"...++++++++++++++++++++++++++++++++++++++++++...",
+"....++++@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@++++...",
+"....+++@@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
+"....+++@@@@@@@+++++@@++++@@@@@@@++@@++++@@+++...",
+"....++++@@@@@@@++++@@++++@@@@@@@++@@@@@@@@++++..",
+"....+++++++++@@++++@@++++@@+++++++@@@@@@@++++++.",
+"....+++++++++@@++++@@++++@@+++++++@@++++++++++++",
+"+...+++++++++@@++++@@++++@@+++++++@@++++++++++++",
+"++..+++@@@@@@@@++++@@++++@@@@@@@@+@@++++++++++++",
+"+++.+++@@@@@@@+++++@@++++@@@@@@@@+@@++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++",
+"+++++++............++++++++++++............+++++",
+"++++++++............++++++++++++............++++",
+"+++++++++............+#++++++++++............+++",
+"++++++++++............++++++++++++............++",
+"#++++++++++............++++++++++++............+",
+"++++++++++++............++++++++++++............",
+".+#++++++++++............+#++++++++++...........",
+"..++++++++++++............+#++++++++++..........",
+"...++++++++++++............++++++++++++.........",
+"....++++++++++++............++++++++++++........",
+".....+#++++++++++............+#++++++++++.......",
+"......++++++++++++............++++++++++++......",
+".......++++++++++++............++++++++++++.....",
+"........+#++++++++++............++++++++++++....",
+".........++++++++++++............+#++++++++++..."};
--- /dev/null
+/* XPM */
+static char * stop_xpm[] = {
+"48 48 4 1",
+" c None",
+". c #000000",
+"+ c #C60021",
+"@ c #FFFFFF",
+" .................... ",
+" .++++++++++++++++++++. ",
+" .++@@@@@@@@@@@@@@@@@@++. ",
+" .++@@++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
+".++@@++++++++++++++++++++++++++++++++++++++@@++.",
+".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@+++++@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@++++@+.",
+".+@++++@@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@@+++@+.",
+".+@++++@@++++++++++@@++++@@@++@@@+@@++++@@+++@+.",
+".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@++++@@@@@@@+++++@@++++@@++++@@+@@++++@@+++@+.",
+".+@+++++@@@@@@@++++@@++++@@++++@@+@@@@@@@@+++@+.",
+".+@++++++++++@@++++@@++++@@++++@@+@@@@@@@++++@+.",
+".+@++++++++++@@++++@@++++@@++++@@+@@+++++++++@+.",
+".+@++++++++++@@++++@@++++@@@++@@@+@@+++++++++@+.",
+".+@++++@@@@@@@@++++@@+++++@@@@@@++@@+++++++++@+.",
+".+@++++@@@@@@@+++++@@+++++@@@@@@++@@+++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@++++++++++++++++++++++++++++++++++++++++++@+.",
+".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
+".++@@++++++++++++++++++++++++++++++++++++++@@++.",
+" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++++@@++. ",
+" .++@@++++++++++++++++@@++. ",
+" .++@@@@@@@@@@@@@@@@@@@+. ",
+" .++++++++++++++++++++. ",
+" .................... "};
--- /dev/null
+// 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"
+
+
+
+
+
+
--- /dev/null
+#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
+
--- /dev/null
+// 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;
+}
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
--- /dev/null
+// 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 );
+ }
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+// 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
+
--- /dev/null
+# 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 $<
--- /dev/null
+/* 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 ) );
+}
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#!/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;
+
+
--- /dev/null
+/* 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 );
+}
+
+
+
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+/* 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 ) );
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+: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
--- /dev/null
+:03000000020033C8
+:1000330075818075D54475A000C290E4F500E50094
+:1000430012007DF586D29005A07400D5E0FDC29024
+:10005300E5AA53E08060F9E5861200690500C3E56F
+:1000630000945040D92222752005740075F000D504
+:10007300F0FDD5E0F7D520F20022248BF582740041
+:100083003400F5837400932252504D3A31303234A8
+:1000930035204D41503A313033204D41543A3131BE
+:1000A30030204241543A31322E3420202020202067
+:1000B3000D0A0A45474F3A31342E36202054505307
+:1000C3003A31303020414E473A33302020434C54AC
+:0B00D3003A313038202020202020206F
+:00000001FF
--- /dev/null
+;*******************************************************************************
+;* 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
+
+
+
+
+
--- /dev/null
+:0600000002003302005172
+:03000B00020033BD
+:03001300020033B5
+:03001B00020033AD
+:03002300020033A5
+:03002B000200339D
+:100033007581601200520000000080FA756016742A
+:100043000075F000D5F0FDD5E0F7D560F2223275EA
+:10005300D544758C02758A55D28CD28E758911223E
+:00000001FF