mirror of
http://git.hugovil.com/git/emu8051.git
synced 2025-10-14 02:48:29 +08:00
Initial import
This commit is contained in:
340
COPYING
Normal file
340
COPYING
Normal file
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 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.
|
492
ChangeLog
Normal file
492
ChangeLog
Normal file
@@ -0,0 +1,492 @@
|
||||
------------------------------------------------------------------------------
|
||||
2002/11/12 Hugo Villeneuve <hugovil@videotron.ca>
|
||||
-Removed some warnings for GCC 3.2: replaced <fstream.h> by <fstream>
|
||||
and <iostream.h> by <iostream>.
|
||||
-Added "using namespace std;" in EmuGtk.hpp (for GCC 3.2)
|
||||
-Removed all unused variables
|
||||
-Corrected error in CPU8051.cpp, in function:
|
||||
'void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )'
|
||||
Modified this:
|
||||
'sprintf( &Text[ TextLength ], ".%X", BitAddress );'
|
||||
instead of:
|
||||
'sprintf( &Text[ TextLength ], ".%X" );'
|
||||
-In Opcode2cpp.pl (line 767), modified for GCC 3.2:
|
||||
'print INST_IMP " funcptr[$i]=&CPU8051::$ifunc;\n";'
|
||||
instead of:
|
||||
'print INST_IMP " funcptr[$i]=&$ifunc;\n";'
|
||||
-EmuGtk.cpp, added '#include <iostream>'
|
||||
-Modified the return type of some functions to void to remove warnings.
|
||||
-In function 'void RegWin::Show( CPU8051 *CPU )' (RegWin.cpp), removed all
|
||||
the '\n' in 'gtk_clist_set_text' calls (to fix a display problem)
|
||||
------------------------------------------------------------------------------
|
||||
99/04/27 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Ajoute les fonctions DumpInt dans EmuConsole.hpp ainsi que ReadInt
|
||||
dans CPU8051.hpp. Corrige des bugs dans WriteInt et WriteExt.
|
||||
|
||||
- Corrige l'implementation des timers. Les 4 modes ont ete testes et
|
||||
semblent bien fonctionner maintenant. LEs flags sont mis correctement
|
||||
et les timers augmentent maintenant (au lieu d'etre decrementes).
|
||||
- Ajoute un fichier timer.hex pour tester les timers.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
99/04/22 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Ajoute les fonctions ME, MI et MP (voir definitions dans
|
||||
EmuConsole.cpp). Ajoute les fonctions membres WriteExt et WriteInt
|
||||
dans la classe CPU8051 afin de suivre la logique de l'espace
|
||||
memoire du 8051. WriteExt permet de modifier la memoire externe
|
||||
qui va de $00 a $FFFF (et non de $100 a $FFFF comme c'etait le cas
|
||||
avant). De meme, WriteInt permet de modifier la memoire interne qui
|
||||
va de $00 a $FF (incluant les SFR). Meme si la memoire externe
|
||||
contient les adresses $00 a $FF, il n'y a pas de conflit avec la
|
||||
memoire interne de $00 a $FF car la memoire externe est accedee avec
|
||||
l'instruction MOVX alors que la memoire interne l'est avec les
|
||||
instructions MOV (direct ou indirect).
|
||||
|
||||
- Renomme l'option DD du menu pour DE (dump External data memory).
|
||||
Change la description de l'option DI du menu pour Dump External
|
||||
Data Memory.
|
||||
|
||||
- Ajoute la fonction ReadExt dans la classe CPU8051, toujours pour
|
||||
la logique de la memoire du 8051. Ajoute la fonction DumpExt dans la
|
||||
classe EmuConsole pour dumper la memoire externe.
|
||||
- Ces nouvelles fonctions ont ete testees et semblent bien fonctionner.
|
||||
------------------------------------------------------------------------------
|
||||
99/04/09 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Refait marche le RunningState avec les classes.
|
||||
- Reconnecte les signaux aux boutons Trace, Run, Reset et Quit.
|
||||
- Ajoute bouton Step qui ajoute un breakpoint a la ligne suivante
|
||||
et passe en RunningState. Pratique lorsqu'arrive un CALL et qu'on ne
|
||||
veut pas y entrer contrairement a Trace.
|
||||
------------------------------------------------------------------------------
|
||||
99/04/06 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Creation de EmuConsole.hpp et EmuConsole.cpp
|
||||
- Cette nouvelle archive est presque rendue au meme niveau que
|
||||
l'ancienne. Vous allez pouvoir commencer a laisser faire l'ancienne
|
||||
et vous concentrer sur celle-ci.
|
||||
------------------------------------------------------------------------------
|
||||
(Les modifs annoncee se rapportent a l'ancienne archive mais elles ont ete
|
||||
ramenee dans celle-ci par Jonathan St-Andre)
|
||||
99/04/05 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Corrige qq malfonctions dans exec de mainconsole.cpp (nb d'inst.
|
||||
peut etre l'infini, caractere est attendu au clavier seulement
|
||||
si l'execution est arretee par une touche.
|
||||
- Corrige probleme d'instructions sans operandes mal desassemblees
|
||||
(il ne faut pas ecrire le caractere ' ' dans la chaine, il faut
|
||||
utiliser sprintf avec " " a la place car sprintf termine la chaine
|
||||
avec un 0 a la fin. La chaine n'etait pas terminee par un 0 et elle
|
||||
affichait du garbage de la memoire)
|
||||
- Corrige probleme dans disasm.cpp en rapport avec addr11 qui ne
|
||||
prenait pas opcode mais memoire[opcode] (je devais etre chaud quand
|
||||
j'ai ecrit ca).
|
||||
- Bouton Run se change en Stop dans l'interface Gtk+ lorsque l'on
|
||||
clique dessus et le cpu se met en mode execution. Les fonctions de
|
||||
l'interface restent disponibles. N'importe quelle action dans
|
||||
l'interface(excepte le fait de cliquer dans les fenetre memoire
|
||||
et programme) cause l'arret de l'execution et la mise a jour
|
||||
de l'affichage.
|
||||
- Il est possible de placer des breakpoints pendant qu'il est
|
||||
dans le "RunningState".
|
||||
- Enleve les pixmaps sur les boutons dans l'interface Gtk+
|
||||
- Ajoute verification de breakpoint deja existant dans
|
||||
setbreakpoint.
|
||||
|
||||
Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
-Modifie l'affichage de disasm pour que les operandes soient alignees.
|
||||
-Modifie la fonction DP pour qu'elle prenne l'adresse du PC par
|
||||
defaut si aucune adresse n'est specifiee.
|
||||
|
||||
- Erreur avec l'instruction ACALL qui ne calculait pas l'adresse
|
||||
correctement et qui ne poussait pas l'adresse de retour sur la pile.
|
||||
Il est important que le PC soit incremente de 2 avant de calculer
|
||||
addr11 et de pousser le PC sur la pile...
|
||||
Il faut aussi modifier le dessassemblage de cette instruction qui
|
||||
n'affiche que la deuxieme operande (adresse de 8 bits), alors que
|
||||
l'adresse est sur 11 bits...
|
||||
-Erreur avec l'instruction RET( fichier siae1.asm adresse 03A4) ,
|
||||
affiche RET @%K
|
||||
-Ajoute la possibilite d'arreter l'execution du programme en pesant
|
||||
sur n'importe quelle touche grace a la fonction kbhit().
|
||||
-Ajoute les fonctions SB, RB et DB pour les breakpoints dans le
|
||||
mode console. L'execution se fait jusqu'au breakpoint. Une fois
|
||||
arrive au breakpoint, si on fait de nouveau EM, on peut continuer
|
||||
l'execution du programme passe ce breakpoint. Autrement dit, EM
|
||||
ne verifie pas si la premiere instruction qu'il execute est un
|
||||
break point, ce qui est pratique pour continuer l'execution du prog
|
||||
apres un breakpoint.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/31-
|
||||
99/04/03 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Reecriture de TOUT les sources en imbriquant au maximum
|
||||
dans des classes pour que ce soit plus lisible et reutilisable.
|
||||
- Les classes sont CPU8051, Memory, EmuGtk, MemWin, RegWin, PgmWin
|
||||
et les exceptions.
|
||||
- Tout est en anglais pour rendre le programme disponible sur
|
||||
internet.
|
||||
- Je n'ai pas encore refais l'interface Console en classes donc
|
||||
elle n'est pas incluse dans cette archive. Il faudrait vraiment
|
||||
la refaire en tant que classe.
|
||||
- Ajout fichiers TODO, CREDITS et COPYING (license GPL)
|
||||
------------------------------------------------------------------------------
|
||||
99/03/30 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Corrige bug lors du desassemblage dans l'interpretation des
|
||||
adresses directes dans 0-7F. disasm.cpp
|
||||
- Corrige bug dans l'opcode 0x85, ajoute conditions particulieres
|
||||
pour cette instruction dans script Perl et dans desassemblage.
|
||||
Les operandes de cette instruction sont inversees dans la memoire
|
||||
programme. Ex.: MOV 50H,51H est ecrit 85 51 50 dans la memoire
|
||||
programme.
|
||||
|
||||
Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Bug dans les instructions ayant un mode d'adressage direct qui
|
||||
utilisent des adresses dans 0-7F. Le desassembleur interprete les
|
||||
adresses comme etant des adresses de bit.
|
||||
- Bug dans l'opcode 0x85 MOV direct,direct. La source et la
|
||||
destination sont inverses dans le desassemblage et dans l'execution.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/29 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Remplace string::erase pour string::replace partout, g++ a
|
||||
l'universite ne connait pas encore string::erase, c'est trop recent.
|
||||
- Ajoute "-w" pour disabler les warnings et "-fhandle-exceptions"
|
||||
pour activer les exceptions a l'universite.
|
||||
|
||||
Pascal Fecteau <fectea00@gel.ulaval.ca>
|
||||
|
||||
- Ajoute .h comme extension aux fichiers inclus, sinon ca ne
|
||||
fonctionne pas a l'universite.
|
||||
|
||||
Pascal Fecteau <fectea00@gel.ulaval.ca>
|
||||
Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Corrige une erreur dans les instructions AJMP addr11
|
||||
------------------------------------------------------------------------------
|
||||
99/03/28 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Modification de la presentation de "Dump Register" sur la console.
|
||||
Beaucoup plus facile a lire maintenant.
|
||||
- Correction d'un bug dans l'instruction DA (opcode 0xD4).
|
||||
------------------------------------------------------------------------------
|
||||
99/03/27 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Correction d'un probleme avec l'instruction CJNE.
|
||||
- Correction de bugs dans LoadHexFile (voir 99/03/22)
|
||||
|
||||
Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Augmente la hauteur de la fenetre Internal RAM.
|
||||
- Correction de probleme avec tous les XCH et XCHD, l'operande source
|
||||
n'etait pas modifiee (Trouve par Hugo et suggestion de correction par
|
||||
Hugo).
|
||||
- Ajout de P0, P1, P2 et P3 dans la fenetre des registres.
|
||||
(Suggestion d'Hugo).
|
||||
- View -> Data Memory Dump et View -> Program Memory Dump sont
|
||||
fonctionnels. On ne peut visionner que les 16384 premiers octets.
|
||||
Il ne veut pas prendre 65536 lignes dans une scrolled window.
|
||||
Probablement parce que 18colonnes x 65536lignes = 1179648 cellules
|
||||
est beaucoup trop.
|
||||
- J'ai remarque qu'avec Gtk, on peut facilement changer les raccoucis
|
||||
dans les menus. Pour associer "View -> Program Memory Dump" au
|
||||
raccourci "Alt-2" par exemple, il suffit d'aller dans le menu "View",
|
||||
se placer au dessus de "Program Memory Dump" et appuyer "Alt-2".
|
||||
Le menu se modifiera automatiquement pour afficher "Alt-2" au bout
|
||||
de la ligne et desormais, lorsque vous appuierez "Alt-2", l'action
|
||||
sera executee. Ca dure seulement durant la session presente.
|
||||
- Reduit la taille de la fenetre principale en largeur de 120 pixels
|
||||
et en hauteur de 20 pixels.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/25 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Fenetre dump connais la position ou on clique dedans.
|
||||
- Generalise dans une classe la fenetre memorydump, il sera plus
|
||||
facile d'ajouter plusieurs fenetres memory dump a partir du menu
|
||||
plus tard.
|
||||
- Implemente Run jusqu'a un breakpoint (si aucun breakpoint,
|
||||
loop sans fin -> il faut killer).
|
||||
- Suffit de cliquer sur une ligne de programme dans Gtk pour placer
|
||||
ou retirer un breakpoint. Les breakpoints apparaissent comme une
|
||||
asterisque (*) a droite de l'adresse dans la fenetre program.
|
||||
- Ajoute bouton Run dans interface Gtk
|
||||
- Implemente quelques fonctions necessaires au breakpoints.
|
||||
- Change un peu le layout
|
||||
- Enleve image de fond (cause leger delai au chargement)
|
||||
- Fait un peu de menage dans fichiers relatifs au Gtk
|
||||
------------------------------------------------------------------------------
|
||||
99/03/23 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Changement des champs GTK_TEXT des fenetres Registre, Program et
|
||||
Internal RAM pour des champs GTK_CLIST. Plus beau, moins de
|
||||
flickering quand on trace et plus pratique pour ce qui s'en vient.
|
||||
- Integration des fichiers xpm dans l'executable. Mais c'est encore
|
||||
trop long a charger lors de l'execution, va probablement falloir les
|
||||
compresser ou laisser faire l'image de fond.
|
||||
- Ajout de pixmaps sur les boutons Trace, Reset et Quit (Gtk)
|
||||
- Ajout de pixmap comme fond (Gtk)
|
||||
------------------------------------------------------------------------------
|
||||
99/03/22 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Corrige un bug dans la fonction LoadHexFile : Le checksum n'etait
|
||||
pas calcule correctement, ce qui entrainait des erreurs a l'ouverture
|
||||
de certains fichiers HEX. L'erreur venait du fait que le checksum se
|
||||
calculait avec la valeur absolue du LoadOffset, au lieu d'utiliser
|
||||
les caracteres composant le LoadOffset. Exemple : si LoadOffset =
|
||||
0103, il faut additionner 01h+03h=4h au Checksum et non pas 0103h =
|
||||
259 en decimal.
|
||||
- Deplace la fonction enleve_espaces de main_console vers mainemu
|
||||
car elle est commune aux deux interfaces graphiques.
|
||||
- Modifie la fonction majuscules pour qu'elle puisse convertir les
|
||||
lettres de minuscule a majuscule meme si la chaine contient des
|
||||
chiffres ou autres signes de ponctuation.
|
||||
- Modifie la declaration des fonctions dans tous les fichiers .hpp:
|
||||
enleve le nom des parametres car c'etait inutile.
|
||||
- Stocke le nom des registres dans un fichier registres8051.hpp.
|
||||
Ainsi, si on veut emuler un autre type de processeur, il suffira
|
||||
de se creer un autre fichier registres8052xxx.hpp par exemple.
|
||||
- Implemente l'affichage en francais ou en anglais dependant de
|
||||
l'option passee sur la ligne de commande. L'interface est beaucoup
|
||||
plus lisible de cette facon. Par defaut, l'affichage est en anglais.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/21 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Ajoute deux parametres qu'on peut passer par la ligne de commande:
|
||||
/? affiche les options disponibles sur la ligne de commande.
|
||||
-f force l'affichage en francais (pas encore implemente!!!)
|
||||
- Ajoute le controle d'erreur pour le chargement d'un fichier HEX.
|
||||
Les differentes erreurs sont controlees ( checksum, rectype,
|
||||
fin de fichier, etc.).
|
||||
- Modifie la fonction unasm pour qu'elle accepte 0,1 ou 2 parametres.
|
||||
U (adresse) (nombre d'instructions)
|
||||
Si adresse et nombre d'instructions non-specifies:
|
||||
Adresse = PC et Nombre d'Instructions = 16
|
||||
Si adresse specifie et nombre d'instructions non-specifie:
|
||||
Adresse = adresse specifiee et Nombre d'Instructions = 16
|
||||
Si adresse specifie et nombre d'instructions specifie:
|
||||
Adresse = adresse specifiee et Nombre d'Instructions = nb specifie
|
||||
A noter: on peut specifier une adresse comme etant un nombre
|
||||
hexadecimal, ou tout simplement en entrant "PC" ou "pc".
|
||||
|
||||
Jonathan St-Andre <standr00@gel.ulaval.ca
|
||||
|
||||
- Fait le menage dans la fonction main
|
||||
- Modifie Makefile.console et Makefile.gtk
|
||||
- Rearrangement des fichiers pour limiter les impacts sur
|
||||
tout le projet lors de modifications dans une partie et
|
||||
pour accelerer la compilation (en modules).
|
||||
- Creation de mainconsole.hpp + mainconsole.cpp
|
||||
- Creation de maingtk.cpp + maingtk.hpp
|
||||
- Creation de mainemu.cpp + mainemu.hpp
|
||||
- Elimine fonctions.cpp.
|
||||
- Elimination du 2e parametre a unasm. Desassemble
|
||||
de nouveau 16 instructions.
|
||||
- Ajustement du menu pour qu'il rentre dans la largeur
|
||||
d'un terminal 80x25.
|
||||
|
||||
Jimmy Ringuette <ringue00@gel.ulaval.ca>
|
||||
|
||||
- Ajout des interruptions du port serie.
|
||||
- Ajout du timer 2 (8052).
|
||||
------------------------------------------------------------------------------
|
||||
99/03/20 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Separe le fichier main.cpp en deux: main.cpp et fonctions.cpp.
|
||||
fonctions.cpp contient les fonctions necessaires a main.cpp.
|
||||
- Ajoute un fichier exceptions.hpp qui permet de gerer les erreurs.
|
||||
- Modifie le Makefile en consequence.
|
||||
- On peut maintenant entrer les adresses < a quatre caracteres :
|
||||
ex: adresse 0000h = 0 ou 00 ou 000 ou 0000.
|
||||
- Enleve le include <stdlib.h>
|
||||
- Remplace toutes les commandes printf du main par cout.
|
||||
- Modifie l'apparence du menu.
|
||||
- Le programme est maintenant plus robuste en ce qui concerne les
|
||||
erreurs de syntaxe, les adresses invalides, etc (a tester...).
|
||||
- Modifier l'operation et la syntaxe de certaines commandes
|
||||
S (set register) devient MR (modify register) car set veut
|
||||
plutot dire "mettre a 1", et on pourra aussi implementer
|
||||
MM (modify Memory).
|
||||
R devient DR (display Register), pour suivre la logique de
|
||||
DP, DM et DI.
|
||||
- Ajoute une commande Execute Memory: EM addr n
|
||||
- La gestion des chaines de caracteres se fait maintenant
|
||||
uniquement avec des variables de type STRING, selon le C++.
|
||||
- Enleve variables i,j,k et inputcars dans le main.
|
||||
- Modifie la fonction RESET pour quelle n'affiche pas les
|
||||
registres au demarrage... ca faisait pas beau! Ajoute
|
||||
cependant un message pour dire que le up est resette.
|
||||
- Pour changer un registre, on doit entrer PC (et non p) ainsi
|
||||
que SP (et non seulement s).
|
||||
- Ajoute une fonction qui convertit une chaine de caracteres
|
||||
en majuscules.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/19 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Fonction reset51() ajoutee dans cpu8051.cpp, reset() ajoutee
|
||||
dans main.cpp.
|
||||
- Commande "Z" fait un reset du processeur sur la console et le
|
||||
bouton Reset fonctionne dans le GUI.
|
||||
|
||||
Jimmy Ringuette <ringue00@gel.ulaval.ca>
|
||||
|
||||
- Les interruptions sont maintenant implementees. check_hardware() a
|
||||
ete supprimee et Do_timers() est appelee directement de exec8051().
|
||||
------------------------------------------------------------------------------
|
||||
99/03/18 Hugo Villeneuve <villen01@gel.ulaval.ca>
|
||||
|
||||
- Modifie l'entree des commandes pour gerer un peu plus les erreurs
|
||||
de syntaxe (je n'ai pas fini, il y a encore de la job a faire pour
|
||||
mettre ca error proof).
|
||||
- Simplifie l'entree des parametres pour chacune des fonctions.
|
||||
- Re-modifie l'instruction trace pour avoir seulement deux modes:
|
||||
trace a adresse et trace 1 instruction. Cela simplifie l'entree de
|
||||
la commande (on n'a pas a faire TA, qui n'est pas une commande
|
||||
standard dans les emulateurs). Si on veut faire tracer pour plusieurs
|
||||
instructions, alors il suffira d'implementer la commande
|
||||
EXECUTE Nombre_instructions, ce qui est beaucoup plus logique et
|
||||
c'est ce qu'on retrouve dans la plupart des emulateurs.
|
||||
- Ajoute la description des commandes en francais (loi 101).
|
||||
------------------------------------------------------------------------------
|
||||
99/03/18 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Le bouton Trace dans la version Gtk+ fonctionne. On peut tracer
|
||||
et les 3 fenetres(registres, memoire, programme) se mettent a jour.
|
||||
- Ajout de 2 nouvelles fonctions trace : "tracenb()" et "traceat()"
|
||||
Qui, respectivement, prenent un nombre d'instruction a executer ou
|
||||
une adresse ou commencer l'execution. La fonction trace() a ete
|
||||
resimplifiee.
|
||||
- Dans les instructions RET, RETI, LCALL, PUSH et POP la pile prend
|
||||
la iram seulement pour les adresses sous 0x80, la data RAM est
|
||||
utilisee autrement. Avant, les SFR se faisaient ecraser!
|
||||
- Modes d'addressage addr16, reladdr, #data16 modifies!
|
||||
En tenant compte de ce que Hugo avait fait remarquer ce matin :
|
||||
ex.: si PC++ apparait 2 fois sur une ligne, les 2 fois il repartira
|
||||
de la meme valeur de PC et suite a cette ligne, on se trouve avec
|
||||
un PC incremente 1 fois au lieu de 2.
|
||||
- Menu accepte maj/minuscules
|
||||
- Corrige bug dans "setreg", les registres peuvent vraiment
|
||||
etre donnes en maj/minuscules maintenant.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/17 Hugo Villeneuve <villen01@gel.ulaval.ca
|
||||
|
||||
- Corrige les instructions LJMP et LCALL qui ne calculaient pas la
|
||||
bonne adresse pour le PC. Toutes les autres instructions de
|
||||
branchement sont probablement a revoir pour le meme probleme. Le
|
||||
probleme etait cause par la syntaxe dans le fichier instructions.hpp
|
||||
(lignes ou on retrouve addr16 = (pgm_mem[PC++] << 8)+pgm_mem[PC++] a
|
||||
remplacer par addr16 = (pgm_mem[PC+1] << 8) + pgm_mem[PC+2] )
|
||||
- Modifie la commande TRACE pour qu'on puisse lui passer une adresse
|
||||
de depart comme parametre (main.cpp lignes 406-409) et modifie
|
||||
en consequence ascii2hex pour qu'il ignore les espaces avant
|
||||
l'adresse. (main.cpp ligne 133).
|
||||
------------------------------------------------------------------------------
|
||||
99/03/14 Pascal Fecteau <fectea00@gel.ulaval.ca>
|
||||
|
||||
- Correction de bugs relatifs a la compilation sur VC5.
|
||||
Dont ajout de #include <string.h>.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/13 Jimmy Ringuette <ringue00@gel.ulaval.ca>
|
||||
|
||||
- Ajout des timers dans cpu8051.cpp. Il faudrait tester a fond.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/12 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Je crois qu'il sera plus interessant si on garde le memory
|
||||
dump normal dans une fenetre exterieur et dont on pourra en ouvrir
|
||||
plusieurs pour monitorer differents endroits de la memoire, c'est
|
||||
pourquoi je n'ai place que "Internal RAM" comme memory dump dans
|
||||
la fenetre principale.
|
||||
- Au demarrage, effectue un premier memory dump dans la fenetre
|
||||
"Internal RAM", un unasm dans "Program" et un show register dans
|
||||
"Registers".
|
||||
- Bouton Quit, menus "File -> Quit" et "Help -> About" reagissent.
|
||||
- Comporte maintenant 2 Makefile : Makefile.console(fonctionne sur
|
||||
toutes les plateformes) et Makefile.gtk(teste seulement sous Linux).
|
||||
- DEBUT d'interface graphique Gtk+ (ne fait qu'afficher une fenetre
|
||||
avec un layout tres simple), presentement je cours apres des sources
|
||||
de documentations.(le manuel n'est pas encore complet)
|
||||
------------------------------------------------------------------------------
|
||||
99/03/09 Jimmy Ringuette <ringue00@gel.ulaval.ca>
|
||||
|
||||
- Regle le bug avec mul (probleme avec les bits 15-8 du resultat
|
||||
ne se ramenaient pas dans les bits 7-0 du registre B)
|
||||
- La conversion chaine->hexadecimal accepte les minuscules
|
||||
- Il n'est plus obligatoire d'ecrire les 4 caracteres lorsqu'il faut
|
||||
entrer une valeur hexadecimale.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/05 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Corrige un warning de compilation sous Solaris.
|
||||
------------------------------------------------------------------------------
|
||||
99/03/04 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Ca execute! (presque)
|
||||
- Phase de corrections des bugs dans les instructions, une premiere
|
||||
implementation est faite pour toutes les instructions.
|
||||
- Ajout fonction "trace" et "dump internal memory"
|
||||
- Les modes d'adressage sont pratiquement termines dans
|
||||
les instructions.
|
||||
- Certaines instructions ont un debut d'implementation.
|
||||
- Desassembleur, bit addressable segment 00-7F -> 20.0-2F.7
|
||||
------------------------------------------------------------------------------
|
||||
99/03/03 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Ajout automatique de certaines lignes de codes concernant
|
||||
l'adressage dans les fonctions d'instructions tres brouillon
|
||||
- Ajout de stub pour write_mem et read_mem, modifs dans exec8051
|
||||
- Ajout de la fonction showregister() et de la commande 'r'.
|
||||
- Correction d'une erreur iram_mem doit etre unsigned char et non int
|
||||
- Note : Il y a des references a certaines parties du 8052 mais
|
||||
elles ne seront pas implementees. Ce n'est qu'a titre d'informations.
|
||||
- Ajout de #define pour faire correspondre les registres SFR avec
|
||||
leur adresse dans la iram.
|
||||
- Renomme instructions.cpp a instructions.hpp et ajout du tableau
|
||||
de pointeurs sur les fonctions
|
||||
- Ajout de la ram interne 00-FF et valeurs initiale au reset
|
||||
dans cpu8051.cpp avec le registre : unsigned int PC.
|
||||
- Ajout de cpu8051.cpp contenant exec8051()
|
||||
------------------------------------------------------------------------------
|
||||
99/03/02 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Ajout de remarques dans le source
|
||||
- Il faudrait maintenant tester avec plusieurs programmes pour
|
||||
reperer les bugs.
|
||||
- Le desassembleur reconnait maintenant les registres du SFR
|
||||
(ex.: 88H est remplace par TCON, F0 par B, etc...)
|
||||
- Changement au desassembleur (instructions peuvent avoir jusqu'a 3
|
||||
arguments ex.: CJNE R0,#data,reladdr)
|
||||
- La vrai instruction CJNE comporte 3 arguments il faut changer
|
||||
radicalement le desassembleur
|
||||
------------------------------------------------------------------------------
|
||||
99/03/01 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Probleme dans opcodes.lst au niveau de l'instruction CJNE (mauvaise
|
||||
definition)
|
||||
- Tous les types d'adressages semblent fonctionner
|
||||
- Le desassembleur peut lire les arguments et les afficher
|
||||
(ex.: MOV A,#data peut devenir plus concret MOV A,#20)
|
||||
- Desassembleur (instructions ont 2 arguments : instleftarg et
|
||||
instrightarg)
|
||||
------------------------------------------------------------------------------
|
||||
99/02/28 Jonathan St-Andre <standr00@gel.ulaval.ca>
|
||||
|
||||
- Charge un fichier .hex donne en parametre (format Intel Hexadecimal
|
||||
produit par ASM51)
|
||||
- Effectue le dump program memory et dump data memory
|
||||
- On peut quitter (YEAH!)
|
||||
- Affiche le menu
|
||||
- Creation de opcodes.lst et script Perl pour l'interpreter
|
||||
- Debut
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
229
INSTALL
Normal file
229
INSTALL
Normal file
@@ -0,0 +1,229 @@
|
||||
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
25
Makefile.am
Normal file
25
Makefile.am
Normal file
@@ -0,0 +1,25 @@
|
||||
## Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
SUBDIRS = src doc
|
||||
|
||||
EXTRA_DIST = bootstrap \
|
||||
$(ac_aux_dir)/debug.m4 \
|
||||
$(ac_aux_dir)/gtk2.m4 \
|
||||
pixmaps/*.xpm \
|
||||
test_files/*
|
||||
|
||||
ACLOCAL = aclocal -I $(ac_aux_dir)
|
||||
|
||||
CLEANFILES = *~
|
||||
|
||||
DISTCLEANFILES = .deps/*.P
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in stamp-h.in \
|
||||
$(ac_aux_dir)/depcomp $(ac_aux_dir)/install-sh $(ac_aux_dir)/missing \
|
||||
$(ac_aux_dir)/mkinstalldirs $(ac_aux_dir)/config.guess \
|
||||
$(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh
|
||||
|
||||
|
||||
|
15
TODO
Normal file
15
TODO
Normal file
@@ -0,0 +1,15 @@
|
||||
THINGS TO DO
|
||||
------------
|
||||
|
||||
-Compile only one program for both graphical and console modes, or
|
||||
support only the graphical mode.
|
||||
- Some fine tuning around the classes
|
||||
- Make MemWin, RegWin be able to make a standalone
|
||||
window if parentwin=0.
|
||||
- Connect File->Open, View->... and Help->License menus.
|
||||
- Make the RegWin and MemWin react when mouse clicked. (modify register or
|
||||
memory)
|
||||
- Enlever les fonctions ReadI, WriteI, dumpI etc... et plutot utiliser les
|
||||
fonctions ReadInt, WriteInt, DumpInt, DumpExt, etc.
|
||||
- Lors d'un DumpInt, verifier a ne pas afficher plus haut que la taille
|
||||
reelle de la memoire interne. (Detail)
|
28
autogen.sh
Executable file
28
autogen.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#! /bin/sh
|
||||
# bootstrap -- Use this script to create generated files from the CVS dist
|
||||
# Copyright (C) 2000 Gary V. Vaughan
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
## @start 1
|
||||
#! /bin/sh
|
||||
|
||||
set -x
|
||||
aclocal -I config
|
||||
##libtoolize --force --copy
|
||||
autoheader
|
||||
automake --add-missing --copy
|
||||
autoconf
|
||||
## @end 1
|
18
config/debug.m4
Normal file
18
config/debug.m4
Normal file
@@ -0,0 +1,18 @@
|
||||
dnl
|
||||
dnl Macro for adding an option to 'configure' for enabling debugging messages
|
||||
dnl
|
||||
AC_DEFUN([HV_CHECK_FOR_DEBUG],[
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
|
||||
[enable debugging messages on console
|
||||
(default is NO)]),[
|
||||
if test x"${enableval}" = xyes; then
|
||||
debug_messages=1
|
||||
AC_DEFINE([DEBUG],1,[Set to 1 to enable debugging messages.])
|
||||
elif test x"${enableval}" = xno; then
|
||||
debug_messages=0
|
||||
else
|
||||
AC_MSG_ERROR(bad value for --enable-debug option)
|
||||
fi
|
||||
], debug_messages=0 )
|
||||
])
|
||||
|
17
config/gtk2.m4
Normal file
17
config/gtk2.m4
Normal file
@@ -0,0 +1,17 @@
|
||||
dnl
|
||||
dnl Macro for adding an option to 'configure' for choosing GTK+-2 instead of the
|
||||
dnl GTK+-1 default
|
||||
dnl
|
||||
AC_DEFUN([HV_CHECK_FOR_GTK2],[dnl
|
||||
AC_ARG_WITH(gtk2, AC_HELP_STRING([--with-gtk2], [use GTK2 (default is GTK1)]),[dnl
|
||||
if test x"${withval}" = xyes; then
|
||||
use_gtk2=1
|
||||
AC_DEFINE([USE_GTK2],1,[Set to 1 to use the Gtk+-2 library.])
|
||||
elif test x"${withval}" = xno; then
|
||||
use_gtk2=0
|
||||
else
|
||||
AC_MSG_ERROR(bad value for --with-gtk2 option)
|
||||
fi
|
||||
], use_gtk2=0 )
|
||||
])
|
||||
|
89
configure.in
Normal file
89
configure.in
Normal file
@@ -0,0 +1,89 @@
|
||||
# configure.in -- Process this file with autoconf to produce configure
|
||||
|
||||
dnl Initialization stuff.
|
||||
AC_INIT(emu8051, 0.1.0)
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CONFIG_SRCDIR(src/CPU8051.cpp)
|
||||
AM_CONFIG_HEADER(config.h:config-h.in)
|
||||
dnl Checking if the NEWS file has been updated to reflect the current version.
|
||||
AM_INIT_AUTOMAKE(check-news)
|
||||
|
||||
dnl Tests the C compiler
|
||||
AC_PROG_CC
|
||||
AC_LANG_C
|
||||
|
||||
dnl Checking for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(strings.h unistd.h)
|
||||
|
||||
dnl Checking for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
dnl Basic CFLAGS values
|
||||
CFLAGS="-Wall"
|
||||
|
||||
dnl Checks for '--enable-debug' option
|
||||
HV_CHECK_FOR_DEBUG
|
||||
|
||||
if test x"${debug_messages}" = x1; then
|
||||
dnl -g is for GDB debugging
|
||||
CFLAGS="${CFLAGS} -g -gdwarf-2 -g3"
|
||||
fi
|
||||
|
||||
dnl Checks for '--with-gtk2' option
|
||||
HV_CHECK_FOR_GTK2
|
||||
|
||||
if test x"${use_gtk2}" = x0; then
|
||||
dnl Checks for Gtk+-1.2.0
|
||||
AM_PATH_GTK(1.2.0, CFLAGS="${CFLAGS} ${GTK_CFLAGS}" LIBS="${LIBS} ${GTK_LIBS}",
|
||||
AC_MSG_ERROR(GTK+ not found!))dnl
|
||||
else
|
||||
dnl Checks for Gtk+-2.0
|
||||
PKG_CHECK_MODULES(GTK,gtk+-2.0 >= 2.0.5, CFLAGS="${CFLAGS} ${GTK_CFLAGS}" \
|
||||
LIBS="${LIBS} ${GTK_LIBS}",AC_MSG_ERROR(GTK+-2.0 not found!))dnl
|
||||
fi
|
||||
|
||||
dnl Tests the C++ compiler
|
||||
AC_PROG_CXX
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
CXXFLAGS="${CFLAGS}"
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(CXXFLAGS)
|
||||
AC_SUBST(LIBS)
|
||||
AC_SUBST(ac_aux_dir)
|
||||
|
||||
dnl Creating output file(s)
|
||||
AC_OUTPUT(Makefile src/Makefile doc/Makefile)
|
||||
|
||||
echo \
|
||||
"---------------------------------------------------------------------------
|
||||
Configuration:
|
||||
|
||||
Install path: ${prefix}
|
||||
Compiler: ${CC}
|
||||
Compiler flags: ${CFLAGS}
|
||||
Linker flags: ${LIBS}"
|
||||
|
||||
echo -n " GTK base version: "
|
||||
if test x"${use_gtk2}" = x1; then
|
||||
echo "2"
|
||||
else
|
||||
echo "1"
|
||||
fi
|
||||
|
||||
echo -n " Debugging messages: "
|
||||
if test x"${debug_messages}" = x1; then
|
||||
echo "yes"
|
||||
else
|
||||
echo "no"
|
||||
fi
|
||||
|
||||
echo \
|
||||
"
|
||||
See config.h for further configuration information.
|
||||
---------------------------------------------------------------------------"
|
9
doc/Makefile.am
Normal file
9
doc/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
## Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
man1_MANS = emu8051.man
|
||||
|
||||
EXTRA_DIST = $(man1_MANS)
|
||||
|
||||
CLEANFILES = *~
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
123
doc/emu8051.man
Normal file
123
doc/emu8051.man
Normal file
@@ -0,0 +1,123 @@
|
||||
.TH WMNOTIFY 1 "March 2003" "wmnotify" "User's Manual"
|
||||
|
||||
.SH NAME
|
||||
wmnotify \- Dockable E-mail notification program for single POP3 account
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B wmnotify
|
||||
[\fIOPTION\fR]...
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBwmnotify\fR is a dockable application (DockApp) for the WindowMaker window
|
||||
manager to periodically check a POP3 E-mail account for new messages. If there
|
||||
are new messages in the mailbox, a simple animation is started to notify the
|
||||
user. An optional beep or sound can also be produced if desired.
|
||||
|
||||
The interface is kept very simple. To immediately check for new messages,
|
||||
single-click on the mailbox image. To start your favorite email program,
|
||||
double-click on the mailbox image.
|
||||
|
||||
When you double-click on the mailbox image to start your email program,
|
||||
the new messages animation is stopped, assuming that you will read your new
|
||||
messages. If you don't, the wmnotify program will simply continue it's
|
||||
periodic checking of your email account and will restart the new messages
|
||||
animation after the usual delay if new messages are unread.
|
||||
|
||||
By default, the interval between checks is 1 minute, and this can be changed in
|
||||
the configuration file. You can also enable audio notification as well as
|
||||
specify an optional audio sound file (WAV or AU). If audio notification is
|
||||
enabled but no audio sound file is specified, a beep will be produced. There is
|
||||
an option in the configuration file to adjust the volume of the sound file.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.BI "\-\^c " config-file
|
||||
.B wmnotify
|
||||
reads your POP3 account settings and preferences from the specified
|
||||
configuration file. This option overrides the use of the default config file,
|
||||
.IR "$HOME/.wmnotifyrc".
|
||||
|
||||
.TP
|
||||
.BI \-display " host" : display
|
||||
Specifies the host and screen to be used by \fBwmnotify\fR. By default this
|
||||
is obtained from the environment variable
|
||||
.SB DISPLAY.
|
||||
|
||||
.TP
|
||||
.BI \-geometry " geometry"
|
||||
.RB ( *geometry )
|
||||
Specifies the initial geometry of the window.
|
||||
|
||||
.TP
|
||||
\fB\-h\fR
|
||||
display usage and exit
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
output version information and exit
|
||||
|
||||
.SH "CONFIGURATION FILE"
|
||||
.IR $HOME/.wmnotifyrc
|
||||
|
||||
The first time the program is run, it will check for the presence of the
|
||||
configuration file in the user's home directory. If this file is not found,
|
||||
wmnotify will automatically create a new one, and exit. Then the user must
|
||||
enter it's POP3 account settings and preferences in the configuration file
|
||||
before restarting wmnotify.
|
||||
|
||||
.TP
|
||||
.BI "server " <pop3-servername>
|
||||
POP3 server name.
|
||||
|
||||
.TP
|
||||
.BI "port " <pop3-portnumber>
|
||||
POP3 port number (optional, default value is 110).
|
||||
|
||||
.TP
|
||||
.BI "username " <pop3-username>
|
||||
POP3 username.
|
||||
|
||||
.TP
|
||||
.BI "password " <pop3-password>
|
||||
POP3 password.
|
||||
|
||||
.TP
|
||||
.BI "mailcheckdelay " <delay-in-minutes>
|
||||
Mail check interval, in minutes (optional, default value is 1).
|
||||
|
||||
.TP
|
||||
.BI "mailclient " <program>
|
||||
The program to start when double-clicking on the mailbox image (optional).
|
||||
|
||||
.TP
|
||||
.BI "enablebeep " <value>
|
||||
This option controls the audio notification enabling/disabling. If this option
|
||||
is enabled and the "audiofile" option below contains a valid audio file, it
|
||||
will be played whenever new message(s) are detected. If "audiofile" is
|
||||
commented, the console beep will be used to produce the audio notification. The
|
||||
value may be set to "0" to disable or to "1" to enable (optional, default value is 0, disabled).
|
||||
|
||||
.TP
|
||||
.BI "audiofile " <path-to-audiofile>
|
||||
Path and filename of the WAV or AU audio sound file to play when new message(s)
|
||||
are detected (optional).
|
||||
|
||||
.TP
|
||||
.BI "volume " <value>
|
||||
Volume value, in percent, when playing an audio file (optional, default value is
|
||||
100%). This volume value is relative to the values you have set in your sound
|
||||
card mixer settings. If you find the audio notification sound to be too loud,
|
||||
just reduce the volume value. On the other hand, if you want to increase the
|
||||
audio notification sound amplitude, just increase the volume. If you increase
|
||||
the volume value to 100% and you find that it is not sufficient, then you would
|
||||
have to increase the volume using your favorite sound card mixer program
|
||||
(ex: with alsamixer, increase the PCM or master value).
|
||||
|
||||
.SH CREDITS
|
||||
\fBwmnotify\fR was written by Hugo Villeneuve <hugovil@videotron.ca>, based on
|
||||
the WMPop3 program by Scott Holden <scotth@thezone.net>.
|
||||
|
||||
.SH COPYRIGHT
|
||||
\fBwmnotify\fR is free; anyone may redistribute it to anyone under the terms
|
||||
stated in the GNU General Public License. A copy of the license is included in
|
||||
the \fBwmnotify\fR distribution. You can also browse it online at
|
||||
.I http://www.gnu.org/copyleft/gpl.html
|
54
pixmaps/reset.xpm
Normal file
54
pixmaps/reset.xpm
Normal file
@@ -0,0 +1,54 @@
|
||||
/* XPM */
|
||||
static char * reset_xpm[] = {
|
||||
"48 48 3 1",
|
||||
" c None",
|
||||
". c #005A9C",
|
||||
"+ c #FFFFFF",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"..+++++++..++++++++..+++++++.++++++++.++++++++..",
|
||||
"..++++++++.++++++++.++++++++.++++++++.++++++++..",
|
||||
"..++....++.++.......++.......++..........++.....",
|
||||
"..++....++.++.......++.......++..........++.....",
|
||||
"..++....++.++.......++.......++..........++.....",
|
||||
"..++....++.+++++++..+++++++..+++++++.....++.....",
|
||||
"..+++++++..+++++++...+++++++.+++++++.....++.....",
|
||||
"..+++++++..++.............++.++..........++.....",
|
||||
"..++....++.++.............++.++..........++.....",
|
||||
"..++....++.++.............++.++..........++.....",
|
||||
"..++....++.++++++++.++++++++.++++++++....++.....",
|
||||
"..++....++.++++++++.+++++++..++++++++....++.....",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................",
|
||||
"................................................"};
|
55
pixmaps/run.xpm
Normal file
55
pixmaps/run.xpm
Normal file
@@ -0,0 +1,55 @@
|
||||
/* XPM */
|
||||
static char * run_xpm[] = {
|
||||
"48 48 4 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #008C6B",
|
||||
"@ c #FFFFFF",
|
||||
" ........... ",
|
||||
" ................... ",
|
||||
" ........+++++++........ ",
|
||||
" ......+++++++++++++++...... ",
|
||||
" .....+++++++++++++++++++..... ",
|
||||
" .....+++++++++++++++++++++++..... ",
|
||||
" .....+++++++++++++++++++++++++..... ",
|
||||
" ....+++++++++++++++++++++++++++++.... ",
|
||||
" ...+++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++... ",
|
||||
" ....+++++++++++++++++++++++++++++++++.... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++++... ",
|
||||
" ..+++++++++++++++++++++++++++++++++++++++++.. ",
|
||||
" ..++++++++@@@@@@@++@@++++@@+@@++++@@+++++++.. ",
|
||||
"...++++++++@@@@@@@@+@@++++@@+@@@+++@@+++++++... ",
|
||||
"...++++++++@@++++@@+@@++++@@+@@@+++@@+++++++... ",
|
||||
"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
|
||||
"..+++++++++@@++++@@+@@++++@@+@@@@++@@++++++++.. ",
|
||||
"..+++++++++@@++++@@+@@++++@@+@@+@@+@@++++++++.. ",
|
||||
"..+++++++++@@@@@@@++@@++++@@+@@+@@+@@++++++++.. ",
|
||||
"..+++++++++@@@@@@@++@@++++@@+@@++@@@@++++++++.. ",
|
||||
"..+++++++++@@++++@@+@@++++@@+@@++@@@@++++++++.. ",
|
||||
"..+++++++++@@++++@@+@@++++@@+@@+++@@@++++++++.. ",
|
||||
"...++++++++@@++++@@+@@@@@@@@+@@+++@@@+++++++... ",
|
||||
"...++++++++@@++++@@++@@@@@@++@@++++@@+++++++... ",
|
||||
" ..+++++++++++++++++++++++++++++++++++++++++.. ",
|
||||
" ..+++++++++++++++++++++++++++++++++++++++++.. ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++++++... ",
|
||||
" ....+++++++++++++++++++++++++++++++++.... ",
|
||||
" ...+++++++++++++++++++++++++++++++++... ",
|
||||
" ...+++++++++++++++++++++++++++++++... ",
|
||||
" ....+++++++++++++++++++++++++++++.... ",
|
||||
" .....+++++++++++++++++++++++++..... ",
|
||||
" .....+++++++++++++++++++++++..... ",
|
||||
" .....+++++++++++++++++++..... ",
|
||||
" ......+++++++++++++++...... ",
|
||||
" ........+++++++........ ",
|
||||
" ................... ",
|
||||
" ........... ",
|
||||
" "};
|
56
pixmaps/step.xpm
Normal file
56
pixmaps/step.xpm
Normal file
@@ -0,0 +1,56 @@
|
||||
/* XPM */
|
||||
static char * step_xpm[] = {
|
||||
"48 48 5 1",
|
||||
" c None",
|
||||
". c #FFDE08",
|
||||
"+ c #000000",
|
||||
"@ c #FFFFFF",
|
||||
"# c #080800",
|
||||
"..........++++++++++++............++++++++++++..",
|
||||
"...........++++++++++++............++++++++++++.",
|
||||
"............++++++++++++............++++++++++++",
|
||||
"+............++++++++++++............+++++++++++",
|
||||
"++............++++++++++++............++++++++++",
|
||||
"+++............++++++++++++............+++++++++",
|
||||
"++++............++++++++++++............++++++++",
|
||||
"+++++............++++++++++++............+++++++",
|
||||
"++++++............++++++++++++............++++++",
|
||||
"+++++++............++++++++++++............+++++",
|
||||
"++++++++............++++++++++++............++++",
|
||||
"+++++++++............++++++++++++............+++",
|
||||
"++++++++++............++++++++++++............++",
|
||||
"+++++++++++............++++++++++++............+",
|
||||
"++++++++++++............++++++++++++............",
|
||||
".++++++++++++++++++++++++++++++++++++++++++++...",
|
||||
"..+++++++++++++++++++++++++++++++++++++++++++...",
|
||||
"...++++++++++++++++++++++++++++++++++++++++++...",
|
||||
"....++++@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@++++...",
|
||||
"....+++@@@@@@@@+@@@@@@@@+@@@@@@@@+@@@@@@@@+++...",
|
||||
"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
|
||||
"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
|
||||
"....+++@@++++++++++@@++++@@+++++++@@++++@@+++...",
|
||||
"....+++@@@@@@@+++++@@++++@@@@@@@++@@++++@@+++...",
|
||||
"....++++@@@@@@@++++@@++++@@@@@@@++@@@@@@@@++++..",
|
||||
"....+++++++++@@++++@@++++@@+++++++@@@@@@@++++++.",
|
||||
"....+++++++++@@++++@@++++@@+++++++@@++++++++++++",
|
||||
"+...+++++++++@@++++@@++++@@+++++++@@++++++++++++",
|
||||
"++..+++@@@@@@@@++++@@++++@@@@@@@@+@@++++++++++++",
|
||||
"+++.+++@@@@@@@+++++@@++++@@@@@@@@+@@++++++++++++",
|
||||
"++++++++++++++++++++++++++++++++++++++++++++++++",
|
||||
"++++++++++++++++++++++++++++++++++++++++++++++++",
|
||||
"++++++++++++++++++++++++++++++++++++++++++++++++",
|
||||
"+++++++............++++++++++++............+++++",
|
||||
"++++++++............++++++++++++............++++",
|
||||
"+++++++++............+#++++++++++............+++",
|
||||
"++++++++++............++++++++++++............++",
|
||||
"#++++++++++............++++++++++++............+",
|
||||
"++++++++++++............++++++++++++............",
|
||||
".+#++++++++++............+#++++++++++...........",
|
||||
"..++++++++++++............+#++++++++++..........",
|
||||
"...++++++++++++............++++++++++++.........",
|
||||
"....++++++++++++............++++++++++++........",
|
||||
".....+#++++++++++............+#++++++++++.......",
|
||||
"......++++++++++++............++++++++++++......",
|
||||
".......++++++++++++............++++++++++++.....",
|
||||
"........+#++++++++++............++++++++++++....",
|
||||
".........++++++++++++............+#++++++++++..."};
|
55
pixmaps/stop.xpm
Normal file
55
pixmaps/stop.xpm
Normal file
@@ -0,0 +1,55 @@
|
||||
/* XPM */
|
||||
static char * stop_xpm[] = {
|
||||
"48 48 4 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #C60021",
|
||||
"@ c #FFFFFF",
|
||||
" .................... ",
|
||||
" .++++++++++++++++++++. ",
|
||||
" .++@@@@@@@@@@@@@@@@@@++. ",
|
||||
" .++@@++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
|
||||
".++@@++++++++++++++++++++++++++++++++++++++@@++.",
|
||||
".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
|
||||
".+@++++++++++++++++++++++++++++++++++++++++++@+.",
|
||||
".+@++++++++++++++++++++++++++++++++++++++++++@+.",
|
||||
".+@+++++@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@++++@+.",
|
||||
".+@++++@@@@@@@@+@@@@@@@@++@@@@@@++@@@@@@@@+++@+.",
|
||||
".+@++++@@++++++++++@@++++@@@++@@@+@@++++@@+++@+.",
|
||||
".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
|
||||
".+@++++@@++++++++++@@++++@@++++@@+@@++++@@+++@+.",
|
||||
".+@++++@@@@@@@+++++@@++++@@++++@@+@@++++@@+++@+.",
|
||||
".+@+++++@@@@@@@++++@@++++@@++++@@+@@@@@@@@+++@+.",
|
||||
".+@++++++++++@@++++@@++++@@++++@@+@@@@@@@++++@+.",
|
||||
".+@++++++++++@@++++@@++++@@++++@@+@@+++++++++@+.",
|
||||
".+@++++++++++@@++++@@++++@@@++@@@+@@+++++++++@+.",
|
||||
".+@++++@@@@@@@@++++@@+++++@@@@@@++@@+++++++++@+.",
|
||||
".+@++++@@@@@@@+++++@@+++++@@@@@@++@@+++++++++@+.",
|
||||
".+@++++++++++++++++++++++++++++++++++++++++++@+.",
|
||||
".+@++++++++++++++++++++++++++++++++++++++++++@+.",
|
||||
".+@@++++++++++++++++++++++++++++++++++++++++@@+.",
|
||||
".++@@++++++++++++++++++++++++++++++++++++++@@++.",
|
||||
" .++@@++++++++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++++@@++. ",
|
||||
" .++@@++++++++++++++++@@++. ",
|
||||
" .++@@@@@@@@@@@@@@@@@@@+. ",
|
||||
" .++++++++++++++++++++. ",
|
||||
" .................... "};
|
644
src/CPU8051.cpp
Normal file
644
src/CPU8051.cpp
Normal file
@@ -0,0 +1,644 @@
|
||||
// CPU8051.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include "CPU8051.hpp"
|
||||
#include "disasm.hpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CPU8051::CPU8051( )
|
||||
// CPU8051 constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
CPU8051::CPU8051( )
|
||||
{
|
||||
InitFuncPtr( );
|
||||
// Cree les objets Memory
|
||||
SFRMem = new Memory( 128 );
|
||||
PGMMem = new Memory( 65536 );
|
||||
IntMem = new Memory( 128 );
|
||||
ExtMem = new Memory( 65536 );
|
||||
PC = 0; CLOCK = 0; ActivePriority = -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CPU8051::~CPU8051( )
|
||||
// CPU8051 destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
CPU8051::~CPU8051( )
|
||||
{
|
||||
// Detruit les objets Memory
|
||||
delete SFRMem;
|
||||
delete PGMMem;
|
||||
delete IntMem;
|
||||
delete ExtMem;
|
||||
|
||||
SFRMem = 0;
|
||||
PGMMem = 0;
|
||||
IntMem = 0;
|
||||
ExtMem = 0;
|
||||
PC = 0;
|
||||
CLOCK = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::Exec( )
|
||||
// Execute at address PC from PGMMem
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::Exec( )
|
||||
{
|
||||
int i;
|
||||
unsigned char opcode = PGMMem->Read8( PC++ );
|
||||
int insttiming = ( this->*funcptr[ opcode ] )();
|
||||
|
||||
for ( i = 0; i < insttiming; i++)
|
||||
{
|
||||
CheckInterrupts();
|
||||
DoTimers();
|
||||
CLOCK++;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned int CPU8051::GetNextAddress( )
|
||||
// Return PC + size in bytes of current instruction
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int CPU8051::GetNextAddress( )
|
||||
{
|
||||
return ( PC + InstSizesTbl[ PGMMem->Read8( PC ) ] );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::Reset( )
|
||||
// Reset the registers and CPU state
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::Reset( )
|
||||
{
|
||||
PC = 0; CLOCK = 0; ActivePriority = -1;
|
||||
// Reinitialisation des registres
|
||||
int i;
|
||||
for ( i = 0; i < 128; i++ )
|
||||
{
|
||||
SFRMem->Write8( i, 0 );
|
||||
IntMem->Write8( i, 0 );
|
||||
}
|
||||
SFRMem->Write8( _P0_ - 0x80, 0xFF );
|
||||
SFRMem->Write8( _P1_ - 0x80, 0xFF );
|
||||
SFRMem->Write8( _P2_ - 0x80, 0xFF );
|
||||
SFRMem->Write8( _P3_ - 0x80, 0xFF );
|
||||
SFRMem->Write8( _SP_ - 0x80, 0x07 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned int CPU8051::GetPC( )
|
||||
// Return the value of PC register
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int CPU8051::GetPC( )
|
||||
{
|
||||
return PC;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::SetPC( unsigned int NewPC )
|
||||
// Set the new value of PC register
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::SetPC( unsigned int NewPC )
|
||||
{
|
||||
PC = NewPC;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WriteD( unsigned int Address, unsigned char Value )
|
||||
// Write with a direct addressing mode at Address the new Value
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WriteD( unsigned int Address, unsigned char Value )
|
||||
{
|
||||
if ( Address > 0x7F ) { SFRMem->Write8( Address - 0x80, Value ); return; }
|
||||
IntMem->Write8( Address, Value );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WriteExt( unsigned int Address, unsigned char Value )
|
||||
// Ecriture d'une valeur dans la memoire externe ( Address = $00 a $FFFF )
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WriteExt( unsigned int Address, unsigned char Value )
|
||||
{
|
||||
ExtMem->Write8( Address, Value );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WriteInt( unsigned int Address, unsigned char Value )
|
||||
// Ecriture d'une valeur dans la memoire interne ( Address = $00 a $FF )
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WriteInt( unsigned int Address, unsigned char Value )
|
||||
{
|
||||
if ( Address > 0x7F )
|
||||
SFRMem->Write8( Address - 0x80, Value );
|
||||
else
|
||||
IntMem->Write8( Address, Value );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WriteI( unsigned int Address, unsigned char Value )
|
||||
// Write with an indirect addressing mode at Address the new Value
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WriteI( unsigned int Address, unsigned char Value )
|
||||
{
|
||||
if ( Address > 0x7F ) { ExtMem->Write8( Address, Value ); return; }
|
||||
IntMem->Write8( Address, Value );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WritePGM( unsigned int Address, unsigned char Value )
|
||||
// Write at Address the new Value in PGMMem
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WritePGM( unsigned int Address, unsigned char Value )
|
||||
{
|
||||
PGMMem->Write8( Address, Value );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadD( unsigned int Address )
|
||||
// Read with a direct addressing mode at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadD( unsigned int Address )
|
||||
{
|
||||
if ( Address > 0xFF ) return ExtMem->Read8( Address );
|
||||
if ( Address > 0x7F ) return SFRMem->Read8( Address - 0x80 );
|
||||
return IntMem->Read8( Address );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadInt( unsigned int Address )
|
||||
// Read Internal data memory at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadInt( unsigned int Address )
|
||||
{
|
||||
if ( Address > 0x7F )
|
||||
return SFRMem->Read8( Address - 0x80 );
|
||||
return IntMem->Read8( Address );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadExt( unsigned int Address )
|
||||
// Lecture du contenu de la memoire externe
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadExt( unsigned int Address )
|
||||
{
|
||||
return ExtMem->Read8( Address );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadI( unsigned int Address )
|
||||
// Read with a indirect addressing mode at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadI( unsigned int Address )
|
||||
{
|
||||
if ( Address > 0x7F ) return ExtMem->Read8( Address );
|
||||
return IntMem->Read8( Address );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadPGM( unsigned int Address )
|
||||
// Read at Address from PGMMem
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadPGM( unsigned int Address )
|
||||
{
|
||||
return PGMMem->Read8( Address );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::WriteB( unsigned int BitAddress, unsigned char Value )
|
||||
// Write with a bit addressing mode at BitAddress the new Value
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::WriteB( unsigned int BitAddress, unsigned char Value )
|
||||
{
|
||||
unsigned int ByteAddress, BitNumber;
|
||||
unsigned char ByteValue, ByteMask;
|
||||
if ( BitAddress > 0x7F ) {
|
||||
// SFR 80-FF
|
||||
ByteAddress = BitAddress & 0xF8;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
else {
|
||||
// 20-2F
|
||||
ByteAddress = ( BitAddress >> 3 ) + 0x20;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
ByteMask = ( ( 1 << BitNumber ) ^ 0xFF );
|
||||
ByteValue = ReadD( ByteAddress ) & ByteMask;
|
||||
ByteValue += Value << BitNumber;
|
||||
WriteD( ByteAddress, ByteValue );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char CPU8051::ReadB( unsigned int BitAddress )
|
||||
// Read with a bit addressing mode at BitAddress
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char CPU8051::ReadB( unsigned int BitAddress )
|
||||
{
|
||||
unsigned int ByteAddress, BitNumber;
|
||||
unsigned char BitValue;
|
||||
if ( BitAddress > 0x7F ) {
|
||||
// SFR 80-FF
|
||||
ByteAddress = BitAddress & 0xF8;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
else {
|
||||
// 20-2F
|
||||
ByteAddress = ( BitAddress >> 3 ) + 0x20;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
BitValue = ( ReadD( ByteAddress ) >> BitNumber );
|
||||
BitValue &= 1;
|
||||
return BitValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::CheckInterrupts()
|
||||
// Check interrupts state and process them as needed
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::CheckInterrupts()
|
||||
{
|
||||
unsigned char SP;
|
||||
|
||||
if ( ReadD( _IE_ ) & 0x80 ) {
|
||||
for ( int i = 1; i >= 0; i-- )
|
||||
if ( ActivePriority < i ) {
|
||||
//------------------------- External interrupt 0 ----------------------------
|
||||
// if ( ( ReadD( _IE_ ) & 0x01 ) && ( ( ReadD( _IP_ ) & 0x01 ) ? i : !i ) && pin0 )
|
||||
//-------------------------- Interrupt timer 0 -------------------------------
|
||||
if ( ( ReadD( _IE_ ) & 0x02 ) && ( ( ReadD( _IP_ & 0x02 ) ? i : !i ) && ( ReadD( _TCON_ ) & 0x20 ) ) ){
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) & 0xDF );
|
||||
SP = ReadD( _SP_ );
|
||||
WriteI( ++SP, ( PC & 0xFF ) );
|
||||
WriteI( ++SP, ( PC >> 8 ) );
|
||||
WriteD( _SP_, SP );
|
||||
PC = 0x0B;
|
||||
ActivePriority = i;
|
||||
return;
|
||||
}
|
||||
//-------------------------- External interrupt 1 ----------------------------
|
||||
// if ( ( ReadD( _IE_ ) & 0x04 ) && ( ( ReadD( _IP_ ) & 0x04 ) ? i : !i ) && pin1 )
|
||||
//-------------------------- Interrupt timer 1 -------------------------------
|
||||
if ( ( ReadD( _IE_ ) & 0x08 ) && ( ( ReadD( _IP_ ) & 0x08 ) ? i : !i ) && ( ReadD( _TCON_ ) & 0x80 ) ) {
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) & 0x7F );
|
||||
SP = ReadD( _SP_ );
|
||||
WriteI( ++SP, ( PC & 0xFF ) );
|
||||
WriteI( ++SP, ( PC >> 8 ) );
|
||||
WriteD( _SP_, SP );
|
||||
PC = 0x1B;
|
||||
ActivePriority = i;
|
||||
return;
|
||||
}
|
||||
//-------------------------- Serial Interrupts -------------------------------
|
||||
if ( ( ReadD( _IE_ ) & 0x10 ) && ( ( ReadD( _IP_ ) & 0x10 ) ? i : !i ) && ( ReadD( _SCON_ ) & 0x03 ) ) {
|
||||
SP = ReadD( _SP_ );
|
||||
WriteI( ++SP, ( PC & 0xFF ) );
|
||||
WriteI( ++SP, ( PC >> 8 ) );
|
||||
WriteD( _SP_, SP );
|
||||
PC = 0x23;
|
||||
ActivePriority = i;
|
||||
return;
|
||||
}
|
||||
//-------------------------- Interrupt timer 2 -------------------------------
|
||||
if ( ( ReadD( _IE_ ) & 0x20 ) && ( ( ReadD( _IP_ ) & 0x20 ) ? i : !i ) && ( ReadD( _T2CON_ ) & 0x80 ) ) {
|
||||
SP = ReadD( _SP_ );
|
||||
WriteI( ++SP, ( PC & 0xFF ) );
|
||||
WriteI( ++SP, ( PC >> 8 ) );
|
||||
WriteD( _SP_, SP );
|
||||
PC = 0x2B;
|
||||
ActivePriority = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::DoTimers( )
|
||||
// Execute les timers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::DoTimers( )
|
||||
{
|
||||
unsigned int tmp;
|
||||
unsigned int TR;
|
||||
unsigned int MODE;
|
||||
unsigned int GATE;
|
||||
unsigned int TimerCounter;
|
||||
|
||||
// ----- Timer 0
|
||||
TR = ReadD( _TCON_ ) & 0x10;
|
||||
MODE = ReadD( _TMOD_ ) & 0x03;
|
||||
GATE = ReadD( _TMOD_ ) & 0x08;
|
||||
TimerCounter = ReadD( _TMOD_ ) & 0x04;
|
||||
|
||||
if ( ( TR && !GATE && !TimerCounter ) || ( MODE == 3 ) )
|
||||
switch( MODE ) {
|
||||
// Mode 0, compteur de 13 bits.
|
||||
case 0 :
|
||||
tmp = ReadD( _TH0_ ) * 0x100 + ReadD( _TL0_ );
|
||||
++tmp &= 0x1FFF; // On ne garde que 13 bits.
|
||||
if ( tmp == 0 ) // If overflow set TF0
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
|
||||
WriteD( _TH0_, tmp / 0x100 );
|
||||
WriteD( _TL0_, tmp & 0xFF );
|
||||
break;
|
||||
|
||||
// Mode 1, compteur de 16 bits.
|
||||
case 1 :
|
||||
tmp = ReadD( _TH0_ ) * 0x100 + ReadD( _TL0_ );
|
||||
++tmp &= 0xFFFF; // On ne garde que 16 bits.
|
||||
if ( tmp == 0 ) // If overflow set TF0
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
|
||||
WriteD( _TH0_, ( tmp / 0x100 ) );
|
||||
WriteD( _TL0_, ( tmp & 0xFF ) );
|
||||
break;
|
||||
|
||||
// Mode 2, Compteur de 8 bits avec Auto-Reload
|
||||
case 2 :
|
||||
tmp = ReadD( _TL0_ );
|
||||
++tmp &= 0xFF;
|
||||
if ( tmp == 0 ) { // If overflow -> reload et set TF0
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
|
||||
WriteD( _TL0_, ReadD( _TH0_ ) );
|
||||
}
|
||||
else
|
||||
WriteD( _TL0_, tmp );
|
||||
break;
|
||||
|
||||
// Mode 3 : TL0 et TH0 sont 2 Timers independants de 8 bits chacuns.
|
||||
case 3 :
|
||||
if ( TR && !GATE && !TimerCounter ) {
|
||||
tmp = ReadD( _TL0_ );
|
||||
++tmp &= 0xFF;
|
||||
if ( tmp == 0 ) // If TL0 overflow set TF0
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x20 );
|
||||
WriteD( _TL0_, tmp );
|
||||
} // TH0 utilise TR1 et TF1.
|
||||
TR = ReadD( _TCON_ ) & 0x40;
|
||||
if ( TR ) {
|
||||
tmp = ReadD( _TH0_ );
|
||||
++tmp &= 0xFF;
|
||||
if ( tmp == 0 ) // If TH0 overflow set TF1
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 ); // TF1 = 1.
|
||||
WriteD( _TH0_, tmp );
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
// ----- Timer 1
|
||||
TR = ReadD( _TCON_ ) & 0x40;
|
||||
MODE = ( ReadD( _TMOD_ ) & 0x30 ) >> 4 ;
|
||||
GATE = ReadD( _TMOD_ ) & 0x80;
|
||||
TimerCounter = ReadD( _TMOD_ ) & 0x40;
|
||||
|
||||
if ( TR && !GATE && !TimerCounter )
|
||||
switch( MODE ) {
|
||||
// Mode 0, compteur de 13 bits.
|
||||
case 0 :
|
||||
tmp = ReadD( _TH1_ ) * 0x100 + ReadD( _TL1_ );
|
||||
++tmp &= 0x1FFF; // On ne garde que 13 bits.
|
||||
if ( tmp == 0 ) // If overflow set TF1
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
|
||||
WriteD( _TH1_, tmp / 0x100 );
|
||||
WriteD( _TL1_, tmp & 0xFF );
|
||||
break;
|
||||
|
||||
// Mode 1, compteur de 16 bits.
|
||||
case 1 :
|
||||
tmp = ReadD( _TH1_ ) * 0x100 + ReadD( _TL1_ );
|
||||
++tmp &= 0xFFFF; // On ne garde que 16 bits.
|
||||
if ( tmp == 0 ) // If overflow set TF1
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
|
||||
WriteD( _TH1_, ( tmp / 0x100 ) );
|
||||
WriteD( _TL1_, ( tmp & 0xFF ) );
|
||||
break;
|
||||
|
||||
// Mode 2, Compteur de 8 bits avec Auto-Reload
|
||||
case 2 :
|
||||
tmp = ReadD( _TL1_ );
|
||||
++tmp &= 0xFF;
|
||||
if ( tmp == 0 ) { // If overflow -> reload et set TF1
|
||||
WriteD( _TCON_, ReadD( _TCON_ ) | 0x80 );
|
||||
WriteD( _TL1_, ReadD( _TH1_ ) );
|
||||
}
|
||||
else
|
||||
WriteD( _TL1_, tmp );
|
||||
break;
|
||||
|
||||
// Mode 3 : mode inactif: retient la valeur de TH1 et TL1.
|
||||
// Equivalent a TR1 = 0.
|
||||
case 3 :
|
||||
break;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Addressing modes defined in the order as they appear in disasm.hpp
|
||||
// from table argstext[]
|
||||
#define ADDR11 0
|
||||
#define ADDR16 1
|
||||
#define DIRECT 3
|
||||
#define BITADDR 14
|
||||
#define RELADDR 15
|
||||
#define DATAIMM 16
|
||||
#define DATA16 22
|
||||
#define CBITADDR 23
|
||||
|
||||
// SFR Memory map [80h - FFh]
|
||||
// ---------------------------------------------------------------
|
||||
// F8 | | | | | | | | | FF
|
||||
// F0 | B | | | | | | | | F7
|
||||
// E8 | | | | | | | | | EF
|
||||
// E0 | ACC | | | | | | | | E7
|
||||
// D8 | | | | | | | | | DF
|
||||
// D0 | PSW | | | | | | | | D7
|
||||
// C8 | T2CON| |RCAP2L|RCAP2H| TL2 | TH2 | | | CF
|
||||
// C0 | | | | | | | | | C7
|
||||
// B8 | IP | | | | | | | | BF
|
||||
// B0 | P3 | | | | | | | | B7
|
||||
// A8 | IE | | | | | | | | AF
|
||||
// A0 | P2 | | | | | | | | A7
|
||||
// 98 | SCON | SBUF | | | | | | | 9F
|
||||
// 90 | P1 | | | | | | | | 97
|
||||
// 88 | TCON | TMOD | TL0 | TL1 | TH0 | TH1 | | | 8F
|
||||
// 80 | P0 | SP | DPL | DPH | | | | PCON | 87
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// int CPU8051::SFRMemInfo( unsigned int Address, char *Text )
|
||||
// Return as Text the name of the SFR register at Address if any
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int CPU8051::SFRMemInfo( unsigned int Address, char *Text )
|
||||
{
|
||||
switch( Address ) {
|
||||
case 0x80 : return sprintf( Text, "P0" );
|
||||
case 0x81 : return sprintf( Text, "SP" );
|
||||
case 0x82 : return sprintf( Text, "DPL" );
|
||||
case 0x83 : return sprintf( Text, "DPH" );
|
||||
case 0x87 : return sprintf( Text, "PCON" );
|
||||
case 0x88 : return sprintf( Text, "TCON" );
|
||||
case 0x89 : return sprintf( Text, "TMOD" );
|
||||
case 0x8A : return sprintf( Text, "TL0" );
|
||||
case 0x8B : return sprintf( Text, "TL1" );
|
||||
case 0x8C : return sprintf( Text, "TH0" );
|
||||
case 0x8D : return sprintf( Text, "TH1" );
|
||||
case 0x90 : return sprintf( Text, "P1" );
|
||||
case 0x98 : return sprintf( Text, "SCON" );
|
||||
case 0x99 : return sprintf( Text, "SBUF" );
|
||||
case 0xA0 : return sprintf( Text, "P2" );
|
||||
case 0xA8 : return sprintf( Text, "IE" );
|
||||
case 0xB0 : return sprintf( Text, "P3" );
|
||||
case 0xB8 : return sprintf( Text, "IP" );
|
||||
case 0xC8 : return sprintf( Text, "T2CON" );
|
||||
case 0xCA : return sprintf( Text, "RCAP2L" );
|
||||
case 0xCB : return sprintf( Text, "RCAP2H" );
|
||||
case 0xCC : return sprintf( Text, "TL2" );
|
||||
case 0xCD : return sprintf( Text, "TH2" );
|
||||
case 0xD0 : return sprintf( Text, "PSW" );
|
||||
case 0xE0 : return sprintf( Text, "ACC" );
|
||||
case 0xF0 : return sprintf( Text, "B" );
|
||||
default : return sprintf( Text, "%.2XH", Address );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )
|
||||
// Return as Text the decoded BitAddress
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void CPU8051::IntMemBitInfo( unsigned int BitAddress, char *Text )
|
||||
{
|
||||
unsigned int ByteAddress, BitNumber;
|
||||
int TextLength;
|
||||
if ( BitAddress > 0x7F ) {
|
||||
// SFR 80-FF
|
||||
ByteAddress = BitAddress & 0xF8;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
else {
|
||||
// 20-2F
|
||||
ByteAddress = ( BitAddress >> 3 ) + 0x20;
|
||||
BitNumber = BitAddress & 0x07;
|
||||
}
|
||||
|
||||
TextLength = SFRMemInfo( ByteAddress, Text );
|
||||
// sprintf( &Text[ TextLength ], ".%X" );
|
||||
// Modified by Hugo Villeneuve to remove compilation warning
|
||||
sprintf( &Text[ TextLength ], ".%X", BitAddress );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// int CPU8051::Disasm( unsigned int Address, char *Text )
|
||||
// Disasm one instruction at Address into a Text string
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int CPU8051::Disasm( unsigned int Address, char *Text )
|
||||
{
|
||||
int TextLength=0;
|
||||
char TextTmp[20];
|
||||
unsigned char OpCode;
|
||||
int ArgTblOfs;
|
||||
int InstSize;
|
||||
int i;
|
||||
|
||||
OpCode = PGMMem->Read8( Address );
|
||||
InstSize = InstSizesTbl[ OpCode ];
|
||||
//printf("%.4X\n", Address);
|
||||
|
||||
TextLength += sprintf( Text, " %.4X ", Address );
|
||||
|
||||
for (i = 0; i < InstSize; i++ )
|
||||
TextLength += sprintf( &Text[TextLength], " %.2X", PGMMem->Read8( Address + i ) );
|
||||
|
||||
Address++;
|
||||
|
||||
for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " );
|
||||
|
||||
TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] );
|
||||
ArgTblOfs = OpCode << 2;
|
||||
|
||||
for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " );
|
||||
|
||||
// MOV direct, direct (OpCode 85h) is peculiar, the operands are inverted
|
||||
if ( OpCode == 0x85 ) {
|
||||
SFRMemInfo( PGMMem->Read8( Address + 1 ), TextTmp );
|
||||
TextLength += sprintf( &Text[ TextLength ], "%s,", TextTmp );
|
||||
SFRMemInfo( PGMMem->Read8( Address ), TextTmp );
|
||||
TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp );
|
||||
Address += 2;
|
||||
return InstSize;
|
||||
}
|
||||
|
||||
for ( i = 1; i <= InstArgTbl[ ArgTblOfs ]; i++ ) {
|
||||
switch( InstArgTbl[ ArgTblOfs + i ] ) {
|
||||
case ADDR11 : {
|
||||
TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( OpCode << 3) & 0xF00 ) + ( PGMMem->Read8( Address ) ) );
|
||||
Address++;
|
||||
break;
|
||||
}
|
||||
case ADDR16 : {
|
||||
TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( PGMMem->Read8( Address ) << 8 ) + PGMMem->Read8( Address + 1 ) ) );
|
||||
Address += 2;
|
||||
break;
|
||||
}
|
||||
case DIRECT : {
|
||||
SFRMemInfo( PGMMem->Read8( Address ), TextTmp );
|
||||
TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp );
|
||||
Address++;
|
||||
break;
|
||||
}
|
||||
case BITADDR : {
|
||||
IntMemBitInfo( ( PGMMem->Read8( Address ) & 0xF8 ), TextTmp );
|
||||
TextLength += sprintf( &Text[ TextLength ], "%s.%X" , TextTmp, ( PGMMem->Read8( Address ) & 7 ) );
|
||||
Address++;
|
||||
break;
|
||||
}
|
||||
case RELADDR : {
|
||||
Address++;
|
||||
TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( Address & 0xFF00 ) + ( ( ( Address & 0xFF ) + PGMMem->Read8( Address - 1 ) ) & 0xFF ) );
|
||||
break;
|
||||
}
|
||||
case DATAIMM : {
|
||||
TextLength += sprintf( &Text[ TextLength ], "#%.2XH", PGMMem->Read8( Address ) );
|
||||
Address++;
|
||||
break;
|
||||
}
|
||||
case DATA16 : {
|
||||
TextLength += sprintf( &Text[ TextLength ],"#%.4XH", ( ( PGMMem->Read8( Address ) << 8 ) + PGMMem->Read8( Address+1 ) ) );
|
||||
Address += 2;
|
||||
break;
|
||||
}
|
||||
case CBITADDR : {
|
||||
IntMemBitInfo( ( PGMMem->Read8( Address ) & 0xF8 ), TextTmp );
|
||||
TextLength += sprintf( &Text[ TextLength ], "/%s.%X", TextTmp, ( PGMMem->Read8( Address ) & 7 ) );
|
||||
Address++;
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] );
|
||||
}
|
||||
}
|
||||
if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); }
|
||||
}
|
||||
|
||||
return InstSize;
|
||||
}
|
||||
|
||||
|
||||
#include "Inst_Imp.cpp"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
62
src/CPU8051.hpp
Normal file
62
src/CPU8051.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef _CPU8051_HPP_
|
||||
#define _CPU8051_HPP_
|
||||
|
||||
#include "Memory.hpp"
|
||||
#include "Reg8051.hpp"
|
||||
|
||||
#define BANKPSW ( ReadD( _PSW_ ) & 0x18 )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CPU8051
|
||||
// Implements the 8051 CPU Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class CPU8051 {
|
||||
public:
|
||||
CPU8051( );
|
||||
~CPU8051( );
|
||||
|
||||
void Exec( );
|
||||
void Reset( );
|
||||
unsigned int GetPC( );
|
||||
void SetPC( unsigned int NewPC );
|
||||
void WriteD( unsigned int Address, unsigned char Value );
|
||||
void WriteExt( unsigned int Address, unsigned char Value );
|
||||
void WriteInt( unsigned int Address, unsigned char Value );
|
||||
void WriteI( unsigned int Address, unsigned char Value );
|
||||
void WritePGM( unsigned int Address, unsigned char Value );
|
||||
unsigned char ReadD( unsigned int Address );
|
||||
unsigned char ReadInt( unsigned int Address );
|
||||
unsigned char ReadExt( unsigned int Address );
|
||||
unsigned char ReadI( unsigned int Address );
|
||||
unsigned char ReadPGM( unsigned int Address );
|
||||
unsigned int GetNextAddress( );
|
||||
|
||||
void WriteB( unsigned int BitAddress, unsigned char Value );
|
||||
unsigned char ReadB( unsigned int BitAddress );
|
||||
|
||||
void CheckInterrupts( );
|
||||
void DoTimers( );
|
||||
|
||||
int SFRMemInfo( unsigned int Address, char *Text );
|
||||
void IntMemBitInfo( unsigned int BitAddress, char *Text );
|
||||
int Disasm( unsigned int Address, char *Text );
|
||||
|
||||
private:
|
||||
Memory *SFRMem;
|
||||
Memory *PGMMem;
|
||||
Memory *IntMem;
|
||||
Memory *ExtMem;
|
||||
unsigned int PC;
|
||||
unsigned long CLOCK;
|
||||
int ActivePriority;
|
||||
int (CPU8051::*funcptr[256])();
|
||||
|
||||
#include "Inst_Def.hpp"
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
737
src/EmuConsole.cpp
Normal file
737
src/EmuConsole.cpp
Normal file
@@ -0,0 +1,737 @@
|
||||
// EmuConsole.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "config.h"
|
||||
#include "EmuConsole.hpp"
|
||||
#include "CPU8051.hpp"
|
||||
#include "Reg8051.hpp"
|
||||
#include "Keyboard.hpp"
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
CPU8051 *maincpu = new CPU8051;
|
||||
|
||||
EmuConsole *emuUI = new EmuConsole( argc, argv, maincpu );
|
||||
|
||||
emuUI->Main();
|
||||
printf( "End of program.\n" );
|
||||
|
||||
delete emuUI;
|
||||
delete maincpu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
|
||||
// EmuConsole constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
|
||||
{
|
||||
CPU = mCPU;
|
||||
CPU->Reset( );
|
||||
NbBreakpoints = 0;
|
||||
if ( argc > 1 ) LoadHexFile( argv[ 1 ] );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuConsole::~EmuConsole( )
|
||||
// EmuConsole destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
EmuConsole::~EmuConsole( )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Main( )
|
||||
// EmuConsole main loop
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Main( )
|
||||
{
|
||||
/*int ASCII_Code;*/
|
||||
unsigned int Index;
|
||||
|
||||
string InputString;
|
||||
string Command;
|
||||
string Parameter1;
|
||||
string Parameter2;
|
||||
char prompt[] = "-> ";
|
||||
|
||||
char *Title[] = { " *******************",
|
||||
" * 8051 Emulator *",
|
||||
" *******************",
|
||||
"", 0 };
|
||||
|
||||
char *Menu[] = {
|
||||
" Available commands, [ ] = options",
|
||||
"",
|
||||
" Set Breakpoint.............. SB [address]",
|
||||
" Remove Breakpoint........... RB [address]",
|
||||
" Display Breakpoint(s)....... DB",
|
||||
" Dump External Data Memory... DE [address]",
|
||||
" Dump Internal Data Memory... DI [address]",
|
||||
" Dump Program Memory......... DP [address]",
|
||||
" Display Registers content... DR",
|
||||
" Execute..................... EM [address [number of instructions]]",
|
||||
" Help........................ H",
|
||||
" Modify External Data Memory. ME address value",
|
||||
" Modify Internal Data Memory. MI address value",
|
||||
" Modify Program Memory....... MP address value",
|
||||
" Modify Register............. MR register value",
|
||||
" Quit Emulator............... Q",
|
||||
" Trace mode.................. T [address]",
|
||||
" Unassemble.................. U [address [numberof instructions]]",
|
||||
" Reset processor............. Z", 0 };
|
||||
|
||||
|
||||
Index = 0;
|
||||
while ( Title[ Index ] != 0 ) printf( "%s%s", Title[ Index++ ], ENDLINE );
|
||||
Index = 0;
|
||||
while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE );
|
||||
|
||||
Reset( );
|
||||
int QuitRequest = 0;
|
||||
|
||||
while( !QuitRequest ) {
|
||||
try {
|
||||
|
||||
printf( prompt );
|
||||
getline ( cin, InputString, '\n' );
|
||||
Capitalize( &InputString );
|
||||
RemoveSpaces( &InputString );
|
||||
|
||||
for ( Index = 0; Index < InputString.size( ); Index++ ) {
|
||||
if ( InputString[ Index ] < 'A' || InputString[ Index ] > 'z' )
|
||||
break;
|
||||
}
|
||||
|
||||
Command = InputString;
|
||||
// Keep only the Command part from the input line
|
||||
Command.replace( Index, Command.size( ), 0, ( char )0 );
|
||||
// Keep only the arguments
|
||||
InputString.replace( 0, Index, 0, ( char )0 );
|
||||
|
||||
RemoveSpaces ( &InputString );
|
||||
Index = 0;
|
||||
while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++;
|
||||
Parameter1 = InputString;
|
||||
Parameter1.replace( Index, Parameter1.size( ), 0, ( char )0 );
|
||||
InputString.replace( 0, Index, 0, ( char )0 );
|
||||
|
||||
RemoveSpaces ( &InputString );
|
||||
Index = 0;
|
||||
while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++;
|
||||
Parameter2 = InputString;
|
||||
Parameter2.replace( Index, Parameter2.size( ), 0, ( char )0 );
|
||||
InputString.replace( 0, Index, 0, ( char )0 );
|
||||
|
||||
RemoveSpaces ( &InputString );
|
||||
if ( !InputString.empty( ) )
|
||||
throw SyntaxError( );
|
||||
|
||||
if ( Command.empty( ) && !Parameter1.empty( ) )
|
||||
throw SyntaxError( );
|
||||
|
||||
if ( ( Parameter1.size( ) > 4 ) || ( Parameter2.size( ) > 4 ) )
|
||||
throw InvalidParameter( );
|
||||
|
||||
if ( !Command.empty( ) ) {
|
||||
switch ( Command [ 0 ] ) {
|
||||
|
||||
case 'D' :
|
||||
if ( Parameter2.empty( ) ) {
|
||||
if ( Command == "DB" && Parameter1.empty( ) )
|
||||
ShowBreakpoints( );
|
||||
else if ( Command == "DE" )
|
||||
DumpExt( Parameter1 );
|
||||
else if ( Command == "DI" )
|
||||
DumpInt( Parameter1 );
|
||||
else if ( Command == "DP" ) {
|
||||
if ( Parameter1.empty( ) )
|
||||
Parameter1 = "PC";
|
||||
DumpPGM( Parameter1 );
|
||||
}
|
||||
else if ( Command == "DR" && Parameter1.empty( ) )
|
||||
ShowRegisters( );
|
||||
else
|
||||
throw SyntaxError( );
|
||||
}
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
|
||||
case 'E' :
|
||||
if ( Command == "EM" )
|
||||
Exec( Parameter1, Parameter2 );
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'H' :
|
||||
if ( Command == "H" && Parameter1.empty( ) && Parameter2.empty( ) )
|
||||
{
|
||||
Index = 0;
|
||||
while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE );
|
||||
}
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'M' :
|
||||
if ( Parameter1.empty() || Parameter2.empty() )
|
||||
throw MissingParameter();
|
||||
else if ( Command == "ME" ) {
|
||||
unsigned int adresse = Ascii2Hex( Parameter1, 4 );
|
||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
||||
CPU->WriteExt( adresse, valeur );
|
||||
}
|
||||
else if ( Command == "MI" ) {
|
||||
unsigned char adresse = Ascii2Hex( Parameter1, 2 );
|
||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
||||
CPU->WriteInt( adresse, valeur );
|
||||
}
|
||||
else if ( Command == "MP" ) {
|
||||
unsigned int adresse = Ascii2Hex( Parameter1, 4 );
|
||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
||||
CPU->WritePGM( adresse, valeur );
|
||||
}
|
||||
else if ( Command == "MR" )
|
||||
SetRegister( Parameter1, Parameter2 );
|
||||
else
|
||||
throw SyntaxError();
|
||||
break;
|
||||
case 'Q' :
|
||||
if ( Command == "Q" && Parameter1.empty( ) && Parameter2.empty( ) )
|
||||
QuitRequest = 1;
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'R' :
|
||||
if ( !Parameter2.empty( ) )
|
||||
throw TooMuchParameters( );
|
||||
if ( Command == "RB" ) {
|
||||
if ( Parameter1.empty( ) )
|
||||
ClearBreakpoint( CPU->GetPC( ) );
|
||||
else
|
||||
ClearBreakpoint( Ascii2Hex( Parameter1, 4 ) );
|
||||
}
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'S' :
|
||||
if ( !Parameter2.empty( ) )
|
||||
throw TooMuchParameters( );
|
||||
if ( Command == "SB" ) {
|
||||
if ( Parameter1.empty( ) )
|
||||
SetBreakpoint( CPU->GetPC( ) );
|
||||
else
|
||||
SetBreakpoint( Ascii2Hex( Parameter1, 4 ) );
|
||||
}
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'T' :
|
||||
if ( !Parameter2.empty( ) )
|
||||
throw TooMuchParameters( );
|
||||
if ( Command == "T" )
|
||||
Trace( Parameter1 );
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'U' :
|
||||
if ( Command == "U" )
|
||||
Disasm( Parameter1, Parameter2 );
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case 'Z' :
|
||||
if ( Command == "Z" && Parameter1.empty( ) && Parameter2.empty( ) )
|
||||
Reset( );
|
||||
else
|
||||
throw SyntaxError( );
|
||||
break;
|
||||
case '\n' :
|
||||
break;
|
||||
default :
|
||||
throw SyntaxError( );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( SyntaxError ) {
|
||||
printf( "Syntax Error!%s", ENDLINE );
|
||||
}
|
||||
catch ( MissingParameter ) {
|
||||
printf( "Missing Parameter!%s", ENDLINE );
|
||||
}
|
||||
catch ( InvalidParameter ) {
|
||||
printf( "Invalid Parameter Format!%s", ENDLINE );
|
||||
}
|
||||
catch ( TooMuchParameters ) {
|
||||
printf( "Wrong Number of Parameters!%s", ENDLINE );
|
||||
}
|
||||
catch ( ResetRequest ) {
|
||||
printf( "Resetting Microcontroler...%s", ENDLINE );
|
||||
}
|
||||
catch ( InvalidRegister ) {
|
||||
printf( "%sInvalid register name!%s", ENDLINE, ENDLINE );
|
||||
printf( "Valid registers are A, B, PC and SP.%s", ENDLINE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Reset( )
|
||||
// CPU reset and Console UI update
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Reset( )
|
||||
{
|
||||
printf( "Resetting... " );
|
||||
CPU->Reset( );
|
||||
printf( "Done.%s", ENDLINE );
|
||||
ShowRegisters( );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Trace( string Address )
|
||||
// CPU trace and Console UI update
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Trace( string Address )
|
||||
{
|
||||
if ( !Address.empty( ) ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
|
||||
CPU->Exec( );
|
||||
ShowRegisters( );
|
||||
DisasmN( CPU->GetPC( ), 1 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Exec( string Address, string NumberInst )
|
||||
// CPU exec and Console UI update
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Exec( string Address, string NumberInst )
|
||||
{
|
||||
char dummy;
|
||||
int NbInst = -1; // -1 is infinity
|
||||
if ( !Address.empty( ) ) {
|
||||
Capitalize( &Address );
|
||||
if ( Address != "PC" ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
|
||||
}
|
||||
|
||||
if ( !NumberInst.empty( ) ) NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
|
||||
|
||||
InitUnixKB( );
|
||||
|
||||
printf( "Program executing...%s", ENDLINE );
|
||||
|
||||
do {
|
||||
CPU->Exec( );
|
||||
if ( NbInst > 0 ) NbInst--;
|
||||
} while ( !IsBreakpoint( CPU->GetPC( ) ) && ( NbInst != 0 ) && !kbhit( ) );
|
||||
if ( kbhit( ) ) {
|
||||
dummy = getch( ); // flush key
|
||||
printf( "Caught break signal!%s", ENDLINE );
|
||||
}
|
||||
if ( NbInst == 0 ) printf( "Number of instructions reached! Stopping!%s", ENDLINE );
|
||||
if ( IsBreakpoint( CPU->GetPC( ) ) ) printf( "Breakpoint hit at %.4X! Stopping!%s", CPU->GetPC( ), ENDLINE );
|
||||
|
||||
ResetUnixKB( );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::ShowBreakpoints( )
|
||||
// Show Breakpoints list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::ShowBreakpoints( )
|
||||
{
|
||||
for ( int Index = 0; Index < NbBreakpoints ; Index++ )
|
||||
printf( "Breakpoint at Address = %.4X%s", Breakpoints[ Index ], ENDLINE );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::ClearBreakpoint( unsigned int Address )
|
||||
// Clear Breakpoint at Address from list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::ClearBreakpoint( unsigned int Address )
|
||||
{
|
||||
int Index = 0;
|
||||
while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
|
||||
if ( Breakpoints[ Index ] != Address ) return;
|
||||
Breakpoints[ Index ] = Breakpoints[ NbBreakpoints - 1 ];
|
||||
NbBreakpoints--;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::SetBreakpoint( unsigned int Address )
|
||||
// Set Breakpoint at Address from list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::SetBreakpoint( unsigned int Address )
|
||||
{
|
||||
if ( IsBreakpoint( Address ) ) return;
|
||||
if ( NbBreakpoints < MAXBP ) Breakpoints[ NbBreakpoints++ ] = Address;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// int EmuConsole::IsBreakpoint( unsigned int Address )
|
||||
// Is the a breakpoint at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int EmuConsole::IsBreakpoint( unsigned int Address )
|
||||
{
|
||||
int Index = 0;
|
||||
while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
|
||||
return ( Breakpoints[ Index ] == Address && Index < NbBreakpoints );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Disasm( string Address, string NumberInst )
|
||||
// Disassemble 16 instructions at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Disasm( string Address, string NumberInst )
|
||||
{
|
||||
unsigned int MemAddress, NbInst;
|
||||
Capitalize( &Address );
|
||||
if ( Address.empty( ) || ( Address == "PC" ) ) MemAddress = CPU->GetPC( );
|
||||
else MemAddress = Ascii2Hex( Address, Address.size( ) );
|
||||
if ( NumberInst.empty( ) ) NumberInst = "10";
|
||||
NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
|
||||
DisasmN( MemAddress, NbInst );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DisasmN( unsigned int Address, int NumberInst )
|
||||
// Disassemble NumberInst instructions at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DisasmN( unsigned int Address, int NumberInst )
|
||||
{
|
||||
char TextTmp[255];
|
||||
int Row;
|
||||
for ( Row = 0; Row < NumberInst ; Row++ ) {
|
||||
Address += CPU->Disasm( Address, TextTmp );
|
||||
printf( "%s%s", TextTmp, ENDLINE );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DumpPGM( string Address )
|
||||
// Dump Program memory
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DumpPGM( string Address )
|
||||
{
|
||||
unsigned int MemAddress = 0;
|
||||
int Offset, Column;
|
||||
unsigned char Byte;
|
||||
if ( !Address.empty( ) ) {
|
||||
Capitalize( &Address );
|
||||
if ( Address == "PC" )
|
||||
MemAddress = CPU->GetPC( );
|
||||
else
|
||||
MemAddress = Ascii2Hex( Address, Address.size( ) );
|
||||
}
|
||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||
printf( "%.4X ", MemAddress + Offset );
|
||||
for ( Column = 0; Column < 16; Column++ )
|
||||
printf( " %.2X", ( int )CPU->ReadPGM( MemAddress + Offset + Column ) );
|
||||
printf( " " );
|
||||
for ( Column = 0; Column < 16; Column++ ) {
|
||||
Byte = CPU->ReadPGM( MemAddress + Offset + Column );
|
||||
if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
|
||||
printf( "%c", Byte );
|
||||
else printf( "." );
|
||||
}
|
||||
printf( "%s", ENDLINE );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DumpI( string Address )
|
||||
// Dump using Indirect read access
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DumpI( string Address )
|
||||
{
|
||||
unsigned int MemAddress = 0;
|
||||
int Offset, Column;
|
||||
unsigned char Byte;
|
||||
if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
|
||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||
printf( "%.4X ", MemAddress + Offset );
|
||||
for ( Column = 0; Column < 16; Column++ )
|
||||
printf( " %.2X", ( int )CPU->ReadI( MemAddress + Offset + Column ) );
|
||||
printf( " " );
|
||||
for ( Column = 0; Column < 16; Column++ ) {
|
||||
Byte = CPU->ReadI( MemAddress + Offset + Column );
|
||||
if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
|
||||
printf( "%c", Byte );
|
||||
else printf( "." );
|
||||
}
|
||||
printf( "%s", ENDLINE );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DumpInt( string Address )
|
||||
// Dump internal Data memory
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DumpInt( string Address )
|
||||
{
|
||||
unsigned int MemAddress = 0;
|
||||
int Offset, Column;
|
||||
unsigned char Byte;
|
||||
if ( !Address.empty( ) )
|
||||
MemAddress = Ascii2Hex( Address, 4 );
|
||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||
printf( "%.4X ", MemAddress + Offset );
|
||||
for ( Column = 0; Column < 16; Column++ )
|
||||
printf( " %.2X", ( int )CPU->ReadInt( MemAddress + Offset + Column ) );
|
||||
printf( " " );
|
||||
for ( Column = 0; Column < 16; Column++ ) {
|
||||
Byte = CPU->ReadInt( MemAddress + Offset + Column );
|
||||
if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
|
||||
printf( "%c", Byte );
|
||||
else printf( "." );
|
||||
}
|
||||
printf( "%s", ENDLINE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DumpExt( string Address )
|
||||
// Dump de la memoire externe ( $00 a $FFFF)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DumpExt( string Address )
|
||||
{
|
||||
unsigned int MemAddress = 0;
|
||||
int Offset, Column;
|
||||
unsigned char Byte;
|
||||
if ( !Address.empty( ) )
|
||||
MemAddress = Ascii2Hex( Address, 4 );
|
||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||
printf( "%.4X ", MemAddress + Offset );
|
||||
for ( Column = 0; Column < 16; Column++ )
|
||||
printf( " %.2X", ( int )CPU->ReadExt( MemAddress + Offset + Column ) );
|
||||
printf( " " );
|
||||
for ( Column = 0; Column < 16; Column++ ) {
|
||||
Byte = CPU->ReadExt( MemAddress + Offset + Column );
|
||||
if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
|
||||
printf( "%c", Byte );
|
||||
else printf( "." );
|
||||
}
|
||||
printf( "%s", ENDLINE );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::DumpD( string Address )
|
||||
// Dump using Direct read access
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::DumpD( string Address )
|
||||
{
|
||||
unsigned int MemAddress = 0;
|
||||
int Offset, Column;
|
||||
unsigned char Byte;
|
||||
if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
|
||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||
printf( "%.4X ", MemAddress + Offset );
|
||||
for ( Column = 0; Column < 16; Column++ )
|
||||
printf( " %.2X", ( int )CPU->ReadD( MemAddress + Offset + Column ) );
|
||||
printf( " " );
|
||||
for ( Column = 0; Column < 16; Column++ ) {
|
||||
Byte = CPU->ReadD( MemAddress + Offset + Column );
|
||||
if ( ( int )Byte >= 32 && ( int )Byte <= 126 )
|
||||
printf( "%c", Byte );
|
||||
else printf( "." );
|
||||
}
|
||||
printf( "%s", ENDLINE );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::SetRegister( string Register, string NewValue )
|
||||
// Set NewValue to Register
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::SetRegister( string Register, string NewValue )
|
||||
{
|
||||
Capitalize( &Register );
|
||||
if ( Register == "PC" ) CPU->SetPC( Ascii2Hex( NewValue, 4 ) );
|
||||
else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex( NewValue, 2 ) );
|
||||
else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex( NewValue, 2 ) );
|
||||
else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex( NewValue, 2 ) );
|
||||
else throw InvalidRegister( );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::Capitalize( string *InputString )
|
||||
// Capitalize all letters in InputString
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::Capitalize( string *InputString )
|
||||
{
|
||||
for (unsigned int Index = 0; Index < InputString->size( ); Index++ ) {
|
||||
{
|
||||
if ( ( ( *InputString )[ Index ] >= 'a' ) && ( ( *InputString )[ Index ] <= 'z' ) )
|
||||
( *InputString )[ Index ] -= ( ( int )'a'- ( int )'A' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::RemoveSpaces( string *InputString )
|
||||
// Remove spaces from InputString
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::RemoveSpaces( string *InputString )
|
||||
{
|
||||
unsigned int Index = 0;
|
||||
|
||||
while ( ( Index < ( *InputString ).size( ) ) && ( *InputString )[ Index ] == ' ' ) {
|
||||
Index++;
|
||||
}
|
||||
( *InputString ).replace( 0, Index, 0, ( char )0 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::ShowRegisters( )
|
||||
// Show CPU registers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::ShowRegisters( )
|
||||
{
|
||||
unsigned char PSW = CPU->ReadD( _PSW_ );
|
||||
int BankSelect = ( PSW & 0x18 );
|
||||
|
||||
printf( "----------------------------------------------------------------------%s", ENDLINE );
|
||||
printf( "| PC | SP | DPTR | ACC | B | PSW: CY AC F0 RS1 RS0 OV - P |%s", ENDLINE );
|
||||
printf( "| %.4X | %.2X | %.4X | %.2X | %.2X |", CPU->GetPC( ), CPU->ReadD( _SP_ ), ( CPU->ReadD( _DPTRHIGH_ ) << 8 ) + CPU->ReadD( _DPTRLOW_ ), CPU->ReadD( _ACC_ ), CPU->ReadD( _B_ ) );
|
||||
printf( " %d %d %d %d %d %d %d %d |", ( PSW >> 7 ) & 1, ( PSW >> 6 ) & 1, ( PSW >> 5 ) & 1, ( PSW >> 4 ) & 1, ( PSW >> 3 ) & 1, ( PSW >> 2 ) & 1, ( PSW >> 1 ) & 1, PSW & 1 );
|
||||
printf( "%s", ENDLINE );
|
||||
printf( "----------------------------------------------------------------------%s", ENDLINE );
|
||||
|
||||
printf( "| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | |%s", ENDLINE );
|
||||
printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( _TCON_ ), CPU->ReadD( _TMOD_ ), CPU->ReadD( _IE_ ), CPU->ReadD( _IP_ ) );
|
||||
printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R0_ ), CPU->ReadD( BankSelect + _R1_ ), CPU->ReadD( BankSelect + _R2_ ), CPU->ReadD( BankSelect + _R3_ ) );
|
||||
printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R4_ ), CPU->ReadD( BankSelect + _R5_ ), CPU->ReadD( BankSelect + _R6_ ), CPU->ReadD( BankSelect + _R7_ ) );
|
||||
printf( "| |%s", ENDLINE );
|
||||
|
||||
printf( "----------------------------------------------------------------------%s", ENDLINE );
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuConsole::LoadHexFile( string Filename )
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuConsole::LoadHexFile( string Filename )
|
||||
{
|
||||
|
||||
printf("LoadHex\n");
|
||||
int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
|
||||
char Line[ 250 ];
|
||||
|
||||
ifstream HexFile( Filename.c_str() );
|
||||
try {
|
||||
if ( ! HexFile )
|
||||
throw ErrorOpeningFile();
|
||||
|
||||
while( ! HexFile.eof() ) {
|
||||
i = 0;
|
||||
Checksum = 0;
|
||||
HexFile.getline( Line, 250, '\n' );
|
||||
|
||||
if ( Line[ i++ ] != ':' )
|
||||
throw ErrorHexFileFormat();
|
||||
|
||||
RecLength = Ascii2Hex( &Line[ i ], 2 );
|
||||
i += 2;
|
||||
Checksum += RecLength;
|
||||
|
||||
LoadOffset = Ascii2Hex( &Line[i], 4 );
|
||||
Checksum += LoadOffset / 256;
|
||||
Checksum += LoadOffset % 256;
|
||||
i += 4;
|
||||
|
||||
RecType = Ascii2Hex( &Line[i],2);
|
||||
i += 2;
|
||||
Checksum += RecType;
|
||||
|
||||
if ( RecType == 1 ) {
|
||||
Checksum += Ascii2Hex( &Line[ i ], 2 );
|
||||
if ( Checksum &= 0x000000FF )
|
||||
throw ErrorHexFileFormat();
|
||||
throw FinishedLoading();
|
||||
}
|
||||
if ( RecType )
|
||||
throw ErrorHexFileFormat();
|
||||
|
||||
for ( j = 0; j < RecLength; j++ ) {
|
||||
Data = Ascii2Hex( &Line[ i ], 2 );
|
||||
CPU->WritePGM( (unsigned int)(LoadOffset + j), (unsigned char)Data );
|
||||
i += 2;
|
||||
Checksum += Data;
|
||||
}
|
||||
RecType = Ascii2Hex( &Line[ i ], 2 );
|
||||
Checksum += RecType;
|
||||
|
||||
if ( Checksum &= 0x000000FF )
|
||||
throw ErrorHexFileFormat();
|
||||
}
|
||||
throw ErrorHexFileFormat();
|
||||
}
|
||||
catch ( ErrorOpeningFile ) {
|
||||
cout << "Error opening file " << Filename << endl;
|
||||
}
|
||||
catch ( ErrorHexFileFormat ) {
|
||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
||||
}
|
||||
catch ( SyntaxError ) {
|
||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
||||
}
|
||||
catch ( MissingParameter ) {
|
||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
||||
}
|
||||
catch ( FinishedLoading ) {
|
||||
cout << "Using file " << Filename << " as input program." << endl;
|
||||
}
|
||||
HexFile.close();
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned int EmuConsole::Ascii2Hex( string istring, int length )
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int EmuConsole::Ascii2Hex( string istring, unsigned int length )
|
||||
{
|
||||
if ( !length || ( length > istring.size() ) )
|
||||
length = istring.size();
|
||||
|
||||
if ( istring.empty() )
|
||||
throw MissingParameter();
|
||||
|
||||
unsigned int result = 0;
|
||||
unsigned int i, ascii_code;
|
||||
for ( i = 0; i < length; i++ ) {
|
||||
ascii_code = istring[ i ];
|
||||
if ( ascii_code > 0x39 )
|
||||
ascii_code &= 0xDF;
|
||||
if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
|
||||
ascii_code -= 0x30;
|
||||
if ( ascii_code > 9 )
|
||||
ascii_code -= 7;
|
||||
result <<= 4;
|
||||
result += ascii_code;
|
||||
}
|
||||
else {
|
||||
throw SyntaxError();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
65
src/EmuConsole.hpp
Normal file
65
src/EmuConsole.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef _EMUCONSOLE_HPP_
|
||||
#define _EMUCONSOLE_HPP_
|
||||
|
||||
#include "CPU8051.hpp"
|
||||
#include <string>
|
||||
#include "exceptions.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Maximum number of BreakPoints
|
||||
#define MAXBP 32
|
||||
|
||||
#define ENDLINE "\n"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuConsole
|
||||
// Implements the Console User Interface as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class EmuConsole {
|
||||
public:
|
||||
|
||||
EmuConsole( int argc, char **argv, CPU8051 *mCPU );
|
||||
~EmuConsole( );
|
||||
|
||||
void Main( );
|
||||
|
||||
void Reset( );
|
||||
void Trace( string Address );
|
||||
void Exec( string Address, string NumberInst );
|
||||
void ShowBreakpoints( );
|
||||
void SetBreakpoint( unsigned int Address );
|
||||
void ClearBreakpoint( unsigned int Address );
|
||||
int IsBreakpoint( unsigned int Address );
|
||||
void Disasm( string Address, string NumberInst );
|
||||
void DisasmN( unsigned int Address, int NumberInst );
|
||||
void DumpPGM( string Address );
|
||||
void DumpD( string Address );
|
||||
void DumpInt( string Address );
|
||||
void DumpExt( string Address );
|
||||
void DumpI( string Address );
|
||||
void ShowRegisters( );
|
||||
void SetRegister( string Register, string NewValue );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
CPU8051 *CPU;
|
||||
int NbBreakpoints;
|
||||
unsigned int Breakpoints[ MAXBP ];
|
||||
|
||||
void LoadHexFile( string Filename );
|
||||
unsigned int Ascii2Hex( string istring, unsigned int length );
|
||||
void Capitalize( string *InputString );
|
||||
void RemoveSpaces( string *InputString );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
735
src/EmuGtk.cpp
Normal file
735
src/EmuGtk.cpp
Normal file
@@ -0,0 +1,735 @@
|
||||
// EmuGtk.cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "CPU8051.hpp"
|
||||
#include "EmuGtk.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "pixmaps/reset.xpm"
|
||||
#include "pixmaps/run.xpm"
|
||||
#include "pixmaps/stop.xpm"
|
||||
#include "pixmaps/step.xpm"
|
||||
|
||||
|
||||
int EmuGtkNumber = 0;
|
||||
int NbSignals = 0;
|
||||
int SignalsData[ 32 ];
|
||||
EmuGtk *EmuGtkPtr;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
DestroySignal=0,
|
||||
DeleteSignal,
|
||||
OpenISignal,
|
||||
QuitISignal,
|
||||
AboutISignal,
|
||||
ResetBSignal,
|
||||
RunBSignal,
|
||||
StopBSignal,
|
||||
StepBSignal
|
||||
};
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
CPU8051 *maincpu = new CPU8051;
|
||||
EmuGtk *emuUI = new EmuGtk( argc, argv, maincpu );
|
||||
|
||||
emuUI->Main();
|
||||
printf( "End of program.\n" );
|
||||
|
||||
delete emuUI;
|
||||
delete maincpu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuGtk::EmuGtk( )
|
||||
// EmuGtk constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
EmuGtk::EmuGtk( int argc, char **argv, CPU8051 *mCPU )
|
||||
{
|
||||
CPU = mCPU;
|
||||
RunningState = 0;
|
||||
|
||||
g_print( "\n" );
|
||||
|
||||
gtk_init( &argc, &argv );
|
||||
|
||||
emuwin = gtk_window_new( GTK_WINDOW_TOPLEVEL );
|
||||
gtk_window_set_title( GTK_WINDOW( emuwin ), "emu8051" );
|
||||
gtk_container_set_border_width( GTK_CONTAINER( emuwin ), 0 );
|
||||
gtk_widget_show( emuwin );
|
||||
|
||||
emufixed = gtk_fixed_new();
|
||||
gtk_widget_set_usize( GTK_WIDGET( emufixed ), MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT );
|
||||
gtk_container_add( GTK_CONTAINER( emuwin ), emufixed );
|
||||
gtk_widget_show( emufixed );
|
||||
|
||||
// EmuMenuBar( );
|
||||
|
||||
// Main window
|
||||
emumainfixed = gtk_fixed_new();
|
||||
gtk_widget_set_usize( GTK_WIDGET( emumainfixed ), MAIN_WIN_WIDTH, REG_WIN_HEIGHT + MEM_WIN_HEIGHT + BUTTONS_BAR_HEIGHT + 10 );
|
||||
gtk_fixed_put( GTK_FIXED( emufixed ), emumainfixed, 0, 25 );
|
||||
gtk_widget_show( emumainfixed );
|
||||
|
||||
ShowMenu();
|
||||
|
||||
AddButtons();
|
||||
|
||||
// Registers frame
|
||||
regfrm = gtk_frame_new( 0 );
|
||||
gtk_frame_set_shadow_type( GTK_FRAME( regfrm ), GTK_SHADOW_ETCHED_OUT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( regfrm ), REG_WIN_WIDTH, REG_WIN_HEIGHT );
|
||||
gtk_fixed_put( GTK_FIXED( emumainfixed ), regfrm, 0, BUTTONS_BAR_HEIGHT );
|
||||
regwin = new RegWin( regfrm );
|
||||
gtk_widget_show( regfrm );
|
||||
|
||||
// Program disassembly frame
|
||||
pgmfrm = gtk_frame_new( 0 );
|
||||
gtk_frame_set_shadow_type( GTK_FRAME( pgmfrm ), GTK_SHADOW_ETCHED_OUT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( pgmfrm ), PGM_WIN_WIDTH, PGM_WIN_HEIGHT );
|
||||
gtk_fixed_put( GTK_FIXED( emumainfixed ), pgmfrm, REG_WIN_WIDTH + 10, BUTTONS_BAR_HEIGHT );
|
||||
pgmwin = new PgmWin( pgmfrm, CPU );
|
||||
gtk_widget_show( pgmfrm );
|
||||
|
||||
// Memory dump frame
|
||||
memfrm = gtk_frame_new( 0 );
|
||||
gtk_frame_set_shadow_type( GTK_FRAME( memfrm ), GTK_SHADOW_ETCHED_OUT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( memfrm ), MEM_WIN_WIDTH, MEM_WIN_HEIGHT );
|
||||
gtk_fixed_put( GTK_FIXED( emumainfixed ), memfrm, 0, REG_WIN_HEIGHT + BUTTONS_BAR_HEIGHT );
|
||||
memwin = new MemWin( memfrm );
|
||||
gtk_widget_show( memfrm );
|
||||
|
||||
|
||||
if ( EmuGtkNumber >= 1 )
|
||||
g_print( "WARNING! Signal too much EmuGtk Objects to handle signals!\n");
|
||||
else
|
||||
{
|
||||
EmuGtkPtr = this;
|
||||
NbSignals = 0;
|
||||
|
||||
// Window DESTROY signal
|
||||
SignalsData[ NbSignals ] = DestroySignal;
|
||||
gtk_signal_connect( GTK_OBJECT( emuwin ), "destroy", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// Window DELETE event
|
||||
SignalsData[ NbSignals ] = DeleteSignal;
|
||||
gtk_signal_connect( GTK_OBJECT( emuwin ), "delete_event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// File->Open
|
||||
SignalsData[ NbSignals ] = OpenISignal;
|
||||
gtk_signal_connect( GTK_OBJECT( OpenItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// File->Quit
|
||||
SignalsData[ NbSignals ] = QuitISignal;
|
||||
gtk_signal_connect( GTK_OBJECT( QuitItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// Help->About
|
||||
SignalsData[ NbSignals ] = AboutISignal;
|
||||
gtk_signal_connect( GTK_OBJECT( AboutItem ), "activate", GTK_SIGNAL_FUNC( EmuGtkSignalStub2 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// RESET button
|
||||
SignalsData[ NbSignals ] = ResetBSignal;
|
||||
gtk_signal_connect( GTK_OBJECT( ButtonReset ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// RUN button
|
||||
SignalsData[ NbSignals ] = RunBSignal;
|
||||
gtk_signal_connect( GTK_OBJECT( ButtonRun ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// STOP button
|
||||
SignalsData[ NbSignals ] = StopBSignal;
|
||||
gtk_signal_connect( GTK_OBJECT( ButtonStop ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
// STEP button
|
||||
SignalsData[ NbSignals ] = StepBSignal;
|
||||
gtk_signal_connect( GTK_OBJECT( ButtonStep ), "button-press-event", GTK_SIGNAL_FUNC( EmuGtkSignalStub3 ), &SignalsData[ NbSignals ] );
|
||||
NbSignals++;
|
||||
|
||||
EmuGtkNumber++;
|
||||
}
|
||||
|
||||
if ( argc > 1 )
|
||||
LoadHexFile( argv[1] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void AddButtons()
|
||||
// Create and show the Reset, Run, Stop, Trace and Step buttons
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::AddButtons( void )
|
||||
{
|
||||
//GtkStyle *Style = gtk_widget_get_style( GTK_WIDGET( emuwin ) );
|
||||
|
||||
RESET_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
|
||||
gtk_widget_get_default_colormap(),
|
||||
&RESET_mask,
|
||||
NULL,
|
||||
( gchar ** ) reset_xpm );
|
||||
RESET_widget = gtk_pixmap_new( RESET_pixmap, RESET_mask );
|
||||
|
||||
RUN_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
|
||||
gtk_widget_get_default_colormap(),
|
||||
&RUN_mask,
|
||||
NULL,
|
||||
( gchar ** ) run_xpm );
|
||||
RUN_widget = gtk_pixmap_new( RUN_pixmap, RUN_mask );
|
||||
|
||||
STOP_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
|
||||
gtk_widget_get_default_colormap(),
|
||||
&STOP_mask,
|
||||
NULL,
|
||||
( gchar ** ) stop_xpm );
|
||||
STOP_widget = gtk_pixmap_new( STOP_pixmap, STOP_mask );
|
||||
|
||||
STEP_pixmap = gdk_pixmap_colormap_create_from_xpm_d( NULL,
|
||||
gtk_widget_get_default_colormap(),
|
||||
&STEP_mask,
|
||||
NULL,
|
||||
( gchar ** ) step_xpm );
|
||||
STEP_widget = gtk_pixmap_new( STEP_pixmap, STEP_mask );
|
||||
|
||||
ButtonTable = gtk_table_new( 1, 4, TRUE );
|
||||
gtk_widget_set_usize( GTK_WIDGET( ButtonTable ), BUTTONS_BAR_WIDTH, BUTTONS_BAR_HEIGHT );
|
||||
gtk_fixed_put( GTK_FIXED( emumainfixed ), ButtonTable, 0, 0 );
|
||||
|
||||
ButtonReset = gtk_button_new();
|
||||
ButtonRun = gtk_button_new();
|
||||
ButtonStop = gtk_button_new();
|
||||
ButtonStep = gtk_button_new();
|
||||
|
||||
gtk_container_add( GTK_CONTAINER( ButtonReset ), RESET_widget );
|
||||
gtk_container_add( GTK_CONTAINER( ButtonRun ), RUN_widget );
|
||||
gtk_container_add( GTK_CONTAINER( ButtonStop ), STOP_widget );
|
||||
gtk_container_add( GTK_CONTAINER( ButtonStep ), STEP_widget );
|
||||
|
||||
|
||||
gtk_widget_set_usize( GTK_WIDGET( ButtonReset ), BUTTON_WIDTH, BUTTON_HEIGHT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( ButtonRun ), BUTTON_WIDTH, BUTTON_HEIGHT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( ButtonStop ), BUTTON_WIDTH, BUTTON_HEIGHT );
|
||||
gtk_widget_set_usize( GTK_WIDGET( ButtonStep ), BUTTON_WIDTH, BUTTON_HEIGHT );
|
||||
|
||||
gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonReset, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonRun, 1, 2, 0, 1);
|
||||
gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStop, 2, 3, 0, 1);
|
||||
gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStep, 3, 4, 0, 1);
|
||||
|
||||
gtk_widget_show( GTK_WIDGET( ButtonReset ) );
|
||||
gtk_widget_show( GTK_WIDGET( ButtonRun ) );
|
||||
gtk_widget_show( GTK_WIDGET( ButtonStop ) );
|
||||
gtk_widget_show( GTK_WIDGET( ButtonStep ) );
|
||||
|
||||
gtk_widget_show_all( GTK_WIDGET( ButtonTable ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuGtk::~EmuGtk( )
|
||||
// EmuGtk destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
EmuGtk::~EmuGtk( )
|
||||
{
|
||||
g_print( "EmuGtk::~EmuGtk( )\n" );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuGtk::Reset( )
|
||||
// CPU reset and Gtk UI update
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::Reset( )
|
||||
{
|
||||
CPU->Reset( );
|
||||
regwin->Show( CPU );
|
||||
pgmwin->Disasm( );
|
||||
memwin->DumpD( CPU, 0 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuGtk::Step( )
|
||||
// CPU Step and Gtk UI update
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::Step( )
|
||||
{
|
||||
CPU->Exec( );
|
||||
regwin->Show( CPU );
|
||||
pgmwin->Disasm( );
|
||||
memwin->DumpD( CPU, 0 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuGtk::Main( )
|
||||
// Gtk UI Main function
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::Main( )
|
||||
{
|
||||
Reset( );
|
||||
gtk_main();
|
||||
g_print( "End of EmuGtk::Main( )\n" );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void EmuGtk::ShowMenu( )
|
||||
// Show the menu
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::ShowMenu( )
|
||||
{
|
||||
FileMenu = gtk_menu_new( );
|
||||
OpenItem = gtk_menu_item_new_with_label( "Open" );
|
||||
QuitItem = gtk_menu_item_new_with_label( "Quit" );
|
||||
gtk_menu_append( GTK_MENU( FileMenu ), GTK_WIDGET( OpenItem ) );
|
||||
gtk_menu_append( GTK_MENU( FileMenu ), GTK_WIDGET( QuitItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( OpenItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( QuitItem ) );
|
||||
|
||||
ViewMenu = gtk_menu_new( );
|
||||
ExtMemItem = gtk_menu_item_new_with_label( "External Memory Dump" );
|
||||
IntMemItem = gtk_menu_item_new_with_label( "Internal Memory Dump" );
|
||||
//PgmMemItem = gtk_menu_item_new_with_label( "Program Memory Dump" );
|
||||
gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( ExtMemItem ) );
|
||||
gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( IntMemItem ) );
|
||||
//gtk_menu_append( GTK_MENU( ViewMenu ), GTK_WIDGET( PgmMemItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( ExtMemItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( IntMemItem ) );
|
||||
//gtk_widget_show( GTK_WIDGET( PgmMemItem ) );
|
||||
|
||||
HelpMenu = gtk_menu_new( );
|
||||
AboutItem = gtk_menu_item_new_with_label( "About" );
|
||||
gtk_menu_append( GTK_MENU( HelpMenu ), GTK_WIDGET( AboutItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( AboutItem ) );
|
||||
|
||||
MenuBar = gtk_menu_bar_new( );
|
||||
gtk_fixed_put( GTK_FIXED( emufixed ), MenuBar, 0, 0 );
|
||||
gtk_widget_show( GTK_WIDGET( MenuBar ) );
|
||||
|
||||
FileItem = gtk_menu_item_new_with_label( "File" );
|
||||
ViewItem = gtk_menu_item_new_with_label( "View" );
|
||||
HelpItem = gtk_menu_item_new_with_label( "Help" );
|
||||
gtk_widget_show( GTK_WIDGET( FileItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( ViewItem ) );
|
||||
gtk_widget_show( GTK_WIDGET( HelpItem ) );
|
||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM( FileItem ), FileMenu );
|
||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM( ViewItem ), ViewMenu );
|
||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM( HelpItem ), HelpMenu );
|
||||
gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), FileItem );
|
||||
gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), ViewItem );
|
||||
gtk_menu_bar_append( GTK_MENU_BAR( MenuBar ), HelpItem );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// gint EmuGtk::DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
// Signal DeleteEvent
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
gboolean EmuGtk::DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
{
|
||||
g_print( "EmuGtk::DeleteEvent(...)\n" );
|
||||
StopRunning( );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// gint EmuGtk::DestroyEvent( GtkWidget *widget, gpointer data )
|
||||
// Signal DestroyEvent
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::DestroyEvent( GtkWidget *widget, gpointer data )
|
||||
{
|
||||
g_print( "EmuGtk::DestroyEvent(...)\n" );
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// gint EmuGtk::AboutEvent( GtkWidget *widget, gpointer data )
|
||||
// Signal AboutEvent ( Help->About in menu )
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void EmuGtk::AboutEvent( GtkWidget *widget, gpointer data )
|
||||
{
|
||||
char about_string[256];
|
||||
GtkWidget *about_window;
|
||||
GtkWidget *text_window;
|
||||
|
||||
sprintf( about_string, "%s\n\nversion %s\n\n\nAuthors:\nHugo Villeneuve\nJonathan St-Andr<64>\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 );
|
||||
}
|
||||
}
|
111
src/EmuGtk.hpp
Normal file
111
src/EmuGtk.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef _EMUGTK_HPP_
|
||||
#define _EMUGTK_HPP_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "CPU8051.hpp"
|
||||
#include "MemWin.hpp"
|
||||
#include "PgmWin.hpp"
|
||||
#include "RegWin.hpp"
|
||||
#include "GtkSizes.hpp"
|
||||
#include "exceptions.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EmuGtk
|
||||
// Implements the Gtk+ Graphical User Interface as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class EmuGtk {
|
||||
public:
|
||||
EmuGtk( int argc , char **argv, CPU8051 *mCPU );
|
||||
~EmuGtk( );
|
||||
|
||||
void Main( );
|
||||
|
||||
void Reset( );
|
||||
void Step( );
|
||||
// void Step( );
|
||||
// void Exec( );
|
||||
|
||||
void AddButtons( );
|
||||
void ShowMenu( );
|
||||
|
||||
gboolean DeleteEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
void DestroyEvent( GtkWidget *widget, gpointer data );
|
||||
|
||||
void OpenEvent( GtkWidget *widget, gpointer data );
|
||||
void QuitEvent( GtkWidget *widget, gpointer data );
|
||||
void AboutEvent( GtkWidget *widget, gpointer data );
|
||||
|
||||
void ResetEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
void RunEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
void StopEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
void StepEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
|
||||
void StartRunning( );
|
||||
void StopRunning( );
|
||||
void Running( );
|
||||
|
||||
void LoadHexFile( string Filename );
|
||||
void UpdateDisplay();
|
||||
|
||||
private:
|
||||
int EmuGtkID;
|
||||
CPU8051 *CPU;
|
||||
int RunningState;
|
||||
int RunFuncTag;
|
||||
MemWin *memwin;
|
||||
PgmWin *pgmwin;
|
||||
RegWin *regwin;
|
||||
GtkWidget *emuwin, *emufixed, *emumainfixed;
|
||||
GtkWidget *regfrm, *pgmfrm, *memfrm;
|
||||
GtkWidget *ButtonTable;
|
||||
|
||||
// GdkPixmap *PixMapT, *PixMapRun, *PixMapR, *PixMapQ;
|
||||
// GtkWidget *PixMapWidT, *PixMapWidRun, *PixMapWidR, *PixMapWidQ;
|
||||
// GdkBitmap *mask;
|
||||
GtkWidget *FileMenu, *OpenItem, *QuitItem, *FileItem;
|
||||
GtkWidget *ViewMenu, *ExtMemItem, *IntMemItem, *ViewItem;
|
||||
// GtkWidget *ViewMenu, *ExtMemItem, *IntMemItem, *PgmMemItem, *ViewItem;
|
||||
GtkWidget *HelpMenu, *AboutItem, *LicenseItem, *HelpItem;
|
||||
GtkWidget *MenuBar;
|
||||
|
||||
// RESET button
|
||||
GdkBitmap *RESET_mask;
|
||||
GdkPixmap *RESET_pixmap;
|
||||
GtkWidget *RESET_widget;
|
||||
GtkWidget *ButtonReset;
|
||||
|
||||
// RUN button
|
||||
GdkBitmap *RUN_mask;
|
||||
GdkPixmap *RUN_pixmap;
|
||||
GtkWidget *RUN_widget;
|
||||
GtkWidget *ButtonRun;
|
||||
|
||||
// STOP button
|
||||
GdkBitmap *STOP_mask;
|
||||
GdkPixmap *STOP_pixmap;
|
||||
GtkWidget *STOP_widget;
|
||||
GtkWidget *ButtonStop;
|
||||
|
||||
// STEP button
|
||||
GdkBitmap *STEP_mask;
|
||||
GdkPixmap *STEP_pixmap;
|
||||
GtkWidget *STEP_widget;
|
||||
GtkWidget *ButtonStep;
|
||||
|
||||
unsigned int Ascii2Hex( string istring, int length );
|
||||
};
|
||||
|
||||
void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
void EmuGtkSignalStub2( GtkWidget *widget, gpointer data );
|
||||
void FileOpenDialog_OK( GtkButton *button, gpointer data );
|
||||
void FileOpenDialog_CANCEL( GtkButton *button, gpointer data );
|
||||
|
||||
gint RunningFunction( );
|
||||
|
||||
|
||||
#endif
|
24
src/GtkSizes.hpp
Normal file
24
src/GtkSizes.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _GTKSIZES_HPP_
|
||||
#define _GTKSIZES_HPP_
|
||||
|
||||
#define NUMBER_OF_BUTTONS 5
|
||||
#define BUTTON_WIDTH 60
|
||||
#define BUTTON_HEIGHT 60
|
||||
#define BUTTONS_BAR_WIDTH (NUMBER_OF_BUTTONS * BUTTON_WIDTH)
|
||||
#define BUTTONS_BAR_HEIGHT BUTTON_HEIGHT
|
||||
|
||||
#define REG_WIN_WIDTH 100
|
||||
#define REG_WIN_HEIGHT 390
|
||||
|
||||
#define PGM_WIN_WIDTH 480
|
||||
#define PGM_WIN_HEIGHT 390
|
||||
|
||||
#define MEM_WIN_WIDTH 590
|
||||
#define MEM_WIN_HEIGHT 280
|
||||
|
||||
#define MENU_BAR_HEIGHT 0
|
||||
|
||||
#define MAIN_WIN_WIDTH (REG_WIN_WIDTH + PGM_WIN_WIDTH)
|
||||
#define MAIN_WIN_HEIGHT (BUTTONS_BAR_HEIGHT + REG_WIN_HEIGHT + MEM_WIN_HEIGHT)
|
||||
|
||||
#endif
|
266
src/Inst_Def.hpp
Normal file
266
src/Inst_Def.hpp
Normal file
@@ -0,0 +1,266 @@
|
||||
#ifndef __INST_DEF_HPP_
|
||||
#define __INST_DEF_HPP_
|
||||
// Do not modify this file directly, it was created by Opcode2cpp.pl
|
||||
// Any modification made directly on this file will be lost
|
||||
|
||||
|
||||
int OP_00( );
|
||||
int OP_01( );
|
||||
int OP_02( );
|
||||
int OP_03( );
|
||||
int OP_04( );
|
||||
int OP_05( );
|
||||
int OP_06( );
|
||||
int OP_07( );
|
||||
int OP_08( );
|
||||
int OP_09( );
|
||||
int OP_0A( );
|
||||
int OP_0B( );
|
||||
int OP_0C( );
|
||||
int OP_0D( );
|
||||
int OP_0E( );
|
||||
int OP_0F( );
|
||||
int OP_10( );
|
||||
int OP_11( );
|
||||
int OP_12( );
|
||||
int OP_13( );
|
||||
int OP_14( );
|
||||
int OP_15( );
|
||||
int OP_16( );
|
||||
int OP_17( );
|
||||
int OP_18( );
|
||||
int OP_19( );
|
||||
int OP_1A( );
|
||||
int OP_1B( );
|
||||
int OP_1C( );
|
||||
int OP_1D( );
|
||||
int OP_1E( );
|
||||
int OP_1F( );
|
||||
int OP_20( );
|
||||
int OP_21( );
|
||||
int OP_22( );
|
||||
int OP_23( );
|
||||
int OP_24( );
|
||||
int OP_25( );
|
||||
int OP_26( );
|
||||
int OP_27( );
|
||||
int OP_28( );
|
||||
int OP_29( );
|
||||
int OP_2A( );
|
||||
int OP_2B( );
|
||||
int OP_2C( );
|
||||
int OP_2D( );
|
||||
int OP_2E( );
|
||||
int OP_2F( );
|
||||
int OP_30( );
|
||||
int OP_31( );
|
||||
int OP_32( );
|
||||
int OP_33( );
|
||||
int OP_34( );
|
||||
int OP_35( );
|
||||
int OP_36( );
|
||||
int OP_37( );
|
||||
int OP_38( );
|
||||
int OP_39( );
|
||||
int OP_3A( );
|
||||
int OP_3B( );
|
||||
int OP_3C( );
|
||||
int OP_3D( );
|
||||
int OP_3E( );
|
||||
int OP_3F( );
|
||||
int OP_40( );
|
||||
int OP_41( );
|
||||
int OP_42( );
|
||||
int OP_43( );
|
||||
int OP_44( );
|
||||
int OP_45( );
|
||||
int OP_46( );
|
||||
int OP_47( );
|
||||
int OP_48( );
|
||||
int OP_49( );
|
||||
int OP_4A( );
|
||||
int OP_4B( );
|
||||
int OP_4C( );
|
||||
int OP_4D( );
|
||||
int OP_4E( );
|
||||
int OP_4F( );
|
||||
int OP_50( );
|
||||
int OP_51( );
|
||||
int OP_52( );
|
||||
int OP_53( );
|
||||
int OP_54( );
|
||||
int OP_55( );
|
||||
int OP_56( );
|
||||
int OP_57( );
|
||||
int OP_58( );
|
||||
int OP_59( );
|
||||
int OP_5A( );
|
||||
int OP_5B( );
|
||||
int OP_5C( );
|
||||
int OP_5D( );
|
||||
int OP_5E( );
|
||||
int OP_5F( );
|
||||
int OP_60( );
|
||||
int OP_61( );
|
||||
int OP_62( );
|
||||
int OP_63( );
|
||||
int OP_64( );
|
||||
int OP_65( );
|
||||
int OP_66( );
|
||||
int OP_67( );
|
||||
int OP_68( );
|
||||
int OP_69( );
|
||||
int OP_6A( );
|
||||
int OP_6B( );
|
||||
int OP_6C( );
|
||||
int OP_6D( );
|
||||
int OP_6E( );
|
||||
int OP_6F( );
|
||||
int OP_70( );
|
||||
int OP_71( );
|
||||
int OP_72( );
|
||||
int OP_73( );
|
||||
int OP_74( );
|
||||
int OP_75( );
|
||||
int OP_76( );
|
||||
int OP_77( );
|
||||
int OP_78( );
|
||||
int OP_79( );
|
||||
int OP_7A( );
|
||||
int OP_7B( );
|
||||
int OP_7C( );
|
||||
int OP_7D( );
|
||||
int OP_7E( );
|
||||
int OP_7F( );
|
||||
int OP_80( );
|
||||
int OP_81( );
|
||||
int OP_82( );
|
||||
int OP_83( );
|
||||
int OP_84( );
|
||||
int OP_85( );
|
||||
int OP_86( );
|
||||
int OP_87( );
|
||||
int OP_88( );
|
||||
int OP_89( );
|
||||
int OP_8A( );
|
||||
int OP_8B( );
|
||||
int OP_8C( );
|
||||
int OP_8D( );
|
||||
int OP_8E( );
|
||||
int OP_8F( );
|
||||
int OP_90( );
|
||||
int OP_91( );
|
||||
int OP_92( );
|
||||
int OP_93( );
|
||||
int OP_94( );
|
||||
int OP_95( );
|
||||
int OP_96( );
|
||||
int OP_97( );
|
||||
int OP_98( );
|
||||
int OP_99( );
|
||||
int OP_9A( );
|
||||
int OP_9B( );
|
||||
int OP_9C( );
|
||||
int OP_9D( );
|
||||
int OP_9E( );
|
||||
int OP_9F( );
|
||||
int OP_A0( );
|
||||
int OP_A1( );
|
||||
int OP_A2( );
|
||||
int OP_A3( );
|
||||
int OP_A4( );
|
||||
int OP_A5( );
|
||||
int OP_A6( );
|
||||
int OP_A7( );
|
||||
int OP_A8( );
|
||||
int OP_A9( );
|
||||
int OP_AA( );
|
||||
int OP_AB( );
|
||||
int OP_AC( );
|
||||
int OP_AD( );
|
||||
int OP_AE( );
|
||||
int OP_AF( );
|
||||
int OP_B0( );
|
||||
int OP_B1( );
|
||||
int OP_B2( );
|
||||
int OP_B3( );
|
||||
int OP_B4( );
|
||||
int OP_B5( );
|
||||
int OP_B6( );
|
||||
int OP_B7( );
|
||||
int OP_B8( );
|
||||
int OP_B9( );
|
||||
int OP_BA( );
|
||||
int OP_BB( );
|
||||
int OP_BC( );
|
||||
int OP_BD( );
|
||||
int OP_BE( );
|
||||
int OP_BF( );
|
||||
int OP_C0( );
|
||||
int OP_C1( );
|
||||
int OP_C2( );
|
||||
int OP_C3( );
|
||||
int OP_C4( );
|
||||
int OP_C5( );
|
||||
int OP_C6( );
|
||||
int OP_C7( );
|
||||
int OP_C8( );
|
||||
int OP_C9( );
|
||||
int OP_CA( );
|
||||
int OP_CB( );
|
||||
int OP_CC( );
|
||||
int OP_CD( );
|
||||
int OP_CE( );
|
||||
int OP_CF( );
|
||||
int OP_D0( );
|
||||
int OP_D1( );
|
||||
int OP_D2( );
|
||||
int OP_D3( );
|
||||
int OP_D4( );
|
||||
int OP_D5( );
|
||||
int OP_D6( );
|
||||
int OP_D7( );
|
||||
int OP_D8( );
|
||||
int OP_D9( );
|
||||
int OP_DA( );
|
||||
int OP_DB( );
|
||||
int OP_DC( );
|
||||
int OP_DD( );
|
||||
int OP_DE( );
|
||||
int OP_DF( );
|
||||
int OP_E0( );
|
||||
int OP_E1( );
|
||||
int OP_E2( );
|
||||
int OP_E3( );
|
||||
int OP_E4( );
|
||||
int OP_E5( );
|
||||
int OP_E6( );
|
||||
int OP_E7( );
|
||||
int OP_E8( );
|
||||
int OP_E9( );
|
||||
int OP_EA( );
|
||||
int OP_EB( );
|
||||
int OP_EC( );
|
||||
int OP_ED( );
|
||||
int OP_EE( );
|
||||
int OP_EF( );
|
||||
int OP_F0( );
|
||||
int OP_F1( );
|
||||
int OP_F2( );
|
||||
int OP_F3( );
|
||||
int OP_F4( );
|
||||
int OP_F5( );
|
||||
int OP_F6( );
|
||||
int OP_F7( );
|
||||
int OP_F8( );
|
||||
int OP_F9( );
|
||||
int OP_FA( );
|
||||
int OP_FB( );
|
||||
int OP_FC( );
|
||||
int OP_FD( );
|
||||
int OP_FE( );
|
||||
int OP_FF( );
|
||||
void InitFuncPtr( );
|
||||
|
||||
|
||||
#endif
|
4208
src/Inst_Imp.cpp
Normal file
4208
src/Inst_Imp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
59
src/Keyboard.hpp
Normal file
59
src/Keyboard.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Keyboard.hpp
|
||||
|
||||
#ifndef _KEYBOARD_HPP_
|
||||
#define _KEYBOARD_HPP_
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static struct termios orig, newtio;
|
||||
static int peek = -1;
|
||||
|
||||
int kbhit()
|
||||
{
|
||||
char ch;
|
||||
int nread;
|
||||
if(peek != -1) return 1;
|
||||
newtio.c_cc[VMIN]=0;
|
||||
tcsetattr(0, TCSANOW, &newtio);
|
||||
nread = read(0,&ch,1);
|
||||
newtio.c_cc[VMIN]=1;
|
||||
tcsetattr(0, TCSANOW, &newtio);
|
||||
if(nread == 1) {
|
||||
peek = ch;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getch()
|
||||
{
|
||||
char ch;
|
||||
if(peek != -1) {
|
||||
ch = peek;
|
||||
peek = -1;
|
||||
return ch;
|
||||
}
|
||||
read(0,&ch,1);
|
||||
return ch;
|
||||
}
|
||||
|
||||
void InitUnixKB( )
|
||||
{
|
||||
tcgetattr(0, &orig);
|
||||
newtio = orig;
|
||||
newtio.c_lflag &= ~ICANON;
|
||||
newtio.c_lflag &= ~ECHO;
|
||||
newtio.c_lflag &= ~ISIG;
|
||||
newtio.c_cc[VMIN] = 1;
|
||||
newtio.c_cc[VTIME] = 0;
|
||||
tcsetattr(0, TCSANOW, &newtio);
|
||||
}
|
||||
|
||||
void ResetUnixKB( )
|
||||
{
|
||||
tcsetattr(0,TCSANOW, &orig);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
37
src/Makefile.am
Normal file
37
src/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
# This file is processed by GNU automake to generate Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/pixmaps
|
||||
|
||||
bin_PROGRAMS = emu8051 emu8051_console
|
||||
|
||||
emu8051_SOURCES = EmuGtk.hpp EmuGtk.cpp CPU8051.hpp CPU8051.cpp Memory.hpp Memory.cpp \
|
||||
MemWin.hpp MemWin.cpp PgmWin.hpp PgmWin.cpp RegWin.hpp RegWin.cpp
|
||||
|
||||
emu8051_console_SOURCES = EmuConsole.hpp EmuConsole.cpp CPU8051.hpp CPU8051.cpp Memory.hpp \
|
||||
Memory.cpp Keyboard.hpp
|
||||
|
||||
# These headers will be included in the distribution tarball, but will not be
|
||||
# installed by 'make install'
|
||||
noinst_HEADERS = Inst_Def.hpp EmuConsole.hpp Keyboard.hpp Reg8051.hpp GtkSizes.hpp disasm.hpp \
|
||||
exceptions.hpp
|
||||
|
||||
CLEANFILES = *~
|
||||
|
||||
DISTCLEANFILES = .deps/*.P
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = Opcode2cpp.pl opcodes.lst Inst_Imp.cpp
|
||||
|
||||
# This rule is used to bypass the default rule which is generated by Automake, in order
|
||||
# to get rid of all the cluttered informations that are displayed by Make before
|
||||
# calling the compiler like in the following example:
|
||||
# source='programming.c' object='programming.o' libtool=no \
|
||||
# depfile='.deps/programming.Po' tmpdepfile='.deps/programming.TPo' \
|
||||
# depmode=gcc3 /bin/sh ../config/depcomp \
|
||||
# gcc -DHAVE_CONFIG_H -I. -I. -I.. -c `test -f 'main.c' || echo './'`main.c
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.cpp.o:
|
||||
$(CXXCOMPILE) -c $<
|
128
src/MemWin.cpp
Normal file
128
src/MemWin.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/* memwin.cpp */
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "MemWin.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MemWin::MemWin( GtkWidget *parentwin )
|
||||
// MemWin constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
MemWin::MemWin( GtkWidget *parentwin )
|
||||
{
|
||||
int i;
|
||||
GtkStyle *style;
|
||||
GdkFont *fixedfont;
|
||||
fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
|
||||
|
||||
memclist = gtk_clist_new( 18 );
|
||||
gtk_clist_set_selection_mode( GTK_CLIST( memclist ), GTK_SELECTION_SINGLE );
|
||||
gtk_widget_set_usize( GTK_WIDGET( memclist ), 620, 250 );
|
||||
|
||||
for ( i = 0; i < 18; i++ ) gtk_clist_set_column_justification( GTK_CLIST( memclist ), i, GTK_JUSTIFY_LEFT );
|
||||
gtk_clist_set_column_width( GTK_CLIST( memclist ), 0, 5*8 );
|
||||
for ( i = 1; i < 17; i++ ) gtk_clist_set_column_width( GTK_CLIST( memclist ), i, 2*8 );
|
||||
gtk_clist_set_column_width( GTK_CLIST( memclist ), 17, 16*8 );
|
||||
|
||||
style = gtk_widget_get_style( GTK_WIDGET( memclist ) );
|
||||
|
||||
#ifdef USE_GTK2
|
||||
gtk_style_set_font( style, fixedfont );
|
||||
#else
|
||||
style->font = fixedfont;
|
||||
#endif
|
||||
|
||||
gtk_widget_set_style( GTK_WIDGET( memclist ), style );
|
||||
|
||||
char *memdummy[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
|
||||
for ( i = 0; i < 16; i++ ) gtk_clist_append( GTK_CLIST( memclist ), memdummy );
|
||||
|
||||
gtk_container_add( GTK_CONTAINER( parentwin ), memclist );
|
||||
|
||||
gtk_widget_show( memclist );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MemWin::~MemWin( )
|
||||
// MemWin destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
MemWin::~MemWin( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void MemWin::DumpD( CPU8051 *mCPU, unsigned int Address )
|
||||
// Dump 16 rows of 16 bytes from Address in Memory (direct addressing)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void MemWin::DumpD( CPU8051 *mCPU, unsigned int Address)
|
||||
{
|
||||
char TextTmp[255];
|
||||
int row, column, TextLength;
|
||||
|
||||
gtk_clist_freeze( GTK_CLIST( memclist ) );
|
||||
for ( row = 0; row < 16; row++ ) {
|
||||
sprintf( TextTmp, "%.4X", Address );
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, 0, TextTmp );
|
||||
|
||||
for ( column = 0; column < 16; column++ ) {
|
||||
sprintf( TextTmp, "%.2X", ( int ) mCPU->ReadD( Address + column ) );
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, column + 1, TextTmp );
|
||||
}
|
||||
|
||||
TextLength = 0;
|
||||
for ( column = 0; column < 16; column++ ) {
|
||||
if ( ( ( int ) mCPU->ReadD( Address + column ) >= 32 ) && ( ( int ) mCPU->ReadD( Address + column ) <= 126 ) )
|
||||
TextLength += sprintf( &TextTmp[ TextLength ], "%c", mCPU->ReadD( Address + column ) );
|
||||
else TextLength += sprintf( &TextTmp[ TextLength ], "." );
|
||||
}
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, 17, TextTmp );
|
||||
|
||||
Address += 16;
|
||||
}
|
||||
|
||||
gtk_clist_select_row( GTK_CLIST( memclist ), 0, 0 );
|
||||
gtk_clist_thaw( GTK_CLIST( memclist ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void MemWin::DumpI( CPU8051 *mCPU, unsigned int Address )
|
||||
// Dump 16 rows of 16 bytes from Address in Memory (indirect addressing)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void MemWin::DumpI( CPU8051 *mCPU, unsigned int Address)
|
||||
{
|
||||
char TextTmp[255];
|
||||
int row, column, TextLength;
|
||||
|
||||
gtk_clist_freeze( GTK_CLIST( memclist ) );
|
||||
for ( row = 0; row < 16; row++ ) {
|
||||
sprintf( TextTmp, "%.4X", Address );
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, 0, TextTmp );
|
||||
|
||||
for ( column = 0; column < 16; column++ ) {
|
||||
sprintf( TextTmp, "%.2X", ( int ) mCPU->ReadI( Address + column ) );
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, column + 1, TextTmp );
|
||||
}
|
||||
|
||||
TextLength = 0;
|
||||
for ( column = 0; column < 16; column++ ) {
|
||||
if ( ( ( int ) mCPU->ReadI( Address + column ) >= 32 ) && ( ( int ) mCPU->ReadI( Address + column ) <= 126 ) )
|
||||
TextLength += sprintf( &TextTmp[ TextLength ], "%c", mCPU->ReadI( Address + column ) );
|
||||
else TextLength += sprintf( &TextTmp[ TextLength ], "." );
|
||||
}
|
||||
gtk_clist_set_text( GTK_CLIST( memclist ), row, 17, TextTmp );
|
||||
|
||||
Address += 16;
|
||||
}
|
||||
gtk_clist_thaw( GTK_CLIST( memclist ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
29
src/MemWin.hpp
Normal file
29
src/MemWin.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _MEMWIN_HPP_
|
||||
#define _MEMWIN_HPP_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "CPU8051.hpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MemWin
|
||||
// Implements a memory Window in Gtk+ as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class MemWin {
|
||||
public:
|
||||
MemWin( GtkWidget *parentwin );
|
||||
~MemWin( );
|
||||
|
||||
void DumpD( CPU8051 *mCPU, unsigned int Address );
|
||||
void DumpI( CPU8051 *mCPU, unsigned int Address );
|
||||
|
||||
private:
|
||||
GtkWidget *memwin;
|
||||
GtkWidget *memclist;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
51
src/Memory.cpp
Normal file
51
src/Memory.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "Memory.hpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Memory::Memory( unsigned long MemSize )
|
||||
// Memory object constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
Memory::Memory( unsigned long MemSize )
|
||||
{
|
||||
memsize = MemSize;
|
||||
memarray = new unsigned char[memsize];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Memory::~Memory( )
|
||||
// Memory object destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
Memory::~Memory( )
|
||||
{
|
||||
delete[] memarray;
|
||||
memarray = 0;
|
||||
memsize = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned long Memory::GetSize( )
|
||||
// Get Memory size
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned long Memory::GetSize( )
|
||||
{
|
||||
return memsize;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void Memory::Write8( unsigned long Address, unsigned char Value )
|
||||
// Write 8-bit Value at Address into Memory
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void Memory::Write8( unsigned long Address, unsigned char Value )
|
||||
{
|
||||
if (Address >= memsize) return;
|
||||
memarray[Address] = Value;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// unsigned char Memory::Read8( unsigned long Address )
|
||||
// Read 8-bit value at Address in Memory
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
unsigned char Memory::Read8( unsigned long Address )
|
||||
{
|
||||
if (Address < memsize) { return memarray[Address]; }
|
||||
return 0;
|
||||
}
|
24
src/Memory.hpp
Normal file
24
src/Memory.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _MEMORY_HPP_
|
||||
#define _MEMORY_HPP_
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Memory
|
||||
// Implements a Memory array to be used by the CPU8051 as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class Memory {
|
||||
public:
|
||||
Memory( unsigned long MemSize );
|
||||
~Memory( );
|
||||
|
||||
unsigned long GetSize( );
|
||||
|
||||
void Write8( unsigned long Address, unsigned char Value );
|
||||
unsigned char Read8( unsigned long Address );
|
||||
|
||||
unsigned char *memarray;
|
||||
unsigned long memsize;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
785
src/Opcode2cpp.pl
Executable file
785
src/Opcode2cpp.pl
Executable file
@@ -0,0 +1,785 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
open INST_DEF,">Inst_Def.hpp" or die "Erreur ouverture Inst_Def.hpp : $!\n";
|
||||
open INST_IMP,">Inst_Imp.cpp" or die "Erreur ouverture Inst_Imp.hpp : $!\n";
|
||||
open OPCODELST,"opcodes.lst" or die "Erreur ouverture opcodes.lst : $!\n";
|
||||
open DISASM_HPP,">disasm.hpp" or die "Erreur ouverture disasm.hpp : $!\n";
|
||||
|
||||
print INST_IMP "#ifndef __INST_IMP_HPP_\n";
|
||||
print INST_IMP "#define __INST_IMP_HPP_\n\n";
|
||||
print INST_IMP "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
|
||||
print INST_IMP "// Any modification made directly on this file will be lost\n\n\n";
|
||||
|
||||
|
||||
print INST_DEF "#ifndef __INST_DEF_HPP_\n";
|
||||
print INST_DEF "#define __INST_DEF_HPP_\n";
|
||||
print INST_DEF "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
|
||||
print INST_DEF "// Any modification made directly on this file will be lost\n\n\n";
|
||||
|
||||
print DISASM_HPP "#ifndef __DISASM_HPP_\n";
|
||||
print DISASM_HPP "#define __DISASM_HPP_\n";
|
||||
print DISASM_HPP "// Do not modify this file directly, it was created by Opcode2cpp.pl\n";
|
||||
print DISASM_HPP "// Any modification made directly on this file will be lost\n\n\n";
|
||||
|
||||
$nbinst=0;
|
||||
$nbaddr=0;
|
||||
$nbargs=0;
|
||||
$instnumb=0;
|
||||
|
||||
$ligne=<OPCODELST>;
|
||||
$ligne=<OPCODELST>;
|
||||
while($ligne=<OPCODELST>) {
|
||||
chop $ligne;
|
||||
if (length $ligne < 2) {next;}
|
||||
@wordlist=split ' ',$ligne;
|
||||
$nbword=@wordlist;
|
||||
$instruction=$wordlist[2];
|
||||
for($i=3;$i<($nbword-2);$i++) {$instruction="$instruction $wordlist[$i]";}
|
||||
|
||||
$a_instruction[$instnumb]=$instruction;
|
||||
$a_bytes[$instnumb]=$wordlist[$nbword-2];
|
||||
$a_cycles[$instnumb]=$wordlist[$nbword-1];
|
||||
$a_opcodehex[$instnumb]=$wordlist[1];
|
||||
$a_opcodebin[$instnumb]=$wordlist[0];
|
||||
|
||||
|
||||
$instfunction[$instnumb]="CPU8051::OP_$wordlist[1]";
|
||||
|
||||
$instargs[$instnumb << 2]=$instargs[($instnumb << 2) + 1]=$instargs[($instnumb << 2) + 2]=$instargs[($instnumb << 2) + 3]=0;
|
||||
if ($nbword > 5) {
|
||||
@argslist=split /\,/,$wordlist[3];
|
||||
$argslistsize=@argslist;
|
||||
$instargs[$instnumb << 2]=$argslistsize;
|
||||
for ($i=0;$i<$argslistsize;$i++) {
|
||||
if (not exists $argstypes{$argslist[$i]}) {
|
||||
$argstypes[$nbargs]=$argslist[$i];
|
||||
$argstypes{$argslist[$i]}=$nbargs++;
|
||||
}
|
||||
$instargs[($instnumb << 2) + $i + 1]=$argstypes{$argslist[$i]};
|
||||
}
|
||||
}
|
||||
|
||||
if (not exists $insttext{$wordlist[2]}) {
|
||||
$insttext[$nbinst]=$wordlist[2];
|
||||
$insttext{$wordlist[2]}=$nbinst++;
|
||||
}
|
||||
|
||||
$insttype[$instnumb]=$insttext{$wordlist[2]};
|
||||
|
||||
if ( not exists $addrmode{$wordlist[3]}) {
|
||||
$addrmode[$nbaddr]=$wordlist[3];
|
||||
$addrmode{$wordlist[3]}=$nbaddr++;
|
||||
}
|
||||
|
||||
$nbbytes[$instnumb]=$wordlist[$nbword-2];
|
||||
|
||||
$instaddr[$instnumb]=$addrmode{$wordlist[3]};
|
||||
|
||||
$instnumb++;
|
||||
}
|
||||
# ------------------------------------------------------------------------------
|
||||
print DISASM_HPP "// For all 256 opcodes, the value in this table gives the instruction type\n";
|
||||
print DISASM_HPP "// ex.: MOV, INC, CLR, CPL,...\n";
|
||||
print DISASM_HPP "// To know what is the instruction type, use the number as an offset in the InstTextTbl[]\n";
|
||||
print DISASM_HPP "static int InstTypesTbl[] = {\n";
|
||||
for($i=0;$i<256;$i++) {
|
||||
print DISASM_HPP " $insttype[$i]";
|
||||
($i != 255) and print DISASM_HPP ",";
|
||||
if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
|
||||
}
|
||||
print DISASM_HPP "};\n";
|
||||
print DISASM_HPP "\n\n";
|
||||
# ------------------------------------------------------------------------------
|
||||
print DISASM_HPP "// Size(in bytes) of each instruction (offset in table is instruction opcode)\n";
|
||||
print DISASM_HPP "static int InstSizesTbl[] = {\n";
|
||||
for($i=0;$i<256;$i++) {
|
||||
print DISASM_HPP " $nbbytes[$i]";
|
||||
($i != 255) and print DISASM_HPP ",";
|
||||
if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
|
||||
}
|
||||
print DISASM_HPP "};\n";
|
||||
print DISASM_HPP "\n\n";
|
||||
# ------------------------------------------------------------------------------
|
||||
print DISASM_HPP "// List of instructions types referenced by InstTypesTbl[]\n";
|
||||
$nbelement=@insttext;
|
||||
print DISASM_HPP "\#define InstTextTblLength $nbelement\n";
|
||||
$elementnb=0;
|
||||
print DISASM_HPP "static char *InstTextTbl[] = {\n";
|
||||
foreach $instruc (@insttext) {
|
||||
print DISASM_HPP " \"$instruc\"";
|
||||
($elementnb++ < $nbelement-1) and print DISASM_HPP ",";
|
||||
print DISASM_HPP "\n";
|
||||
}
|
||||
print DISASM_HPP "};\n";
|
||||
print DISASM_HPP "\n\n";
|
||||
# ------------------------------------------------------------------------------
|
||||
print DISASM_HPP "// Table describing all arguments types of an instruction\n";
|
||||
print DISASM_HPP "// The table is indexed InstArgTbl[ opcode * 4]\n";
|
||||
print DISASM_HPP "// InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
|
||||
print DISASM_HPP "// InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
|
||||
print DISASM_HPP "// for most instructions, the 3rd argument isn't used\n";
|
||||
print DISASM_HPP "// the argument type is referecing to ArgsTextTbl[]\n";
|
||||
print DISASM_HPP "\#define InstArgTblLength 256\n";
|
||||
print DISASM_HPP "static int InstArgTbl[] = {\n";
|
||||
for($i=0;$i<1024;$i++) {
|
||||
print DISASM_HPP " $instargs[$i]";
|
||||
($i != 1023) and print DISASM_HPP ",";
|
||||
if (($i+1) % 16 == 0) { print DISASM_HPP "\n"; }
|
||||
}
|
||||
print DISASM_HPP "};\n";
|
||||
print DISASM_HPP "\n\n";
|
||||
# ------------------------------------------------------------------------------
|
||||
print DISASM_HPP "// List all types of arguments available to instructions\n";
|
||||
print DISASM_HPP "// Referenced by InstArgsTbl[]\n";
|
||||
$nbelement=@argstypes;
|
||||
print DISASM_HPP "\#define ArgsTextTblLength $nbelement\n";
|
||||
$elementnb=0;
|
||||
print DISASM_HPP "static char *ArgsTextTbl[] = {\n";
|
||||
foreach $args (@argstypes) {
|
||||
print DISASM_HPP " \"$args\"";
|
||||
($elementnb++ < $nbelement-1) and print DISASM_HPP ",";
|
||||
print DISASM_HPP "\n";
|
||||
}
|
||||
print DISASM_HPP "};\n";
|
||||
print DISASM_HPP "\n\n";
|
||||
# ------------------------------------------------------------------------------
|
||||
for ($i=0 ; $i< 256; $i++) {
|
||||
print INST_IMP "/"x78,"\n";
|
||||
print INST_IMP "// void CPU8051::OP_$a_opcodehex[$i]( )\n";
|
||||
print INST_IMP "// Instruction \"$a_instruction[$i]\" takes $a_cycles[$i] cycle(s) and $a_bytes[$i] byte(s)\n";
|
||||
print INST_IMP "/"x78,"\n";
|
||||
print INST_IMP "int CPU8051::OP_$a_opcodehex[$i]( )\n";
|
||||
print INST_DEF "int OP_$a_opcodehex[$i]( );\n";
|
||||
print INST_IMP "{\n";
|
||||
|
||||
if ($i == 0x85) {
|
||||
# Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
|
||||
print INST_IMP "unsigned char srcaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "unsigned char source = ReadD( srcaddr );\n";
|
||||
print INST_IMP "unsigned char destaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "unsigned char destination = ReadD( destaddr );\n";
|
||||
print INST_IMP "destination = source;\n";
|
||||
print INST_IMP "WriteD( destaddr, destination );\n";
|
||||
} else {
|
||||
|
||||
if ($instargs[$i*4] > 0) {
|
||||
$op_destination=$instargs[$i*4+1];
|
||||
if ($op_destination == 0) { # addr11
|
||||
print INST_IMP "unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_destination == 1) { # addr16
|
||||
print INST_IMP "unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );\n";
|
||||
print INST_IMP "addr16 += PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_destination == 2) { # A
|
||||
print INST_IMP "unsigned char destination = ReadD( _ACC_ );\n";
|
||||
}
|
||||
if ($op_destination == 3) { # direct
|
||||
print INST_IMP "unsigned char destaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "unsigned char destination = ReadD( destaddr );\n";
|
||||
}
|
||||
if ($op_destination == 4) { # @R0
|
||||
print INST_IMP "unsigned char destination = ReadI ( ReadD( BANKPSW + _R0_ ) );\n";
|
||||
}
|
||||
if ($op_destination == 5) { # @R1
|
||||
print INST_IMP "unsigned char destination = ReadI ( ReadD( BANKPSW + _R1_ ) );\n";
|
||||
}
|
||||
|
||||
if ($op_destination == 6) { # R0
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R0_ );\n";
|
||||
}
|
||||
if ($op_destination == 7) { # R1
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R1_ );\n";
|
||||
}
|
||||
if ($op_destination == 8) { # R2
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R2_ );\n";
|
||||
}
|
||||
if ($op_destination == 9) { # R3
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R3_ );\n";
|
||||
}
|
||||
if ($op_destination == 10) { # R4
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R4_ );\n";
|
||||
}
|
||||
if ($op_destination == 11) { # R5
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R5_ );\n";
|
||||
}
|
||||
if ($op_destination == 12) { # R6
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R6_ );\n";
|
||||
}
|
||||
if ($op_destination == 13) { # R7
|
||||
print INST_IMP "unsigned char destination = ReadD( BANKPSW + _R7_ );\n";
|
||||
}
|
||||
if ($op_destination == 14) { # bitaddr
|
||||
print INST_IMP "unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "destination = ReadB( dstbitaddr );\n";
|
||||
}
|
||||
if ($op_destination == 15) { # reladdr
|
||||
print INST_IMP "PC++;\n";
|
||||
print INST_IMP "unsigned int destination = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );\n";
|
||||
}
|
||||
if ($op_destination == 16) { # #data
|
||||
print INST_IMP "unsigned char destination = PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_destination == 17) { # C
|
||||
print INST_IMP "unsigned char destination = ( ReadD( _PSW_ ) >> 7 );\n";
|
||||
}
|
||||
if ($op_destination == 18) { # @A+DPTR
|
||||
print INST_IMP "unsigned int destination = ReadI( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );\n";
|
||||
}
|
||||
# Mis en commentaire car donnait un warning (destination et source unused variables...)
|
||||
# if ($op_destination == 20) { # AB
|
||||
# print INST_IMP "unsigned char destination = ReadD( _ACC_ );\n";
|
||||
# print INST_IMP "unsigned char source = ReadD( _B_ );\n";
|
||||
# }
|
||||
if ($op_destination == 21) { # DPTR
|
||||
print INST_IMP "unsigned int destination = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );\n";
|
||||
}
|
||||
if ($op_destination == 22) { # #data16
|
||||
print INST_IMP "unsigned char destination = ( PGMMem->Read8( PC++ ) << 8 );\n";
|
||||
print INST_IMP "destination += PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_destination == 23) { # /bitaddr
|
||||
print INST_IMP "unsigned char destination, dstbitaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "destination = ( ReadB( dstbitaddr ) ^ 1 );\n";
|
||||
}
|
||||
if ($op_destination == 24) { # @DPTR
|
||||
print INST_IMP "unsigned char destination = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($instargs[$i*4] > 1) {
|
||||
$op_source=$instargs[$i*4+2];
|
||||
if ($op_source == 0) { # addr11
|
||||
print INST_IMP "unsigned int addr11 = ( ( PGMMem->Read8( PC - 1 ) << 3 ) & 0xF00 ) + PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_source == 1) { # addr16
|
||||
print INST_IMP "unsigned int addr16 = ( PGMMem->Read8( PC++ ) << 8 );\n";
|
||||
print INST_IMP "addr16 += PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_source == 2) { # A
|
||||
print INST_IMP "unsigned char source = ReadD( _ACC_ );\n";
|
||||
}
|
||||
if ($op_source == 3) { # direct
|
||||
print INST_IMP "unsigned char srcaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "unsigned char source = ReadD( srcaddr );\n";
|
||||
}
|
||||
if ($op_source == 4) { # @R0
|
||||
print INST_IMP "unsigned char source = ReadI ( ReadD( BANKPSW + _R0_ ) );\n";
|
||||
}
|
||||
if ($op_source == 5) { # @R1
|
||||
print INST_IMP "unsigned char source = ReadI ( ReadD( BANKPSW + _R1_ ) );\n";
|
||||
}
|
||||
if ($op_source == 6) { # R0
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R0_ );\n";
|
||||
}
|
||||
if ($op_source == 7) { # R1
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R1_ );\n";
|
||||
}
|
||||
if ($op_source == 8) { # R2
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R2_ );\n";
|
||||
}
|
||||
if ($op_source == 9) { # R3
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R3_ );\n";
|
||||
}
|
||||
if ($op_source == 10) { # R4
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R4_ );\n";
|
||||
}
|
||||
if ($op_source == 11) { # R5
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R5_ );\n";
|
||||
}
|
||||
if ($op_source == 12) { # R6
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R6_ );\n";
|
||||
}
|
||||
if ($op_source == 13) { # R7
|
||||
print INST_IMP "unsigned char source = ReadD( BANKPSW + _R7_ );\n";
|
||||
}
|
||||
|
||||
if ($op_source == 14) { # bitaddr
|
||||
print INST_IMP "unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "source = ReadB( srcbitaddr );\n";
|
||||
}
|
||||
if ($op_source == 15) { # reladdr
|
||||
print INST_IMP "PC++;\n";
|
||||
print INST_IMP "unsigned int source = ( ( PGMMem->Read8( PC - 1 ) + PC ) & 0xFF ) + ( PC & 0xFF00 );\n";
|
||||
}
|
||||
if ($op_source == 16) { # #data
|
||||
print INST_IMP "unsigned char source = PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_source == 17) { # C
|
||||
print INST_IMP "unsigned char source = ( ReadD( _PSW_ ) >> 7 );\n";
|
||||
}
|
||||
if ($op_source == 18) { # @A+DPTR
|
||||
print INST_IMP "unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ReadD( _DPTRLOW_ ) + ( ReadD( _DPTRHIGH_ ) << 8 ) );\n";
|
||||
}
|
||||
if ($op_source == 19) { # @A+PC
|
||||
print INST_IMP "unsigned char source = PGMMem->Read8( ReadD( _ACC_ ) + ( ++PC ) );\n";
|
||||
}
|
||||
if ($op_source == 21) { # DPTR
|
||||
print INST_IMP "unsigned int source = ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ );\n";
|
||||
}
|
||||
if ($op_source == 22) { # #data16
|
||||
print INST_IMP "unsigned char source = ( PGMMem->Read8( PC++ ) << 8 );\n";
|
||||
print INST_IMP "source += PGMMem->Read8( PC++ );\n";
|
||||
}
|
||||
if ($op_source == 23) { # /bitaddr
|
||||
print INST_IMP "unsigned char source, srcbitaddr = PGMMem->Read8( PC++ );\n";
|
||||
print INST_IMP "source = ( ReadB( srcbitaddr ) ^ 1 );\n";
|
||||
}
|
||||
if ($op_source == 24) { # @DPTR
|
||||
print INST_IMP "unsigned char source = ReadI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_) );\n";
|
||||
}
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
$modifysrc=0;
|
||||
# print INST_IMP "\n// Inserer le code ici\n\n";
|
||||
|
||||
# RR
|
||||
if ($insttype[$i] == 3) {
|
||||
print INST_IMP "destination = ( destination >> 1 ) | ( destination << 7 );\n";
|
||||
}
|
||||
|
||||
# INC
|
||||
if ($insttype[$i] == 4) {
|
||||
print INST_IMP "destination++;\n";
|
||||
}
|
||||
|
||||
# JBC
|
||||
if ($insttype[$i] == 5) {
|
||||
print INST_IMP "if ( destination == 1 ) { PC = source; destination = 0; }\n";
|
||||
}
|
||||
|
||||
# ACALL
|
||||
if ($insttype[$i] == 6) {
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "WriteI( ++SP, ( PC & 0x00FF ) );\n";
|
||||
print INST_IMP "WriteI( ++SP, ( PC >> 8 ) );\n";
|
||||
print INST_IMP "WriteD( _SP_, SP );\n";
|
||||
}
|
||||
|
||||
# LCALL
|
||||
if ($insttype[$i] == 7) {
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "WriteI( ++SP, ( PC & 0x00FF ) );\n";
|
||||
print INST_IMP "WriteI( ++SP, ( PC >> 8 ) );\n";
|
||||
print INST_IMP "WriteD( _SP_, SP );\n";
|
||||
}
|
||||
|
||||
# RRC
|
||||
if ($insttype[$i] == 8) {
|
||||
print INST_IMP "unsigned char tmpval = destination;\n";
|
||||
print INST_IMP "destination = ( destination >> 1 ) | ( ReadD( _PSW_ ) & 0x80 );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval << 7 ) );\n";
|
||||
}
|
||||
|
||||
# DEC
|
||||
if ($insttype[$i] == 9) {
|
||||
print INST_IMP "destination--;\n";
|
||||
}
|
||||
|
||||
# JB
|
||||
if ($insttype[$i] == 10) {
|
||||
print INST_IMP "if ( destination == 1 ) { PC = source; }\n";
|
||||
}
|
||||
|
||||
# RET
|
||||
if ($insttype[$i] == 11) {
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "PC = ( ReadI( SP-- ) << 8 );\n";
|
||||
print INST_IMP "PC += ReadI ( SP-- );\n";
|
||||
print INST_IMP "WriteD( _SP_, SP );\n";
|
||||
}
|
||||
|
||||
# RL
|
||||
if ($insttype[$i] == 12) {
|
||||
print INST_IMP "destination = ( destination << 1 ) | ( destination >> 7 );\n";
|
||||
}
|
||||
|
||||
# ADD
|
||||
if ($insttype[$i] == 13) {
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
|
||||
print INST_IMP "if ( destination + source > 0xFF ) {\n";
|
||||
print INST_IMP " WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP " if ( ( destination & 0x7F ) + ( source & 0x7F ) < 0x80 ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "} else if ( ( destination & 0x7F ) + ( source & 0x7F ) > 0x7F ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "if ( ( destination & 0x0F ) + ( source & 0x0F ) > 0x0F ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "destination += source;\n";
|
||||
}
|
||||
|
||||
# JNB
|
||||
if ($insttype[$i] == 14) {
|
||||
print INST_IMP "if ( destination == 0 ) { PC = source; }\n";
|
||||
}
|
||||
|
||||
# RETI
|
||||
if ($insttype[$i] == 15) {
|
||||
print INST_IMP "ActivePriority = -1;\n";
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "PC = ( ReadI( SP-- ) << 8 );\n";
|
||||
print INST_IMP "PC += ReadI( SP-- );\n";
|
||||
}
|
||||
|
||||
# RLC
|
||||
if ($insttype[$i] == 16) {
|
||||
print INST_IMP "unsigned char tmpval = destination;\n";
|
||||
print INST_IMP "destination = ( destination << 1 ) | ( ( ReadD( _PSW_ ) & 0x80 ) >> 7 );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) | ( tmpval & 0x80 ) );\n";
|
||||
}
|
||||
|
||||
# ADDC
|
||||
if ($insttype[$i] == 17) {
|
||||
print INST_IMP "unsigned char carryflag = ( ReadD( _PSW_ ) >> 7 );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
|
||||
print INST_IMP "if ( destination + source + carryflag > 0xFF ) {\n";
|
||||
print INST_IMP " WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP " if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag < 0x80 ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "} else if ( ( destination & 0x7F ) + ( source & 0x7F ) + carryflag > 0x7F ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "if ( ( destination & 0x0F ) + ( source & 0x0F ) + carryflag > 0x0F ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );\n";
|
||||
print INST_IMP "destination += source;\n";
|
||||
}
|
||||
|
||||
# JC
|
||||
if ($insttype[$i] == 18) {
|
||||
print INST_IMP "if ( ReadD( _PSW_ ) > 0x7F) { PC = destination; }\n";
|
||||
}
|
||||
|
||||
# ORL
|
||||
if ($insttype[$i] == 19) {
|
||||
if ($instargs[$i*4+1] == 17) {
|
||||
# sur des bits
|
||||
print INST_IMP "WriteD( _PSW_ , ( ( destination | source ) << 7 ) );\n";
|
||||
} else {
|
||||
# sur des bytes
|
||||
print INST_IMP "destination |= source;\n";
|
||||
}
|
||||
}
|
||||
|
||||
# JNC
|
||||
if ($insttype[$i] == 20) {
|
||||
print INST_IMP "if ( ReadD( _PSW_ ) < 0x80 ) { PC = destination; }\n";
|
||||
}
|
||||
|
||||
# ANL
|
||||
if ($insttype[$i] == 21) {
|
||||
if ($instargs[$i*4+1] == 17) {
|
||||
# sur des bits
|
||||
print INST_IMP "WriteD( _PSW_, ( ( destination & source) << 7 ) );\n";
|
||||
} else {
|
||||
# sur des bytes
|
||||
print INST_IMP "destination &= source;\n";
|
||||
}
|
||||
}
|
||||
|
||||
# JZ
|
||||
if ($insttype[$i] == 22) {
|
||||
print INST_IMP "if ( ReadD( _ACC_ ) == 0 ) { PC = destination; }\n";
|
||||
}
|
||||
|
||||
# XRL
|
||||
if ($insttype[$i] == 23) {
|
||||
print INST_IMP "destination ^= source;\n";
|
||||
}
|
||||
|
||||
# JNZ
|
||||
if ($insttype[$i] == 24) {
|
||||
print INST_IMP "if ( ReadD( _ACC_ ) != 0 ) { PC = destination; }\n";
|
||||
}
|
||||
|
||||
# JMP
|
||||
if ($insttype[$i] == 25) {
|
||||
print INST_IMP "PC = destination;\n";
|
||||
}
|
||||
|
||||
# MOV
|
||||
if ($insttype[$i] == 26) {
|
||||
print INST_IMP "destination = source;\n";
|
||||
}
|
||||
|
||||
# SJMP
|
||||
if ($insttype[$i] == 27) {
|
||||
print INST_IMP "PC = destination;\n";
|
||||
}
|
||||
|
||||
# MOVC
|
||||
if ($insttype[$i] == 28) {
|
||||
print INST_IMP "destination = source;\n";
|
||||
}
|
||||
|
||||
# DIV
|
||||
if ($insttype[$i] == 29) {
|
||||
print INST_IMP "unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );\n";
|
||||
print INST_IMP "if ( B != 0 ) {\n";
|
||||
print INST_IMP "WriteD( _ACC_, A/B ); WriteD( _B_, A%B );\n";
|
||||
print INST_IMP "} else WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
}
|
||||
|
||||
# SUBB
|
||||
if ($insttype[$i] == 30) {
|
||||
print INST_IMP "unsigned char carryflag = ReadD( _PSW_ ) >> 7;\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x3B ) );\n";
|
||||
print INST_IMP "if ( destination < ( source + carryflag ) ) {\n";
|
||||
print INST_IMP " WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP " if ( ( destination & 0x7F ) > ( ( source + carryflag ) & 0x7F ) ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "} else if ( ( destination & 0x7F ) < ( ( source + carryflag ) & 0x7F ) ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
print INST_IMP "if ( ( destination & 0x0F ) < ( ( source + carryflag ) & 0x0F ) ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x40 ) );\n";
|
||||
print INST_IMP "destination -= source + carryflag;\n";
|
||||
}
|
||||
|
||||
# MUL
|
||||
if ($insttype[$i] == 31) {
|
||||
print INST_IMP "unsigned char A = ReadD( _ACC_ ), B = ReadD( _B_ );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7B ) );\n";
|
||||
print INST_IMP "WriteD( _ACC_ , ( ( A * B ) & 0x00FF ) ); WriteD( _B_, ( A * B ) / 0x100 );\n";
|
||||
print INST_IMP "if ( ReadD( _B_ ) > 0) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x04 ) );\n";
|
||||
}
|
||||
|
||||
# CPL
|
||||
if ($insttype[$i] == 33) {
|
||||
if ($instargs[$i*4+1] == 2) { print INST_IMP "destination ^= 0xFF;\n"; }
|
||||
else { print INST_IMP "destination ^= 0x01;\n"; }
|
||||
}
|
||||
|
||||
# CJNE
|
||||
if ($insttype[$i] == 34) {
|
||||
print INST_IMP "unsigned int reladdr = ( ( PGMMem->Read8( PC ) + ( ( PC + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( PC + 1 ) & 0xFF00 );\n";
|
||||
print INST_IMP "WriteD( _PSW_, ( ReadD( _PSW_ ) & 0x7F ) );\n";
|
||||
print INST_IMP "if ( destination < source ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP "if ( destination != source ) PC = reladdr;\n";
|
||||
}
|
||||
|
||||
# PUSH
|
||||
if ($insttype[$i] == 35) {
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "WriteI( ++SP, destination );\n";
|
||||
print INST_IMP "WriteD( _SP_, SP );\n";
|
||||
}
|
||||
|
||||
# CLR
|
||||
if ($insttype[$i] == 36) {
|
||||
print INST_IMP "destination = 0;\n";
|
||||
}
|
||||
|
||||
# SWAP
|
||||
if ($insttype[$i] == 37) {
|
||||
print INST_IMP "destination = ( destination << 4 ) + ( destination >> 4 );\n";
|
||||
}
|
||||
|
||||
# XCH
|
||||
if ($insttype[$i] == 38) {
|
||||
print INST_IMP "unsigned char tmpval = destination;\n";
|
||||
print INST_IMP "destination = source; source = tmpval;\n";
|
||||
$modifysrc=1;
|
||||
}
|
||||
|
||||
# POP
|
||||
if ($insttype[$i] == 39) {
|
||||
print INST_IMP "unsigned char SP = ReadD( _SP_ );\n";
|
||||
print INST_IMP "destination = ReadI( SP-- );\n";
|
||||
print INST_IMP "WriteD( _SP_, SP );\n";
|
||||
}
|
||||
|
||||
# SETB
|
||||
if ($insttype[$i] == 40) {
|
||||
print INST_IMP "destination = 1;\n";
|
||||
}
|
||||
|
||||
# DA
|
||||
if ($insttype[$i] == 41) {
|
||||
print INST_IMP "if ( ( ( destination & 0x0F ) > 9) || ( ReadD( _PSW_ ) | 0x40)) {\n";
|
||||
print INST_IMP " if ( ( destination + 6 ) > 0xFF) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP " destination += 6;\n";
|
||||
print INST_IMP "}\n";
|
||||
print INST_IMP "if ( ( ReadD( _PSW_ ) & 0x80) || ( ( destination & 0xF0 ) > 0x90 ) ) {\n";
|
||||
print INST_IMP " if ( ( destination + 0x60 ) > 0xFF ) WriteD( _PSW_, ( ReadD( _PSW_ ) | 0x80 ) );\n";
|
||||
print INST_IMP " destination += 0x60;\n";
|
||||
print INST_IMP "}\n";
|
||||
}
|
||||
|
||||
# DJNZ
|
||||
if ($insttype[$i] == 42) {
|
||||
print INST_IMP "destination--;\n";
|
||||
print INST_IMP "if ( destination != 0 ) PC = source;\n";
|
||||
}
|
||||
|
||||
# XCHD
|
||||
if ($insttype[$i] == 43) {
|
||||
print INST_IMP "unsigned char tmpval = ( destination & 0x0F );\n";
|
||||
print INST_IMP "destination = ( destination & 0xF0 ) + ( source & 0x0F );\n";
|
||||
print INST_IMP "source = ( source & 0xF0 ) + tmpval;\n";
|
||||
$modifysrc=1;
|
||||
}
|
||||
|
||||
# MOVX
|
||||
if ($insttype[$i] == 44) {
|
||||
print INST_IMP "destination = source;\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
||||
if ($instargs[$i*4] > 0) {
|
||||
$op_destination=$instargs[$i*4+1];
|
||||
if ($op_destination == 0) { # addr11
|
||||
print INST_IMP "PC = ( PC & 0xF800 ) | addr11;\n";
|
||||
}
|
||||
if ($op_destination == 1) { # addr16
|
||||
print INST_IMP "PC = addr16;\n";
|
||||
}
|
||||
if ($op_destination == 2) { # A
|
||||
print INST_IMP "WriteD( _ACC_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 3) { # direct
|
||||
print INST_IMP "WriteD( destaddr, destination );\n";
|
||||
}
|
||||
if ($op_destination == 4) { # @R0
|
||||
print INST_IMP "WriteI( ReadD( BANKPSW + _R0_ ), destination );\n";
|
||||
}
|
||||
if ($op_destination == 5) { # @R1
|
||||
print INST_IMP "WriteI( ReadD( BANKPSW + _R1_ ), destination );\n";
|
||||
}
|
||||
if ($op_destination == 6) { # R0
|
||||
print INST_IMP "WriteD( BANKPSW + _R0_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 7) { # R1
|
||||
print INST_IMP "WriteD( BANKPSW + _R1_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 8) { # R2
|
||||
print INST_IMP "WriteD( BANKPSW + _R2_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 9) { # R3
|
||||
print INST_IMP "WriteD( BANKPSW + _R3_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 10) { # R4
|
||||
print INST_IMP "WriteD( BANKPSW + _R4_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 11) { # R5
|
||||
print INST_IMP "WriteD( BANKPSW + _R5_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 12) { # R6
|
||||
print INST_IMP "WriteD( BANKPSW + _R6_, destination );\n";
|
||||
}
|
||||
if ($op_destination == 13) { # R7
|
||||
print INST_IMP "WriteD( BANKPSW + _R7_, destination );\n";
|
||||
}
|
||||
|
||||
if ($op_destination == 14) { # bitaddr
|
||||
print INST_IMP "WriteB( dstbitaddr, destination );\n";
|
||||
}
|
||||
if ($op_destination == 17) { # C
|
||||
print INST_IMP "WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( destination << 7 ) ) );\n";
|
||||
}
|
||||
if ($op_destination == 21) { # DPTR
|
||||
print INST_IMP "WriteD( _DPTRHIGH_, ( destination >> 8 ) );\n";
|
||||
print INST_IMP "WriteD( _DPTRLOW_, ( destination & 0xFF ) );\n";
|
||||
}
|
||||
if ($op_destination == 23) { # /bitaddr
|
||||
print INST_IMP "WriteB( dstbitaddr, destination );\n";
|
||||
}
|
||||
if ($op_destination == 24) { # @DPTR
|
||||
print INST_IMP "WriteI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ ), destination );\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($modifysrc == 1) {
|
||||
if ($instargs[$i*4] > 1) {
|
||||
$op_source=$instargs[$i*4+2];
|
||||
if ($op_source == 0) { # addr11
|
||||
print INST_IMP "PC = ( PC & 0xF800 ) | addr11;\n";
|
||||
}
|
||||
if ($op_source == 1) { # addr16
|
||||
print INST_IMP "PC = addr16;\n";
|
||||
}
|
||||
if ($op_source == 2) { # A
|
||||
print INST_IMP "WriteD( _ACC_, source );\n";
|
||||
}
|
||||
if ($op_source == 3) { # direct
|
||||
print INST_IMP "WriteD( srcaddr, source );\n";
|
||||
}
|
||||
if ($op_source == 4) { # @R0
|
||||
print INST_IMP "WriteI( ReadD( BANKPSW + _R0_ ), source );\n";
|
||||
}
|
||||
if ($op_source == 5) { # @R1
|
||||
print INST_IMP "WriteI( ReadD( BANKPSW + _R1_ ), source );\n";
|
||||
}
|
||||
if ($op_source == 6) { # R0
|
||||
print INST_IMP "WriteD( BANKPSW + _R0_, source );\n";
|
||||
}
|
||||
if ($op_source == 7) { # R1
|
||||
print INST_IMP "WriteD( BANKPSW + _R1_, source );\n";
|
||||
}
|
||||
if ($op_source == 8) { # R2
|
||||
print INST_IMP "WriteD( BANKPSW + _R2_, source );\n";
|
||||
}
|
||||
if ($op_source == 9) { # R3
|
||||
print INST_IMP "WriteD( BANKPSW + _R3_, source );\n";
|
||||
}
|
||||
if ($op_source == 10) { # R4
|
||||
print INST_IMP "WriteD( BANKPSW + _R4_, source );\n";
|
||||
}
|
||||
if ($op_source == 11) { # R5
|
||||
print INST_IMP "WriteD( BANKPSW + _R5_, source );\n";
|
||||
}
|
||||
if ($op_source == 12) { # R6
|
||||
print INST_IMP "WriteD( BANKPSW + _R6_, source );\n";
|
||||
}
|
||||
if ($op_source == 13) { # R7
|
||||
print INST_IMP "WriteD( BANKPSW + _R7_, source );\n";
|
||||
}
|
||||
if ($op_source == 14) { # bitaddr
|
||||
print INST_IMP "WriteB( srcbitaddr, source );\n";
|
||||
}
|
||||
if ($op_source == 17) { # C
|
||||
print INST_IMP "WriteD( _PSW_, ( ( ReadD( _PSW_ ) & 0x7F) | ( source << 7 ) ) );\n";
|
||||
}
|
||||
if ($op_source == 21) { # DPTR
|
||||
print INST_IMP "WriteD( _DPTRHIGH_, ( source >> 8 ) );\n";
|
||||
print INST_IMP "WriteD( _DPTRLOW_, ( source & 0xFF ) );\n";
|
||||
}
|
||||
if ($op_source == 23) { # /bitaddr
|
||||
print INST_IMP "WriteB( srcbitaddr, source );\n";
|
||||
}
|
||||
if ($op_source == 24) { # @DPTR
|
||||
print INST_IMP "WriteI( ( ReadD( _DPTRHIGH_ ) << 8 ) + ReadD( _DPTRLOW_ ), source );\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print INST_IMP "return $a_cycles[$i];\n";
|
||||
print INST_IMP "}\n";
|
||||
print INST_IMP "\n\n";
|
||||
}
|
||||
# ------------------------------------------------------------------------------
|
||||
print INST_IMP "\n\n";
|
||||
|
||||
print INST_IMP "/"x78,"\n";
|
||||
print INST_IMP "// void CPU8051::InitFuncPtr( )\n";
|
||||
print INST_IMP "// Initialize Functions Pointers\n";
|
||||
print INST_IMP "/"x78,"\n";
|
||||
print INST_IMP "void CPU8051::InitFuncPtr( )\n";
|
||||
print INST_DEF "void InitFuncPtr( );\n";
|
||||
print INST_IMP "{\n";
|
||||
|
||||
|
||||
#print INST_IMP "static int (*instfnc[])() = {\n";
|
||||
for ($i=0;$i<256;$i++) {
|
||||
$ifunc=substr($instfunction[$i], 9);
|
||||
print INST_IMP " funcptr[$i]=&CPU8051::$ifunc;\n";
|
||||
# ($i < 255) and print INST_IMP ",\n";
|
||||
# (($i+1) % 4 == 0) and print INST_IMP "\n";
|
||||
}
|
||||
print INST_IMP "\n}\n";
|
||||
|
||||
print INST_IMP "\n\n#endif\n";
|
||||
print INST_DEF "\n\n#endif\n";
|
||||
print DISASM_HPP "\n\n#endif\n";
|
||||
|
||||
|
||||
close DISASM_HPP;
|
||||
close OPCODELST;
|
||||
close INST_DEF;
|
||||
close INST_IMP;
|
||||
|
||||
|
186
src/PgmWin.cpp
Normal file
186
src/PgmWin.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* pgmwin.cpp */
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "PgmWin.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
int PgmWinNumber = 0;
|
||||
int PgmWinNumbers[ 1 ];
|
||||
PgmWin *PgmWinPtrs[ 1 ];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// PgmWin::PgmWin( GtkWidget *parentwin, CPU8051 *mCPU )
|
||||
// PgmWin constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
PgmWin::PgmWin( GtkWidget *parentwin, CPU8051 *mCPU )
|
||||
{
|
||||
CPU = mCPU;
|
||||
int i;
|
||||
GtkStyle *style;
|
||||
GdkFont *fixedfont;
|
||||
fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
|
||||
|
||||
pgmclist = gtk_clist_new( 1 );
|
||||
gtk_clist_set_selection_mode( GTK_CLIST( pgmclist ), GTK_SELECTION_SINGLE );
|
||||
gtk_widget_set_usize( GTK_WIDGET( pgmclist ), PGM_WIN_WIDTH, PGM_WIN_HEIGHT );
|
||||
gtk_clist_set_column_justification( GTK_CLIST( pgmclist ), 0, GTK_JUSTIFY_LEFT );
|
||||
gtk_clist_set_column_width( GTK_CLIST( pgmclist ), 0, PGM_WIN_WIDTH-10 );
|
||||
|
||||
style = gtk_widget_get_style( GTK_WIDGET( pgmclist ) );
|
||||
|
||||
#ifdef USE_GTK2
|
||||
gtk_style_set_font( style, fixedfont );
|
||||
#else
|
||||
style->font = fixedfont;
|
||||
#endif
|
||||
|
||||
gtk_widget_set_style( GTK_WIDGET( pgmclist ), style );
|
||||
|
||||
char *pgmdummy[] = { 0 };
|
||||
for ( i = 0; i < 24; i++ ) gtk_clist_append( GTK_CLIST( pgmclist ), pgmdummy );
|
||||
|
||||
gtk_container_add( GTK_CONTAINER( parentwin ), pgmclist );
|
||||
|
||||
gtk_widget_show( pgmclist );
|
||||
|
||||
NbBreakpoints = 0;
|
||||
|
||||
if ( PgmWinNumber >= 1 ) g_print( "WARNING! Too many PgmWin objects to handle signals!\n");
|
||||
else {
|
||||
PgmWinPtrs[ PgmWinNumber ] = this;
|
||||
PgmWinNumbers[ PgmWinNumber ] = PgmWinNumber;
|
||||
gtk_signal_connect( GTK_OBJECT( pgmclist ), "button-press-event", GTK_SIGNAL_FUNC( PgmWinButtonPress ), &PgmWinNumbers[ PgmWinNumber++ ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// PgmWin::~PgmWin( )
|
||||
// PgmWin destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
PgmWin::~PgmWin( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void PgmWin::Disasm( )
|
||||
// Disasm 24 lines from CPU
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWin::Disasm( )
|
||||
{
|
||||
char TextTmp[255];
|
||||
int row;
|
||||
//int TextLength;
|
||||
int InstSize;
|
||||
unsigned int Address;
|
||||
Address = CPU->GetPC( );
|
||||
|
||||
gtk_clist_freeze( GTK_CLIST( pgmclist ) );
|
||||
for ( row = 0; row < 24; row++ ) {
|
||||
InstSize = CPU->Disasm( Address, TextTmp );
|
||||
if ( IsBreakpoint( Address ) ) TextTmp[0] = '*';
|
||||
gtk_clist_set_text( GTK_CLIST( pgmclist ), row, 0, TextTmp );
|
||||
DisasmAddresses[ row ] = Address;
|
||||
Address += InstSize;
|
||||
}
|
||||
gtk_clist_select_row( GTK_CLIST( pgmclist ), 0, 0 );
|
||||
gtk_clist_thaw( GTK_CLIST( pgmclist ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// gint PgmWin::ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
// Mouse button pressed in the window
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
gint PgmWin::ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
{
|
||||
gint row, column;
|
||||
char TextTmp[ 255 ];
|
||||
//g_print( "PgmWin::ButtonPressEvent(...)\n" );
|
||||
gtk_clist_get_selection_info( GTK_CLIST( pgmclist ), ( int )event->button.x ,( int )event->button.y, &row, &column );
|
||||
if (row >= 24 || row < 0)
|
||||
return TRUE;
|
||||
if (column >= 1 || column < 0)
|
||||
return TRUE;
|
||||
sprintf( TextTmp, "PgmWin::ButtonPressEvent( ) at %d,%d\n", column, row );
|
||||
g_print( TextTmp );
|
||||
ToggleBreakpoint( DisasmAddresses[ row ] );
|
||||
Disasm( );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// gint PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
// Signal Stub with 3 parameters
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data )
|
||||
{
|
||||
int PWNumber = (* ( static_cast< int * >( data ) ) );
|
||||
PgmWinPtrs[ PWNumber ]->ButtonPressEvent( widget, event, 0 );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void PgmWin::ShowBreakpoints( )
|
||||
// Show Breakpoints list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWin::ShowBreakpoints( )
|
||||
{
|
||||
for ( int Index = 0; Index < NbBreakpoints ; Index++ )
|
||||
printf( "Breakpoint at Address = %.4X\n", Breakpoints[ Index ] );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void PgmWin::ClearBreakpoint( unsigned int Address )
|
||||
// Clear Breakpoint at Address from list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWin::ClearBreakpoint( unsigned int Address )
|
||||
{
|
||||
int Index = 0;
|
||||
while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
|
||||
if ( Breakpoints[ Index ] != Address ) return;
|
||||
Breakpoints[ Index ] = Breakpoints[ NbBreakpoints - 1 ];
|
||||
NbBreakpoints--;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void PgmWin::SetBreakpoint( unsigned int Address )
|
||||
// Set Breakpoint at Address from list
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWin::SetBreakpoint( unsigned int Address )
|
||||
{
|
||||
if ( IsBreakpoint( Address ) ) return;
|
||||
if ( NbBreakpoints < MAXBP ) Breakpoints[ NbBreakpoints++ ] = Address;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// int PgmWin::IsBreakpoint( unsigned int Address )
|
||||
// Is the a breakpoint at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int PgmWin::IsBreakpoint( unsigned int Address )
|
||||
{
|
||||
int Index = 0;
|
||||
while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++;
|
||||
return ( Breakpoints[ Index ] == Address && Index < NbBreakpoints );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void PgmWin::ToggleBreakpoint( unsigned int Address )
|
||||
// Toggle the breakpoint at Address
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void PgmWin::ToggleBreakpoint( unsigned int Address )
|
||||
{
|
||||
if ( IsBreakpoint( Address ) ) ClearBreakpoint( Address );
|
||||
else SetBreakpoint( Address );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
41
src/PgmWin.hpp
Normal file
41
src/PgmWin.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef _PGMWIN_HPP_
|
||||
#define _PGMWIN_HPP_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "CPU8051.hpp"
|
||||
#include "GtkSizes.hpp"
|
||||
|
||||
#define MAXBP 32
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// PgmWin
|
||||
// Implements a Program Window in Gtk+ as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class PgmWin {
|
||||
public:
|
||||
PgmWin( GtkWidget *parentwin, CPU8051 *mCPU );
|
||||
~PgmWin( );
|
||||
|
||||
void Disasm( );
|
||||
gint ButtonPressEvent( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
|
||||
void ShowBreakpoints( );
|
||||
void SetBreakpoint( unsigned int Address );
|
||||
void ClearBreakpoint( unsigned int Address );
|
||||
int IsBreakpoint( unsigned int Address );
|
||||
void ToggleBreakpoint( unsigned int Address );
|
||||
|
||||
private:
|
||||
CPU8051 *CPU;
|
||||
GtkWidget *pgmwin;
|
||||
GtkWidget *pgmclist;
|
||||
int NbBreakpoints;
|
||||
unsigned int Breakpoints[ MAXBP ];
|
||||
unsigned int DisasmAddresses[ 24 ];
|
||||
|
||||
};
|
||||
|
||||
void PgmWinButtonPress( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||
|
||||
|
||||
#endif
|
44
src/Reg8051.hpp
Normal file
44
src/Reg8051.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __REGISTRES8051_HPP_
|
||||
#define __REGISTRES8051_HPP_
|
||||
|
||||
// SFR Registers ( $80 - $FF )
|
||||
#define _ACC_ 0xE0
|
||||
#define _B_ 0xF0
|
||||
#define _PSW_ 0xD0
|
||||
#define _SP_ 0x81
|
||||
#define _DPTRLOW_ _DPL_
|
||||
#define _DPTRHIGH_ _DPH_
|
||||
#define _DPL_ 0x82
|
||||
#define _DPH_ 0x83
|
||||
#define _P0_ 0x80
|
||||
#define _P1_ 0x90
|
||||
#define _P2_ 0xA0
|
||||
#define _P3_ 0xB0
|
||||
#define _IP_ 0xB8
|
||||
#define _IE_ 0xA8
|
||||
#define _TMOD_ 0x89
|
||||
#define _TCON_ 0x88
|
||||
#define _TH0_ 0x8C
|
||||
#define _TL0_ 0x8A
|
||||
#define _TH1_ 0x8D
|
||||
#define _TL1_ 0x8B
|
||||
#define _SCON_ 0x98
|
||||
#define _SBUF_ 0x99
|
||||
#define _PCON_ 0x87
|
||||
#define _T2CON_ 0xC8
|
||||
|
||||
#define _R0_ 0x00
|
||||
#define _R1_ 0x01
|
||||
#define _R2_ 0x02
|
||||
#define _R3_ 0x03
|
||||
#define _R4_ 0x04
|
||||
#define _R5_ 0x05
|
||||
#define _R6_ 0x06
|
||||
#define _R7_ 0x07
|
||||
|
||||
#define _BANK0_ 0x00
|
||||
#define _BANK1_ 0x08
|
||||
#define _BANK2_ 0x10
|
||||
#define _BANK3_ 0x18
|
||||
|
||||
#endif
|
131
src/RegWin.cpp
Normal file
131
src/RegWin.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/* regwin.cpp */
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "RegWin.hpp"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// RegWin::RegWin( GtkWidget *parentwin )
|
||||
// RegWin constructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
RegWin::RegWin( GtkWidget *parentwin )
|
||||
{
|
||||
int i;
|
||||
GtkStyle *style;
|
||||
GdkFont *fixedfont;
|
||||
fixedfont = gdk_font_load( "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" );
|
||||
|
||||
regclist = gtk_clist_new( 1 );
|
||||
gtk_clist_set_selection_mode( GTK_CLIST( regclist ), GTK_SELECTION_SINGLE );
|
||||
gtk_widget_set_usize( GTK_WIDGET( regclist ), REG_WIN_WIDTH, REG_WIN_HEIGHT );
|
||||
gtk_clist_set_column_justification( GTK_CLIST( regclist ), 0, GTK_JUSTIFY_LEFT );
|
||||
gtk_clist_set_column_width( GTK_CLIST( regclist ), 0, REG_WIN_WIDTH );
|
||||
|
||||
style = gtk_widget_get_style( GTK_WIDGET( regclist ) );
|
||||
|
||||
#ifdef USE_GTK2
|
||||
gtk_style_set_font( style, fixedfont );
|
||||
#else
|
||||
style->font = fixedfont;
|
||||
#endif
|
||||
|
||||
gtk_widget_set_style( GTK_WIDGET( regclist ), style );
|
||||
|
||||
char *regdummy[] = { 0 };
|
||||
for ( i = 0; i < 24; i++ )
|
||||
gtk_clist_append( GTK_CLIST( regclist ), regdummy );
|
||||
|
||||
gtk_container_add( GTK_CONTAINER( parentwin ), regclist );
|
||||
|
||||
gtk_widget_show( regclist );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// RegWin::~RegWin( )
|
||||
// RegWin destructor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
RegWin::~RegWin( )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// void RegWin::Show( CPU8051 *CPU )
|
||||
// Show registers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void RegWin::Show( CPU8051 *CPU )
|
||||
{
|
||||
char TextTmp[255];
|
||||
int row = 0;
|
||||
unsigned char PSW = CPU->ReadD( _PSW_ );
|
||||
unsigned char Rbank;
|
||||
|
||||
gtk_clist_freeze( GTK_CLIST( regclist ) );
|
||||
|
||||
// Main registers
|
||||
sprintf( TextTmp , "PC = %.4X", CPU->GetPC( ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "SP = %.2X", CPU->ReadD( _SP_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "A = %.2X", CPU->ReadD( _ACC_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "B = %.2X", CPU->ReadD( _B_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "DPTR = %.4X", ( CPU->ReadD( _DPTRHIGH_ ) << 8 ) + CPU->ReadD( _DPTRLOW_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
|
||||
// Program Status Word
|
||||
sprintf( TextTmp , "PSW = %.2X",PSW);
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
|
||||
// Ports registers
|
||||
sprintf( TextTmp , "P0 = %.2X", CPU->ReadD( _P0_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "P1 = %.2X", CPU->ReadD( _P1_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "P2 = %.2X", CPU->ReadD( _P2_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "P3 = %.2X", CPU->ReadD( _P3_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
|
||||
// Misc Registers
|
||||
sprintf( TextTmp , "TCON = %.2X", CPU->ReadD( _TCON_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "TMOD = %.2X", CPU->ReadD( _TMOD_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "SCON = %.2X", CPU->ReadD( _SCON_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "IE = %.2X", CPU->ReadD( _IE_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "IP = %.2X", CPU->ReadD( _IP_ ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
|
||||
// R0-R7 Registers in current Bank
|
||||
Rbank = CPU->ReadD( _PSW_ ) & 0x18;
|
||||
sprintf( TextTmp , "Bank = %.2X", Rbank);
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R0 = %.2X", CPU->ReadD( _R0_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R1 = %.2X", CPU->ReadD( _R1_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R2 = %.2X", CPU->ReadD( _R2_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R3 = %.2X", CPU->ReadD( _R3_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R4 = %.2X", CPU->ReadD( _R4_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R5 = %.2X", CPU->ReadD( _R5_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R6 = %.2X", CPU->ReadD( _R6_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
sprintf( TextTmp , "R7 = %.2X", CPU->ReadD( _R7_ + Rbank ) );
|
||||
gtk_clist_set_text( GTK_CLIST( regclist ), row++, 0, TextTmp );
|
||||
|
||||
gtk_clist_select_row(GTK_CLIST(regclist),0,0);
|
||||
gtk_clist_thaw( GTK_CLIST( regclist ) );
|
||||
}
|
26
src/RegWin.hpp
Normal file
26
src/RegWin.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _REGWIN_HPP_
|
||||
#define _REGWIN_HPP_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "CPU8051.hpp"
|
||||
#include "GtkSizes.hpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// RegWin
|
||||
// Implements a Registers Window in Gtk+ as an Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class RegWin {
|
||||
public:
|
||||
RegWin( GtkWidget *parentwin );
|
||||
~RegWin( );
|
||||
|
||||
void Show( CPU8051 *CPU );
|
||||
|
||||
private:
|
||||
GtkWidget *regwin;
|
||||
GtkWidget *regclist;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
211
src/disasm.hpp
Normal file
211
src/disasm.hpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#ifndef __DISASM_HPP_
|
||||
#define __DISASM_HPP_
|
||||
// Do not modify this file directly, it was created by Opcode2cpp.pl
|
||||
// Any modification made directly on this file will be lost
|
||||
|
||||
|
||||
// For all 256 opcodes, the value in this table gives the instruction type
|
||||
// ex.: MOV, INC, CLR, CPL,...
|
||||
// To know what is the instruction type, use the number as an offset in the InstTextTbl[]
|
||||
static int InstTypesTbl[] = {
|
||||
0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
10, 1, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
14, 6, 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
18, 1, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
20, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
22, 1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
24, 6, 19, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
27, 1, 21, 28, 29, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 6, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
|
||||
19, 1, 26, 4, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
21, 6, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
35, 1, 36, 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
|
||||
39, 6, 40, 40, 41, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||
44, 1, 44, 44, 36, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
44, 6, 44, 44, 33, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
|
||||
};
|
||||
|
||||
|
||||
// Size(in bytes) of each instruction (offset in table is instruction opcode)
|
||||
static int InstSizesTbl[] = {
|
||||
1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
3, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
3, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
3, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 1, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 1, 1, 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
|
||||
// List of instructions types referenced by InstTypesTbl[]
|
||||
#define InstTextTblLength 45
|
||||
static char *InstTextTbl[] = {
|
||||
"NOP",
|
||||
"AJMP",
|
||||
"LJMP",
|
||||
"RR",
|
||||
"INC",
|
||||
"JBC",
|
||||
"ACALL",
|
||||
"LCALL",
|
||||
"RRC",
|
||||
"DEC",
|
||||
"JB",
|
||||
"RET",
|
||||
"RL",
|
||||
"ADD",
|
||||
"JNB",
|
||||
"RETI",
|
||||
"RLC",
|
||||
"ADDC",
|
||||
"JC",
|
||||
"ORL",
|
||||
"JNC",
|
||||
"ANL",
|
||||
"JZ",
|
||||
"XRL",
|
||||
"JNZ",
|
||||
"JMP",
|
||||
"MOV",
|
||||
"SJMP",
|
||||
"MOVC",
|
||||
"DIV",
|
||||
"SUBB",
|
||||
"MUL",
|
||||
"INVALID",
|
||||
"CPL",
|
||||
"CJNE",
|
||||
"PUSH",
|
||||
"CLR",
|
||||
"SWAP",
|
||||
"XCH",
|
||||
"POP",
|
||||
"SETB",
|
||||
"DA",
|
||||
"DJNZ",
|
||||
"XCHD",
|
||||
"MOVX"
|
||||
};
|
||||
|
||||
|
||||
// Table describing all arguments types of an instruction
|
||||
// The table is indexed InstArgTbl[ opcode * 4]
|
||||
// InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has
|
||||
// InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument
|
||||
// for most instructions, the 3rd argument isn't used
|
||||
// the argument type is referecing to ArgsTextTbl[]
|
||||
#define InstArgTblLength 256
|
||||
static int InstArgTbl[] = {
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0,
|
||||
1, 2, 0, 0, 1, 3, 0, 0, 1, 4, 0, 0, 1, 5, 0, 0,
|
||||
1, 6, 0, 0, 1, 7, 0, 0, 1, 8, 0, 0, 1, 9, 0, 0,
|
||||
1, 10, 0, 0, 1, 11, 0, 0, 1, 12, 0, 0, 1, 13, 0, 0,
|
||||
2, 14, 15, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0,
|
||||
1, 2, 0, 0, 1, 3, 0, 0, 1, 4, 0, 0, 1, 5, 0, 0,
|
||||
1, 6, 0, 0, 1, 7, 0, 0, 1, 8, 0, 0, 1, 9, 0, 0,
|
||||
1, 10, 0, 0, 1, 11, 0, 0, 1, 12, 0, 0, 1, 13, 0, 0,
|
||||
2, 14, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
2, 14, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
1, 15, 0, 0, 1, 0, 0, 0, 2, 3, 2, 0, 2, 3, 16, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
1, 15, 0, 0, 1, 0, 0, 0, 2, 17, 14, 0, 1, 18, 0, 0,
|
||||
2, 2, 16, 0, 2, 3, 16, 0, 2, 4, 16, 0, 2, 5, 16, 0,
|
||||
2, 6, 16, 0, 2, 7, 16, 0, 2, 8, 16, 0, 2, 9, 16, 0,
|
||||
2, 10, 16, 0, 2, 11, 16, 0, 2, 12, 16, 0, 2, 13, 16, 0,
|
||||
1, 15, 0, 0, 1, 0, 0, 0, 2, 17, 14, 0, 2, 2, 19, 0,
|
||||
1, 20, 0, 0, 2, 3, 3, 0, 2, 3, 4, 0, 2, 3, 5, 0,
|
||||
2, 3, 6, 0, 2, 3, 7, 0, 2, 3, 8, 0, 2, 3, 9, 0,
|
||||
2, 3, 10, 0, 2, 3, 11, 0, 2, 3, 12, 0, 2, 3, 13, 0,
|
||||
2, 21, 22, 0, 1, 0, 0, 0, 2, 14, 17, 0, 2, 2, 18, 0,
|
||||
2, 2, 16, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
2, 17, 23, 0, 1, 0, 0, 0, 2, 17, 14, 0, 1, 21, 0, 0,
|
||||
1, 20, 0, 0, 0, 0, 0, 0, 2, 4, 3, 0, 2, 5, 3, 0,
|
||||
2, 6, 3, 0, 2, 7, 3, 0, 2, 8, 3, 0, 2, 9, 3, 0,
|
||||
2, 10, 3, 0, 2, 11, 3, 0, 2, 12, 3, 0, 2, 13, 3, 0,
|
||||
2, 17, 23, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
|
||||
3, 2, 16, 15, 3, 2, 3, 15, 3, 4, 16, 15, 3, 5, 16, 15,
|
||||
3, 6, 16, 15, 3, 7, 16, 15, 3, 8, 16, 15, 3, 9, 16, 15,
|
||||
3, 10, 16, 15, 3, 11, 16, 15, 3, 12, 16, 15, 3, 13, 16, 15,
|
||||
1, 3, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
|
||||
1, 2, 0, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
1, 3, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 1, 17, 0, 0,
|
||||
1, 2, 0, 0, 2, 3, 15, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 6, 15, 0, 2, 7, 15, 0, 2, 8, 15, 0, 2, 9, 15, 0,
|
||||
2, 10, 15, 0, 2, 11, 15, 0, 2, 12, 15, 0, 2, 13, 15, 0,
|
||||
2, 2, 24, 0, 1, 0, 0, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
1, 2, 0, 0, 2, 2, 3, 0, 2, 2, 4, 0, 2, 2, 5, 0,
|
||||
2, 2, 6, 0, 2, 2, 7, 0, 2, 2, 8, 0, 2, 2, 9, 0,
|
||||
2, 2, 10, 0, 2, 2, 11, 0, 2, 2, 12, 0, 2, 2, 13, 0,
|
||||
2, 24, 2, 0, 1, 0, 0, 0, 2, 4, 2, 0, 2, 5, 2, 0,
|
||||
1, 2, 0, 0, 2, 3, 2, 0, 2, 4, 2, 0, 2, 5, 2, 0,
|
||||
2, 6, 2, 0, 2, 7, 2, 0, 2, 8, 2, 0, 2, 9, 2, 0,
|
||||
2, 10, 2, 0, 2, 11, 2, 0, 2, 12, 2, 0, 2, 13, 2, 0
|
||||
};
|
||||
|
||||
|
||||
// List all types of arguments available to instructions
|
||||
// Referenced by InstArgsTbl[]
|
||||
#define ArgsTextTblLength 25
|
||||
static char *ArgsTextTbl[] = {
|
||||
"addr11",
|
||||
"addr16",
|
||||
"A",
|
||||
"direct",
|
||||
"@R0",
|
||||
"@R1",
|
||||
"R0",
|
||||
"R1",
|
||||
"R2",
|
||||
"R3",
|
||||
"R4",
|
||||
"R5",
|
||||
"R6",
|
||||
"R7",
|
||||
"bitaddr",
|
||||
"reladdr",
|
||||
"#data",
|
||||
"C",
|
||||
"@A+DPTR",
|
||||
"@A+PC",
|
||||
"AB",
|
||||
"DPTR",
|
||||
"#data16",
|
||||
"/bitaddr",
|
||||
"@DPTR"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
19
src/exceptions.hpp
Normal file
19
src/exceptions.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Exceptions.hpp
|
||||
// Gestion des erreurs pour le programme d'emulation du 8051.
|
||||
|
||||
#ifndef _EXCEPTION_HPP_
|
||||
#define _EXCEPTION_HPP_
|
||||
|
||||
class ShowOptions { /* ... */ };
|
||||
class FinishedLoading { /* ... */ };
|
||||
class ErrorOpeningFile { /* ... */ };
|
||||
class ErrorHexFileFormat { /* ... */ };
|
||||
class SyntaxError { /* ... */ };
|
||||
class InvalidAddress { /* ... */ };
|
||||
class MissingParameter { /* ... */ };
|
||||
class InvalidParameter { /* ... */ };
|
||||
class InvalidRegister { /* ... */ };
|
||||
class TooMuchParameters { /* ... */ };
|
||||
class ResetRequest { /* ... */ };
|
||||
|
||||
#endif
|
258
src/opcodes.lst
Normal file
258
src/opcodes.lst
Normal file
@@ -0,0 +1,258 @@
|
||||
Opcode(bin) Opcode Instruction Bytes Cycles
|
||||
--------------------------------------------------------------
|
||||
00000000 00 NOP 1 1
|
||||
00000001 01 AJMP addr11 2 2
|
||||
00000010 02 LJMP addr16 3 2
|
||||
00000011 03 RR A 1 1
|
||||
00000100 04 INC A 1 1
|
||||
00000101 05 INC direct 2 1
|
||||
00000110 06 INC @R0 1 1
|
||||
00000111 07 INC @R1 1 1
|
||||
00001000 08 INC R0 1 1
|
||||
00001001 09 INC R1 1 1
|
||||
00001010 0A INC R2 1 1
|
||||
00001011 0B INC R3 1 1
|
||||
00001100 0C INC R4 1 1
|
||||
00001101 0D INC R5 1 1
|
||||
00001110 0E INC R6 1 1
|
||||
00001111 0F INC R7 1 1
|
||||
00010000 10 JBC bitaddr,reladdr 3 2
|
||||
00010001 11 ACALL addr11 2 2
|
||||
00010010 12 LCALL addr16 3 2
|
||||
00010011 13 RRC A 1 1
|
||||
00010100 14 DEC A 1 1
|
||||
00010101 15 DEC direct 2 1
|
||||
00010110 16 DEC @R0 1 1
|
||||
00010111 17 DEC @R1 1 1
|
||||
00011000 18 DEC R0 1 1
|
||||
00011001 19 DEC R1 1 1
|
||||
00011010 1A DEC R2 1 1
|
||||
00011011 1B DEC R3 1 1
|
||||
00011100 1C DEC R4 1 1
|
||||
00011101 1D DEC R5 1 1
|
||||
00011110 1E DEC R6 1 1
|
||||
00011111 1F DEC R7 1 1
|
||||
00100000 20 JB bitaddr,reladdr 3 2
|
||||
00100001 21 AJMP addr11 2 2
|
||||
00100010 22 RET 1 2
|
||||
00100011 23 RL A 1 1
|
||||
00100100 24 ADD A,#data 2 1
|
||||
00100101 25 ADD A,direct 2 1
|
||||
00100110 26 ADD A,@R0 1 1
|
||||
00100111 27 ADD A,@R1 1 1
|
||||
00101000 28 ADD A,R0 1 1
|
||||
00101001 29 ADD A,R1 1 1
|
||||
00101010 2A ADD A,R2 1 1
|
||||
00101011 2B ADD A,R3 1 1
|
||||
00101100 2C ADD A,R4 1 1
|
||||
00101101 2D ADD A,R5 1 1
|
||||
00101110 2E ADD A,R6 1 1
|
||||
00101111 2F ADD A,R7 1 1
|
||||
00110000 30 JNB bitaddr,reladdr 3 2
|
||||
00110001 31 ACALL addr11 2 2
|
||||
00110010 32 RETI 1 2
|
||||
00110011 33 RLC A 1 1
|
||||
00110100 34 ADDC A,#data 2 1
|
||||
00110101 35 ADDC A,direct 2 1
|
||||
00110110 36 ADDC A,@R0 1 1
|
||||
00110111 37 ADDC A,@R1 1 1
|
||||
00111000 38 ADDC A,R0 1 1
|
||||
00111001 39 ADDC A,R1 1 1
|
||||
00111010 3A ADDC A,R2 1 1
|
||||
00111011 3B ADDC A,R3 1 1
|
||||
00111100 3C ADDC A,R4 1 1
|
||||
00111101 3D ADDC A,R5 1 1
|
||||
00111110 3E ADDC A,R6 1 1
|
||||
00111111 3F ADDC A,R7 1 1
|
||||
01000000 40 JC reladdr 2 2
|
||||
01000001 41 AJMP addr11 2 2
|
||||
01000010 42 ORL direct,A 2 1
|
||||
01000011 43 ORL direct,#data 3 2
|
||||
01000100 44 ORL A,#data 2 1
|
||||
01000101 45 ORL A,direct 2 1
|
||||
01000110 46 ORL A,@R0 1 1
|
||||
01000111 47 ORL A,@R1 1 1
|
||||
01001000 48 ORL A,R0 1 1
|
||||
01001001 49 ORL A,R1 1 1
|
||||
01001010 4A ORL A,R2 1 1
|
||||
01001011 4B ORL A,R3 1 1
|
||||
01001100 4C ORL A,R4 1 1
|
||||
01001101 4D ORL A,R5 1 1
|
||||
01001110 4E ORL A,R6 1 1
|
||||
01001111 4F ORL A,R7 1 1
|
||||
01010000 50 JNC reladdr 2 2
|
||||
01010001 51 ACALL addr11 2 2
|
||||
01010010 52 ANL direct,A 2 1
|
||||
01010011 53 ANL direct,#data 3 2
|
||||
01010100 54 ANL A,#data 2 1
|
||||
01010101 55 ANL A,direct 2 1
|
||||
01010110 56 ANL A,@R0 1 1
|
||||
01010111 57 ANL A,@R1 1 1
|
||||
01011000 58 ANL A,R0 1 1
|
||||
01011001 59 ANL A,R1 1 1
|
||||
01011010 5A ANL A,R2 1 1
|
||||
01011011 5B ANL A,R3 1 1
|
||||
01011100 5C ANL A,R4 1 1
|
||||
01011101 5D ANL A,R5 1 1
|
||||
01011110 5E ANL A,R6 1 1
|
||||
01011111 5F ANL A,R7 1 1
|
||||
01100000 60 JZ reladdr 2 2
|
||||
01100001 61 AJMP addr11 2 2
|
||||
01100010 62 XRL direct,A 2 1
|
||||
01100011 63 XRL direct,#data 3 2
|
||||
01100100 64 XRL A,#data 2 1
|
||||
01100101 65 XRL A,direct 2 1
|
||||
01100110 66 XRL A,@R0 1 1
|
||||
01100111 67 XRL A,@R1 1 1
|
||||
01101000 68 XRL A,R0 1 1
|
||||
01101001 69 XRL A,R1 1 1
|
||||
01101010 6A XRL A,R2 1 1
|
||||
01101011 6B XRL A,R3 1 1
|
||||
01101100 6C XRL A,R4 1 1
|
||||
01101101 6D XRL A,R5 1 1
|
||||
01101110 6E XRL A,R6 1 1
|
||||
01101111 6F XRL A,R7 1 1
|
||||
01110000 70 JNZ reladdr 2 2
|
||||
01110001 71 ACALL addr11 2 2
|
||||
01110010 72 ORL C,bitaddr 2 2
|
||||
01110011 73 JMP @A+DPTR 1 2
|
||||
01110100 74 MOV A,#data 2 1
|
||||
01110101 75 MOV direct,#data 3 2
|
||||
01110110 76 MOV @R0,#data 2 1
|
||||
01110111 77 MOV @R1,#data 2 1
|
||||
01111000 78 MOV R0,#data 2 1
|
||||
01111001 79 MOV R1,#data 2 1
|
||||
01111010 7A MOV R2,#data 2 1
|
||||
01111011 7B MOV R3,#data 2 1
|
||||
01111100 7C MOV R4,#data 2 1
|
||||
01111101 7D MOV R5,#data 2 1
|
||||
01111110 7E MOV R6,#data 2 1
|
||||
01111111 7F MOV R7,#data 2 1
|
||||
10000000 80 SJMP reladdr 2 2
|
||||
10000001 81 AJMP addr11 2 2
|
||||
10000010 82 ANL C,bitaddr 2 1
|
||||
10000011 83 MOVC A,@A+PC 1 1
|
||||
10000100 84 DIV AB 1 4
|
||||
10000101 85 MOV direct,direct 3 1
|
||||
10000110 86 MOV direct,@R0 2 2
|
||||
10000111 87 MOV direct,@R1 2 2
|
||||
10001000 88 MOV direct,R0 2 2
|
||||
10001001 89 MOV direct,R1 2 2
|
||||
10001010 8A MOV direct,R2 2 2
|
||||
10001011 8B MOV direct,R3 2 2
|
||||
10001100 8C MOV direct,R4 2 2
|
||||
10001101 8D MOV direct,R5 2 2
|
||||
10001110 8E MOV direct,R6 2 2
|
||||
10001111 8F MOV direct,R7 2 2
|
||||
10010000 90 MOV DPTR,#data16 3 2
|
||||
10010001 91 ACALL addr11 2 2
|
||||
10010010 92 MOV bitaddr,C 2 2
|
||||
10010011 93 MOVC A,@A+DPTR 1 2
|
||||
10010100 94 SUBB A,#data 2 1
|
||||
10010101 95 SUBB A,direct 2 1
|
||||
10010110 96 SUBB A,@R0 1 1
|
||||
10010111 97 SUBB A,@R1 1 1
|
||||
10011000 98 SUBB A,R0 1 1
|
||||
10011001 99 SUBB A,R1 1 1
|
||||
10011010 9A SUBB A,R2 1 1
|
||||
10011011 9B SUBB A,R3 1 1
|
||||
10011100 9C SUBB A,R4 1 1
|
||||
10011101 9D SUBB A,R5 1 1
|
||||
10011110 9E SUBB A,R6 1 1
|
||||
10011111 9F SUBB A,R7 1 1
|
||||
10100000 A0 ORL C,/bitaddr 2 1
|
||||
10100001 A1 AJMP addr11 2 2
|
||||
10100010 A2 MOV C,bitaddr 2 1
|
||||
10100011 A3 INC DPTR 1 2
|
||||
10100100 A4 MUL AB 1 4
|
||||
10100101 A5 INVALID 1 1
|
||||
10100110 A6 MOV @R0,direct 2 2
|
||||
10100111 A7 MOV @R1,direct 2 2
|
||||
10101000 A8 MOV R0,direct 2 2
|
||||
10101001 A9 MOV R1,direct 2 2
|
||||
10101010 AA MOV R2,direct 2 2
|
||||
10101011 AB MOV R3,direct 2 2
|
||||
10101100 AC MOV R4,direct 2 2
|
||||
10101101 AD MOV R5,direct 2 2
|
||||
10101110 AE MOV R6,direct 2 2
|
||||
10101111 AF MOV R7,direct 2 2
|
||||
10110000 B0 ANL C,/bitaddr 2 1
|
||||
10110001 B1 ACALL addr11 2 2
|
||||
10110010 B2 CPL bitaddr 2 1
|
||||
10110011 B3 CPL C 1 1
|
||||
10110100 B4 CJNE A,#data,reladdr 3 2
|
||||
10110101 B5 CJNE A,direct,reladdr 3 2
|
||||
10110110 B6 CJNE @R0,#data,reladdr 3 2
|
||||
10110111 B7 CJNE @R1,#data,reladdr 3 2
|
||||
10111000 B8 CJNE R0,#data,reladdr 3 2
|
||||
10111001 B9 CJNE R1,#data,reladdr 3 2
|
||||
10111010 BA CJNE R2,#data,reladdr 3 2
|
||||
10111011 BB CJNE R3,#data,reladdr 3 2
|
||||
10111100 BC CJNE R4,#data,reladdr 3 2
|
||||
10111101 BD CJNE R5,#data,reladdr 3 2
|
||||
10111110 BE CJNE R6,#data,reladdr 3 2
|
||||
10111111 BF CJNE R7,#data,reladdr 3 2
|
||||
11000000 C0 PUSH direct 2 2
|
||||
11000001 C1 AJMP addr11 2 2
|
||||
11000010 C2 CLR bitaddr 2 1
|
||||
11000011 C3 CLR C 1 1
|
||||
11000100 C4 SWAP A 1 1
|
||||
11000101 C5 XCH A,direct 2 1
|
||||
11000110 C6 XCH A,@R0 1 1
|
||||
11000111 C7 XCH A,@R1 1 1
|
||||
11001000 C8 XCH A,R0 1 1
|
||||
11001001 C9 XCH A,R1 1 1
|
||||
11001010 CA XCH A,R2 1 1
|
||||
11001011 CB XCH A,R3 1 1
|
||||
11001100 CC XCH A,R4 1 1
|
||||
11001101 CD XCH A,R5 1 1
|
||||
11001110 CE XCH A,R6 1 1
|
||||
11001111 CF XCH A,R7 1 1
|
||||
11010000 D0 POP direct 2 2
|
||||
11010001 D1 ACALL addr11 2 2
|
||||
11010010 D2 SETB bitaddr 2 1
|
||||
11010011 D3 SETB C 1 1
|
||||
11010100 D4 DA A 1 1
|
||||
11010101 D5 DJNZ direct,reladdr 3 2
|
||||
11010110 D6 XCHD A,@R0 1 1
|
||||
11010111 D7 XCHD A,@R1 1 1
|
||||
11011000 D8 DJNZ R0,reladdr 2 2
|
||||
11011001 D9 DJNZ R1,reladdr 2 2
|
||||
11011010 DA DJNZ R2,reladdr 2 2
|
||||
11011011 DB DJNZ R3,reladdr 2 2
|
||||
11011100 DC DJNZ R4,reladdr 2 2
|
||||
11011101 DD DJNZ R5,reladdr 2 2
|
||||
11011110 DE DJNZ R6,reladdr 2 2
|
||||
11011111 DF DJNZ R7,reladdr 2 2
|
||||
11100000 E0 MOVX A,@DPTR 1 2
|
||||
11100001 E1 AJMP addr11 2 2
|
||||
11100010 E2 MOVX A,@R0 1 2
|
||||
11100011 E3 MOVX A,@R1 1 2
|
||||
11100100 E4 CLR A 1 1
|
||||
11100101 E5 MOV A,direct 2 1
|
||||
11100110 E6 MOV A,@R0 1 1
|
||||
11100111 E7 MOV A,@R1 1 1
|
||||
11101000 E8 MOV A,R0 1 1
|
||||
11101001 E9 MOV A,R1 1 1
|
||||
11101010 EA MOV A,R2 1 1
|
||||
11101011 EB MOV A,R3 1 1
|
||||
11101100 EC MOV A,R4 1 1
|
||||
11101101 ED MOV A,R5 1 1
|
||||
11101110 EE MOV A,R6 1 1
|
||||
11101111 EF MOV A,R7 1 1
|
||||
11110000 F0 MOVX @DPTR,A 1 2
|
||||
11110001 F1 ACALL addr11 2 2
|
||||
11110010 F2 MOVX @R0,A 1 2
|
||||
11110011 F3 MOVX @R1,A 1 2
|
||||
11110100 F4 CPL A 1 1
|
||||
11110101 F5 MOV direct,A 2 1
|
||||
11110110 F6 MOV @R0,A 1 1
|
||||
11110111 F7 MOV @R1,A 1 1
|
||||
11111000 F8 MOV R0,A 1 1
|
||||
11111001 F9 MOV R1,A 1 1
|
||||
11111010 FA MOV R2,A 1 1
|
||||
11111011 FB MOV R3,A 1 1
|
||||
11111100 FC MOV R4,A 1 1
|
||||
11111101 FD MOV R5,A 1 1
|
||||
11111110 FE MOV R6,A 1 1
|
||||
11111111 FF MOV R7,A 1 1
|
115
test_files/siae1.hex
Normal file
115
test_files/siae1.hex
Normal file
@@ -0,0 +1,115 @@
|
||||
:0600000002003302003390
|
||||
:03000B00020033BD
|
||||
:03001300020033B5
|
||||
:03001B00020033AD
|
||||
:03002300020033A5
|
||||
:03002B000200339D
|
||||
:100033007581801202D312024375540075550085F1
|
||||
:100043004356854457755BC61204C8120493740360
|
||||
:100053002557F543855A56855B57755B0A1204C8C5
|
||||
:10006300120493E5574430F55E75F000E543120240
|
||||
:10007300DC85514F85525085535175522E855E5301
|
||||
:1000830074501203067404120306E54F120306E5C7
|
||||
:1000930050120306E551120306E552120306E55317
|
||||
:1000A300120306745A12030675300075315D7532FA
|
||||
:1000B300C01204E78534F0E5351202DC74501203F4
|
||||
:1000C300067401120306E54F120306E550120306F8
|
||||
:1000D300E551120306E552120306E55312030674B3
|
||||
:1000E3005A12030675F000E5361202DC745012034F
|
||||
:1000F300067405120306E551120306E552120306C0
|
||||
:10010300E553120306745A12030675F000E537121D
|
||||
:1001130002DC74501203067406120306E55112033F
|
||||
:1001230006E552120306E553120306745A12030638
|
||||
:10013300E53875F00584C5F0C3334430F55FC5F089
|
||||
:1001430075F0001202DC85525085535175522E858D
|
||||
:100153005F5374501203067408120306E55012032A
|
||||
:1001630006E551120306E552120306E55312030690
|
||||
:10017300745A12030675540075550085415685421D
|
||||
:1001830057755B641204C87554001204938556F0C6
|
||||
:10019300E5571202DC74501203067402120306E5DB
|
||||
:1001A30051120306E552120306E553120306745A6D
|
||||
:1001B300120306755400755500853B56853C5775EB
|
||||
:1001C3005B0F1204C812049385575C855A56855BEE
|
||||
:1001D30057755B641204C81204938556F0E55712F1
|
||||
:1001E30002DC85525D85535E75F000E55C1202DC2E
|
||||
:1001F30085524F85535075512E855D52855E5374DC
|
||||
:10020300501203067407120306E54F120306E55066
|
||||
:10021300120306E551120306E552120306E55312D3
|
||||
:100223000306745A12030674201203060139756219
|
||||
:1002330016740075F000D5F0FDD5E0F7D562F22213
|
||||
:10024300783B7900E9120255A64E08A64D0809B974
|
||||
:1002530008F2D2B3C2B1C2B300D2B3C2B6C2B300C2
|
||||
:10026300D2B3F580C2B300D2B3D2B6C2B300D2B315
|
||||
:10027300D2B1C2B31202CA7580FFD2B3C2B1C2B344
|
||||
:1002830000D2B3C2B7C2B30085804DD2B3D2B7C2D6
|
||||
:10029300B300D2B3D2B1C2B300D2B3D2B2C2B300AD
|
||||
:1002A300D2B3C2B1C2B300D2B3C2B7C2B300858066
|
||||
:1002B3004E00D2B3D2B7C2B300D2B3D2B1C2B300ED
|
||||
:1002C300D2B3C2B2C2B322D2B300C2B330B0F822A7
|
||||
:1002D30075D54475B0F3513122C00078537554007D
|
||||
:1002E30075550085F056F557755800755900755AC0
|
||||
:1002F30000755B0A120314E55B4430F618B84EE848
|
||||
:10030300D00022F586B290E5AA53E08060F9E58635
|
||||
:1003130022C004C003C002C001C0007504207503DD
|
||||
:100323000075020075010075000012038F1203A50A
|
||||
:100333004022C3E5039558403A7019C3E502955925
|
||||
:1003430040317010C3E501955A40287007C3E5009A
|
||||
:10035300955B401FC3E500955BF500E501955AF5F4
|
||||
:1003630001E5029559F502E5039558F503E557D2E2
|
||||
:10037300E0F557DCB585035885025985015A850098
|
||||
:100383005BD000D001D002D003D00422C3E55733A1
|
||||
:10039300F557E55633F556E55533F555E55433F53D
|
||||
:1003A3005422E50033F500E50133F501E50233F5A9
|
||||
:1003B30002E50333F50322C002C001C00075021B2E
|
||||
:1003C30075010075000012040312041D4010C3E5FB
|
||||
:1003D30001955A401C7007C3E500955B4013C3E5C4
|
||||
:1003E30000955BF500E501955AF501E557D2E0F577
|
||||
:1003F30057DAD385015A85005BD000D001D00222A1
|
||||
:10040300C3E55733F557E55633F556E55533F555FB
|
||||
:10041300E5543392E35407F55422E50033F500E540
|
||||
:100423000133F50122C002C001C000750216750137
|
||||
:10043300007500001204711204844010C3E5019595
|
||||
:100443005A401C7007C3E500955B4013C3E5009554
|
||||
:100453005BF500E501955AF501E557D2E0F557DA6A
|
||||
:10046300D385015A85005BD000D001D00222C3E5B9
|
||||
:100473005733F557E55633F556E55533F55592E6BB
|
||||
:1004830022E50033F500E5013392E6543FF50122FE
|
||||
:1004930085575B85565A535A0F1204B81204B81283
|
||||
:1004A30004B81204B853540F8556578555568554CE
|
||||
:1004B3005575540022E55413F554E55513F555E5E8
|
||||
:1004C3005613F55622E556855BF0A4F55685F0558F
|
||||
:1004D300E557855BF0A4F557C5F02556F556E43589
|
||||
:1004E30055F555221205751205981205B5E53654D2
|
||||
:1004F300F0C4C5F0E53754F025F0F5F01205DAF84D
|
||||
:10050300E5F0240130D605E8F90205131205DAF9FE
|
||||
:10051300E5F024105007E8FAE9FB020536F5F0127E
|
||||
:1005230005DAFAE5F0240130D605EAFB02053612B6
|
||||
:1005330005DAFB88F0E9AC36120553F88AF0EBAC28
|
||||
:1005430036120553FA88F0EAAC37120553F5382210
|
||||
:10055300C0F0C223C395F05005F42401D223F5F073
|
||||
:10056300EC540FA454F0C4302303F42401D0F02539
|
||||
:10057300F02275540775552775560E755700E530EB
|
||||
:10058300B4000B85315A85325B71BA0205918556E9
|
||||
:100593003485573522C3E5359490F556E5349401F7
|
||||
:1005A300F555755700C3755A25755B809128855796
|
||||
:1005B3003622755400755500C3E54394285001E471
|
||||
:1005C300F556755700755800755900755A00755BD7
|
||||
:1005D300A071148557372224E8F58274053400F599
|
||||
:1005E3008374009322111123465F5F666666666615
|
||||
:1005F3006666585858111123465F5F6666666666DD
|
||||
:100603006666585858111123465F5F6666666666CC
|
||||
:100613006666585858111123465F5F6666666666BC
|
||||
:100623006666585858111123465F5F6666666666AC
|
||||
:100633006666585858111123465F5F66666666669C
|
||||
:100643006666585858111123465F5F66666666668C
|
||||
:100653006666585858111123465B5B626262626298
|
||||
:1006630062625454541111234651515858585858E2
|
||||
:100673005858585858111123464A4A51515151510B
|
||||
:10068300515151515111111C3846464A4A4A4A4A5E
|
||||
:100693004A4A4A4A4A11111C343F3F4343434343A6
|
||||
:1006A300434343434311111C3438383C3C3C3C3CEA
|
||||
:1006B3003C3C3C3C3C11111C2A2D2D313131313154
|
||||
:1006C300313131313111111C3438383C3C3C3C3C24
|
||||
:1006D3003C3C3C3C3C11111C2A2D2D313131313134
|
||||
:0506E30031313131311D
|
||||
:00000001FF
|
13
test_files/test.hex
Normal file
13
test_files/test.hex
Normal file
@@ -0,0 +1,13 @@
|
||||
:03000000020033C8
|
||||
:1000330075818075D54475A000C290E4F500E50094
|
||||
:1000430012007DF586D29005A07400D5E0FDC29024
|
||||
:10005300E5AA53E08060F9E5861200690500C3E56F
|
||||
:1000630000945040D92222752005740075F000D504
|
||||
:10007300F0FDD5E0F7D520F20022248BF582740041
|
||||
:100083003400F5837400932252504D3A31303234A8
|
||||
:1000930035204D41503A313033204D41543A3131BE
|
||||
:1000A30030204241543A31322E3420202020202067
|
||||
:1000B3000D0A0A45474F3A31342E36202054505307
|
||||
:1000C3003A31303020414E473A33302020434C54AC
|
||||
:0B00D3003A313038202020202020206F
|
||||
:00000001FF
|
179
test_files/timer.asm
Normal file
179
test_files/timer.asm
Normal file
@@ -0,0 +1,179 @@
|
||||
;*******************************************************************************
|
||||
;* Syst<73>me d'Injection et d'Allumage <20>lectronique *
|
||||
;* Version : 01 *
|
||||
;* Auteur : Hugo Villeneuve *
|
||||
;* *
|
||||
;* 10 mars 1999 *
|
||||
;*******************************************************************************
|
||||
|
||||
$MOD52 ; Micro-contr<74>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<69> par la sous-routine MULT8_16
|
||||
SIGNE: DBIT 4 ; Utilis<69> 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<75> <20> 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<75>rique.
|
||||
MSB_CAN: DS 1 ; Octet de poids fort de la conversion Analogique-Num<75>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<74>matiques.
|
||||
C2: DS 1
|
||||
C1: DS 1
|
||||
C0: DS 1
|
||||
D3: DS 1 ; Accumulateur D de 32 bits pour les calculs math<74>matiques.
|
||||
D2: DS 1
|
||||
D1: DS 1
|
||||
D0: DS 1
|
||||
TMP6: DS 1 ; Variables temporaires utilis<69>es pour les calculs math<74>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<73>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<69>e;
|
||||
; Activation du port SPI;
|
||||
; Ordre des transferts : MSB en premier;
|
||||
; Op<4F>ration en mode escalve (SLAVE);
|
||||
; Polarit<69> 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<63>ment<6E>s par l'horloge interne
|
||||
; Chaque timer est incr<63>ment<6E> tant que le bit correspondant de
|
||||
; TCON est <20> 1 (TCON.4 et TCON.6).
|
||||
RET
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
|
10
test_files/timer.hex
Normal file
10
test_files/timer.hex
Normal file
@@ -0,0 +1,10 @@
|
||||
:0600000002003302005172
|
||||
:03000B00020033BD
|
||||
:03001300020033B5
|
||||
:03001B00020033AD
|
||||
:03002300020033A5
|
||||
:03002B000200339D
|
||||
:100033007581601200520000000080FA756016742A
|
||||
:100043000075F000D5F0FDD5E0F7D560F2223275EA
|
||||
:10005300D544758C02758A55D28CD28E758911223E
|
||||
:00000001FF
|
Reference in New Issue
Block a user