summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS14
-rw-r--r--COPYING340
-rw-r--r--ChangeLog431
-rw-r--r--ChangeLog.11807
-rw-r--r--INSTALL339
-rw-r--r--Makefile.am24
-rw-r--r--NEWS450
-rw-r--r--README43
-rw-r--r--THANKS59
-rw-r--r--TODO19
-rwxr-xr-xautogen.sh79
-rw-r--r--configure.in175
-rw-r--r--doc/Makefile.am23
-rwxr-xr-xdoc/gendocs.sh285
-rw-r--r--doc/gendocs_template100
-rw-r--r--doc/img/Makefile.am16
-rw-r--r--doc/img/ss_devdir.jpgbin0 -> 5344 bytes
-rw-r--r--doc/img/ss_devform.jpgbin0 -> 6995 bytes
-rw-r--r--doc/img/ss_devices.jpgbin0 -> 74404 bytes
-rw-r--r--doc/img/ss_extprog.jpgbin0 -> 10282 bytes
-rw-r--r--doc/img/ss_mix.jpgbin0 -> 50408 bytes
-rw-r--r--doc/img/ss_mix.txt31
-rw-r--r--doc/img/ss_mixal.jpgbin0 -> 60476 bytes
-rw-r--r--doc/img/ss_split.jpgbin0 -> 143101 bytes
-rw-r--r--doc/img/ss_symbols.jpgbin0 -> 13691 bytes
-rw-r--r--doc/img/ss_worddlg.jpgbin0 -> 7916 bytes
-rw-r--r--doc/mdk.texi248
-rw-r--r--doc/mdk_ack.texi63
-rw-r--r--doc/mdk_bugs.texi24
-rw-r--r--doc/mdk_copying.texi866
-rw-r--r--doc/mdk_emacs.texi136
-rw-r--r--doc/mdk_findex.texi11
-rw-r--r--doc/mdk_gmixvm.texi394
-rw-r--r--doc/mdk_gstart.texi1058
-rw-r--r--doc/mdk_index.texi14
-rw-r--r--doc/mdk_install.texi287
-rw-r--r--doc/mdk_intro.texi70
-rw-r--r--doc/mdk_mixasm.texi89
-rw-r--r--doc/mdk_mixguile.texi445
-rw-r--r--doc/mdk_mixvm.texi813
-rw-r--r--doc/mdk_tut.texi1319
-rw-r--r--lib/Makefile.am17
-rw-r--r--lib/getopt.h129
-rw-r--r--lib/getopt_long.c1086
-rw-r--r--mdk.spec142
-rw-r--r--misc/Makefile.am16
-rw-r--r--misc/mixal-mode.el1321
-rw-r--r--misc/mixvm.el158
-rw-r--r--mixgtk/Makefile.am47
-rw-r--r--mixgtk/gmixvm.c124
-rw-r--r--mixgtk/mixgtk.c79
-rw-r--r--mixgtk/mixgtk.glade3913
-rw-r--r--mixgtk/mixgtk.gladep9
-rw-r--r--mixgtk/mixgtk.h49
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.c547
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.h61
-rw-r--r--mixgtk/mixgtk_config.c113
-rw-r--r--mixgtk/mixgtk_config.h70
-rw-r--r--mixgtk/mixgtk_device.c625
-rw-r--r--mixgtk/mixgtk_device.h45
-rw-r--r--mixgtk/mixgtk_fontsel.c142
-rw-r--r--mixgtk/mixgtk_fontsel.h51
-rw-r--r--mixgtk/mixgtk_gen_handlers.c165
-rw-r--r--mixgtk/mixgtk_gen_handlers.h62
-rw-r--r--mixgtk/mixgtk_input.c233
-rw-r--r--mixgtk/mixgtk_input.h49
-rw-r--r--mixgtk/mixgtk_mixal.c580
-rw-r--r--mixgtk/mixgtk_mixal.h66
-rw-r--r--mixgtk/mixgtk_mixvm.c529
-rw-r--r--mixgtk/mixgtk_mixvm.h72
-rw-r--r--mixgtk/mixgtk_widgets.c153
-rw-r--r--mixgtk/mixgtk_widgets.h102
-rw-r--r--mixgtk/mixgtk_wm.c573
-rw-r--r--mixgtk/mixgtk_wm.h46
-rw-r--r--mixguile/Makefile.am43
-rw-r--r--mixguile/mixguile-commands.scm254
-rw-r--r--mixguile/mixguile-vm-stat.scm71
-rw-r--r--mixguile/mixguile.c124
-rw-r--r--mixguile/mixguile.h72
-rw-r--r--mixguile/mixguile.scm25
-rw-r--r--mixguile/mixguile_cmd_dispatcher.c122
-rw-r--r--mixguile/mixguile_cmd_dispatcher.h57
-rw-r--r--mixguile/mixguile_main.c94
-rw-r--r--mixguile/xmixguile_cmd_dispatcher.c558
-rw-r--r--mixguile/xmixguile_cmd_dispatcher.h67
-rw-r--r--mixlib/Makefile.am42
-rw-r--r--mixlib/gettext.h69
-rw-r--r--mixlib/mix.c99
-rw-r--r--mixlib/mix.h78
-rw-r--r--mixlib/mix_code_file.c330
-rw-r--r--mixlib/mix_code_file.h106
-rw-r--r--mixlib/mix_config.c298
-rw-r--r--mixlib/mix_config.h100
-rw-r--r--mixlib/mix_device.c164
-rw-r--r--mixlib/mix_device.h160
-rw-r--r--mixlib/mix_eval.c191
-rw-r--r--mixlib/mix_eval.h110
-rw-r--r--mixlib/mix_eval_scanner.l276
-rw-r--r--mixlib/mix_file.c159
-rw-r--r--mixlib/mix_file.h65
-rw-r--r--mixlib/mix_ins.c269
-rw-r--r--mixlib/mix_ins.h195
-rw-r--r--mixlib/mix_io.c208
-rw-r--r--mixlib/mix_io.h119
-rw-r--r--mixlib/mix_parser.c605
-rw-r--r--mixlib/mix_parser.h111
-rw-r--r--mixlib/mix_predicate.c215
-rw-r--r--mixlib/mix_predicate.h80
-rw-r--r--mixlib/mix_predicate_list.c117
-rw-r--r--mixlib/mix_predicate_list.h64
-rw-r--r--mixlib/mix_scanner.l581
-rw-r--r--mixlib/mix_src_file.c157
-rw-r--r--mixlib/mix_src_file.h57
-rw-r--r--mixlib/mix_symbol_table.c198
-rw-r--r--mixlib/mix_symbol_table.h109
-rw-r--r--mixlib/mix_types.c569
-rw-r--r--mixlib/mix_types.h293
-rw-r--r--mixlib/mix_vm.c706
-rw-r--r--mixlib/mix_vm.h255
-rw-r--r--mixlib/mix_vm_clock.c70
-rw-r--r--mixlib/mix_vm_clock.h55
-rw-r--r--mixlib/mix_vm_command.c641
-rw-r--r--mixlib/mix_vm_command.h256
-rw-r--r--mixlib/mix_vm_dump.c147
-rw-r--r--mixlib/mix_vm_dump.h91
-rw-r--r--mixlib/testsuite/Makefile.am32
-rw-r--r--mixlib/testsuite/mix_device_t.c76
-rw-r--r--mixlib/testsuite/mix_eval_t.c119
-rw-r--r--mixlib/testsuite/mix_ins_t.c79
-rw-r--r--mixlib/testsuite/mix_parser_t.c85
-rw-r--r--mixlib/testsuite/mix_types_t.c369
-rw-r--r--mixlib/testsuite/mix_vm_ins_t.c505
-rw-r--r--mixlib/testsuite/test.h44
-rw-r--r--mixlib/xmix_device.c199
-rw-r--r--mixlib/xmix_device.h96
-rw-r--r--mixlib/xmix_eval.h55
-rw-r--r--mixlib/xmix_io.c57
-rw-r--r--mixlib/xmix_io.h64
-rw-r--r--mixlib/xmix_parser.h111
-rw-r--r--mixlib/xmix_vm.c598
-rw-r--r--mixlib/xmix_vm.h139
-rw-r--r--mixlib/xmix_vm_command.c64
-rw-r--r--mixlib/xmix_vm_command.h102
-rw-r--r--mixlib/xmix_vm_handlers.c1387
-rw-r--r--mixlib/xmix_vm_handlers.h87
-rw-r--r--mixutils/Makefile.am27
-rw-r--r--mixutils/mixasm.c136
-rw-r--r--mixutils/mixasm_comp.c72
-rw-r--r--mixutils/mixasm_comp.h35
-rw-r--r--mixutils/mixvm.c150
-rw-r--r--mixutils/mixvm_command.c270
-rw-r--r--mixutils/mixvm_command.h38
-rw-r--r--mixutils/mixvm_loop.c160
-rw-r--r--mixutils/mixvm_loop.h38
-rw-r--r--po/ChangeLog143
-rw-r--r--po/LINGUAS2
-rw-r--r--po/Makevars25
-rw-r--r--po/POTFILES.in27
-rw-r--r--po/de.po1553
-rw-r--r--samples/Makefile.am16
-rw-r--r--samples/echo.mixal10
-rw-r--r--samples/hello.mixal11
-rw-r--r--samples/m.mixal25
-rw-r--r--samples/permutations.cardrd3
-rw-r--r--samples/permutations.mixal89
-rw-r--r--samples/primes.mixal53
-rw-r--r--samples/primes.result51
-rw-r--r--samples/tests/bt.mixal6
-rw-r--r--samples/tests/cbp.mixal14
-rw-r--r--samples/tests/ldan.mixal5
-rw-r--r--samples/tests/lockonw.mixal3
-rw-r--r--samples/tests/negwrite.mixal4
-rw-r--r--samples/tests/stress0.mixal8
-rw-r--r--samples/tests/stress1.mixal9
-rw-r--r--samples/tests/stress2.mixal7
-rw-r--r--samples/tests/stress4.mixal7
-rw-r--r--samples/tests/stress5.mixal17
-rw-r--r--samples/tests/stress6.mixal9
-rwxr-xr-xupdatelog1
179 files changed, 38640 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..7bde8b5
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,14 @@
+Authors of GNU MDK.
+See also the files THANKS and ChangeLog.
+
+Jose A. Ortega Ruiz designed and implemented mdk.
+
+Pieter E. J. Pareit designed, implemented and documented
+mixal-mode.el, and fixed bugs in other mdk code.
+
+Philip E. King designed and implemented mixvm.el.
+
+Michael Scholz wrote the German translation po/de.po.
+
+Sergey Poznyakoff provided patches to mixlib/mix_scanner.l improving
+MIXAL compliance.
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..2991320
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,431 @@
+2005-09-20 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mdk: version 1.2.1 tagged (v1r2_1).
+
+ * doc/mdk_copying.texi: FDL license updated to 1.2.
+
+ * mdk (Module): FSF address updated.
+
+ * mixguile/xmixguile_cmd_dispatcher.c (Module): use unsigned int
+ for length parameters.
+
+ * doc/mdk_tut.texi: compliance with 'traditional' ALF directive
+ documented.
+
+2005-09-19 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * po/de.po: corrections by Jens Seidel.
+
+ * mixgtk/Makefile.am (AM_LDFLAGS): fix libglade dynamic linking.
+
+ * mixutils/mixasm.c:improve -g handling (accept it to not break
+ potential user scripts)
+
+2005-04-05 Pieter Pareit <pieter.pareit@scarlet.be>
+
+ * mixutils/mixasm.c: make handeling of arguments somewhat robuster.
+
+ * misc/mixal-mode.el: -g option no longer needed on compilation.
+
+ * doc/mdk_mixasm.texi: fix of grammer mistake.
+
+2005-03-26 Sergey Poznyakoff <gray@gnu.org>
+
+ * mixlib/mix_scanner.l (ENTER_WEVAL) Accept an argument, specifying
+ how many characters to exclude from yyless.
+ (ws): Removed '+' closure. Throughout the code this macro is used
+ as {ws}+ or {ws}*, so it is superfluous.
+ (%{...%} block) [FLEX_DEBUG]: Set yy_flex_debug from the environment
+ variable. Useful for debugging.
+ (ALF): Pad with spaces arguments shorter than 5 characters
+ Accept traditional ALF syntax (withoutq quotes)
+ (<ADDRESS>): Accept w-expressions in literals (between = =).
+
+2004-08-05 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mdk: version 1.2 tagged (v1r2).
+
+ * Makefile.am: distclean-local rule added to handle intltool
+ products and make distcheck happy.
+
+2004-08-03 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * doc: documentation cleanup.
+
+2004-08-02 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * INSTALL:
+ * doc/mdk_install.texi: new library dependencies.
+
+ * doc/mdk_gmixvm.texi: new gui documentation.
+
+ * configure.in: -fno-strict-aliasing.
+
+ * mixgtk/mixgtk_cmd_dispatcher.c (on_external_programs_activate):
+ new-style handling of the external programs dialog.
+
+ * mixlib/mix_parser.c (mix_parser_delete):
+ * mixlib/mix_vm.c (mix_vm_get_lineno_address): g_tree_foreach
+ instead of deprecated g_tree_traverse.
+
+2004-08-01 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixutils/mixvm_command.c (init_dis_):
+ * mixgtk/mixgtk_cmd_dispatcher.c (read_config_): -g option not
+ needed by mixasm.
+ (mixgtk_cmd_dispatcher_init): do not redirect stderr to the
+ command log windows.
+
+ * doc/mdk_mixasm.texi (Invoking @code{mixasm}): document -O option.
+
+2004-07-30 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixutils/mixasm.c (main): new option -O to disable debug, which
+ is now enabled by default.
+
+ * configure.in: check also for libpango.
+
+2004-07-11 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/mixgtk_cmd_dispatcher.c (complete_command_)
+ (on_command_prompt_key_press_event): fixed cursor position after
+ completion.
+
+2004-07-10 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * po/POTFILES.in:
+ * configure.in:
+ * autogen.sh:
+ * Makefile.am: use intltool to allow glade file string translations.
+
+ * mixgtk/Makefile.am (-DLOCAL_GLADE_FILE): really allow off-tree builds.
+
+2004-07-05 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/mixgtk_wm.c: preserve order of detachable windows when
+ reatached.
+
+ * mixgtk/mixgtk_mixvm.c:
+ * mixgtk/mixgtk_mixal.{hc}:
+ * mixgtk/mixgtk_fontsel.{hc}:
+ * mixgtk/mixgtk_device.{hc}:
+ * mixgtk/mixgtk_cmd_dispatcher.{hc}:
+ * mixgtk/mixgtk.glade: new menu item to change all fonts at once,
+ and the symbol list font.
+
+2004-07-02 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/mixgtk_wm.{hc}: toolbar visibility and new attach all
+ toolbar button.
+
+ * mixgtk/mixgtk_mixvm.c: go to dialog handling simplified.
+
+ * mixgtk/mixgtk_cmd_dispatcher.c (log_command_): correctly place
+ cursor before insertion.
+
+ * mixgtk/mixgtk_device.c (write_char_): scroll on output and
+ cursor placement.
+
+2004-06-30 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * autogen.sh: do not run configure.
+
+ * mixgtk/Makefile.am (-DLOCAL_GLADE_FILE): allow off-tree builds.
+
+ * mixgtk/mixgtk_wm.c (on_nb_switch_): warning on null widget page
+ fixed.
+
+ * mixgtk/*.xpm:
+ * mixgtk/Makefile.am (Module): only stock icons are used now.
+
+ * mixgtk/mixgtk_wm.{hc}:
+ * mixgtk/mixgtk_widgets.{hc}:
+ * mixgtk/mixgtk_mixvm.{hc}:
+ * mixgtk/mixgtk_mixal.{hc}:
+ * mixgtk/mixgtk_device.{hc}:
+ * mixgtk/mixgtk_config.{hc}:
+ * mixgtk/mixgtk.{hc}:
+ * mixgtk/mixgtk.glade: all the old functionality, including
+ slipit mode revamped as detachable windows in place using gtk+2.
+ Still some rough borders to polish, probably.
+
+2004-06-24 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/mixgtk_widgets.{hc}:
+ * mixgtk/mixgtk_mixvm.c:
+ * mixgtk/mixgtk_mixal.c:
+ * mixgtk/mixgtk_fontsel.{hc}:
+ * mixgtk/mixgtk_device.{hc}:
+ * mixgtk/mixgtk_cmd_dispatcher.c:
+ * mixgtk/mixgtk.glade:
+ * mixgtk/mixgtk.c: almost complete (barring bugs) reimplementation
+ of all gmixvm functionality in non-split mode for gtk 2.4.x.
+
+2004-06-23 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk (Module): first, incomplete port to gtk 2.4.x. Basic
+ functionality in place.
+
+ * mixguile/xmixguile_cmd_dispatcher.c (Module):
+ * mixlib (Module): update to glib 2.x.
+
+ * mixgtk/mixgtk_colorsel.h (Module):
+ * mixgtk/mixgtk_colorsel.c (Module): removed (no longer used).
+
+ * configure.in (Module): default help messages for disable/enable
+ features (Adrian). Port to pkg-config and gtk+2.
+
+ * mixlib/mix_vm.c (vm_reset_reload_): do not delete output char
+ devices after reload.
+
+2004-06-22 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/mix_parser.c: do not store bogus line number for added
+ CON instructions.
+
+2004-06-12 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mdk (Module): version 1.1 tagged (v1r1).
+
+ * mixlib/xmix_parser.h (Module):
+ * mixlib/mix_scanner.l (Module):
+ * mixlib/mix_parser.c (Module): recognition of ALF in listings.
+
+ * mixlib/mix_io.c (mix_io_write_word_array_as_char): drop bogus
+ EOF comparison.
+
+2004-06-12 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * configure.in (Module): new version; fix guile checking.
+
+ * doc/mdk_mixvm.texi (Devices):
+ * mixlib/xmix_device.c: the paper tape is really an input device.
+
+ * mixgtk/mixgtk_widgets.h (Module):
+ * mixgtk/mixgtk_widgets.c (Module):
+ * mixgtk/mixgtk_device.c (Module):
+ * mixgtk/mixgtk.glade (Module): support for terminal device input
+ in the form of a new dialog.
+
+2004-06-10 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/mix_parser.c (mix_parser_compile): correctly set the loc
+ pointer.
+
+ * mixlib/mix_io.c (Module): allow truncated lines in char input
+ device files.
+
+ * mixlib/testsuite/mix_types_t.c (Module): test char to byte
+ conversions.
+
+ * mixlib/mix_types.c (Module):
+ * doc/mdk_tut.texi (Module): new ASCII rep for delta, sigma
+ and pi.
+
+ * mixlib/testsuite/mix_vm_ins_t.c (Module):
+ * mixlib/testsuite/mix_types_t.c (Module): adaptation to new
+ character set and LDN instructions behaviour.
+
+2004-06-09 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * doc/mdk_mixvm.texi (Devices): documentation for the console i/o.
+
+ * mixlib/mix_io.{hc}:
+ * mixlib/mix_device.h:
+ * mixlib/xmix_device.{hc}: the console is now in/out
+
+2004-06-07 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/mix_symbol_table.c (print_sym_rows_): align symbol values.
+
+ * mixutils/mixasm.c: correct usage message.
+
+ * mixlib/mix_scanner.l (Module): fix for bug #5654, including
+ support for both field specs and indexing in local constants.
+
+ * mixlib/mix_parser.c (Module): produce better listings,
+ identifying trailing CON instructions.
+
+ * mixutils/mixvm_loop.c (Module):
+ * mixlib/mix_config.c (Module): always use prompts ending in
+ whitespace.
+
+ * mixutils/mixvm_loop.c (mix_vmrun): do not save command line
+ options when -r is passed to mixvm.
+
+ * doc/mdk_mixvm.texi (Devices): documentation for the changes below.
+
+ * mixlib/mix_types.c (mix_ascii_to_char): accept lower case
+ characters.
+
+ * mixlib/xmix_device.c (read_): blocks in input char devices must
+ be separated by newline characters.
+
+ * mixlib/mix_vm.c (Module): correct error tracking and reporting.
+
+ * mixlib/mix_parser.{ch} (Module): properly treat undefined
+ forward references, inserting new addresses at the program's end.
+
+2004-06-06 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/xmix_vm_handlers.c (Module):
+ * mixlib/xmix_vm.{hc} (Module): keep track of runtime errors and
+ correctly report them.
+
+ * mixlib/mix_io.c (Module): bug fix: read only worked in debug mode;
+ more robust error reporting.
+
+ * mixlib/xmix_parser.h (Module):
+ * mixlib/mix_scanner.l (Module): keep track of program's end
+ address.
+
+2004-06-05 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * THANKS:
+ * doc/mdk_ack.texi (Acknowledgments): reorganisation.
+
+ * mixlib/xmix_vm.c (lda_handler_): always reverse sign in LDAN,
+ LDXN and LDiN, even if fspec is not zero (Ruslan Batdalov, closes
+ Debian bug #247392).
+
+ * autogen.sh: error messages improved and autotools versions updated.
+
+2004-01-09 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * configure.in: check for guile headers.
+
+2003-06-09 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mdk (Module): version 1.0.1 tagged (v1r0_1) and released.
+
+2003-06-09 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * misc/Makefile.am (pkgdata_DATA): include mixal-mode.el in the
+ distribution and install it.
+
+ * doc/mdk_ack.texi:
+ * THANKS: Eli added.
+
+2003-06-06 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * doc/mdk_tut.texi (Shift operators): SLC and SRC act on AX, not
+ on A.
+ (Conversion operators): correct description of digit
+ representation.
+
+2003-06-04 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * doc: documentation for emacs support merged in one file
+ (mdk_emacs.texi), substituting mdk_emixvm.texi and
+ mdk_mixal-mode.texi.
+
+ * mixlib/mix_code_file.c (mix_code_file_new_): properly initialise
+ source_path pointer to NULL, preventing later deletion of an
+ uninitialised pointer (which caused a segfault).
+
+2003-06-03 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * AUTHORS: Added Pieter Pareit.
+
+ * doc/mdk_ack.texi (Acknowledgments):
+ * THANKS: Thanks to P. E. J. Pareit, N. H. F. Beebe and Ronald Cole.
+
+ * doc/mdk_install.texi (Supported platforms): added platforms
+ tested by N. H. F. Beebe.
+
+ * doc/mdk_mixal-mode.texi (mixal-mode.el): minor editing of
+ Pieter's original documentation.
+
+ * doc/mdk_tut.texi (Address transfer operators): mixed bug in
+ DECX's MOD value.
+
+2003-05-28 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/mix_scanner.l, mixlib/mix_parser.h, mixlib/mix_parser.c:
+ new error message for missing ALF operand quotes (bug #3750 fixed)
+
+2003-04-06 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixguile/xmixguile_cmd_dispatcher.c: Missing standard header for
+ strlen #included.
+
+2003-02-13 Pieter E J Pareit <pieter.pareit@skynet.be>
+
+ * mixguile/xmixguile_cmd_dispatcher.c: bug fix: mix_reg_() and
+ mix_set_reg_() did not convert argument to string if it was a
+ symbol.
+
+2003-01-17 Pieter E J Pareit <pieter.pareit@skynet.be>
+
+ * misc/mixal-mode.el: bug fix: a regex was missing a '-'.
+
+ * doc/mdk_mixal-mode.texi: added documentation for mixal-mode.el.
+
+ * doc/mdk.texi: updated menu to include documentation for mixal-mode.el.
+
+ * doc/mdk_emixvm.texi: updated nodes to include mixal-mode.el.
+
+ * doc/mdk_egstart.texi: updated nodes to include mixal-mode.el.
+
+ * doc/mdk_install.texi: added documentation to node 'Emacs support'.
+
+2003-01-12 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/xmix_vm.h (inc_loc_): Stop program execution if the
+ program counter is incremented beyond the maximum address (3999).
+
+2003-01-11 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/xmix_vm_handlers.c: Bug #1704 fixed.
+
+ * doc/mdk_mixguile.texi (mixvm wrappers): Bug #1703 fixed.
+
+ * misc/mixal-mode.el (Module): new emacs mode written by Pieter Pareit.
+
+ * misc/mixvm.el: bug fix: correctly detect the absence of menu bar.
+
+2002-12-08 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * Makefile.am, aclocal.m4, configure.in, mixlib/gettext.h,
+ mixlib/mix.h: corrections to gettext infrastructure.
+
+2002-12-08 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * autogen.sh: use autopoint instead of gettextize.
+
+2002-10-19 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * THANKS: Vasilij removed, as he requested.
+
+2002-04-11 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/gmixvm.c, mixgtk/mixgtk.c, mixgtk/mixgtk_device.c,
+ mixgtk/mixgtk_gen_handlers.c, mixgtk/mixgtk_mixal.c,
+ mixgtk/mixgtk_mixvm.c, mixguile/mixguile.c, mixlib/mix.c,
+ mixlib/mix_config.c, mixlib/mix_predicate.c,
+ mixlib/mix_vm_command.c, mixutils/mixvm_command.c:
+
+ _() i18n macro added to all strings missing it.
+
+2002-04-11 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * po/POTFILES.in: file list updated.
+
+2002-04-10 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/: mixgtk_mixal.c, mixgtk_mixvm.c: sprintf -> g_snprintf.
+
+2002-04-10 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixlib/xmix_vm_handlers.c: bug fix in 'load' command.
+
+2002-04-10 Jose A Ortega Ruiz <jao@gnu.org>
+
+ * mixgtk/mixgtk_cmd_dispatcher.c, mixgtk/mixgtk_device.c,
+ mixgtk/mixgtk_input.c, mixgtk/mixgtk_mixal.c,
+ mixgtk/mixgtk_mixvm.c, mixguile/xmixguile_cmd_dispatcher.c,
+ mixlib/mix_predicate.c, mixlib/mix_vm_command.c,
+ mixlib/xmix_vm_command.c, mixlib/xmix_vm_handlers.c:
+
+ portability fix: snprintf -> g_snprintf.
+
diff --git a/ChangeLog.1 b/ChangeLog.1
new file mode 100644
index 0000000..b3d4c3c
--- /dev/null
+++ b/ChangeLog.1
@@ -0,0 +1,1807 @@
+***** Changes up to version 1.0 ******
+
+2002-04-08 03:06 jao
+
+ * NEWS:
+
+ date added
+
+2002-04-08 02:33 jao
+
+ * mixutils/mixvm_loop.c:
+
+ configurable prompt support
+
+2002-04-08 02:32 jao
+
+ * mixutils/mixvm_command.c:
+
+ new command: prompt
+
+2002-04-08 02:32 jao
+
+ * mixutils/mixvm_command.h:
+
+ $Id: ChangeLog.1,v 1.1 2003/02/01 23:07:02 jao Exp $ tag added
+
+2002-04-08 02:31 jao
+
+ * mixutils/mixvm.c:
+
+ new option (-t/--time)
+
+2002-04-08 02:30 jao
+
+ * mixutils/Makefile.am:
+
+ new file
+
+2002-04-08 02:29 jao
+
+ * INSTALL, NEWS, README, THANKS, aclocal.m4, configure.in:
+
+ candidate release 1.0
+
+2002-04-08 02:26 jao
+
+ * doc/: mdk_mixvm.texi, mdk_tut.texi, mdk.texi, mdk_ack.texi,
+ mdk_gstart.texi, mdk_install.texi:
+
+ candidate release 1.0
+
+2002-04-08 00:22 jao
+
+ * mixutils/mixvm_loop.h:
+
+ initial revision
+
+2002-03-29 17:31 jao
+
+ * mixgtk/mixgtk.c:
+
+ $Id: ChangeLog.1,v 1.1 2003/02/01 23:07:02 jao Exp $ tag added
+
+2002-03-29 17:30 jao
+
+ * mixgtk/: gmixvm.c, mixgtk.c, mixgtk_config.c, mixgtk_device.c,
+ mixgtk_wm.c:
+
+ missing standard headers included
+
+2002-03-24 02:22 jao
+
+ * mixlib/mix_code_file.c:
+
+ version compatibility check disabled
+
+2002-03-24 01:23 jao
+
+ * mixlib/xmix_vm.h:
+
+ wrapping up location pointer when address 3999 is reached
+
+2002-03-24 01:22 jao
+
+ * samples/.cvsignore:
+
+ new ignored files
+
+2002-03-20 02:33 jao
+
+ * configure.in:
+
+ copyright an cvs Id
+
+2002-03-20 02:31 jao
+
+ * po/ChangeLog:
+
+ new gettext version
+
+2002-03-20 02:30 jao
+
+ * mixutils/: mixasm.c, mixvm.c, mixvm_loop.c:
+
+ new option -t (--time)
+
+2002-03-20 02:28 jao
+
+ * configure.in:
+
+ correctly grouping commands inside []
+
+2002-03-19 23:55 jao
+
+ * mixlib/mix_parser.c:
+
+ comment corrected
+
+2002-03-19 23:38 jao
+
+ * doc/: mdk_gstart.texi, mdk_tut.texi:
+
+ fxn suggestions
+
+2002-03-19 23:36 jao
+
+ * .cvsignore, mixgtk/.cvsignore, mixutils/.cvsignore,
+ samples/.cvsignore:
+
+ new ignored files
+
+2001-09-30 22:29 jao
+
+ * mixguile/Makefile.am:
+
+ scm init file added
+
+2001-09-29 04:11 jao
+
+ * ChangeLog:
+
+ release 0.5
+
+2001-09-29 03:56 jao
+
+ * NEWS:
+
+ version 0.5 update
+
+2001-09-29 03:55 jao
+
+ * doc/mdk_gmixvm.texi:
+
+ exclude images in dvi
+
+2001-09-29 03:54 jao
+
+ * mixlib/mix.h:
+
+ CVS $Id: ChangeLog.1,v 1.1 2003/02/01 23:07:02 jao Exp $ added
+
+2001-09-29 03:53 jao
+
+ * doc/Makefile.am, mixgtk/Makefile.am, mixguile/Makefile.am,
+ mixlib/Makefile.am, mixlib/testsuite/Makefile.am,
+ mixutils/Makefile.am, samples/Makefile.am:
+
+ INCLUDES fixed to allow VPATH builds
+
+2001-09-29 01:29 jao
+
+ * NEWS, NEWS:
+
+ version 0.5 update
+
+2001-09-29 01:11 jao
+
+ * TODO, doc/Makefile.am, doc/mdk.texi, doc/mdk_gmixvm.texi,
+ doc/mdk_mixguile.texi:
+
+ version 0.5 update
+
+2001-09-29 01:10 jao
+
+ * mixgtk/gmixvm.c, mixguile/mixguile.c, mixguile/mixguile.h,
+ mixguile/mixguile_main.c, mixlib/mix.c, mixlib/mix.h,
+ mixutils/mixasm.c, mixutils/mixvm.c:
+
+ uniform command line options handling
+
+2001-09-27 01:15 jao
+
+ * doc/: mdk.texi, mdk_gstart.texi, mdk_install.texi,
+ mdk_mixasm.texi, mdk_mixvm.texi, mdk_tut.texi:
+
+ minor cosmetic changes
+
+2001-09-27 01:13 jao
+
+ * doc/mdk_mixguile.texi:
+
+ partial doc update
+
+2001-09-26 00:46 jao
+
+ * TODO:
+
+ $Id: ChangeLog.1,v 1.1 2003/02/01 23:07:02 jao Exp $ cvs tag
+
+2001-09-26 00:45 jao
+
+ * TODO:
+
+ new todo items
+
+2001-09-26 00:43 jao
+
+ * po/ChangeLog:
+
+ gettextize new entry
+
+2001-09-26 00:41 jao
+
+ * mixguile/.cvsignore:
+
+ new ignored files
+
+2001-09-25 23:41 jao
+
+ * mixguile/xmixguile_cmd_dispatcher.c:
+
+ new scheme primitive (mix-last-result)
+
+2001-09-25 01:27 jao
+
+ * mixguile/: mixguile.c, mixguile.h, mixguile_main.c:
+
+ optionally load local startup file
+
+2001-09-25 01:27 jao
+
+ * mixutils/: mixvm.c, mixvm_loop.c:
+
+ -q option added
+
+2001-09-25 01:26 jao
+
+ * mixlib/mix.c:
+
+ GPL notice shortened
+
+2001-09-19 00:55 jao
+
+ * TODO:
+
+ new todo items
+
+2001-09-19 00:53 jao
+
+ * NEWS, doc/mdk.texi, doc/mdk_bugs.texi, doc/mdk_emixvm.texi,
+ doc/mdk_gmixvm.texi, doc/mdk_gstart.texi, doc/mdk_mixasm.texi,
+ doc/mdk_mixguile.texi, doc/mdk_mixvm.texi:
+
+ partial doc update
+
+2001-09-19 00:51 jao
+
+ * doc/.cvsignore:
+
+ new ignored file
+
+2001-09-19 00:51 jao
+
+ * mixgtk/mixgtk_fontsel.c:
+
+ remove fonts that cannot be loaded from the config file
+
+2001-09-19 00:50 jao
+
+ * mixgtk/: mixgtk_config.c, mixgtk_config.h:
+
+ (mixgtk_config_remove) new function to remove configuration items
+
+2001-09-19 00:49 jao
+
+ * mixlib/: mix_config.c, mix_config.h:
+
+ (mix_config_remove) new function to remove configuration items
+
+2001-09-18 23:49 jao
+
+ * mixgtk/mixgtk_fontsel.c:
+
+ use of $Id: ChangeLog.1,v 1.1 2003/02/01 23:07:02 jao Exp $
+
+2001-09-18 23:49 jao
+
+ * mixgtk/mixgtk_fontsel.c:
+
+ loc widget fonts are updated correctly
+
+2001-09-18 01:36 jao
+
+ * doc/mdk_mixvm.texi:
+
+ new mixvm commands documented
+
+2001-09-18 01:26 jao
+
+ * mixlib/xmix_vm_handlers.c:
+
+ (cmd_pstat_) alway print an endline character
+
+2001-09-17 00:47 jao
+
+ * mixguile/xmixguile_cmd_dispatcher.c:
+
+ virtual machine status
+
+2001-09-17 00:43 jao
+
+ * mixguile/mixguile.scm:
+
+ load mixguile-stat-vm.scm
+
+2001-09-17 00:42 jao
+
+ * mixguile/mixguile-vm-stat.scm:
+
+ header corrected
+
+2001-09-17 00:40 jao
+
+ * mixguile/.cvsignore, samples/.cvsignore:
+
+ new ignored files
+
+2001-09-17 00:39 jao
+
+ * mixlib/xmix_vm_command.h:
+
+ minor changes
+
+2001-09-17 00:38 jao
+
+ * mixlib/xmix_vm.h:
+
+ maintain virtual machine status
+
+2001-09-17 00:37 jao
+
+ * mixlib/xmix_vm_handlers.h:
+
+ pstat command
+
+2001-09-17 00:32 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ minor changes
+
+2001-09-17 00:29 jao
+
+ * mixlib/: mix_vm.c, mix_vm.h:
+
+ maintain virtual machine status
+
+2001-09-17 00:28 jao
+
+ * mixlib/: mix_predicate.c, mix_predicate.h, mix_predicate_list.h:
+
+ access to the predicate type added
+
+2001-09-17 00:17 jao
+
+ * INSTALL, NEWS, doc/.cvsignore, doc/mdk.texi, doc/mdk_ack.texi,
+ doc/mdk_copying.texi, doc/mdk_gstart.texi, doc/mdk_index.texi,
+ doc/mdk_install.texi, doc/mdk_intro.texi:
+
+ partial doc update
+
+2001-09-15 04:14 jao
+
+ * doc/mdk_gstart.texi:
+
+ partial doc update
+
+2001-09-15 04:12 jao
+
+ * mixguile/mixguile-commands.scm:
+
+ all commands implemented in terms of mixvm-cmd to allow hook calling
+
+2001-09-14 02:48 jao
+
+ * doc/mdk_ack.texi:
+
+ typo
+
+2001-09-14 02:41 jao
+
+ * doc/mdk_gstart.texi:
+
+ doc update for version 0.5
+
+2001-09-14 02:08 jao
+
+ * mixguile/mixguile-commands.scm:
+
+ (mix-pmem) no accepts two arguments (from, to)
+
+2001-09-13 02:13 jao
+
+ * doc/: mdk.texi, mdk_bugs.texi, mdk_copying.texi, mdk_emixvm.texi,
+ mdk_findex.texi, mdk_gmixvm.texi, mdk_gstart.texi, mdk_index.texi,
+ mdk_install.texi, mdk_intro.texi, mdk_mixasm.texi, mdk_mixvm.texi,
+ mdk_tut.texi:
+
+ partial doc update for version 0.5
+
+2001-09-13 01:14 jao
+
+ * mixlib/xmix_vm_handlers.c:
+
+ add a newline character to the output of psrc and pprog
+
+2001-09-12 01:31 jao
+
+ * doc/mdk_ack.texi:
+
+ initial version (from the THANKS file)
+
+2001-09-12 01:20 jao
+
+ * THANKS:
+
+ Vasilij contribution
+
+2001-09-12 01:18 jao
+
+ * THANKS:
+
+ Radu Butnaru
+
+2001-09-12 00:53 jao
+
+ * mixlib/mix_vm_clock.c:
+
+ (mix_vm_clock_add_lapse) fixed time del for the MOVE instruction
+
+2001-09-11 01:42 jao
+
+ * doc/mdk_intro.texi:
+
+ version 0.5 update
+
+2001-09-10 22:35 jao
+
+ * doc/mdk_gmixvm.texi:
+
+ version 0.5 update
+
+2001-09-05 00:14 jao
+
+ * doc/img/.cvsignore:
+
+ ignore eps files
+
+2001-09-05 00:13 jao
+
+ * doc/Makefile.am:
+
+ licenses in one appendix
+
+2001-09-05 00:09 jao
+
+ * doc/: .cvsignore, fdl.texi, gpl.texi, mdk.texi, mdk_copying.texi,
+ mdk_gmixvm.texi, mdk_index.texi:
+
+ licenses in one appendix
+
+2001-09-04 04:36 jao
+
+ * mixguile/mixguile-vm-stat.scm:
+
+ using Id tag
+
+2001-09-04 04:35 jao
+
+ * mixguile/mixguile-vm-stat.scm:
+
+ vm status guile commands
+
+2001-09-04 04:31 jao
+
+ * doc/Makefile.am:
+
+ copyright notice updated
+
+2001-09-04 04:30 jao
+
+ * doc/Makefile.am:
+
+ fdl.texi file added
+
+2001-09-04 04:30 jao
+
+ * doc/img/Makefile.am:
+
+ missing files added
+
+2001-09-02 02:49 jao
+
+ * mixguile/xmixguile_cmd_dispatcher.c:
+
+ new procedures mix-src-line, mix-src-line-no
+
+2001-09-01 02:22 jao
+
+ * mixguile/: mixguile-commands.scm, mixguile_cmd_dispatcher.c,
+ mixguile_cmd_dispatcher.h, xmixguile_cmd_dispatcher.c,
+ xmixguile_cmd_dispatcher.h:
+
+ new mixguile commands
+
+2001-09-01 02:21 jao
+
+ * mixguile/.cvsignore:
+
+ more ignored files
+
+2001-09-01 02:21 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ use of new command pddir
+
+2001-09-01 02:19 jao
+
+ * mixutils/.cvsignore, mixutils/mixvm_command.c,
+ mixlib/mix_vm_command.c, mixlib/mix_vm_command.h,
+ mixlib/xmix_vm_command.c, mixlib/xmix_vm_command.h,
+ mixlib/xmix_vm_handlers.c, mixlib/xmix_vm_handlers.h:
+
+ new commands: pddir, sddir, ptime, psrc, pprog, pline
+
+2001-09-01 02:16 jao
+
+ * mixguile/mixguile.c:
+
+ using access to check for bootstrap files
+
+2001-09-01 02:04 jao
+
+ * mixgtk/mixgtk_widgets.c:
+
+ using access to check for glade file
+
+2001-08-29 04:14 jao
+
+ * mixguile/xmixguile_cmd_dispatcher.c, mixlib/mix_vm_command.c,
+ mixlib/mix_vm_command.h:
+
+ new mix-guile commands
+
+2001-08-28 18:41 jao
+
+ * mixguile/.cvsignore:
+
+ more ignored files
+
+2001-08-28 18:38 jao
+
+ * NEWS, configure.in, mixgtk/Makefile.am, mixgtk/gmixvm.c,
+ mixgtk/mixgtk_cmd_dispatcher.c, mixgtk/mixgtk_mixvm.c,
+ mixguile/Makefile.am, mixguile/mixguile.c, mixguile/mixguile.h,
+ mixguile/mixguile_cmd_dispatcher.c, mixguile/mixguile_main.c,
+ mixguile/xmixguile_cmd_dispatcher.c, mixlib/Makefile.am,
+ mixlib/mix_config.c, mixlib/mix_config.h, mixlib/mix_vm_command.c,
+ mixlib/mix_vm_command.h, mixlib/xmix_vm_command.c,
+ mixlib/xmix_vm_command.h, mixlib/xmix_vm_handlers.c,
+ mixlib/xmix_vm_handlers.h, mixutils/Makefile.am, mixutils/mixvm.c,
+ mixutils/mixvm_command.c, mixutils/mixvm_command.h,
+ mixutils/mixvm_loop.c, po/ChangeLog, .cvsignore:
+
+ guile integration
+
+2001-08-23 02:01 jao
+
+ * configure.in, mixgtk/Makefile.am, mixguile/Makefile.am,
+ mixguile/mixguile_main.c, mixutils/Makefile.am, po/ChangeLog,
+ mixguile/.cvsignore, mixguile/mixguile-commands.scm,
+ mixguile/mixguile.scm:
+
+ mixguile commands
+
+2001-08-23 01:45 jao
+
+ * mixutils/mixguile.c:
+
+ file moved to mixguile dir
+
+2001-08-22 04:43 jao
+
+ * mixguile/xmixguile_cmd_dispatcher.c:
+
+ more commands
+
+2001-08-22 02:44 jao
+
+ * mixutils/.cvsignore:
+
+ more ignored files
+
+2001-08-22 02:42 jao
+
+ * mixguile/Makefile.am, mixguile/mixguile.c, mixguile/mixguile.h,
+ mixguile/mixguile_cmd_dispatcher.c,
+ mixguile/mixguile_cmd_dispatcher.h,
+ mixguile/xmixguile_cmd_dispatcher.c,
+ mixguile/xmixguile_cmd_dispatcher.h, mixlib/mix_vm_command.c,
+ mixlib/mix_vm_command.h, mixutils/Makefile.am, mixutils/mixguile.c:
+
+ mixguile: first version
+
+2001-08-21 02:31 jao
+
+ * mixguile/.cvsignore:
+
+ ignored files
+
+2001-08-21 02:30 jao
+
+ * Makefile.am, configure.in, mixguile/Makefile.am,
+ mixguile/mixguile.c, mixguile/mixguile.h,
+ mixguile/mixguile_cmd_dispatcher.c,
+ mixguile/mixguile_cmd_dispatcher.h:
+
+ initial guile support
+
+2001-08-20 02:42 jao
+
+ * mixlib/mix_vm_command.c:
+
+ memory leak fixed
+
+2001-08-20 02:36 jao
+
+ * mixgtk/: mixgtk_fontsel.c, mixgtk_mixvm.c:
+
+ memory leak fixed
+
+2001-08-17 04:32 jao
+
+ * ChangeLog, NEWS:
+
+ version 0.4.2
+
+2001-08-17 04:26 jao
+
+ * NEWS, mdk.spec, doc/img/ss_devices.jpg, doc/img/ss_mix.jpg,
+ doc/img/ss_mixal.jpg, doc/img/ss_split.jpg:
+
+ version 0.4.2
+
+2001-08-17 03:54 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ devices destruction fixed
+
+2001-08-17 03:05 jao
+
+ * ChangeLog, NEWS:
+
+ version 0.4.2
+
+2001-08-17 02:07 jao
+
+ * mixgtk/Makefile.am:
+
+ data files always included in distribution
+
+2001-08-17 02:06 jao
+
+ * mixgtk/: Makefile.am, devdir.xpm, extern.xpm, mixgtk.glade:
+
+ new toolbar buttons
+
+2001-08-17 01:08 jao
+
+ * mixgtk/mixgtk.glade:
+
+ MIXAL status bar
+
+2001-08-17 01:06 jao
+
+ * mixgtk/mixgtk_mixal.c:
+
+ display symbol values in MIXAL status bar when split
+
+2001-08-17 00:38 jao
+
+ * aclocal.m4, configure.in:
+
+ version 0.4.2
+
+2001-08-17 00:37 jao
+
+ * po/ChangeLog:
+
+ new gettext version
+
+2001-08-17 00:32 jao
+
+ * NEWS, mixgtk/.cvsignore, mixgtk/Makefile.am:
+
+ toolbars added
+
+2001-08-17 00:28 jao
+
+ * mixgtk/: clear.xpm, colors.xpm, compile.xpm, edit.xpm, font.xpm,
+ fontl.xpm, jump.xpm, mixgtk.glade, mixgtk_config.c,
+ mixgtk_config.h, mixgtk_wm.c, mixgtk_wm.h, next.xpm, onew.xpm,
+ open.xpm, output.xpm, run.xpm, splitw.xpm, symbols.xpm:
+
+ toolbars added
+
+2001-07-26 00:00 jao
+
+ * aclocal.m4, configure.in, mixutils/mixvm_command.c, po/ChangeLog:
+
+ rl_completion_matches check
+
+2001-07-22 23:30 jao
+
+ * mixgtk/mixgtk_mixal.c:
+
+ release 0.4
+
+2001-07-22 23:11 jao
+
+ * NEWS:
+
+ version 0.4
+
+2001-07-22 23:08 jao
+
+ * NEWS, doc/mdk_gstart.texi, doc/mdk_mixvm.texi, mixlib/mix_vm.c,
+ mixlib/mix_vm.h, mixlib/mix_vm_command.c, mixlib/mix_vm_command.h,
+ samples/.cvsignore, samples/bt.mixal, samples/cbp.mixal:
+
+ version 0.4
+
+2001-07-22 15:47 jao
+
+ * mixlib/: mix_vm_command.c, xmix_vm.h:
+
+ release 0.4
+
+2001-07-22 01:02 jao
+
+ * ChangeLog, mdk.spec:
+
+ version 0.4
+
+2001-07-22 00:54 jao
+
+ * mixlib/: mix_predicate.c, mix_predicate_list.c,
+ mix_predicate_list.h, mix_vm.c, mix_vm.h, mix_vm_command.c:
+
+ conditional breakpoints finished
+
+2001-07-22 00:09 jao
+
+ * doc/: mdk_gstart.texi, mdk_mixvm.texi:
+
+ conditional breakpoints
+
+2001-07-21 23:21 jao
+
+ * NEWS:
+
+ conditional breakpoints
+
+2001-07-21 23:14 jao
+
+ * mixlib/mix_vm_command.c, mixlib/mix_vm_command.h,
+ mixutils/mixvm_command.c, samples/.cvsignore, samples/cbp.mixal:
+
+ mem and register conditional breakpoints
+
+2001-07-21 23:11 jao
+
+ * aclocal.m4:
+
+ new macros
+
+2001-07-19 02:24 jao
+
+ * mixlib/Makefile.am, mixlib/mix_config.c, mixlib/mix_predicate.c,
+ mixlib/mix_predicate.h, mixlib/mix_predicate_list.c,
+ mixlib/mix_predicate_list.h, mixlib/mix_vm.c, mixlib/mix_vm.h,
+ mixlib/mix_vm_command.c, mixlib/xmix_vm.h, mixutils/mixvm_loop.c,
+ po/ChangeLog:
+
+ cond bp support
+
+2001-07-13 22:17 jao
+
+ * doc/: mdk_gmixvm.texi, mdk_gstart.texi, img/ss_devdir.jpg,
+ img/ss_split.jpg:
+
+ version 0.4
+
+2001-07-11 01:04 jao
+
+ * doc/: .cvsignore, mdk.texi, mdk_mixvm.texi:
+
+ version 0.4
+
+2001-07-10 00:55 jao
+
+ * configure.in:
+
+ version 0.4
+
+2001-07-10 00:49 jao
+
+ * NEWS, mixgtk/mixgtk.c, mixgtk/mixgtk_cmd_dispatcher.c,
+ mixgtk/mixgtk_cmd_dispatcher.h, mixlib/mix_config.c,
+ mixlib/mix_config.h, mixlib/mix_vm_command.c,
+ mixutils/mixvm_loop.c:
+
+ history file
+
+2001-07-08 23:55 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_device.c,
+ mixgtk/mixgtk_gen_handlers.c, mixgtk/mixgtk_gen_handlers.h,
+ mixgtk/mixgtk_widgets.c, mixgtk/mixgtk_widgets.h:
+
+ devdir command via menu
+
+2001-07-08 02:18 jao
+
+ * mixgtk/: mixgtk_cmd_dispatcher.c, mixgtk_config.c,
+ mixgtk_config.h, mixgtk_device.c:
+
+ use of mix_config
+
+2001-07-08 01:34 jao
+
+ * mixlib/mix_config.c, mixlib/mix_device.c, mixlib/mix_device.h,
+ mixlib/mix_vm_command.c, mixlib/mix_vm_command.h, mixutils/mixvm.c,
+ mixutils/mixvm_command.c, mixutils/mixvm_command.h,
+ mixutils/mixvm_loop.c:
+
+ use of devdir command
+
+2001-07-08 00:57 jao
+
+ * mixlib/mix_config.h:
+
+ (mix_config_get_filename) new function
+
+2001-07-07 22:46 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ timing command
+
+2001-07-07 22:31 jao
+
+ * mixlib/mix_vm_command.c:
+
+ trace->tracing
+
+2001-07-07 00:28 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ (mix_vm_cmd_dispatcher_new_with_config) new constructor tron/troff
+ substituted by trace on|off
+
+2001-07-06 01:38 jao
+
+ * mixlib/: mix_device.c, mix_device.h, xmix_device.c,
+ xmix_device.h:
+
+ externally provided device files directory
+
+2001-07-06 01:37 jao
+
+ * mixlib/mix_config.c:
+
+ use mix_stat_dir
+
+2001-07-06 01:37 jao
+
+ * mixlib/: mix.c, mix.h:
+
+ (mix_stat_dir) new function
+
+2001-07-06 01:35 jao
+
+ * mixgtk/: mixgtk.h, mixgtk_config.c, mixgtk_device.c:
+
+ use of .mdk instead of .gmixvm
+
+2001-07-03 00:56 jao
+
+ * mixgtk/mixgtk_config.c:
+
+ use of mix_config_t
+
+2001-07-03 00:39 jao
+
+ * mixlib/: mix_config.c, mix_config.h, Makefile.am:
+
+ shared config handler
+
+2001-07-01 15:33 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_cmd_dispatcher.c,
+ mixgtk/mixgtk_device.c:
+
+ split improved
+
+2001-06-30 21:35 jao
+
+ * mixgtk/: mixgtk.c, mixgtk_cmd_dispatcher.c, mixgtk_device.c,
+ mixgtk_widgets.c, mixgtk_wm.c:
+
+ split improved
+
+2001-06-28 00:50 jao
+
+ * mixgtk/: mixgtk.c, mixgtk.glade, mixgtk.h, mixgtk_fontsel.c,
+ mixgtk_fontsel.h, mixgtk_mixal.c, mixgtk_mixvm.c, mixgtk_widgets.c,
+ mixgtk_widgets.h, mixgtk_wm.c:
+
+ hot split swap
+
+2001-06-26 01:52 jao
+
+ * mixgtk/: mixgtk.c, mixgtk.h, mixgtk_cmd_dispatcher.c,
+ mixgtk_colorsel.c, mixgtk_colorsel.h, mixgtk_device.c,
+ mixgtk_fontsel.c, mixgtk_gen_handlers.c, mixgtk_input.c,
+ mixgtk_input.h, mixgtk_mixal.c, mixgtk_widgets.c, mixgtk_wm.c:
+
+ hot split/unsplit
+
+2001-06-24 18:58 jao
+
+ * mixgtk/mixgtk.glade:
+
+ split windows mode
+
+2001-06-24 18:56 jao
+
+ * NEWS:
+
+ display file in title
+
+2001-06-24 18:51 jao
+
+ * mixgtk/mixgtk_cmd_dispatcher.c:
+
+ display file in title
+
+2001-06-24 15:06 jao
+
+ * mixgtk/: .cvsignore, Makefile.am, mixgtk.c, mixgtk.glade,
+ mixgtk_cmd_dispatcher.c, mixgtk_cmd_dispatcher.h, mixgtk_config.c,
+ mixgtk_config.h, mixgtk_fontsel.c, mixgtk_fontsel.h,
+ mixgtk_mixal.c, mixgtk_mixal.h, mixgtk_mixvm.c, mixgtk_mixvm.h,
+ mixgtk_widgets.c, mixgtk_widgets.h, mixgtk_wm.c, mixgtk_wm.h:
+
+ split windows mode
+
+2001-06-23 10:05 jao
+
+ * samples/.cvsignore:
+
+ release 0.3.5
+
+2001-06-22 04:16 jao
+
+ * doc/img/Makefile.am, ChangeLog:
+
+ version 0.3.5
+
+2001-06-22 04:12 jao
+
+ * README:
+
+ url
+
+2001-06-21 23:13 jao
+
+ * mixgtk/mixgtk.glade:
+
+ release 0.3.5
+
+2001-06-21 22:47 jao
+
+ * mixgtk/mixgtk_mixal.c:
+
+ release 0.3.5
+
+2001-06-21 22:27 jao
+
+ * mdk.spec, doc/mdk.texi, doc/mdk_gmixvm.texi,
+ doc/img/ss_colors.jpg, doc/img/ss_devform.jpg,
+ doc/img/ss_devices.jpg, doc/img/ss_extprog.jpg,
+ doc/img/ss_goto.jpg, doc/img/ss_mix.jpg, doc/img/ss_mixal.jpg,
+ doc/img/ss_symbols.jpg, doc/img/ss_worddlg.jpg,
+ mixgtk/mixgtk.glade, mdk.spec:
+
+ release 0.3.5
+
+2001-06-19 00:59 jao
+
+ * NEWS:
+
+ psym bugs fixed
+
+2001-06-19 00:54 jao
+
+ * mixlib/mix_symbol_table.c:
+
+ (add_symbol_) symbol value correctly recovered (including sign)
+
+2001-06-19 00:43 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (cmd_psym_) symbols printed to the correct stream
+
+2001-06-19 00:27 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_mixal.c,
+ mixgtk/mixgtk_widgets.c, mixgtk/mixgtk_widgets.h:
+
+ gmixvm symbols dialog
+
+2001-06-18 01:26 jao
+
+ * mixgtk/mixgtk.glade:
+
+ minor change
+
+2001-06-18 01:05 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_mixal.c:
+
+ variables in status bar
+
+2001-06-15 23:09 jao
+
+ * configure.in:
+
+ version 0.3.5
+
+2001-06-15 23:08 jao
+
+ * NEWS:
+
+ font config bug fixed
+
+2001-06-15 22:37 jao
+
+ * mixgtk/mixgtk_fontsel.c:
+
+ font config bug fixed
+
+2001-06-15 17:00 jao
+
+ * mixgtk/: mixgtk_gen_handlers.c, mixgtk_gen_handlers.c:
+
+ bug corrected
+
+2001-06-12 23:37 jao
+
+ * doc/mdk.texi:
+
+ version 0.3.4
+
+2001-06-12 23:34 jao
+
+ * NEWS:
+
+ version 0.3.4
+
+2001-06-12 23:28 jao
+
+ * configure.in:
+
+ version 0.3.4
+
+2001-06-12 18:07 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ segfault corrected
+
+2001-06-11 22:39 jao
+
+ * THANKS:
+
+ adrian
+
+2001-06-11 22:38 jao
+
+ * THANKS:
+
+ minor changes
+
+2001-06-10 14:45 jao
+
+ * doc/mdk_gmixvm.texi:
+
+ minor changes
+
+2001-06-10 14:15 jao
+
+ * doc/mdk_gmixvm.texi:
+
+ minor changes
+
+2001-06-10 00:49 jao
+
+ * ChangeLog, mdk.spec, doc/.cvsignore, doc/img/.cvsignore:
+
+ version 0.3.3
+
+2001-06-09 16:38 jao
+
+ * NEWS, mdk.spec, doc/mdk.texi, doc/mdk_gmixvm.texi,
+ doc/mdk_mixvm.texi, doc/img/.cvsignore, doc/img/Makefile.am,
+ doc/img/ss_devform.jpg, doc/img/ss_extprog.jpg:
+
+ version 0.3.3
+
+2001-06-09 00:58 jao
+
+ * aclocal.m4:
+
+ version 0.3.3
+
+2001-06-09 00:31 jao
+
+ * configure.in:
+
+ version 0.3.3
+
+2001-06-09 00:29 jao
+
+ * NEWS:
+
+ minor changes
+
+2001-06-09 00:27 jao
+
+ * mixgtk/: mixgtk.glade, mixgtk_cmd_dispatcher.c,
+ mixgtk_cmd_dispatcher.h, mixgtk_gen_handlers.c,
+ mixgtk_gen_handlers.h:
+
+ edit and compile menu entries added
+
+2001-06-09 00:26 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ src file path accessor added
+
+2001-06-08 02:49 jao
+
+ * THANKS:
+
+ new guys
+
+2001-06-08 02:08 jao
+
+ * doc/mdk_tut.texi:
+
+ minor correction
+
+2001-06-07 00:49 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_cmd_dispatcher.c:
+
+ command history and tab completion added
+
+2001-06-07 00:48 jao
+
+ * mixutils/.cvsignore:
+
+ new ignored file
+
+2001-06-05 23:26 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (cmd_edit_) messages about executed command added
+
+2001-06-05 23:23 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (cmd_compile_) messages about executed command added
+
+2001-06-05 23:17 jao
+
+ * mixutils/mixvm_command.c:
+
+ use of mix_vm_cmd_dispatcher edit and compile commands
+
+2001-06-05 23:04 jao
+
+ * mixlib/mix_parser.c:
+
+ copyright notice
+
+2001-06-05 23:03 jao
+
+ * mixlib/mix_parser.c:
+
+ the src path always correctly stored
+
+2001-06-05 23:02 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ edit and compile commands added
+
+2001-06-05 22:15 jao
+
+ * mixlib/: mix_vm_command.c, mix_vm_command.h:
+
+ edit and compile commands added
+
+2001-06-05 00:13 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_cmd_dispatcher.c,
+ mixgtk/mixgtk_mixvm.h, mixgtk/mixgtk_widgets.c,
+ mixgtk/mixgtk_widgets.h, mixlib/mix_file.c, mixlib/mix_file.h,
+ samples/primes.mixal:
+
+ edit and compile commands added to gmixvm
+
+2001-06-05 00:05 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (mix_vm_cmd_dispatch) \n added to unknown command message
+
+2001-06-03 13:24 jao
+
+ * mixgtk/mixgtk.glade:
+
+ extern program dialog added
+
+2001-06-03 13:19 jao
+
+ * mixgtk/.cvsignore, mixlib/.cvsignore, samples/.cvsignore:
+
+ new ignored files
+
+2001-06-03 13:16 jao
+
+ * NEWS:
+
+ when a file is reloaded, breakpoints are no reset
+
+2001-06-03 13:06 jao
+
+ * mixlib/mix_vm.c:
+
+ (mix_vm_load_file) when a file is reloaded, breakpoints are no reset
+
+2001-06-03 11:04 jao
+
+ * mixlib/mix_scanner.l:
+
+ CON bug fixed
+
+2001-05-31 00:15 jao
+
+ * NEWS, mixgtk/mixgtk.glade, mixgtk/mixgtk_device.c,
+ mixgtk/mixgtk_device.h, mixgtk/mixgtk_widgets.c,
+ mixgtk/mixgtk_widgets.h, mixlib/mix_vm.c, mixlib/mix_vm.h:
+
+ binary devices output formats added
+
+2001-05-25 00:56 jao
+
+ * doc/: fdl.texi, gpl.texi, mdk.texi, mdk_bugs.texi,
+ mdk_emixvm.texi, mdk_gmixvm.texi, mdk_gstart.texi, mdk_index.texi,
+ mdk_install.texi, mdk_intro.texi, mdk_mixasm.texi, mdk_mixvm.texi,
+ mdk_tut.texi:
+
+ license changed to gfdl
+
+2001-05-24 02:38 jao
+
+ * mixgtk/: mixgtk.c, mixgtk.glade, mixgtk.h, mixgtk_colorsel.c,
+ mixgtk_colorsel.h, mixgtk_fontsel.c, mixgtk_fontsel.h,
+ mixgtk_input.c, mixgtk_input.h, mixgtk_mixvm.c, mixgtk_widgets.c,
+ mixgtk_widgets.h:
+
+ deferred dialog creation
+
+2001-05-19 20:53 jao
+
+ * doc/img/ss_goto.jpg:
+
+ 0.3.2 release
+
+2001-05-19 16:58 jao
+
+ * Makefile.am, mdk.spec:
+
+ file mdk.spec added to the distribution
+
+2001-05-19 16:55 jao
+
+ * mixgtk/mixgtk_mixvm.c, doc/img/ss_colors.jpg,
+ doc/img/ss_devices.jpg, doc/img/ss_goto.jpg, doc/img/ss_mix.jpg,
+ doc/img/ss_mixal.jpg, doc/img/ss_worddlg.jpg:
+
+ 0.3.2 release
+
+2001-05-16 23:09 jao
+
+ * ChangeLog:
+
+ 0.3.2 release
+
+2001-05-16 23:06 jao
+
+ * samples/: stress5.mixal, stress6.mixal:
+
+ 0.3.2 release
+
+2001-05-16 23:02 jao
+
+ * INSTALL, samples/.cvsignore:
+
+ 0.3.2 release
+
+2001-05-16 01:28 jao
+
+ * doc/mdk_install.texi:
+
+ CVS URL corrected
+
+2001-05-16 01:20 jao
+
+ * doc/img/Makefile.am:
+
+ new figures added
+
+2001-05-16 01:11 jao
+
+ * ChangeLog:
+
+ 0.3.2 release
+
+2001-05-16 01:08 jao
+
+ * .cvsignore, configure.in, updatelog, doc/mdk.texi,
+ doc/mdk_gmixvm.texi, doc/mdk_install.texi, doc/img/ss_colors.jpg,
+ doc/img/ss_goto.jpg, mixlib/mix.h, samples/.cvsignore:
+
+ 0.3.2 release
+
+2001-05-14 00:58 jao
+
+ * THANKS, NEWS:
+
+ name typo
+
+2001-05-14 00:54 jao
+
+ * NEWS, THANKS:
+
+ 0.3.2 release
+
+2001-05-11 00:10 jao
+
+ * NEWS:
+
+ 0.3.2 release
+
+2001-05-10 23:48 jao
+
+ * mixgtk/: mixgtk.glade, mixgtk_device.c, mixgtk_fontsel.c:
+
+ devices font customisation added
+
+2001-05-10 01:45 jao
+
+ * mixlib/: mix_file.c, xmix_io.c:
+
+ read/write files not truncated if they already exist
+
+2001-05-10 01:17 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ minor changes
+
+2001-05-10 01:16 jao
+
+ * mixlib/: mix_io.c, xmix_device.c, xmix_io.c:
+
+ (mix_io_write_*_array) bug corrected
+
+2001-05-08 01:03 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ use of virtual device destructor to delete devices after program
+ reload
+
+2001-05-08 01:02 jao
+
+ * mixlib/: mix_device.c, mix_vm.c, xmix_device.c, xmix_device.h:
+
+ mix_device_t: virtual destructor added
+
+2001-05-06 23:38 jao
+
+ * mixgtk/mixgtk_device.c, mixlib/mix_device.c,
+ mixlib/xmix_device.c, mixlib/xmix_device.h:
+
+ support for gtk binary devices added
+
+2001-05-04 01:48 jao
+
+ * mixlib/: mix_vm.c, mix_vm.h, xmix_vm.c, xmix_vm.h:
+
+ new devices are created by a (possibly externally provided) factory
+
+2001-05-04 01:35 jao
+
+ * mixgtk/mixgtk_fontsel.c:
+
+ (change_font_) setting current font on fontsel dialog when available
+
+2001-05-04 01:34 jao
+
+ * mixgtk/mixgtk.c:
+
+ (mixgtk_init) check for the existence of glade xml file(s) before
+ using it
+
+2001-04-30 01:28 jao
+
+ * mixgtk/mixgtk.glade:
+
+ minor changes
+
+2001-04-29 22:40 jao
+
+ * mixgtk/: mixgtk_fontsel.c, mixgtk_mixal.c:
+
+ config file handling added
+
+2001-04-29 14:56 jao
+
+ * mixgtk/: Makefile.am, mixgtk.c, mixgtk.glade, mixgtk.h,
+ mixgtk_config.c, mixgtk_config.h, mixgtk_fontsel.c,
+ mixgtk_gen_handlers.c, mixgtk_gen_handlers.h, mixgtk_widgets.c:
+
+ config file handling added
+
+2001-04-28 22:54 jao
+
+ * mixgtk/: Makefile.am, gmixvm.c, mixgtk.c, mixgtk.h:
+
+ initialisation, clean-up and main functionality split
+
+2001-04-28 00:54 jao
+
+ * mixgtk/: .cvsignore, Makefile.am, mixgtk.c, mixgtk.glade,
+ mixgtk_fontsel.c, mixgtk_fontsel.h, mixgtk_widgets.c,
+ mixgtk_widgets.h:
+
+ font customization added
+
+2001-04-23 23:30 jao
+
+ * mixutils/Makefile.am:
+
+ intlibs recovered
+
+2001-04-22 22:07 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (cmd_pmem_) seg fault when freeing (changed) arg valued corrected
+
+2001-04-22 02:04 jao
+
+ * mixgtk/: Makefile.am, mixgtk.c, mixgtk.glade, mixgtk_colorsel.c,
+ mixgtk_colorsel.h, mixgtk_mixal.c, mixgtk_mixal.h,
+ mixgtk_widgets.c, mixgtk_widgets.h:
+
+ color custumozation added
+
+2001-04-21 23:59 jao
+
+ * doc/mdk_install.texi:
+
+ minor changes
+
+2001-04-21 23:30 jao
+
+ * mixgtk/mixgtk_mixal.c:
+
+ (on_mixal_select_row) set/unset breakpoints on location line
+
+2001-04-09 01:15 jao
+
+ * INSTALL:
+
+ release 0.3.1
+
+2001-04-09 00:40 jao
+
+ * .cvsignore:
+
+ ignored files
+
+2001-04-09 00:40 jao
+
+ * doc/mdk.texi, doc/mdk_install.texi, ChangeLog:
+
+ release 0.3.1
+
+2001-04-09 00:19 jao
+
+ * aclocal.m4, NEWS:
+
+ release 0.3.1
+
+2001-04-08 22:35 jao
+
+ * aclocal.m4, configure.in:
+
+ gtk test recovered
+
+2001-04-08 22:23 jao
+
+ * NEWS, THANKS, mixgtk/mixgtk_cmd_dispatcher.c:
+
+ compilation on FreeBSD fixed
+
+2001-04-08 00:13 jao
+
+ * lib/.cvsignore, samples/.cvsignore:
+
+ ignored files
+
+2001-04-08 00:12 jao
+
+ * Makefile.am, aclocal.m4, configure.in, lib/Makefile.am,
+ lib/getopt.h, lib/getopt_long.c, mixgtk/Makefile.am,
+ mixutils/Makefile.am, mixutils/mixasm.c, mixutils/mixvm.c:
+
+ getopt and getopt_long provided if missing
+
+2001-04-07 12:23 jao
+
+ * mixlib/mix_file.h:
+
+ minor changes
+
+2001-04-03 00:19 jao
+
+ * mixutils/mixvm_loop.c:
+
+ use of gets avoided for FreeBSD portability
+
+2001-04-03 00:11 jao
+
+ * mixgtk/mixgtk_device.c:
+
+ use of opem_memstream avoided for FreeBSD portability
+
+2001-04-02 21:32 jao
+
+ * misc/Makefile.am:
+
+ mixvm.el installed as package data
+
+2001-04-01 15:23 jao
+
+ * mixgtk/: mixgtk_cmd_dispatcher.c, mixgtk_mixal.c, mixgtk_input.c:
+
+ including prototype for strlen (string.h)
+
+2001-04-01 15:22 jao
+
+ * mixlib/mix_vm_command.c:
+
+ (cmd_smem_) variables always initialised
+
+2001-04-01 15:09 jao
+
+ * mixlib/: mix_eval_scanner.l, mix_scanner.l:
+
+ including prototype for strlen (string.h)
+
+2001-04-01 15:06 jao
+
+ * mixlib/: mix_code_file.c, mix_parser.c:
+
+ including prototype for strlen (string.h)
+
+2001-04-01 15:04 jao
+
+ * mixlib/mix_file.c:
+
+ including prototype for strlen and strcmp (string.h)
+
+2001-04-01 15:01 jao
+
+ * mixlib/mix_symbol_table.c:
+
+ including prototype for strlen (string.h)
+
+2001-04-01 14:59 jao
+
+ * mixlib/xmix_vm.h:
+
+ including prototype for memset (string.h)
+
+2001-04-01 00:04 jao
+
+ * configure.in, doc/mdk.texi, mixgtk/mixgtk_mixal.h:
+
+ minor changes
+
+2001-03-31 02:35 jao
+
+ * doc/mdk.texi:
+
+ direntry added
+
+2001-03-30 23:09 jao
+
+ * doc/Makefile.am:
+
+ missing file
+
+2001-03-30 02:23 jao
+
+ * mixgtk/Makefile.am, mixutils/Makefile.am:
+
+ included gettext libs properly used when specified in configuration
+
+2001-03-28 01:20 jao
+
+ * TODO:
+
+ release 0.3
+
+2001-03-28 01:16 jao
+
+ * THANKS, NEWS:
+
+ release 0.3
+
+2001-03-28 01:12 jao
+
+ * .cvsignore, NEWS, configure.in, doc/Makefile.am, doc/mdk.texi,
+ doc/mdk_gmixvm.texi, doc/ss_devices.png, doc/ss_mix.png,
+ doc/ss_mix.txt, doc/ss_mixal.png, doc/ss_mixal.txt,
+ doc/ss_worddlg.png, doc/img/.cvsignore, doc/img/Makefile.am,
+ samples/stress2.mixal:
+
+ 0.3 release
+
+2001-03-26 00:54 jao
+
+ * doc/img/: ss_devices.jpg, ss_devices.png, ss_mix.jpg, ss_mix.png,
+ ss_mixal.jpg, ss_mixal.png, ss_worddlg.jpg, ss_worddlg.png:
+
+ images translated to jpg
+
+2001-03-26 00:45 jao
+
+ * doc/img/: Makefile.am, ss_devices.png, ss_mix.png, ss_mix.txt,
+ ss_mixal.png, ss_mixal.txt, ss_worddlg.png, ss_mixal.txt:
+
+ doc images
+
+2001-03-26 00:06 jao
+
+ * doc/ss_mixal.txt:
+
+ info mode figure
+
+2001-03-22 04:01 jao
+
+ * .cvsignore, AUTHORS, COPYING, ChangeLog, INSTALL, Makefile.am,
+ NEWS, README, THANKS, TODO, acconfig.h, aclocal.m4, autogen.sh,
+ configure.in, doc/.cvsignore, doc/Makefile.am, doc/gpl.texi,
+ doc/mdk.texi, doc/mdk_bugs.texi, doc/mdk_emixvm.texi,
+ doc/mdk_gmixvm.texi, doc/mdk_gstart.texi, doc/mdk_index.texi,
+ doc/mdk_install.texi, doc/mdk_intro.texi, doc/mdk_mixasm.texi,
+ doc/mdk_mixvm.texi, doc/mdk_tut.texi, doc/ss_devices.png,
+ doc/ss_mix.png, doc/ss_mix.txt, doc/ss_mixal.png,
+ doc/ss_worddlg.png, misc/.cvsignore, misc/Makefile.am,
+ misc/mixvm.el, mixgtk/.cvsignore, mixgtk/Makefile.am,
+ mixgtk/mixgtk.c, mixgtk/mixgtk.glade,
+ mixgtk/mixgtk_cmd_dispatcher.c, mixgtk/mixgtk_cmd_dispatcher.h,
+ mixgtk/mixgtk_device.c, mixgtk/mixgtk_device.h,
+ mixgtk/mixgtk_gen_handlers.c, mixgtk/mixgtk_gen_handlers.h,
+ mixgtk/mixgtk_input.c, mixgtk/mixgtk_input.h,
+ mixgtk/mixgtk_mixal.c, mixgtk/mixgtk_mixal.h,
+ mixgtk/mixgtk_mixvm.c, mixgtk/mixgtk_mixvm.h,
+ mixgtk/mixgtk_widgets.c, mixgtk/mixgtk_widgets.h,
+ mixlib/.cvsignore, mixlib/Makefile.am, mixlib/mix.c, mixlib/mix.h,
+ mixlib/mix_code_file.c, mixlib/mix_code_file.h,
+ mixlib/mix_device.c, mixlib/mix_device.h, mixlib/mix_eval.c,
+ mixlib/mix_eval.h, mixlib/mix_eval_scanner.l, mixlib/mix_file.c,
+ mixlib/mix_file.h, mixlib/mix_ins.c, mixlib/mix_ins.h,
+ mixlib/mix_io.c, mixlib/mix_io.h, mixlib/mix_parser.c,
+ mixlib/mix_parser.h, mixlib/mix_scanner.l, mixlib/mix_src_file.c,
+ mixlib/mix_src_file.h, mixlib/mix_symbol_table.c,
+ mixlib/mix_symbol_table.h, mixlib/mix_types.c, mixlib/mix_types.h,
+ mixlib/mix_vm.c, mixlib/mix_vm.h, mixlib/mix_vm_clock.c,
+ mixlib/mix_vm_clock.h, mixlib/mix_vm_command.c,
+ mixlib/mix_vm_command.h, mixlib/mix_vm_dump.c,
+ mixlib/mix_vm_dump.h, mixlib/xmix_device.c, mixlib/xmix_device.h,
+ mixlib/xmix_eval.h, mixlib/xmix_io.c, mixlib/xmix_io.h,
+ mixlib/xmix_parser.h, mixlib/xmix_vm.c, mixlib/xmix_vm.h,
+ mixlib/testsuite/.cvsignore, mixlib/testsuite/Makefile.am,
+ mixlib/testsuite/mix_device_t.c, mixlib/testsuite/mix_eval_t.c,
+ mixlib/testsuite/mix_ins_t.c, mixlib/testsuite/mix_parser_t.c,
+ mixlib/testsuite/mix_types_t.c, mixlib/testsuite/mix_vm_ins_t.c,
+ mixlib/testsuite/test.h, mixutils/.cvsignore, mixutils/Makefile.am,
+ mixutils/mixasm.c, mixutils/mixasm_comp.c, mixutils/mixasm_comp.h,
+ mixutils/mixvm.c, mixutils/mixvm_command.c,
+ mixutils/mixvm_command.h, mixutils/mixvm_loop.c, po/.cvsignore,
+ po/ChangeLog, po/POTFILES.in, samples/.cvsignore,
+ samples/Makefile.am, samples/hello.mixal, samples/primes.mixal,
+ samples/primes.result, samples/stress1.mixal,
+ samples/stress2.mixal, samples/stress4.mixal:
+
+ Initial revision
+
+2001-03-22 04:01 jao
+
+ * .cvsignore, AUTHORS, COPYING, ChangeLog, INSTALL, Makefile.am,
+ NEWS, README, THANKS, TODO, acconfig.h, aclocal.m4, autogen.sh,
+ configure.in, doc/.cvsignore, doc/Makefile.am, doc/gpl.texi,
+ doc/mdk.texi, doc/mdk_bugs.texi, doc/mdk_emixvm.texi,
+ doc/mdk_gmixvm.texi, doc/mdk_gstart.texi, doc/mdk_index.texi,
+ doc/mdk_install.texi, doc/mdk_intro.texi, doc/mdk_mixasm.texi,
+ doc/mdk_mixvm.texi, doc/mdk_tut.texi, doc/ss_devices.png,
+ doc/ss_mix.png, doc/ss_mix.txt, doc/ss_mixal.png,
+ doc/ss_worddlg.png, misc/.cvsignore, misc/Makefile.am,
+ misc/mixvm.el, mixgtk/.cvsignore, mixgtk/Makefile.am,
+ mixgtk/mixgtk.c, mixgtk/mixgtk.glade,
+ mixgtk/mixgtk_cmd_dispatcher.c, mixgtk/mixgtk_cmd_dispatcher.h,
+ mixgtk/mixgtk_device.c, mixgtk/mixgtk_device.h,
+ mixgtk/mixgtk_gen_handlers.c, mixgtk/mixgtk_gen_handlers.h,
+ mixgtk/mixgtk_input.c, mixgtk/mixgtk_input.h,
+ mixgtk/mixgtk_mixal.c, mixgtk/mixgtk_mixal.h,
+ mixgtk/mixgtk_mixvm.c, mixgtk/mixgtk_mixvm.h,
+ mixgtk/mixgtk_widgets.c, mixgtk/mixgtk_widgets.h,
+ mixlib/.cvsignore, mixlib/Makefile.am, mixlib/mix.c, mixlib/mix.h,
+ mixlib/mix_code_file.c, mixlib/mix_code_file.h,
+ mixlib/mix_device.c, mixlib/mix_device.h, mixlib/mix_eval.c,
+ mixlib/mix_eval.h, mixlib/mix_eval_scanner.l, mixlib/mix_file.c,
+ mixlib/mix_file.h, mixlib/mix_ins.c, mixlib/mix_ins.h,
+ mixlib/mix_io.c, mixlib/mix_io.h, mixlib/mix_parser.c,
+ mixlib/mix_parser.h, mixlib/mix_scanner.l, mixlib/mix_src_file.c,
+ mixlib/mix_src_file.h, mixlib/mix_symbol_table.c,
+ mixlib/mix_symbol_table.h, mixlib/mix_types.c, mixlib/mix_types.h,
+ mixlib/mix_vm.c, mixlib/mix_vm.h, mixlib/mix_vm_clock.c,
+ mixlib/mix_vm_clock.h, mixlib/mix_vm_command.c,
+ mixlib/mix_vm_command.h, mixlib/mix_vm_dump.c,
+ mixlib/mix_vm_dump.h, mixlib/xmix_device.c, mixlib/xmix_device.h,
+ mixlib/xmix_eval.h, mixlib/xmix_io.c, mixlib/xmix_io.h,
+ mixlib/xmix_parser.h, mixlib/xmix_vm.c, mixlib/xmix_vm.h,
+ mixlib/testsuite/.cvsignore, mixlib/testsuite/Makefile.am,
+ mixlib/testsuite/mix_device_t.c, mixlib/testsuite/mix_eval_t.c,
+ mixlib/testsuite/mix_ins_t.c, mixlib/testsuite/mix_parser_t.c,
+ mixlib/testsuite/mix_types_t.c, mixlib/testsuite/mix_vm_ins_t.c,
+ mixlib/testsuite/test.h, mixutils/.cvsignore, mixutils/Makefile.am,
+ mixutils/mixasm.c, mixutils/mixasm_comp.c, mixutils/mixasm_comp.h,
+ mixutils/mixvm.c, mixutils/mixvm_command.c,
+ mixutils/mixvm_command.h, mixutils/mixvm_loop.c, po/.cvsignore,
+ po/ChangeLog, po/POTFILES.in, samples/.cvsignore,
+ samples/Makefile.am, samples/hello.mixal, samples/primes.mixal,
+ samples/primes.result, samples/stress1.mixal,
+ samples/stress2.mixal, samples/stress4.mixal:
+
+ initial import (sf 0.3beta)
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..4a960d7
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,339 @@
+Installing MDK
+**************
+
+Download the source tarball
+===========================
+
+ GNU MDK is distributed as a source tarball available for download in
+the following URLs:
+
+ * <ftp://ftp.gnu.org/pub/gnu/mdk> (or one of its mirrors
+ (http://www.gnu.org/prep/ftp.html))
+
+ * `http://sourceforge.net/project/showfiles.php?group_id=13897'
+
+ The above sites contain the latest stable releases of MDK. The
+development branch is available at:
+
+ * `https://savannah.gnu.org/cvs/?group_id=118'
+
+ After you have downloaded the source tarball, unpack it in a
+directory of your choice using the command:
+
+ tar xfvz mdk-X.Y.tar.gz
+
+where X.Y stands for the downloaded version (the current stable release
+being version 1.2.1).
+
+Requirements
+============
+
+ In order to build and install MDK, you will need the following
+libraries installed in your system:
+
+ - GLIB 2.4.0 (http://www.gtk.org) (required)
+
+ - GNU Flex 2.5 (http://www.gnu.org/software/flex/flex.html)
+ (required)
+
+ - GTK 2.4.0 (http://www.gtk.org) (optional)
+
+ - Libglade 2.4.0 (http://ftp.gnome.org/pub/GNOME/sources/libglade/2.4/)
+ (optional)
+
+ - GNU Readline
+ (http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html)
+ (optional)
+
+ - GNU Libguile 1.6 (http://www.gnu.org/software/guile) (optional)
+
+ If present, readline and history are used to provide command
+completion and history management to the command line MIX virtual
+machine, `mixvm'. GTK+ and libglade are needed if you want to build
+the graphical interface to the MIX virtual machine, `gmixvm'. Finally,
+if libguile is found, the MDK utilities will be compiled with Guile
+support and will be extensible using Scheme.
+
+ *Please note*: you need both the libraries _and_ the headers; this
+means both the library package and the `-dev' package if you do not
+compile your libraries yourself (ex: installing `libgtk2.0' and
+`libgtk2.0-dev' on Debian).
+
+Basic installation
+==================
+
+ MDK uses GNU Autoconf and Automake tools, and, therefore, should be
+built and installed without hassle using the following commands inside
+the source directory:
+
+ ./configure
+ make
+ make install
+
+where the last one must be run as root.
+
+ The first command, `configure', will setup the makefiles for your
+system. In particular, `configure' will look for GTK+ and libglade,
+and, if they are present, will generate the appropiate makefiles for
+building the `gmixvm' graphical user interface. Upon completion, you
+should see a message with the configuration results like the following:
+
+ *** GNU MDK 1.2.1 has been successfully configured. ***
+
+ Type 'make' to build the following utilities:
+ - mixasm (MIX assembler)
+ - mixvm (MIX virtual machine, with readline support,
+ with guile support)
+ - gmixvm (mixvm GTK+ GUI, with guile support)
+ - mixguile (the mixvm guile shell)
+
+where the last lines may be missing if you lack the above mentioned
+libraries.
+
+ The next command, `make', will actually build the MDK programs in
+the following locations:
+
+ - `mixutils/mixasm'
+
+ - `mixutils/mixvm'
+
+ - `mixgtk/gmixvm'
+
+ - `mixguile/mixguile'
+
+ You can run these programs from within their directories, but I
+recommend you to install them in proper locations using `make install'
+from a root shell.
+
+Emacs support
+=============
+
+ `mixvm' can be run within an Emacs GUD buffer using the elisp
+program `misc/mixvm.el', kindly contributed by {No value for `PHILIP'}.
+
+ `mixvm.el' provides an interface between MDK's `mixvm' and Emacs,
+via GUD. Place this file in your load-path, optionally adding the
+following line to your `.emacs' file:
+
+ (autoload 'mixvm "mixvm" "mixvm/gud interaction" t)
+
+Special configure flags
+=======================
+
+ You can fine tunning the configuration process using the following
+switches with configure:
+
+ - User Option: -enable-gui[=yes|no]
+ - User Option: -disable-gui
+ Enables/disables the build of the MIX virtual machine GUI
+ (`gmixvm'). If the required libraries are missing (*note
+ Requirements::) the configure script with automatically disable
+ this feature.
+
+ - User Option: -with-guile[=yes|no]
+ - User Option: -without-guile
+ Enables/disables the Guile support for `mixvm' and `gmixvm', and
+ the build of `mixguile'. If the required libraries are missing
+ (*note Requirements::) the configure script with automatically
+ disable this feature.
+
+ - User Option: -with-readline[=yes|no]
+ - User Option: -without-readline
+ Enables/disables the GNU Readline support for `mixvm'. If the
+ required libraries are missing (*note Requirements::) the configure
+ script with automatically disable this feature.
+
+ For additional, boilerplate configure options, see the
+ `Generic configure help' below, or run
+
+ configure --help
+
+------------------------------------------------------------------------
+------------------------------------------------------------------------
+
+Generic configure help
+**********************
+
+
+Basic Installation
+==================
+
+ For more information specific to this package, please read the README
+file. This source code distribution is autoconfiguring and you should be
+able to compile it and install it without manual interventions such as
+editing Makefiles, configuration files, and so on. These are generic
+instructions for people who are not familiar with installing autoconfiguring
+software.
+
+The simplest way to compile this package is to enter the source code
+main directory and do the following:
+
+ 1. Configure the source code by typing:
+ % sh ./configure
+
+ If you're planning to install the package into your home directory
+ or to a location other than `/usr/local' then add the flag
+ `--prefix=PATH' to `configure'. For example, if your home directory
+ is `/home/luser' you can configure the package to install itself there
+ by invoking:
+ % sh ./configure --prefix=/home/luser
+
+ While running, `configure' prints some messages telling which
+ features is it checking for.
+
+ 2. Compile the package by typing:
+ % make
+ Running `make' takes a while. If this is a very large package, now
+ is the time to go make some coffee.
+
+ 3. Some packages are bundled with self-tests for source-code
+ verification. If this package includes such tests, you can
+ optionally run them after compilation by typing
+ % make check
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. Type `make uninstall' to undo the installation.
+ During installation, the following files go to the following directories:
+ Executables -> /prefix/bin
+ Libraries -> /prefix/lib
+ Public header files -> /prefix/include
+ Man pages -> /prefix/man/man?
+ Info files -> /prefix/info
+ where `prefix' is either `/usr/local' or the PATH that you specified
+ in the `--prefix' flag.
+
+ If any of these directories do not presently exist, they will be
+ created on demand.
+
+ If you are installing in your home directory make sure that
+ `/home/luser/bin' is in your path. If you're using the bash shell
+ add this line at the end of your .cshrc file:
+ PATH="/home/luser/bin:${PATH}"
+ export PATH
+ If you are using csh or tcsh, then use this line instead:
+ setenv PATH /home/luser/bin:${PATH}
+ By prepending your home directory to the rest of the PATH you can
+ override systemwide installed software with your own custom installation.
+
+ 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'.
+
+Compiler configuration
+======================
+
+ The `configure' shell script is responsible for choosing and configuring
+the compiler(s).
+
+The following options allow you to specify whether you
+want to enable or disable various debugging mechanisms:
+
+`--with-warnings'
+ Make the compilers very picky about warnings. Try this whenever you
+ write new code since it may catch a few bugs. This is not active by
+ default because all too often warnings can be too picky and scare
+ the end-user.
+
+`--disable-assert'
+ Compile without using assertions. This results in faster code,
+ but should not be used during developerment, or to run `make check'
+ which depends on assertions. It should only be used for production
+ runs on code that you believe is bug free.
+
+All programs are compiled with optimization level 2 by default (-O2).
+Occasionally that confuses the debugger when code is inlined. To disable
+optimization and enable debugging, set the shell environment variables
+CFLAGS, CXXFLAGS, FFLAGS to `-g'. On the bash shell, you can do this
+like this:
+ $ export CFLAGS="-g"
+ $ export CXXFLAGS="-g"
+ $ export FFLAGS="-g"
+On the tcsh shell, use the `setenv' command instead:
+ % setenv CFLAGS "-g"
+ ...etc...
+For other shell, please consult your shell's documentation.
+
+Similarly, you can increase the optimization level by assigning these
+variables to "-g -O3".
+
+The following options allow you to reconsider the `configure' shell script's
+choice of Fortran compilers.
+
+`--with-f2c'
+ Compile the Fortran code by translating it to C, even if a native
+ Fortran compiler is available. A copy of the f2c translator should be
+ bundled in the distribution. It will be compiled and then used to
+ compile your Fortran code.
+`--with-g77'
+ Compile the Fortran code with g77 even if a proprietary Fortran
+ compiler is available
+`--with-f77=F77'
+ Compile the Fortran code with the specified Fortran compiler.
+
+Depending on what languages the package uses, some of these options may
+or may not be available. To see what is available, type:
+ % sh ./configure --help
+
+About the configure script
+==========================
+
+ 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, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ 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 at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+Advanced installation options.
+==============================
+
+ The `configure' script also understands the following more advanced
+options, to handle situations for which `--prefix' alone is not sufficient.
+
+ 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.
+
+----
+
+$Id: INSTALL,v 1.7 2005/09/20 20:18:58 jao Exp $
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..cfd46d1
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,24 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+EXTRA_DIST = config.rpath ABOUT-NLS intltool-extract.in intltool-merge.in \
+ intltool-update.in
+SUBDIRS = po intl doc lib mixlib mixguile mixutils mixgtk misc samples
+
+distclean-local:
+ rm -f intltool-extract
+ rm -f intltool-merge
+ rm -f intltool-update
+
+docdir = $(top_builddir)/doc
+
+ACLOCAL_AMFLAGS = -I m4
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..5aee4ec
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,450 @@
+GNU MDK -- History of visible changes.
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, Free Software Foundation, Inc.
+See the end for copying conditions.
+
+Please send mdk bug reports to bug-mdk@gnu.org.
+
+---------------------------------------------------------------------------
+* Version 1.2.1 (20/09/05)
+
+** MIXAL compliance improvements (Sergey Poznyakoff):
+
+ - w-expressions in literals are now admitted (e.g. LDA =8(1:1)=)
+ - ALF now accepts non-quoted arguments (in addition to quoted
+ - ones), as in the original TAOCP definition.
+
+** German translation updated (thanks to Jens Seidel)
+
+** mixal.el improvements (Pieter Pareit)
+
+** Bug fixes:
+
+ - gmixvm's failure to dynamically link with libglade (#13661)
+ (thanks to Sascha Wilde)
+ - mixal.el calls mixasm with obsolete -g option (#14569) (thanks to
+ Sascha Wilde)
+ - mixasm -g causes a coredump (#14579) (Pieter Pareit)
+
+---------------------------------------------------------------------------
+* Version 1.2 (05/08/04)
+
+** Graphical user interface (gmixvm) updated to gtk+ 2.4.x
+
+ - gmixvm now uses the latest version of the gtk+ toolkit, including
+ antialiased Pango fonts.
+ - Individually detachable windows for the virtual machine, the
+ source window and the devices notebook (there is no 'split mode'
+ anymore).
+ - Detachable toolbars.
+ - Current source line and breakpoints are now marked via icons.
+ - New menu option to change all fonts at once.
+
+** German i18n available (thanks to Mike Scholz). Set LANG to
+ de_DE.UTF-8 to use it.
+
+** mixasm includes debug info in compiled mix files by default: the
+ options -g and --debug are gone; if you want to compile without
+ debug info, use -O or --ndebug.
+
+---------------------------------------------------------------------------
+* Version 1.1 (12/06/04)
+
+** The typewriter device (19) is now input/output, so that you can
+ read characters from standard input (mixvm) or a popup dialog
+ (gmixvm) in your MIXAL programs (see samples/echo.mixal for a
+ simple usage sample).
+
+** Input character device files may now contain lines with less than the
+ required block size; the virtual machine pads the missing
+ characters in memory using 0 (MIX char 'space').
+
+** The paper tape device (20) was incorrectly defined as an output
+ device. It is now an input char device (cf. TAOCP vol.1 p. 133,
+ where it is mentioned as the 'paper tape reader'; thanks to Michael
+ Talbot-Wilson).
+
+** Listings produced by mixasm improved: better layout, and correct
+ identification of 'ALF' and 'CON' instructions (including those
+ added by the compiler as a result of local constant definitions and
+ future references.
+
+** Local constants can now be modified by a field spec or an index,
+ as in, say, CMPA =0=,1(3:2) (closes #5654).
+
+** The virtual machine reader is now case-insensitive, i.e., it
+ automatically converts lowercase characters in input char device
+ files to their uppercase counterparts (which are the only ones
+ admitted by MIX). The ASCII representation for MIX chars delta,
+ sigma and pi is now ~, [ and #.
+
+** Bug fix: mixvm prompt's ending whitespace is now correctly set.
+
+** Bug fix: blocks in input char devices (e.g. the card reader) are
+ now expected to be separated by newlines, mirroring char output,
+ which is done so (i.e. with one ASCII line per block).
+
+** Improved virtual machine error messages (bad memory address, device
+ no., fspec, etc.).
+
+** Bug fix: undefined symbols are transformed to new addresses just
+ before the end of a compiled program (as per TAOCP v1 p. 156;
+ thanks to WeiZeng).
+
+** Bug fix: the vm no longer blows up on memory access violations
+ (thanks to Joel R. Holveck; closes #5649).
+
+** Bug fix: LDAN, LDXN and LDiN always negate the result, even if zero
+ (thanks to Ruslan Batdalov; closes Debian's #247392).
+
+---------------------------------------------------------------------------
+* Version 1.0.1 (09/06/03)
+
+** New misc/mixal-mode.el for emacs (and associated docs), written by
+ Pieter Pareit.
+
+** Error message for unquoted ALF operand improved.
+
+** Fixed bug that caused (g)mixvm to segfault when reading a false MIX
+ file.
+
+** All translatable strings are ready for i18n.
+
+** Portability fixes to extend supported platforms.
+
+** When the program counter reaches address 4000 during program
+ execution, it is set back to its maximum value, 3999, and the
+ program halts, to avoid infinite loops.
+
+** Minor documentation improvements.
+
+** Minor bug fixes.
+
+---------------------------------------------------------------------------
+* Version 1.0 (08/04/02)
+
+** The stable release.
+
+** New command line option added to 'mixvm': -t (--time) to turn on
+ virtual execution time printing (it is now off by default).
+
+** New 'mixvm' command: prompt, lets you change the mixvm command
+ prompt ("MIX > " by default).
+
+** When the program counter reaches address 4000 during program
+ execution, it wraps up to value 0, to keep always a valid
+ address. Caveat: a program missing the HLT instruction can loop
+ indefinitely.
+
+** New supported platform: Mac OS X.
+
+** User manual reviewed and updated.
+
+** Bug fix: 'configure' libraries detection now works properly.
+
+** Bug fix: missing #includes added to avoid compilation errors in
+ some platforms (RedHat 7.1, ia64 with gcc 3.0).
+
+---------------------------------------------------------------------------
+* Version 0.5 (29/09/01)
+
+** Added Guile support:
+ - New utility 'mixguile': a Guile shell with an embedded MIX
+ virtual machine.
+ - gmixvm and mixvm have an embedded Guile interpreter: Scheme
+ can be used as an extension language.
+ - See the updated User's Manual for details.
+
+** New (g)mixvm commands:
+ - psrc: print the current program's source file path
+ - pprog: print the current program's path
+ - pline: print the current program line
+ - pstat: print the current virtual machine status
+ - slog: set on/off the logging of info messages to stdout (or
+ the command log in gmixvm)
+
+** For the sake of coherence, the following (g)mixvm commands
+ have been renamed:
+ - tracing -> strace
+ - timing -> stime (set on/off timing),
+ ptime (print timing stats)
+ - devdir -> sddir (set the devices dir),
+ pddir (print the devices dir)
+
+** Major documentation update to include Guile support and various
+ cosmetic corrections for pretty ps and pdf manuals (provided in the
+ distribution in addition to the html format).
+
+** In gmixvm, when a font specified in the config file cannot be
+ loaded, it is removed from the configuration.
+
+** gmixvm now accepts the standard command line options -vuh
+
+** Bug fix: when the MIX font is changed in gmixvm, the loc widget
+ font is correctly updated.
+
+** Bug fix: help messages are now correctly aligned in (g)mixvm.
+
+** Bug fix: timing statitics for the MOVE instruction are correctly
+ computed.
+
+** Bug fix: pressing return at an empty 'MIX >' prompt does not
+ produce an error message.
+
+** Bug fix: the configure script now correctly detects the absence of
+ libglade (needed by gmixvm).
+
+** Bug fix: makefiles corrected so that mdk accepts a VPATH build
+ ('make distcheck' works now)
+
+---------------------------------------------------------------------------
+* Version 0.4.2 (17/08/01)
+
+** New toolbars for gmixvm windows.
+
+** Toolbars can be hidden, using View->Toolbar checkbox.
+
+** New icon for the "goto loc pointer address" button.
+
+** The menu entry "Split windows" has been moved from "Settings" to
+ "View" main menu, and renamed to "One window" in split mode.
+
+** In split mode, the MIXAL window has its own statusbar to display
+ symbol values in it (instead of in the main window toolbar).
+
+** Bug fix: the visibility of split windows when changing mode is now
+ correctly handled.
+
+** Bug fix: the devices window is now correctly destroyed, avoiding
+ GTK warnings on gmixvm exit.
+
+---------------------------------------------------------------------------
+* Version 0.4 (22/07/01)
+
+** Split mode: gmixvm can now be run with the MIXVM, MIXAL and Devices
+ windows detached (instead of arranged in a notebook).
+
+** When running in split mode, the MIXVM, MIXAL and Devices windows
+ can be hidden.
+
+** Conditional breakpoints can be set in mixvm and gmixvm using the
+ commands 'sbp[rmco]', which cause the execution to stop when a
+ given register, memory cell contents, comparison flag or overflow
+ toggle change (e.g. 'sbpr A' will set a breakpoint on register A
+ contents change). Conditional breakpoints can be deleted using the
+ new commands 'cbp[rmco]'.
+
+** New vm command 'pbt' which prints a backtrace of the last executed
+ instructions.
+
+** The gmixvm main window displays the path to the current MIX file in
+ its title bar.
+
+** The mixvm and gmixvm configuration files are now stored in ~/.mdk
+ (instead of ~/.gmixvm).
+
+** The default device files directory is also ~/.mdk. It can be
+ configured using the new command 'devdir' or (in gmixvm) with the
+ new Settings->Devices dir menu command.
+
+** The commands 'tron' and 'troff' have been substituted by 'tracing
+ on|off'.
+
+** The trace flag is saved as a configuration parameter in mixvm and
+ gmixvm.
+
+** New vm commands: 'pedit'/'sedit' (print/set editor command) and
+ 'pasm'/'sasm' (print/set compile command). Their value is stored as
+ a config param also in mixvm.
+
+** New command 'timing' for setting on/off and printing the timing
+ statistics (both in gmixvm and mixvm). Its value is also stored as
+ a config param.
+
+** mixvm and gmixvm now save a history file so that they remember
+ commands typed in previous sessions.
+
+** Bug fix: changes in the device format are now correctly stored (gmixvm).
+
+---------------------------------------------------------------------------
+* Version 0.3.5 (23/06/01)
+
+** In gmixvm, when the mouse pointer is over a MIXAL source line, the
+ status bar shows the value of the variables appearing in this line.
+
+** The current symbol table can be displayed, in gmixvm, using the menu
+ command Debug->Symbols...
+
+** Bug fix: the load, compile and run file dialogs now get the correct
+ filename under linux.
+
+** Bug fix: fonts used by gmixvm are now always correctly saved.
+
+** Bug fix: 'psym' now works correctly in gmixvm.
+
+** Bug fix: the symbol table for a MIX file is now correctly recovered
+ both in gmixvm and mixvm (negative values where incorrectly
+ converted to a positive value).
+
+---------------------------------------------------------------------------
+* Version 0.3.4 (12/06/01)
+
+** Bug fix for a segfault which made gmixvm unusable in version 0.3.3.
+
+---------------------------------------------------------------------------
+* Version 0.3.3 (10/06/01)
+
+** The output of the contents of binary devices in gmixvm can be
+ configured to be in decimal or word format (for each block device).
+
+** The main gmixvm window is not shown until it is completely drawn.
+
+** The commands 'edit' and 'compile' are now understood by gmixvm. The
+ external programs used can be configured using the menu entry
+ Settings->External programs.
+
+** The commands 'edit' and 'compile' can be now executed without
+ argument (both in mixvm and gmixvm). When no argument is given, the
+ MIXAL source file corresponding to the currently loaded MIX program
+ is edited/compiled.
+
+** Bug in CON fixed : 'CON wexpr' didn't compile correctly unless wexpr
+ represented a valid instruction; now, wexpr can evaluate to an
+ arbitrary value (Vasilij Ozmetelenko).
+
+** The completion key for the gmixvm command prompt is now TAB
+ (instead of RETURN).
+
+** The gmixvm command prompt maintains now a history of previously
+ typed commands, which can be visited using the arrow keys (UP for
+ previous command, DOWN for next one).
+
+** When a file is reloaded by the virtual machine (both in mixvm and
+ gmixvm), the currently set breakpoints are conserved.
+
+** When compiling a source file which is not in the current directory, the
+ correct path is now stored in the compiled file.
+
+** Fixed a bug which caused gmixvm to segfault when creating the
+ virtual machine (Andrew Hood)
+
+** The GNU MDK documentation is now distributed under the GFDL
+ license.
+
+---------------------------------------------------------------------------
+* Version 0.3.2 (10/05/01)
+
+** The colors used for highlighting MIXAL source lines in gmixvm are now
+ customizable.
+
+** The fonts used in the different gmixvm widgets are now
+ customizable.
+
+** Input/output for all MIX block devices is shown in gmixvm.
+
+** All gmixvm customizations are stored in a configuration file
+ (inside ~/.gmixvm directory).
+
+** Device files used by gmixvm are stored in ~/.gmixvm, instead of the
+ working directory.
+
+** Output to binary devices works now correctly.
+
+** Bug on pmem fixed (thanks to Christoph von Nathusius and Jason
+ Uhlenkott).
+
+---------------------------------------------------------------------------
+* Version 0.3.1 (9/04/01)
+
+** New binary and html RPMs (RedHat) contributed by Agustin Navarro
+ <anp@cantv.net>.
+
+** The package can be correctly build in FreeBSD 4.2 (Ying-Chieh Liao)
+
+** Fixed configuration process when included gettext is used.
+
+** The info files are now properly categorized in a dir entry, so that
+ they can be properly installed.
+
+** Compilation warnings fixed.
+
+** getopt implementation provided for systems missing it.
+
+---------------------------------------------------------------------------
+* Version 0.3 (28/03/01)
+
+** MDK is now an official GNU package.
+
+** New GTK+ interface for the virtual machine (gmixvm).
+
+** New mixvm-Emacs/GUD interface via mixvm.el (Philip King).
+
+** Readline and history support for mixvm are now optional features.
+
+** JRED is now properly implemented (bug pointed out by
+ Vasilij Ozmetelenko).
+
+---------------------------------------------------------------------------
+* Version 0.2 (07/01/01)
+
+** mixvm provides virtual execution time statistics after each
+ invocation of run or next.
+
+** mixvm can trace instructions as they are executed. tron/troff
+ commands turn on/off instruction tracing.
+
+** mixvm accepts a new command, w2d, which computes the
+ decimal value of a MIX word given as a series of
+ bytes (e.g. - 01 00 34 32 22).
+
+** Symbols can be defined at the mixvm prompt with the
+ new command ssym.
+
+** mixvm accepts a new command, weval, which allows the
+ evaluation of MIXAL w-expressions.
+
+** Expressions containing strings of successive '*' are now
+ correctly evaluated.
+
+** When using block devices in mixvm, the buffers are now
+ flushed after each OUT operation.
+
+---------------------------------------------------------------------------
+* Version 0.1.1 (18/11/00)
+
+** MDK is now compilable in rpm-based linuxes.
+** MDK fully compliant with Knuth's specification. In particular,
+ local symbols are now properly handled in special cases such as
+ 3H ORIG 3B
+ instructions. See samples/stress{1,2}.mixal.
+** Future references affected by unary minus are accepted
+ with a warning (they are banned in Knuth's specification).
+ Also future refs in EQU directives are now properly handled.
+ See samples/stress{3,4}.mixal.
+** When mixvm executes a program and reaches the end of the
+ available memory without encountering a HALT instruction,
+ it halts anyway.
+
+---------------------------------------------------------------------------
+* Version 0.1 (31/10/00)
+
+** Initial version
+
+---------------------------------------------------------------------------
+Copying information:
+
+Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ Permission is granted to anyone to make or distribute verbatim copies
+ of this document as received, in any medium, provided that the
+ copyright notice and this permission notice are preserved,
+ thus giving the recipient permission to redistribute in turn.
+
+ Permission is granted to distribute modified versions
+ of this document, or of portions of it,
+ under the above conditions, provided also that they
+ carry prominent notices stating who last changed them.
+
+
+---
+$Id: NEWS,v 1.55 2005/09/20 20:18:58 jao Exp $
diff --git a/README b/README
new file mode 100644
index 0000000..b693dba
--- /dev/null
+++ b/README
@@ -0,0 +1,43 @@
+Welcome to GNU MDK.
+
+GNU MDK is part of the GNU project [0].
+
+MDK stands for MIX Development Kit, and provides tools for developing
+and executing, in a MIX virtual machine, MIXAL programs.
+
+The MIX is Donald Knuth's mythical computer, described in the first
+volume of The Art of Computer Programming, which is programmed using
+MIXAL, the MIX assembly language.
+
+MDK includes a MIXAL assembler (mixasm) and a MIX virtual machine
+(mixvm) with a command line interface. In addition, a GTK+ GUI to
+mixvm, called gmixvm, is provided; and, in case you are an Emacs guy,
+you can try misc/mixvm.el, which allows running mixvm inside an Emacs
+GUD buffer.
+
+Using these interfaces, you can debug your MIXAL programs at source
+code level, and read/modify the contents of all the components of the
+MIX computer (including block devices, which are simultated using the
+file system).
+
+Project homepage: http://www.gnu.org/software/mdk/mdk.html
+
+GNU MDK is free software. Please see the file COPYING for details.
+
+For documentation, please see the files in the doc subdirectory.
+
+For building and installation instructions please see the INSTALL file.
+
+For sample MIXAL programs, please see the samples subdirectory.
+
+For translations (MDK uses GNU's gettext), please see the po subdirectory[1].
+
+--
+[0] To learn more about GNU, the FSF and its goals, please visit
+ http://www.gnu.org.
+
+[1] New translations are welcome. If you'd like to contribute one,
+ please contact the author, jao@gnu.org.
+
+--
+$Id: README,v 1.3 2002/04/08 00:29:59 jao Exp $ \ No newline at end of file
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..5338c6d
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,59 @@
+Acknowledgements
+****************
+
+ Many people have further contributed to MDK by reporting problems,
+suggesting various improvements, or submitting actual code. Here is a
+list of these people. Help me keep it complete and exempt of errors.
+
+ * Richard Stallman (<rms@gnu.org>) suggested various improvements to
+ the documentation and has always kept an eye on every MDK release.
+
+ * Philip Ellis King (<pking@pdq.net>) provided MIXAL test programs
+ pinpointing bugs in the first MDK release, and useful discussions
+ as well. Philip has also contributed with the Emacs port of
+ `mixvm' and influenced the `gmixvm' GUI design with insightful
+ comments and prototypes.
+
+ * Pieter E.J. Pareit (<pieter.pareit@skynet.be>) is the author of
+ the Emacs MIXAL mode, and has also contributed many bug fixes.
+
+ * Michael Scholz (<scholz-micha@gmx.de>) is the author of the
+ German translation of MDK's user interface.
+
+ * Sergey Poznyakoff(<gray@gnu.org>) provided patches to
+ mixlib/mix_scanner.l improving MIXAL compliance.
+
+ * Francesc Xavier Noria (<fxn@retemail.es>) kindly and thoroughly
+ reviewed the MDK documentation, providing insightful advice.
+
+ * Agustin Navarro (<anp@cantv.net>), Ying-Chieh Liao
+ (<ijliao@csie.nctu.edu.tw>), Adrian Bunk (<bunk@fs.tum.de>),
+ Baruch Even (<baruch@debian.org>) and Ronald Cole
+ (<ronald@forte-intl.com>) created and/or maintain packages of MDK
+ for different operating systems.
+
+ * Jason Uhlenkott, Andrew Hood (<ajhood@fl.net.au>), Radu Butnaru
+ (<rbb@email.ro>), Aleix Conchillo (<aleix@member.fsf.org>),
+ Ruslan Batdalov (<linnando@tolkien.ru>), WeiZheng
+ (<pro_zw@lol365.com>) and Sascha Wilde reported (sometimes with
+ fixes) several bugs in MDK.
+
+ * Nelson H. F. Beebe (<beebe@math.utah.edu>,
+ http://www.math.utah.edu/~beebe) has tested MDK in a lot of Unix
+ platforms, suggesting portability enhancements to the source
+ code.
+
+ * Christoph von Nathusius (<nathusiu@gmx.net>), Stephen Ramsay
+ (<sjr3a@virginia.edu>) and Johan Swanljung (<johanswa@yahoo.com>)
+ tested MDK on different platforms.
+
+ * Eli Bendersky (<spur4444@yahoo.com>), Milan Bella
+ (<milanbella@hotmail.com>) and Jens Seidel reported several
+ documentation bugs.
+
+ * MDK was inspired by Darius Bacon's MIXAL program
+ (http://www.accesscom.com/~darius/).
+
+--
+$Id: THANKS,v 1.20 2005/09/20 19:14:16 jao Exp $
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..84b7dcc
--- /dev/null
+++ b/TODO
@@ -0,0 +1,19 @@
+-*- mode: outline -*-
+
+* Version 1.2.2
+** gmixvm: list of last loaded programs
+** gmixvm: history in terminal input dialog
+** Add entries to concept index
+** Sync docs with published book
+
+* Misc
+** MIX types manipulation library in Scheme
+** Macro recorder (implemented in Scheme)
+** Add scheme functions to remove installed hooks
+
+** Allow MIXAL instructions as commands at the mixvm prompt
+ (e.g. MIX > exec LDA 2000)
+
+** gtkhtml for help system
+
+* $Id: TODO,v 1.12 2005/09/20 20:18:58 jao Exp $
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..d76540d
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+PROJECT=mdk
+TEST_TYPE=-d
+FILE=mixlib
+
+DIE=0
+
+grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && {
+ (gettext --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`gettext' installed to compile $PROJECT."
+ echo "(0.13.1 or a newer version if it is available)"
+ DIE=1
+ }
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have autoconf installed to compile $PROJECT."
+ echo "(2.53 or a newer version if it is available)"
+ DIE=1
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have automake installed to compile $PROJECT."
+ echo "(1.5 or a newer version if it is available)"
+ DIE=1
+ NO_AUTOMAKE=yes
+}
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: Missing \`aclocal'. The version of \`automake'"
+ echo "installed doesn't appear recent enough."
+ DIE=1
+}
+
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+test $TEST_TYPE $FILE || {
+ echo "You must run this script in the top-level $PROJECT directory"
+ exit 1
+}
+
+case $CC in
+*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;;
+esac
+
+echo "Running gettext's autopoint..."
+autopoint --force
+
+echo "Running intltoolize"
+intltoolize --copy --force --automake
+
+ACLOCAL_FLAGS="-I m4"
+echo "Running aclocal ..."
+aclocal $ACLOCAL_FLAGS
+
+# optionally feature autoheader
+(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
+
+echo "Running automake --add-missing --gnu $am_opt ..."
+automake -a --gnu $am_opt
+
+echo "Running autoconf ..."
+autoconf
+cd $ORIGDIR
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..4e38888
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,175 @@
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# $Id: configure.in,v 1.38 2005/09/20 20:18:58 jao Exp $
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+AC_INIT([GNU MDK],1.2.1,[bug-mdk@gnu.org],mdk)
+AM_INIT_AUTOMAKE(mdk,1.2.1)
+AM_CONFIG_HEADER(config.h)
+
+AM_MAINTAINER_MODE
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+AM_PROG_LEX
+AC_PROG_RANLIB
+
+dnl additional c flags
+CFLAGS="$CFLAGS -fno-strict-aliasing"
+AC_SUBST(CFLAGS)
+
+dnl i18n stuff
+AM_GNU_GETTEXT_VERSION(0.14)
+AM_GNU_GETTEXT
+AC_PROG_INTLTOOL([0.30], [no-xml])
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+
+AH_TEMPLATE(LOCALEDIR,[locale directory])
+AC_DEFINE_UNQUOTED(LOCALEDIR, "${prefix}/share/locale")
+
+dnl Check for readline and history
+AC_ARG_WITH(readline,
+[ --without-readline build mixvm without readline support],
+[case "${withval}" in
+ yes) readl=true ;;
+ no) readl=false ;;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-readline) ;;
+esac], [readl=true])
+
+if test x$readl = xtrue; then
+ AC_CHECK_LIB(ncurses, initscr, ,
+ [AC_MSG_WARN(Cannot find ncurses lib); readl=false])
+fi
+
+if test x$readl = xtrue; then
+ AC_CHECK_LIB(readline, readline, ,
+ [AC_MSG_WARN(Cannot find GNU readline lib); readl=false])
+fi
+
+if test x$readl = xtrue; then
+AC_CHECK_LIB(history, add_history, ,
+ [AC_MSG_WARN(Cannot find GNU history lib); readl=false])
+dnl old versions of readline use completion_matches instead
+dnl of rl_completion_matches
+AC_CHECK_FUNCS(rl_completion_matches,,)
+fi
+
+dnl Check for guile
+AC_ARG_WITH(guile,
+[ --without-guile build MDK without Guile support],
+[case "${withval}" in
+ yes) wguile=true ;;
+ no) wguile=false ;;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-guile) ;;
+esac], [wguile=true])
+
+if test x$wguile = xtrue; then
+dnl AC_CHECK_HEADER(guile/gh.h,,wguile=false)
+ AC_MSG_CHECKING(for Guile)
+ guile-config link > /dev/null || {
+ AC_MSG_RESULT(no)
+ wguile=false
+ }
+fi
+
+if test x$wguile = xtrue; then
+ GUILE_CFLAGS="`guile-config compile`"
+ GUILE_LDFLAGS="`guile-config link`"
+ LIBS="$LIBS $GUILE_LDFLAGS"
+ CFLAGS="$CFLAGS $GUILE_CFLAGS"
+ AC_SUBST(MAKE_GUILE)
+ AC_MSG_RESULT(yes)
+fi
+
+AM_CONDITIONAL(MAKE_GUILE, test x$wguile = xtrue)
+
+dnl Check for glib
+PKG_CHECK_MODULES(GLIB,glib-2.0 >= 2.0)
+
+LIBS="$LIBS $GLIB_LIBS"
+CFLAGS="$CFLAGS $GLIB_CFLAGS -DG_DISABLE_DEPRECATED"
+
+dnl Check if the gtk gui is required
+AC_ARG_ENABLE(gui,
+[ --disable-gui do not build the GTK+ GUI for mixvm (gmixvm)],
+[case "${enableval}" in
+ yes) gui=true ;;
+ no) gui=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-gui) ;;
+esac],[gui=true])
+
+dnl Check for gtk+
+if test x$gui = xtrue; then
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.4.0 libglade-2.0 >= 2.0.0 pango >= 1.4,
+ [LIBS="$LIBS $GTK_LIBS" CFLAGS="$CFLAGS $GTK_CFLAGS"],
+ [AC_MSG_WARN(Cannot find GTK+: the GUI shall not be built)
+ gui=false])
+fi
+
+if test x$gui = xtrue; then
+CFLAGS="$CFLAGS -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED"
+fi
+
+dnl use the provided getopt if gnu getopt is not available
+AC_REPLACE_FUNCS(getopt_long)
+
+AM_CONDITIONAL(MAKE_GUI, test x$gui = xtrue)
+
+dnl AC_CANONICAL_HOST
+case "${host_os}" in
+darwin*) CFLAGS="$CFLAGS -Wall -traditional-cpp";;
+*) CFLAGS="$CFLAGS -Wall";;
+esac
+
+AC_SUBST(CFLAGS)
+
+AC_CONFIG_FILES(
+Makefile
+doc/Makefile
+doc/img/Makefile
+mixlib/Makefile
+mixlib/testsuite/Makefile
+mixguile/Makefile
+mixutils/Makefile
+mixgtk/Makefile
+lib/Makefile
+misc/Makefile
+samples/Makefile
+po/Makefile.in
+intl/Makefile
+)
+
+AC_OUTPUT
+
+if test x$readl = xtrue; then
+ rlinfo=", with readline support"
+fi
+
+if test x$wguile = xtrue; then
+ guileinfo=", with guile support"
+fi
+
+echo
+echo "*** $PACKAGE_NAME $VERSION has been successfully configured. ***"
+echo
+echo "Type 'make' to build the following utilities:"
+echo " - mixasm (MIX assembler)"
+echo " - mixvm (MIX virtual machine${rlinfo}${guileinfo})"
+if test x$gui = xtrue; then
+echo " - gmixvm (mixvm GTK+ GUI${guileinfo})"
+fi
+if test x$wguile = xtrue; then
+echo " - mixguile (the mixvm guile shell)"
+fi
+echo
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..b2b73f0
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,23 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.11 2004/08/06 12:14:07 jao Exp $
+
+SUBDIRS = img
+SUFFIXES = .html
+
+info_TEXINFOS = mdk.texi
+mdk_TEXINFOS = mdk_intro.texi mdk_ack.texi mdk_tut.texi mdk_gstart.texi \
+ mdk_mixvm.texi mdk_emacs.texi mdk_mixasm.texi mdk_bugs.texi \
+ mdk_index.texi mdk_gmixvm.texi mdk_install.texi \
+ mdk_mixguile.texi mdk_copying.texi mdk_findex.texi
+
diff --git a/doc/gendocs.sh b/doc/gendocs.sh
new file mode 100755
index 0000000..7b8a3ca
--- /dev/null
+++ b/doc/gendocs.sh
@@ -0,0 +1,285 @@
+#!/bin/sh
+# gendocs.sh -- generate a GNU manual in many formats. This script is
+# mentioned in maintain.texi. See the help message below for usage details.
+# $Id: gendocs.sh,v 1.4 2005/09/20 20:18:58 jao Exp $
+#
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# 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, you can either send email to this
+# program's maintainer or write to: The Free Software Foundation,
+# Inc.; 51 Franklin Street, Fifth Floor; Boston, MA 02110-1301, USA.
+#
+# Original author: Mohit Agarwal.
+# Send bug reports and any other correspondence to bug-texinfo@gnu.org.
+
+prog="`basename \"$0\"`"
+srcdir=`pwd`
+
+scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs.sh"
+templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs_template"
+
+: ${MAKEINFO="makeinfo"}
+: ${TEXI2DVI="texi2dvi -t @finalout"}
+: ${DVIPS="dvips"}
+: ${DOCBOOK2TXT="docbook2txt"}
+: ${DOCBOOK2HTML="docbook2html"}
+: ${DOCBOOK2PDF="docbook2pdf"}
+: ${DOCBOOK2PS="docbook2ps"}
+: ${GENDOCS_TEMPLATE_DIR="."}
+unset CDPATH
+
+rcs_revision='$Revision: 1.4 $'
+rcs_version=`set - $rcs_revision; echo $2`
+program=`echo $0 | sed -e 's!.*/!!'`
+version="gendocs.sh $rcs_version
+
+Copyright (C) 2005 Free Software Foundation, Inc.
+There is NO warranty. You may redistribute this software
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING."
+
+usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
+
+Generate various output formats from PACKAGE.texinfo (or .texi or .txi) source.
+See the GNU Maintainers document for a more extensive discussion:
+ http://www.gnu.org/prep/maintain_toc.html
+
+Options:
+ -o OUTDIR write files into OUTDIR, instead of manual/.
+ --docbook convert to DocBook too (xml, txt, html, pdf and ps).
+ --html ARG pass indicated ARG to makeinfo for HTML targets.
+ --help display this help and exit successfully.
+ --version display version information and exit successfully.
+
+Simple example: $prog emacs \"GNU Emacs Manual\"
+
+Typical sequence:
+ cd YOURPACKAGESOURCE/doc
+ wget \"$scripturl\"
+ wget \"$templateurl\"
+ $prog YOURMANUAL \"GNU YOURMANUAL - One-line description\"
+
+Output will be in a new subdirectory \"manual\" (by default, use -o OUTDIR
+to override). Move all the new files into your web CVS tree, as
+explained in the Web Pages node of maintain.texi.
+
+MANUAL-TITLE is included as part of the HTML <title> of the overall
+manual/index.html file. It should include the name of the package being
+documented. manual/index.html is created by substitution from the file
+$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the
+generic template for your own purposes.)
+
+If you have several manuals, you'll need to run this script several
+times with different YOURMANUAL values, specifying a different output
+directory with -o each time. Then write (by hand) an overall index.html
+with links to them all.
+
+You can set the environment variables MAKEINFO, TEXI2DVI, and DVIPS to
+control the programs that get executed, and GENDOCS_TEMPLATE_DIR to
+control where the gendocs_template file is looked for.
+
+Email bug reports or enhancement requests to bug-texinfo@gnu.org.
+"
+
+calcsize()
+{
+ size="`ls -ksl $1 | awk '{print $1}'`"
+ echo $size
+}
+
+outdir=manual
+html=
+PACKAGE=
+MANUAL_TITLE=
+
+while test $# -gt 0; do
+ case $1 in
+ --help) echo "$usage"; exit 0;;
+ --version) echo "$version"; exit 0;;
+ -o) shift; outdir=$1;;
+ --docbook) docbook=yes;;
+ --html) shift; html=$1;;
+ -*)
+ echo "$0: Unknown or ambiguous option \`$1'." >&2
+ echo "$0: Try \`--help' for more information." >&2
+ exit 1;;
+ *)
+ if test -z "$PACKAGE"; then
+ PACKAGE=$1
+ elif test -z "$MANUAL_TITLE"; then
+ MANUAL_TITLE=$1
+ else
+ echo "$0: extra non-option argument \`$1'." >&2
+ exit 1
+ fi;;
+ esac
+ shift
+done
+
+if test -s $srcdir/$PACKAGE.texinfo; then
+ srcfile=$srcdir/$PACKAGE.texinfo
+elif test -s $srcdir/$PACKAGE.texi; then
+ srcfile=$srcdir/$PACKAGE.texi
+elif test -s $srcdir/$PACKAGE.txi; then
+ srcfile=$srcdir/$PACKAGE.txi
+else
+ echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
+ exit 1
+fi
+
+if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
+ echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
+ echo "$0: it is available from $templateurl." >&2
+ exit 1
+fi
+
+echo Generating output formats for $srcfile
+
+cmd="${MAKEINFO} -o $PACKAGE.info $srcfile"
+echo "Generating info files... ($cmd)"
+eval $cmd
+mkdir -p $outdir/
+tar czf $outdir/$PACKAGE.info.tar.gz $PACKAGE.info*
+info_tgz_size="`calcsize $outdir/$PACKAGE.info.tar.gz`"
+# do not mv the info files, there's no point in having them available
+# separately on the web.
+
+cmd="${TEXI2DVI} $srcfile"
+echo "Generating dvi ... ($cmd)"
+eval $cmd
+
+# now, before we compress dvi:
+echo Generating postscript...
+${DVIPS} $PACKAGE -o
+gzip -f -9 $PACKAGE.ps
+ps_gz_size="`calcsize $PACKAGE.ps.gz`"
+mv $PACKAGE.ps.gz $outdir/
+
+# compress/finish dvi:
+gzip -f -9 $PACKAGE.dvi
+dvi_gz_size="`calcsize $PACKAGE.dvi.gz`"
+mv $PACKAGE.dvi.gz $outdir/
+
+cmd="${TEXI2DVI} --pdf $srcfile"
+echo "Generating pdf ... ($cmd)"
+eval $cmd
+pdf_size="`calcsize $PACKAGE.pdf`"
+mv $PACKAGE.pdf $outdir/
+
+cmd="${MAKEINFO} -o $PACKAGE.txt --no-split --no-headers $srcfile"
+echo "Generating ASCII... ($cmd)"
+eval $cmd
+ascii_size="`calcsize $PACKAGE.txt`"
+gzip -f -9 -c $PACKAGE.txt >$outdir/$PACKAGE.txt.gz
+ascii_gz_size="`calcsize $outdir/$PACKAGE.txt.gz`"
+mv $PACKAGE.txt $outdir/
+
+cmd="${MAKEINFO} --no-split --html -o $PACKAGE.html $html $srcfile"
+echo "Generating monolithic html... ($cmd)"
+rm -rf $PACKAGE.html # in case a directory is left over
+eval $cmd
+html_mono_size="`calcsize $PACKAGE.html`"
+gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
+html_mono_gz_size="`calcsize $outdir/$PACKAGE.html.gz`"
+mv $PACKAGE.html $outdir/
+
+cmd="${MAKEINFO} --html -o $PACKAGE.html $html $srcfile"
+echo "Generating html by node... ($cmd)"
+eval $cmd
+split_html_dir=$PACKAGE.html
+(
+ cd ${split_html_dir} || exit 1
+ tar -czf ../$outdir/${PACKAGE}.html_node.tar.gz -- *.html
+)
+html_node_tgz_size="`calcsize $outdir/${PACKAGE}.html_node.tar.gz`"
+rm -f $outdir/html_node/*.html
+mkdir -p $outdir/html_node/
+mv ${split_html_dir}/*.html $outdir/html_node/
+rmdir ${split_html_dir}
+
+echo Making .tar.gz for sources...
+srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null`
+tar cvzfh $outdir/$PACKAGE.texi.tar.gz $srcfiles
+texi_tgz_size="`calcsize $outdir/$PACKAGE.texi.tar.gz`"
+
+if test -n "$docbook"; then
+ cmd="${MAKEINFO} -o - --docbook $srcfile > ${srcdir}/$PACKAGE-db.xml"
+ echo "Generating docbook XML... $(cmd)"
+ eval $cmd
+ docbook_xml_size="`calcsize $PACKAGE-db.xml`"
+ gzip -f -9 -c $PACKAGE-db.xml >$outdir/$PACKAGE-db.xml.gz
+ docbook_xml_gz_size="`calcsize $outdir/$PACKAGE-db.xml.gz`"
+ mv $PACKAGE-db.xml $outdir/
+
+ cmd="${DOCBOOK2HTML} -o $split_html_db_dir ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook HTML... ($cmd)"
+ eval $cmd
+ split_html_db_dir=html_node_db
+ (
+ cd ${split_html_db_dir} || exit 1
+ tar -czf ../$outdir/${PACKAGE}.html_node_db.tar.gz -- *.html
+ )
+ html_node_db_tgz_size="`calcsize $outdir/${PACKAGE}.html_node_db.tar.gz`"
+ rm -f $outdir/html_node_db/*.html
+ mkdir -p $outdir/html_node_db
+ mv ${split_html_db_dir}/*.html $outdir/html_node_db/
+ rmdir ${split_html_db_dir}
+
+ cmd="${DOCBOOK2TXT} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook ASCII... ($cmd)"
+ eval $cmd
+ docbook_ascii_size="`calcsize $PACKAGE-db.txt`"
+ mv $PACKAGE-db.txt $outdir/
+
+ cmd="${DOCBOOK2PS} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook PS... $(cmd)"
+ eval $cmd
+ gzip -f -9 -c $PACKAGE-db.ps >$outdir/$PACKAGE-db.ps.gz
+ docbook_ps_gz_size="`calcsize $outdir/$PACKAGE-db.ps.gz`"
+ mv $PACKAGE-db.ps $outdir/
+
+ cmd="${DOCBOOK2PDF} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook PDF... ($cmd)"
+ eval $cmd
+ docbook_pdf_size="`calcsize $PACKAGE-db.pdf`"
+ mv $PACKAGE-db.pdf $outdir/
+fi
+
+echo Writing index file...
+curdate="`date '+%B %d, %Y'`"
+sed \
+ -e "s!%%TITLE%%!$MANUAL_TITLE!g" \
+ -e "s!%%DATE%%!$curdate!g" \
+ -e "s!%%PACKAGE%%!$PACKAGE!g" \
+ -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
+ -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
+ -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
+ -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
+ -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
+ -e "s!%%PDF_SIZE%%!$pdf_size!g" \
+ -e "s!%%PS_GZ_SIZE%%!$ps_gz_size!g" \
+ -e "s!%%ASCII_SIZE%%!$ascii_size!g" \
+ -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
+ -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
+ -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
+ -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
+ -e "s!%%DOCBOOK_PS_GZ_SIZE%%!$docbook_ps_gz_size!g" \
+ -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
+ -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
+ -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
+ -e "s,%%SCRIPTURL%%,$scripturl,g" \
+ -e "s!%%SCRIPTNAME%%!$prog!g" \
+$GENDOCS_TEMPLATE_DIR/gendocs_template >$outdir/index.html
+
+echo "Done! See $outdir/ subdirectory for new files."
diff --git a/doc/gendocs_template b/doc/gendocs_template
new file mode 100644
index 0000000..3fd6fd2
--- /dev/null
+++ b/doc/gendocs_template
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!-- $Id: gendocs_template,v 1.4 2005/09/20 20:18:58 jao Exp $ -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+<head>
+<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
+<meta http-equiv="content-type" content='text/html; charset=utf-8' />
+<link rel="stylesheet" type="text/css" href="/gnu.css" />
+<link rev="made" href="webmasters@gnu.org" />
+</head>
+
+<!-- This document is in XML, and xhtml 1.0 -->
+<!-- Please make sure to properly nest your tags -->
+<!-- and ensure that your final document validates -->
+<!-- consistent with W3C xhtml 1.0 and CSS standards -->
+<!-- See validator.w3.org -->
+
+<body>
+
+<h3>%%TITLE%%</h3>
+
+<address>Free Software Foundation</address>
+<address>last updated %%DATE%%</address>
+<p>
+<a href="/graphics/gnu-head.jpg">
+ <img src="/graphics/gnu-head-sm.jpg"
+ alt=" [image of the head of a GNU] "
+ width="129" height="122" />
+</a>
+<a href="/philosophy/gif.html">(no gifs due to patent problems)</a>
+</p>
+<hr />
+
+<p>This manual (%%PACKAGE%%) is available in the following formats:</p>
+
+<ul>
+ <li><a href="%%PACKAGE%%.html">HTML
+ (%%HTML_MONO_SIZE%%K characters)</a> - entirely on one web page.</li>
+ <li><a href="html_node/index.html">HTML</a> - with one web page per
+ node.</li>
+ <li><a href="%%PACKAGE%%.html.gz">HTML compressed
+ (%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
+ one web page.</li>
+ <li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
+ (%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
+ with one web page per node.</li>
+ <li><a href="%%PACKAGE%%.info.tar.gz">Info document
+ (%%INFO_TGZ_SIZE%%K characters gzipped tar file)</a>.</li>
+ <li><a href="%%PACKAGE%%.txt">ASCII text
+ (%%ASCII_SIZE%%K characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
+ (%%ASCII_GZ_SIZE%%K gzipped characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
+ (%%DVI_GZ_SIZE%%K characters gzipped)</a>.</li>
+ <li><a href="%%PACKAGE%%.ps.gz">PostScript file
+ (%%PS_GZ_SIZE%%K characters gzipped)</a>.</li>
+ <li><a href="%%PACKAGE%%.pdf">PDF file
+ (%%PDF_SIZE%%K characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
+ (%%TEXI_TGZ_SIZE%%K characters gzipped tar file)</a></li>
+</ul>
+
+<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
+script</a>.)</p>
+
+<div class="copyright">
+<p>
+Return to the <a href="/home.html">GNU Project home page</a>.
+</p>
+
+<p>
+Please send FSF &amp; GNU inquiries to
+<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>.
+There are also <a href="/home.html#ContactInfo">other ways to contact</a>
+the FSF.
+<br />
+Please send broken links and other corrections (or suggestions) to
+<a href="mailto:webmasters@gnu.org"><em>webmasters@gnu.org</em></a>.
+</p>
+
+<p>
+Copyright (C) 2004 Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
+<br />
+Verbatim copying and distribution of this entire article is
+permitted in any medium, provided this notice is preserved.
+</p>
+
+<p>
+Updated:
+<!-- timestamp start -->
+$Date: 2005/09/20 20:18:58 $ $Author: jao $
+<!-- timestamp end -->
+</p>
+</div>
+
+</body>
+</html>
diff --git a/doc/img/Makefile.am b/doc/img/Makefile.am
new file mode 100644
index 0000000..f59647e
--- /dev/null
+++ b/doc/img/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+EXTRA_DIST = ss_mix.jpg ss_mixal.jpg ss_devices.jpg ss_worddlg.jpg \
+ ss_mix.txt ss_devform.jpg ss_extprog.jpg ss_symbols.jpg \
+ ss_devdir.jpg ss_split.jpg
+
diff --git a/doc/img/ss_devdir.jpg b/doc/img/ss_devdir.jpg
new file mode 100644
index 0000000..009fa43
--- /dev/null
+++ b/doc/img/ss_devdir.jpg
Binary files differ
diff --git a/doc/img/ss_devform.jpg b/doc/img/ss_devform.jpg
new file mode 100644
index 0000000..a93e5a0
--- /dev/null
+++ b/doc/img/ss_devform.jpg
Binary files differ
diff --git a/doc/img/ss_devices.jpg b/doc/img/ss_devices.jpg
new file mode 100644
index 0000000..ecb3679
--- /dev/null
+++ b/doc/img/ss_devices.jpg
Binary files differ
diff --git a/doc/img/ss_extprog.jpg b/doc/img/ss_extprog.jpg
new file mode 100644
index 0000000..f5607de
--- /dev/null
+++ b/doc/img/ss_extprog.jpg
Binary files differ
diff --git a/doc/img/ss_mix.jpg b/doc/img/ss_mix.jpg
new file mode 100644
index 0000000..8b4080f
--- /dev/null
+++ b/doc/img/ss_mix.jpg
Binary files differ
diff --git a/doc/img/ss_mix.txt b/doc/img/ss_mix.txt
new file mode 100644
index 0000000..757026e
--- /dev/null
+++ b/doc/img/ss_mix.txt
@@ -0,0 +1,31 @@
+|-----------------------------------------------------------|
+| Menu |
+|-----------------------------------------------------------|
+| |
+| |
+| |
+| |
+| MIXVM / MIXAL / Devices |
+| |
+| |
+| |
+| |
+| |
+| |
+|-----------------------------------------------------------|
+| |
+| Command output |
+| |
+| |
+| |
+|-----------------------------------------------------------|
+| Command prompt |
+|-----------------------------------------------------------|
+| Status bar |
+|-----------------------------------------------------------|
+
+
+
+
+
+
diff --git a/doc/img/ss_mixal.jpg b/doc/img/ss_mixal.jpg
new file mode 100644
index 0000000..5227b5a
--- /dev/null
+++ b/doc/img/ss_mixal.jpg
Binary files differ
diff --git a/doc/img/ss_split.jpg b/doc/img/ss_split.jpg
new file mode 100644
index 0000000..66fd4a7
--- /dev/null
+++ b/doc/img/ss_split.jpg
Binary files differ
diff --git a/doc/img/ss_symbols.jpg b/doc/img/ss_symbols.jpg
new file mode 100644
index 0000000..6a0e827
--- /dev/null
+++ b/doc/img/ss_symbols.jpg
Binary files differ
diff --git a/doc/img/ss_worddlg.jpg b/doc/img/ss_worddlg.jpg
new file mode 100644
index 0000000..fc19000
--- /dev/null
+++ b/doc/img/ss_worddlg.jpg
Binary files differ
diff --git a/doc/mdk.texi b/doc/mdk.texi
new file mode 100644
index 0000000..ce86b37
--- /dev/null
+++ b/doc/mdk.texi
@@ -0,0 +1,248 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename mdk.info
+@settitle GNU MIX Development Kit (mdk)
+@syncodeindex pg cp
+@finalout
+@setchapternewpage odd
+@c $Id: mdk.texi,v 1.28 2005/09/20 21:00:22 jao Exp $
+@c %**end of header
+
+@set UPDATED September, 2005
+@set EDITION 1.2.1
+@set VERSION 1.2.1
+@set JAO Jose Antonio Ortega Ruiz
+@set PHILIP Philip E. King
+@set PIETER Pieter E. J. Pareit
+@set MIKE Michael Scholz
+
+@copying
+This manual is for GNU MDK (version @value{VERSION}, @value{UPDATED}),
+a set of utilities for developing programs using Donald Knuth's MIX
+mythical computer and MIXAL, its assembly language.
+
+Copyright @copyright{} 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below. A copy of the
+license is included in the section entitled ``GNU Free Documentation
+License.''
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+@end quotation
+@end copying
+
+@dircategory GNU programming tools
+@direntry
+* MDK: (mdk). The GNU MIX Development Kit.
+@end direntry
+
+
+@footnotestyle separate
+
+@titlepage
+@title GNU MDK
+@subtitle GNU MIX Development Kit
+@subtitle Edition @value{EDITION}, for GNU @sc{mdk} Version @value{VERSION}
+@subtitle @value{UPDATED}
+@author by @value{JAO} (@email{jao@@gnu.org})
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@shortcontents
+@contents
+
+@ifnottex
+@node Top, Introduction, (dir), (dir)
+
+@insertcopying
+
+GNU MDK was written and designed by @value{JAO}.
+
+@value{PIETER} is the author of the Emacs @code{MIXAL} mode
+(@pxref{MIXAL mode}), and has also contributed many bug fixes.
+
+@value{PHILIP} has contributed to this package development with many
+helpful discussions, as well as actual code (@pxref{GUD integration}).
+
+@value{MIKE} is the author of the German translation of @sc{mdk}'s
+user interface.
+
+@end ifnottex
+
+@menu
+* Introduction::
+* Acknowledgments::
+* Installing MDK:: Installing GNU MDK from the source tarball.
+* MIX and MIXAL tutorial:: Learn the innards of MIX and MIXAL.
+* Getting started:: Basic usage of the @sc{mdk} tools.
+* Emacs tools:: Programming the MIX using Emacs.
+* mixasm:: Invoking the MIXAL assembler.
+* mixvm:: Invoking and using the MIX virtual machine.
+* gmixvm:: Invoking and using the GTK+ virtual machine.
+* mixguile:: Invoking and using the Scheme virtual machine.
+* Problems:: Reporting bugs.
+* Copying:: @sc{mdk} licensing terms.
+* Concept Index:: Index of concepts.
+* Instructions and commands:: Index of MIXAL instructions and MIXVM commands.
+
+
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Installing @sc{mdk}
+
+* Download::
+* Requirements::
+* Basic installation::
+* Emacs support::
+* Special configure flags::
+* Supported platforms::
+
+MIX and MIXAL tutorial
+
+* The MIX computer:: Architecture and instruction set
+ of the MIX computer.
+* MIXAL:: The MIX assembly language.
+
+The MIX computer
+
+* MIX architecture::
+* MIX instruction set::
+
+MIX instruction set
+
+* Instruction structure::
+* Loading operators::
+* Storing operators::
+* Arithmetic operators::
+* Address transfer operators::
+* Comparison operators::
+* Jump operators::
+* Input-output operators::
+* Conversion operators::
+* Shift operators::
+* Miscellaneous operators::
+* Execution times::
+
+MIXAL
+
+* Basic structure:: Writing basic MIXAL programs.
+* MIXAL directives:: Assembler directives.
+* Expressions:: Evaluation of expressions.
+* W-expressions:: Evaluation of w-expressions.
+* Local symbols:: Special symbol table entries.
+* Literal constants:: Specifying an immediate operand.
+
+Getting started
+
+* Writing a source file:: A sample MIXAL source file.
+* Compiling:: Using @code{mixasm} to compile source
+ files into binary format.
+* Running the program:: Running and debugging your programs.
+* Using mixguile:: Using the Scheme interpreter to run and
+ debug your programs.
+* Using Scheme in mixvm and gmixvm::
+
+Running the program
+
+* Non-interactive mode:: Running your programs non-interactively.
+* Interactive mode:: Running programs interactively.
+* Debugging:: Commands for debugging your programs.
+
+Using @code{mixguile}
+
+* The mixguile shell:: Using the Scheme MIX virtual machine.
+* Additional functions:: Scheme functions accessing the VM.
+* Defining new functions:: Defining your own Scheme functions.
+* Hook functions:: Using command and break hook functions.
+* Scheme scripts::
+
+Hook functions
+
+* Command hooks::
+* Break hooks::
+
+Emacs tools
+
+* MIXAL mode:: Editing MIXAL files.
+* GUD integration:: Invoking @code{mixvm} within Emacs.
+
+MIXAL mode
+
+* Basics:: Editing code, font locking and indentation.
+* Help system:: Using the interactive help system.
+* Compiling and running:: Invoking compiler and/or virtual machine.
+
+@code{mixasm}, the MIXAL assembler
+
+* Invoking mixasm::
+
+@code{mixvm}, the MIX computer simulator
+
+* Invocation::
+* Commands:: Commands available in interactive mode.
+* Devices:: MIX block devices implementation.
+
+Interactive commands
+
+* File commands:: Loading and executing programs.
+* Debug commands:: Debugging programs.
+* State commands:: Inspecting the virtual machine state.
+* Configuration commands:: Changing and storing mixvm settings.
+* Scheme commands::
+
+@code{gmixvm}, the GTK virtual machine
+
+* Invoking gmixvm::
+* MIXVM console:: Using @code{mixvm} commands.
+* MIX virtual machine:: The MIX virtual machine window.
+* MIXAL source view:: Viewing the MIXAL source code.
+* MIX devices view:: Device output.
+* Menu and status bars:: Available menu commands.
+
+@code{mixguile}, the Scheme virtual machine
+
+* Invoking mixguile:: Command line options.
+* Scheme functions reference:: Scheme functions accessing the VM.
+
+Scheme functions reference
+
+* mixvm wrappers:: Functions invoking mixvm commands.
+* Hooks:: Adding hooks to mixvm commands.
+* Additional VM functions:: Functions accessing the MIX virtual machine.
+
+Copying
+
+* GNU General Public License::
+* GNU Free Documentation License::
+
+@end detailmenu
+@end menu
+
+@include mdk_intro.texi
+@include mdk_ack.texi
+@include mdk_install.texi
+@include mdk_tut.texi
+@include mdk_gstart.texi
+@include mdk_emacs.texi
+@include mdk_mixasm.texi
+@include mdk_mixvm.texi
+@include mdk_gmixvm.texi
+@include mdk_mixguile.texi
+@include mdk_bugs.texi
+@include mdk_copying.texi
+@include mdk_index.texi
+@include mdk_findex.texi
+
+@bye
+
diff --git a/doc/mdk_ack.texi b/doc/mdk_ack.texi
new file mode 100644
index 0000000..807e276
--- /dev/null
+++ b/doc/mdk_ack.texi
@@ -0,0 +1,63 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_ack.texi,v 1.15 2005/09/20 00:26:00 jao Exp $
+
+@node Acknowledgments, Installing MDK, Introduction, Top
+@comment node-name, next, previous, up
+@unnumbered Acknowledgements
+
+Many people have further contributed to @sc{mdk} by reporting problems,
+suggesting various improvements, or submitting actual code. Here is
+a list of these people. Help me keep it complete and exempt of errors.
+
+@itemize @bullet
+@item Richard Stallman
+suggested various improvements to the documentation and has always
+kept an eye on each @sc{mdk} release.
+
+@item Philip Ellis King
+provided MIXAL test programs pinpointing bugs in the first @sc{mdk}
+release, and useful discussions as well. Philip has also contributed
+with the Emacs port of @code{mixvm} and influenced the @code{gmixvm} GUI
+design with insightful comments and prototypes.
+
+@item Pieter E J Pareit
+is the author of the Emacs MIXAL mode, and has also contributed many
+bug fixes.
+
+@item Michael Scholz
+is the author of the German translation of @sc{mdk}'s user interface.
+
+@item Sergey Poznyakoff
+provided patches to mixlib/mix_scanner.l improving MIXAL compliance.
+
+@item Francesc Xavier Noria
+kindly and thoroughly reviewed the @sc{mdk} documentation, providing
+insightful advice.
+
+@item Nelson H. F. Beebe
+has tested @sc{mdk} in a lot of Unix platforms, suggesting portability
+enhancements to the source code.
+
+@item Agustin Navarro, Ying-Chieh Liao, Adrian Bunk, Baruch Even, and Ronald Cole
+ported @sc{mdk} to different platforms, and created and/or maintain
+packages for it.
+
+@item Jason Uhlenkott, Andrew Hood, Aleix Conchillo, Radu Butnaru, Ruslan Batdalov, WeiZheng and Sascha Wilde
+reported bugs and suggested fixes to them.
+
+@item Eli Bendersky, Milan Bella and Jens Seidel reported bugs on the documentation.
+
+@item Christoph von Nathusius, Stephen Ramsay and Johan Swanljung
+tested @sc{mdk} on different platforms, and helped fix the configuration
+process in them.
+
+@item @sc{mdk} was inspired by Darius Bacon's
+@uref{http://www.accesscom.com/@/~darius/, MIXAL program}.
+
+@end itemize
+
diff --git a/doc/mdk_bugs.texi b/doc/mdk_bugs.texi
new file mode 100644
index 0000000..1b18064
--- /dev/null
+++ b/doc/mdk_bugs.texi
@@ -0,0 +1,24 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_bugs.texi,v 1.6 2004/08/03 13:23:06 jao Exp $
+
+@node Problems, Copying, mixguile, Top
+@chapter Reporting Bugs
+@cindex bugs
+@cindex problems
+@cindex questions
+@cindex suggestions
+
+If you have any questions, comments or suggestions, please send
+electronic mail to @email{jao@@gnu.org, the author}.
+
+If you find a bug in @sc{mdk}, please send electronic mail to
+@email{bug-mdk@@gnu.org, the @sc{mdk} bug list}.
+
+In your report, please include the version number, which you can find by
+running @w{@samp{mixasm --version}}. Also include in your message the
+output that the program produced and the output you expected.
diff --git a/doc/mdk_copying.texi b/doc/mdk_copying.texi
new file mode 100644
index 0000000..8aa5e90
--- /dev/null
+++ b/doc/mdk_copying.texi
@@ -0,0 +1,866 @@
+@node Copying, Concept Index, Problems, Top
+@appendix Copying
+
+@menu
+* GNU General Public License::
+* GNU Free Documentation License::
+@end menu
+
+GNU MDK is distributed under the GNU General Public License (GPL) and
+this manual under the GNU Free Documentation License (GFDL).
+
+@node GNU General Public License, GNU Free Documentation License, Copying, Copying
+@appendixsec GNU General Public License
+@cindex GPL, GNU General Public License
+
+@lowersections
+
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@unnumberedsec 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.
+
+@iftex
+@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+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.
+
+@item
+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.
+
+@item
+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:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+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.
+
+@item
+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.)
+@end enumerate
+
+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.
+
+@item
+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:
+
+@enumerate a
+@item
+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,
+
+@item
+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,
+
+@item
+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.)
+@end enumerate
+
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+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.
+
+@item
+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 enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@unnumberedsec 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.
+
+@smallexample
+@var{one line to give the program's name and an idea of what it does.}
+Copyright (C) 19@var{yy} @var{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., 675 Mass Ave, Cambridge, MA 02139, USA.
+@end smallexample
+
+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:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{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.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{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:
+
+@smallexample
+@group
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end group
+@end smallexample
+
+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.
+
+@raisesections
+
+
+
+@node GNU Free Documentation License
+@appendixsec GNU Free Documentation License
+
+@cindex FDL, GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document 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.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation 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. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@page
+@appendixsubsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/doc/mdk_emacs.texi b/doc/mdk_emacs.texi
new file mode 100644
index 0000000..e0c6973
--- /dev/null
+++ b/doc/mdk_emacs.texi
@@ -0,0 +1,136 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@node Emacs tools, mixasm, Getting started, Top
+@chapter Emacs tools
+
+Everyone writing code knows how important a good editor is. Most
+systems already come with Emacs, and excellent programmer's editor.
+@sc{mdk} adds support to Emacs for both writing and debugging MIX
+programs. A major mode for MIXAL source files eases edition of your
+code, while integration with Emacs' debugging interface
+(@acronym{GUD}) lets you use @code{mixvm} without leaving your
+favourite text editor.
+
+This chapter shows how to use the Elisp modules included in @sc{mdk},
+assuming that you have followed the installation instructions in
+@xref{Emacs support}.
+
+@menu
+* MIXAL mode:: Editing MIXAL files.
+* GUD integration:: Invoking @code{mixvm} within Emacs.
+@end menu
+
+@node MIXAL mode, GUD integration, Emacs tools, Emacs tools
+@section MIXAL mode
+
+The module @file{mixal-mode.el} provides a new mode, mixal-mode, for
+editing MIXAL source files@footnote{mixal-mode has been developed and
+documented by @value{PIETER}}. When everything is installed correctly,
+Emacs will select it as the major mode for editing files with extension
+@code{.mixal}. You can also activate mixal-mode in any buffer
+issuing the Emacs command @code{M-x mixal-mode}.
+
+@menu
+* Basics:: Editing code, font locking and indentation.
+* Help system:: Using the interactive help system.
+* Compiling and running:: Invoking compiler and/or virtual machine.
+@end menu
+
+@node Basics, Help system, MIXAL mode, MIXAL mode
+@comment node-name, next, previous, up
+@subsection Basics
+
+The mode for editing mixal source files is inherited from
+fundamental-mode, meaning that all your favorite editing operations
+will still work. If you want a short introduction to Emacs, type
+@kbd{C-h t} inside Emacs to start the tutorial.
+
+Mixal mode adds font locking. If you do not have font locking globally
+enabled, you can turn it on for mixal-mode by placing the following
+line in your @file{.emacs} file:
+
+@lisp
+(add-hook 'mixal-mode-hook 'turn-on-font-lock)
+@end lisp
+
+You can also customize the colors used to colour your mixal code by
+changing the requisite faces. This is the list of faces used by
+mixal-mode:
+
+@itemize
+@item @var{font-lock-comment-face}
+Face to use for comments.
+@item @var{mixal-font-lock-label-face}
+Face to use for label names.
+@item @var{mixal-font-lock-operation-code-face}
+Face to use for operation code names.
+@item @var{mixal-font-lock-assembly-pseudoinstruction-face}
+Face to use for assembly pseudo-instruction names.
+@end itemize
+
+@node Help system, Compiling and running, Basics, MIXAL mode
+@comment node-name, next, previous, up
+@subsection Help system
+
+When coding your program, you will be thinking, looking up
+documentation and editing files. Emacs already helps you with editing
+files, but Emacs can do much more. In particular, looking up
+documentation is one of its strong points. Besides the info system
+(which you are probably already using), mixal-mode defines commands
+for getting particular information about a MIX operation code.
+
+With @kbd{M-x mixal-describe-operation-code} (or its keyboard shortcut
+@kbd{C-h o}) you will get the documentation about a particular MIX
+operation code. Keep in mind that these are not assembly (MIXAL)
+pseudoinstructions. When the @code{point} is around a MIXAL
+pseudoinstruction in your source file, Emacs will recognize it and
+will suggest the right MIX operation code.
+
+@node Compiling and running, , Help system, MIXAL mode
+@comment node-name, next, previous, up
+@subsection Compiling and running
+
+After you have written your MIXAL program, you'll probably want to
+test it. This can be done with the MIX virtual machine. First you will
+need to compile your code into MIX byte code. This can be done within
+Emacs with the command @kbd{M-x compile} (@kbd{C-c c}). In case of
+compilation errors, you can jump to the offending source code line
+with @kbd{M-x next-error}.
+
+Once the program compiles without errors, you can debug or run
+it. To invoke the debugger, use @kbd{M-x mixal-debug} (@kbd{C-c d}).
+Emacs will open a @code{GUD} buffer where you can
+use the debugging commands described in @xref{mixvm}.
+
+If you just want to execute the program, you can do so with @kbd{M-x
+mixal-run} (@kbd{C-c r}). This will invoke mixvm,
+execute the program and show its output in a separate buffer.
+
+@node GUD integration, , MIXAL mode, Emacs tools
+@section GUD integration
+
+If you are an Emacs user and write your MIXAL programs using this
+editor, you will find the elisp program @file{mixvm.el} quite
+useful@footnote{@file{mixvm.el} has been kindly contributed by
+@value{PHILIP}. @file{mixvm.el} is based on a study of gdb, perldb, and
+pdb as found in @file{gud.el}, and @file{rubydb3x.el} distributed with
+the source code to the Ruby language.}. @file{mixvm.el} allows running
+the MIX virtual machine @code{mixvm} (@pxref{mixvm}) inside an Emacs
+@acronym{GUD} buffer, while visiting the MIXAL source file in another
+buffer.
+
+After installing @file{mixvm.el} (@pxref{Emacs support}), you can
+initiate an @sc{mdk}/@acronym{GUD} session inside Emacs with the command
+
+@example
+M-x mixvm
+@end example
+
+@noindent
+and you will have a @code{mixvm} prompt inside a newly created
+@acronym{GUD} buffer. @acronym{GUD} will reflect the current line in the
+corresponding source file buffer.
diff --git a/doc/mdk_findex.texi b/doc/mdk_findex.texi
new file mode 100644
index 0000000..24a269f
--- /dev/null
+++ b/doc/mdk_findex.texi
@@ -0,0 +1,11 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_findex.texi,v 1.3 2004/08/03 13:23:06 jao Exp $
+
+@node Instructions and commands, , Concept Index, Top
+@unnumbered Instructions and commands
+@printindex fn
diff --git a/doc/mdk_gmixvm.texi b/doc/mdk_gmixvm.texi
new file mode 100644
index 0000000..bddb362
--- /dev/null
+++ b/doc/mdk_gmixvm.texi
@@ -0,0 +1,394 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_gmixvm.texi,v 1.18 2004/08/03 13:23:06 jao Exp $
+
+@node gmixvm, mixguile, mixvm, Top
+@comment node-name, next, previous, up
+@chapter @code{gmixvm}, the GTK virtual machine
+@cindex @code{gmixvm}
+@cindex GUI
+@cindex GTK+
+
+This chapter describes the graphical MIX virtual machine emulator
+shipped with @sc{mdk}. In addition to having all the command-oriented
+functionalities of the other virtual machines (@code{mixvm} and
+@code{mixguile}), @code{gmixvm} offers you a graphical interface
+displaying the status of the virtual machine, the source code of the the
+downloaded programs and the contents of the MIX devices.
+
+@menu
+* Invoking gmixvm::
+* MIXVM console:: Using @code{mixvm} commands.
+* MIX virtual machine:: The MIX virtual machine window.
+* MIXAL source view:: Viewing the MIXAL source code.
+* MIX devices view:: Device output.
+* Menu and status bars:: Available menu commands.
+@end menu
+
+@node Invoking gmixvm, MIXVM console, gmixvm, gmixvm
+@comment node-name, next, previous, up
+@section Invoking @code{gmixvm}
+
+If you have built @sc{mdk} with GTK+ support (@pxref{Installing MDK}), a
+graphical front-end for the MIX virtual machine will be available in
+your system. You can invoke it by typing
+
+@example
+gmixvm [-vhuq] [--version] [--help] [--usage] [--noinit]
+@end example
+@noindent
+at your command prompt, where the options have the following meanings:
+
+@defopt -v
+@defoptx --version
+Prints version and copyleft information and exits.
+@end defopt
+
+@defopt -h
+@defoptx --help
+@defoptx -u
+@defoptx --usage
+Prints a summary of available options and exits.
+@end defopt
+
+@defopt -q
+@defoptx --noinit
+Do not load the Guile initialisation file @code{~/.mdk/mixguile.scm} at
+startup. This file contains any local Scheme code to be executed by the
+embedded Guile interpreter at startup (@pxref{Using Scheme in mixvm and
+gmixvm}).
+@end defopt
+
+Typing @code{gmixvm} or @code{gmixvm -q} at your command prompt, the
+main window will appear, offering you a graphical interface to run and
+debug your MIX programs.
+
+@ifinfo
+@image{img/ss_mix, 400pt}
+@end ifinfo
+
+@ifhtml
+@image{../img/ss_mix, 400pt}
+@end ifhtml
+
+Apart from the menu and status bars, we can distinguish two zones (or
+halves) in this main window. In the upper half of @code{gmixvm}'s main
+window there is a notebook with three pages, namely,
+
+@itemize
+@item
+a MIX virtual machine view, which shows you the registers, flags, memory
+contents and time statistics of the virtual machine;
+@item
+a MIXAL source view, which shows the MIXAL file and lets you manage
+breakpoints;
+@item
+a Devices view, which shows you the output to character based MIX block
+devices.
+@end itemize
+
+@noindent
+These three windows can be detached from the notebook, using either
+the penultimate toolbar button (which detachs the currently visible
+notebook page) or the menu entries under @code{@w{View->Detached windows}}.
+
+@ifhtml
+Here is an screenshot showing how @code{gmixvm} looks like when running
+with a couple of detached windows:
+
+@image{../img/ss_split, 420pt}
+
+@end ifhtml
+
+On the other hand, the main window's lower half presents you a
+@code{mixvm} command prompt and a logging area where results of the
+issued commands are presented. These widgets implement a @code{mixvm}
+console which offers almost the same functionality as its
+@acronym{CLI} counterpart.
+
+When @code{gmixvm} is run, it creates a directory named @file{.mdk} in
+your home directory (if it does not already exist). The @file{.mdk}
+directory contains the program settings, the device files used by your
+MIX programs (@pxref{Devices}), and a command history file.
+
+The following sections describe the above mentioned components of
+@code{gmixvm}.
+
+@node MIXVM console, MIX virtual machine, Invoking gmixvm, gmixvm
+@comment node-name, next, previous, up
+@section MIXVM console
+
+In the lower half of the @code{gmixvm} main window, you will find a
+command text entry and, above it, an echo area. These widgets offer you
+the same functionality as its @acronym{CLI} counterpart, @code{mixvm}
+(@pxref{mixvm}). You can issue almost all @code{mixmv} commands at the
+@code{gmixvm}'s command prompt in order to manipulate the MIX virtual
+machine. Please refer to @xref{mixvm}, for a description of these
+commands, and to @xref{Getting started}, for a tutorial on using the MIX
+virtual machine. The command prompt offers command line completion for
+partially typed commands using the @key{TAB} key; e.g., if you type
+
+@example
+lo @key{TAB}
+@end example
+@noindent
+the command is automatically completed to @code{load}. If multiple
+completions are available, they will be shown in the echo area. Thus,
+typing
+
+@example
+p @key{TAB}
+@end example
+@noindent
+will produce the following output on the echo area:
+
+@example
+Completions:
+pc psym preg pflags pall
+pmem
+@end example
+@noindent
+which lists all the available commands starting with @code{p}. In
+addition, the command prompt maintains a history of typed commands,
+which can be recovered using the arrow up and down keys. As mentioned
+above, a file containing previous sessions' commands is stored in the
+configuration directory @file{~/.mdk}, and reloaded every time you start
+@code{gmixvm}.
+
+You can change the font used to display the issued commands and the
+messages in the echo area using the @code{@w{Settings->Change font->Command
+prompt}} and @code{@w{Settings->Change font->Command log}} menu commands.
+
+@node MIX virtual machine, MIXAL source view, MIXVM console, gmixvm
+@comment node-name, next, previous, up
+@section MIX virtual machine
+
+The first notebook's page displays the current status of the virtual
+machine. There you can find the registers' contents, the value of the
+comparison and overflow flags, the location pointer, a list with all MIX
+memory cells and their contents, and the time statistics (including
+total uptime, elapsed time since the last run command and total
+execution time for the currently loaded MIX program).
+
+If you click any register entry, you will be prompted for a new register's
+contents.
+
+@ifhtml
+The next figure shows the enter word dialog.
+
+@image{../img/ss_worddlg, 250pt}
+
+@end ifhtml
+
+In the same manner, click on any address of the memory cells list to be
+prompted for the new contents of the clicked cell. If you click the
+address column's title, a dialog asking you for a memory address will
+appear; if you introduce a valid address, this will be the first cell
+displayed in the scrollable list after you click the OK button.
+
+The register contents are shown as a list of MIX bytes plus sign. If you
+place the mouse pointer over any of them, the decimal value of this MIX
+word will appear inside a tooltip.
+
+You can change the font used to display the MIX virtual machine contents
+using the @code{@w{Settings->Change font->MIX}} menu command.
+
+@node MIXAL source view, MIX devices view, MIX virtual machine, gmixvm
+@comment node-name, next, previous, up
+@section MIXAL source view
+
+The second notebook's page, dubbed Source, shows you the MIXAL source of
+the currently loaded MIX file.
+
+@ifhtml
+@image{../img/ss_mixal, 400pt}
+@end ifhtml
+
+The information is presented in four columns. The first column
+displays little icons showing the current program pointer and any set
+breakpoints. The second and third columns show the address and memory
+contents of the compiled MIX instruction, while the last one displays
+its corresponding MIXAL representation, together with the source file
+line number. You can set/unset breakpoints by clicking on any line
+that has an associated memory address.
+
+You can change the font used to display the MIXAL source code
+using the @code{@w{Settings->Change font->MIXAL}} menu command.
+
+@node MIX devices view, Menu and status bars, MIXAL source view, gmixvm
+@comment node-name, next, previous, up
+@section MIX devices view
+
+The last notebook page, dubbed Devices, shows you the output/input
+to/from MIX block devices (the console, line printer, paper tape,
+disks, card and tapes @pxref{Devices}) produced by the running
+program.
+
+@ifhtml
+
+@image{../img/ss_devices, 400pt}
+
+@end ifhtml
+
+Input device contents is read from files located in the @file{~/.mdk}
+directory, and the output is also written to files at the same
+location. Note that device tabs will appear as they are used by the MIX
+program being run, and that loading a new MIX program will close all
+previously open devices.
+
+The input/output for binary block devices (tapes and disks) is a list
+of MIX words, which can be displayed either in decimal or word format
+(e.g. @w{- 67} or @w{- 00 00 00 01 03}). The format used by
+@code{gmixvm} can be configured using the @code{@w{Settings->Device output}}
+menu command for each binary device.
+
+You can change the font used to display the devices content
+using the @code{@w{Settings->Change font->Devices}} menu command.
+
+@node Menu and status bars, , MIX devices view, gmixvm
+@comment node-name, next, previous, up
+@section Menu and status bars
+
+The menu bar gives you access to the following commands:
+
+@deffn File Load...
+Opens a file dialog that lets you specify a binary MIX file to be loaded
+in the virtual machine's memory. It is equivalent to the @code{mixvm}'s
+@code{load} command (@pxref{File commands}).
+@end deffn
+
+@deffn File Edit...
+Opens a file dialog that lets your specify a MIXAL source file to be
+edited. It is equivalent to the @code{mixvm}'s @code{edit} command
+(@pxref{File commands}). The program used for editing can be specified
+using the menu entry @code{@w{Settings->External programs}}, or using the
+@code{mixvm} command @code{sedit}.
+@end deffn
+
+@deffn File Compile...
+Opens a file dialog that lets your specify a MIXAL source file to be
+compiled. It is equivalent to the @code{mixvm}'s @code{compile} command
+(@pxref{File commands}). The command used for compiling can be specified
+using the menu entry @code{@w{Settings->External programs}}, or using the
+@code{mixvm} command @code{sasm}.
+@end deffn
+
+@deffn File Exit
+Exits the application.
+@end deffn
+
+@deffn Debug Run
+Runs the currently loaded MIX program, up to the next breakpoint. It is
+equivalent to the @code{mixvm}'s @code{run} command (@pxref{Debug
+commands}).
+@end deffn
+
+@deffn Debug Next
+Executes the next MIX instruction. It is equivalent to the
+@code{mixvm}'s @code{next} command (@pxref{Debug commands}).
+@end deffn
+
+@deffn Debug @w{Clear breakpoints}
+Clears all currently set breakpoints. It is equivalent to the
+@code{mixvm}'s @code{cabp} command.
+@end deffn
+
+@deffn Debug Symbols...
+Opens a dialog showing the list of symbols defined in the currently
+loaded MIX program. The font used to display this list can be
+customised using the meny entry @code{@w{Settings->Change font->Symbol
+list}}.
+
+@ifhtml
+
+@image{../img/ss_symbols, 250pt}
+
+@end ifhtml
+
+@end deffn
+
+@deffn View @w{Toolbar(s)}
+Toggles the toolbar(s) in the @code{gmixvm} window(s) (when notebook
+pages are detached, each one has its own toolbar).
+@end deffn
+
+@deffn View @w{Detached windows} @w{Virtual machine}
+@deffnx View @w{Detached windows} Source
+@deffnx View @w{Detached windows} Devices
+
+These toggles let you detach (or re-attach) the corresponding notebook
+page.
+
+@end deffn
+
+@deffn Settings @w{Change font}
+Lets you change the font used in the various @code{gmixv} widgets
+(i.e. commad prompt, command log, Virtual machine, Source, Devices and
+Symbol list). There is also an entry (@code{All}) to change all fonts
+at once.
+@end deffn
+
+@deffn Settings @w{Device output...}
+Opens a dialog that lets you specify which format shall be used to show
+the contents of MIX binary block devices.
+
+@ifhtml
+@image{../img/ss_devform, 250pt}
+@end ifhtml
+
+The available formats are decimal (e.g. @w{-1234}) and MIX word
+(e.g. @w{- 00 00 00 19 18}).
+@end deffn
+
+@deffn Settings @w{Devices dir...}
+Opens a dialog that lets you choose where the MIX device files will be
+stored (@file{~/.mdk} is the default location).
+
+@ifhtml
+@image{../img/ss_devdir, 250pt}
+@end ifhtml
+
+You can also specify the devices directory using the @code{mixvm}
+command @code{sddir} (@pxref{Configuration commands}).
+
+@end deffn
+
+@deffn Settings @w{External programs...}
+This menu command opens a dialog that lets you specify the commands used
+for editing and compiling MIXAL source files.
+
+@ifhtml
+@image{../img/ss_extprog, 250pt}
+@end ifhtml
+
+The commands are specified as template strings, where the control
+substring @code{%s} will be substituted by the actual file name. Thus,
+if you want to edit programs using @code{vi} running in an @code{xterm},
+you must enter the command template @code{@w{xterm -e vi %s}} in the
+corresponding dialog entry. These settings can also be changed using the
+@code{mixvm} commands @code{sedit} and @code{sasm} (@pxref{Configuration
+commands}).
+@end deffn
+
+
+@deffn Settings Save
+Saves the current settings.
+@end deffn
+
+@deffn Settings @w{Save on exit}
+Mark this checkbox if you want @code{gmixvm} to save its settings
+every time you quit the program.
+@end deffn
+
+@deffn Help About...
+Shows information about @code{gmixvm}'s version and copyright.
+@end deffn
+
+On the other hand, the status bar displays the name of the last loaded
+MIX file. In addition, when the mouse pointer is over a MIXAL source
+file line that contains symbols, a list of these symbols with their
+values will appear in the status bar.
diff --git a/doc/mdk_gstart.texi b/doc/mdk_gstart.texi
new file mode 100644
index 0000000..9eab3f6
--- /dev/null
+++ b/doc/mdk_gstart.texi
@@ -0,0 +1,1058 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2002, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_gstart.texi,v 1.17 2004/08/01 21:43:29 jao Exp $
+
+@node Getting started, Emacs tools, MIX and MIXAL tutorial, Top
+@chapter Getting started
+@cindex tutorial
+
+In this chapter, you will find a sample code-compile-run-debug session
+using the @sc{mdk} utilities. Familiarity with the MIX mythical computer
+and its assembly language MIXAL (as described in Knuth's TAOCP) is
+assumed; for a compact reminder, see @ref{MIX and MIXAL tutorial}.
+
+@menu
+* Writing a source file:: A sample MIXAL source file.
+* Compiling:: Using @code{mixasm} to compile source
+ files into binary format.
+* Running the program:: Running and debugging your programs.
+* Using mixguile:: Using the Scheme interpreter to run and
+ debug your programs.
+* Using Scheme in mixvm and gmixvm::
+@end menu
+
+@node Writing a source file, Compiling, Getting started, Getting started
+@section Writing a source file
+@cindex MIXAL
+@cindex source file
+@cindex .mixal file
+
+MIXAL programs can be written as ASCII files with your editor of choice.
+Here you have the mandatory @emph{hello world} as written in the MIXAL
+assembly language:
+
+@example
+* (1)
+* hello.mixal: say 'hello world' in MIXAL (2)
+* (3)
+* label ins operand comment (4)
+TERM EQU 19 the MIX console device number (5)
+ ORIG 1000 start address (6)
+START OUT MSG(TERM) output data at address MSG (7)
+ HLT halt execution (8)
+MSG ALF "MIXAL" (9)
+ ALF " HELL" (10)
+ ALF "O WOR" (11)
+ ALF "LD " (12)
+ END START end of the program (13)
+@end example
+
+@noindent MIXAL source files should have the extension @file{.mixal}
+when used with the @sc{mdk} utilities. As you can see in the above
+sample, each line in a MIXAL file can be divided into four fields
+separated by an arbitrary amount of whitespace characters (blanks and or
+tabs). While in Knuth's definition of MIXAL each field must start at a
+fixed pre-defined column number, the @sc{mdk} assembler loosens this
+requirement and lets you format the file as you see fit. The only
+restrictions retained are for comment lines (like 1-4) which must begin
+with an asterisk (*) placed at column 1, and for the label field (see
+below) which, if present, must also start at column 1. The four fields
+in each non-comment line are:
+
+@itemize @minus
+@item
+an optional label, which either refers to the current memory address (as
+@code{START} and @code{MSG} in lines 7 and 9) or a defined symbol
+(@code{TERM}) (if present, the label must always start at the first
+column in its line, for the first whitespace in the line maks the
+beginning of the second field),
+@item
+an operation mnemonic, which can represent either a MIX instruction
+(@code{OUT} and @code{HLT} in lines 7 and 8 above), or an assembly
+pseudoinstruction (e.g., the @code{ORIG} pseudoinstruction in line
+6@footnote{If an @code{ORIG} directive is not used, the program will
+be loaded by the virtual machine at address 0. @code{ORIG} allows
+allocating the executable code where you see fit.}.
+@item
+an optional operand for the (pseudo)instruction, and
+@item
+an optional free text comment.
+@end itemize
+
+@noindent Lines 9-12 of the @file{hello.mixal} file above also show the
+second (and last) difference between Knuth's MIXAL definition and ours:
+the operand of the @code{ALF} pseudoinstruction (a word of five
+characters) must be quoted using ""@footnote{In Knuth's definition,
+the operand always starts at a fixed column number, and the use of
+quotation is therefore unnecessary. As @code{mixasm} releases this
+requirement, marking the beginning and end of the @code{ALF} operand
+disambiguates the parser's recognition of this operand when it includes
+blanks. Note that double-quotes (") are not part of the MIX character
+set, and, therefore, no escape characters are needed within
+@code{ALF}'s operands.}.
+
+The workings of this sample program should be straightforward if you are
+familiar with MIXAL. See TAOCP vol. 1 for a thorough definition or
+@ref{MIX and MIXAL tutorial}, for a tutorial.
+
+@node Compiling, Running the program, Writing a source file, Getting started
+@section Compiling
+@cindex compiling
+@cindex binary programs
+@cindex virtual machine
+@cindex assembler
+@cindex @code{mixasm}
+
+Three simulators of the MIX computer, called @code{mixvm}, @code{gmixvm}
+and @code{mixguile}, are included in the @sc{mdk} tools. They are able to
+run binary files containing MIX instructions written in their binary
+representation. You can translate MIXAL source files into this binary
+form using @code{mixasm}, the MIXAL assembler. So, in order to compile
+the @file{hello.mixal} file, you can type the following command at your
+shell prompt:
+
+@example
+mixasm hello @key{RET}
+@end example
+
+@cindex .mix file
+
+If the source file contains no errors, this will produce a binary file
+called @file{hello.mix} which can be loaded and run by the MIX virtual
+machine. Unless the @code{mixasm} option @code{-O} is provided, the
+assembler will include debug information in the executable file (for a
+complete description of all the compilation options, see
+@ref{mixasm}). Now, your are ready to run your first MIX program, as
+described in the following section.
+
+
+@node Running the program, Using mixguile, Compiling, Getting started
+@section Running the program
+@cindex @code{mixvm}
+@cindex non-interactive mode
+@cindex interactive mode
+
+MIX is a mythical computer, so it is no use ordering it from your
+favorite hardware provider. @sc{mdk} provides three software simulators of
+the computer, though. They are
+
+@itemize @bullet
+@item
+@code{mixvm}, a command line oriented simulator,
+@item
+@code{gmixvm}, a GTK based graphical interface to @code{mixvm}, and
+@item
+@code{mixguile}, a Guile shell with a built-in MIX simulator.
+@end itemize
+
+All three simulators accept the same set of user commands, but offer a
+different user interface, as noted above. In this section we shall
+describe some of these commands, and show you how to use them from
+@code{mixvm}'s command line. You can use them as well at @code{gmixvm}'s
+command prompt (@pxref{gmixvm}), or using the built-in Scheme primitives
+of @code{mixguile} (@pxref{Using mixguile}).
+
+Using the MIX simulators, you can run your MIXAL programs, after
+compiling them with @code{mixasm} into binary @file{.mix}
+files. @code{mixvm} can be used either in @dfn{interactive} or
+@dfn{non-interactive} mode. In the second case, @code{mixvm} will load
+your program into memory, execute it (producing any output due to
+MIXAL @code{OUT} instructions present in the program), and exit when
+it encounters a @code{HLT} instruction. In interactive mode, you will
+enter a shell prompt which allows you issuing commands to the running
+virtual machine. This commands will permit you to load, run and debug
+programs, as well as to inspect the MIX computer state (register
+contents, memory cells contents and so on).
+
+@menu
+* Non-interactive mode:: Running your programs non-interactively.
+* Interactive mode:: Running programs interactively.
+* Debugging:: Commands for debugging your programs.
+@end menu
+
+@node Non-interactive mode, Interactive mode, Running the program, Running the program
+@comment node-name, next, previous, up
+@subsection Non-interactive mode
+@cindex non-interactive mode
+
+To make @code{mixvm} work in non-interactive mode, use the @code{-r}
+flag. Thus, to run our @file{hello.mix} program, simply type
+
+@example
+mixvm -r hello @key{RET}
+@end example
+
+@noindent at your command prompt, and you will get the following output:
+
+@example
+MIXAL HELLO WORLD
+@end example
+
+@noindent Since our hello world program uses MIX's device number 19 as
+its output device (@pxref{Writing a source file}), the output is
+redirected to the shell's standard output. Had you used any other MIX
+output devices (disks, drums, line printer, etc.), @code{mixvm} would
+have created a file named after the device used (e.g. @file{disk4.dev})
+and written its output there@footnote{The device files are stored, by
+default, in a directory called @file{.mdk}, which is created in your
+home directory the first time @code{mixvm} is run. You can change this
+default directory using the command @code{devdir} when running
+@code{mixvm} in interactive mode (@pxref{Configuration commands})}.
+
+The virtual machine can also report the execution time of the program,
+according to the (virtual) time spent in each of the binary instructions
+(@pxref{Execution times}). Printing of execution time statistics is
+activated with the @code{-t} flag; running
+
+@example
+mixvm -t -r hello @key{RET}
+@end example
+
+@noindent
+produces the following output:
+
+@example
+MIXAL HELLO WORLD
+** Execution time: 11
+@end example
+
+Sometimes, you will prefer to store the results of your program in MIX
+registers rather than writing them to a device. In such cases,
+@code{mixvm}'s @code{-d} flag is your friend: it makes @code{mixvm} to
+dump the contents of its registers and flags after executing the loaded
+program. For instance, typing the following command at your shell's
+prompt
+
+@example
+mixvm -d -r hello
+@end example
+
+@noindent you will obtain the following output:
+
+@example
+MIXAL HELLO WORLD
+rA: + 00 00 00 00 00 (0000000000)
+rX: + 00 00 00 00 00 (0000000000)
+rJ: + 00 00 (0000)
+rI1: + 00 00 (0000) rI2: + 00 00 (0000)
+rI3: + 00 00 (0000) rI4: + 00 00 (0000)
+rI5: + 00 00 (0000) rI6: + 00 00 (0000)
+Overflow: F
+Cmp: E
+@end example
+
+@noindent which, in addition to the program's outputs and execution
+time, gives you the contents of the MIX registers and the values of the
+overflow toggle and comparison flag (admittedly, rather uninteresting in
+our sample).
+
+As you can see, running programs non-interactively has many
+limitations. You cannot peek the virtual machine's memory contents, not
+to mention stepping through your program's instructions or setting
+breakpoints@footnote{The @code{mixguile} program allows you to execute
+arbitrary combinations of @code{mixvm} commands (using Scheme)
+non-interactively. @xref{Scheme scripts}.}. Enter interactive mode.
+
+@node Interactive mode, Debugging, Non-interactive mode, Running the program
+@comment node-name, next, previous, up
+@subsection Interactive mode
+@cindex interactive mode
+
+To enter the MIX virtual machine interactive mode, simply type
+
+@example
+mixvm @key{RET}
+@end example
+
+@noindent at your shell command prompt. This command enters the
+@code{mixvm} command shell. You will be presented the following command
+prompt:
+
+@example
+MIX >
+@end example
+
+@noindent The virtual machine is initialised and ready to accept your
+commands. The @code{mixvm} command shell uses GNU's readline, so that
+you have at your disposal command completion (using @key{TAB}) and
+history functionality, as well as other line editing shortcuts common to
+all utilities using this library (for a complete description of
+readline's line editing usage, see @ref{Command Line
+Editing,,,Readline}.)
+
+@cindex @code{load}
+Usually, the first thing you will want to do is loading a compiled MIX
+program into memory. This is acomplished by the @code{load} command,
+which takes as an argument the name of the @file{.mix} file to be
+loaded. Thus, typing
+
+@example
+MIX > load hello @key{RET}
+Program loaded. Start address: 3000
+MIX >
+@end example
+
+@noindent will load @file{hello.mix} into the virtual machine's memory
+and set the program counter to the address of the first instruction. You
+can obtain the contents of the program counter using the command
+@code{pc}:
+
+@cindex @code{pc}
+@example
+MIX > pc
+Current address: 3000
+MIX >
+@end example
+
+@cindex @code{run}
+After loading it, you are ready to run the program, using, as you surely
+have guessed, the @code{run} command:
+
+@example
+MIX > run
+Running ...
+MIXAL HELLO WORLD
+... done
+Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
+MIX >
+@end example
+
+@noindent Note that now the timing statistics are richer. You obtain the
+elapsed execution time (i.e., the time spent executing instructions
+since the last breakpoint), the total execution time for the program up
+to now (which in our case coincides with the elapsed time, since there
+were no breakpoints), and the total uptime for the virtual machine (you
+can load and run more than one program in the same
+session)@footnote{Printing of timing statistics can be disabled using
+the command @code{timing} (@pxref{Configuration commands}).}. After
+running the program, the program counter will point to the address after
+the one containing the @code{HLT} instruction. In our case, asking the
+value of the program counter after executing the program will give us
+
+@example
+MIX > pc
+Current address: 3002
+MIX >
+@end example
+
+@cindex @code{pmem}
+@noindent You can check the contents of a memory cell giving its address
+as an argument of the command @code{pmem}, like this
+
+@example
+MIX > pmem 3001
+3001: + 00 00 00 02 05 (0000000133)
+MIX >
+@end example
+
+@noindent
+and convince yourself that address 3001 contains the binary
+representation of the instruction @code{HLT}. An address range of the
+form FROM-TO can also be used as the argument of @code{pmem}:
+
+@example
+MIX > pmem 3000-3006
+3000: + 46 58 00 19 37 (0786957541)
+3001: + 00 00 00 02 05 (0000000133)
+3002: + 14 09 27 01 13 (0237350989)
+3003: + 00 08 05 13 13 (0002118477)
+3004: + 16 00 26 16 19 (0268542995)
+3005: + 13 04 00 00 00 (0219152384)
+3006: + 00 00 00 00 00 (0000000000)
+MIX >
+@end example
+
+@cindex @code{preg}
+@noindent
+In a similar manner, you can look at the contents of the MIX registers
+and flags. For instance, to ask for the contents of the A register you
+can type
+
+@example
+MIX > preg A
+rA: + 00 00 00 00 00 (0000000000)
+MIX >
+@end example
+
+@cindex @code{help}
+@noindent
+Use the comand @code{help} to obtain a list of all available commands,
+and @code{help COMMAND} for help on a specific command, e.g.
+
+@example
+MIX > help run
+run Run loaded or given MIX code file. Usage: run [FILENAME]
+MIX >
+@end example
+
+@noindent
+For a complete list of commands available at the MIX propmt,
+@xref{mixvm}. In the following subsection, you will find a quick tour
+over commands useful for debugging your programs.
+
+@node Debugging, , Interactive mode, Running the program
+@comment node-name, next, previous, up
+@subsection Debugging commands
+
+@cindex @code{next}
+The interactive mode of @code{mixvm} lets you step by step execution of
+programs as well as breakpoint setting. Use @code{next} to step through
+the program, running its instructions one by one. To run our
+two-instruction @file{hello.mix} sample you can do the following:
+
+@example
+MIX > load hello
+Program loaded. Start address: 3000
+MIX > pc
+Current address: 3000
+MIX > next
+MIXAL HELLO WORLD
+Elapsed time: 1 /Total program time: 1 (Total uptime: 1)
+MIX > pc
+Current address: 3001
+MIX > next
+End of program reached at address 3002
+Elapsed time: 10 /Total program time: 11 (Total uptime: 11)
+MIX > pc
+Current address: 3002
+MIX > next
+MIXAL HELLO WORLD
+Elapsed time: 1 /Total program time: 1 (Total uptime: 12)
+MIX >
+MIX > run
+Running ...
+... done
+Elapsed time: 10 /Total program time: 11 (Total uptime: 22)
+MIX >
+@end example
+@noindent
+(As an aside, the above sample also shows how the virtual machine
+handles cummulative time statistics and automatic program restart).
+
+@cindex @code{sbpa}
+@cindex breakpoints
+
+You can set a breakpoint at a given address using the command
+@code{sbpa} (set breakpoint at address). When a breakpoint is set,
+@code{run} will stop before executing the instruction at the given
+address. Typing @code{run} again will resume program execution. Coming
+back to our hello world example, we would have:
+
+@example
+MIX > sbpa 3001
+Breakpoint set at address 3001
+MIX > run
+Running ...
+MIXAL HELLO WORLD
+... stopped: breakpoint at line 8 (address 3001)
+Elapsed time: 1 /Total program time: 1 (Total uptime: 23)
+MIX > run
+Running ...
+... done
+Elapsed time: 10 /Total program time: 11 (Total uptime: 33)
+MIX >
+@end example
+
+@cindex @code{sbp}
+@cindex breakpoints
+@noindent
+Note that, since we compiled @file{hello.mixal} with debug info
+enabled, the virtual machine is able to tell us the line in the
+source file corresponding to the breakpoint we are setting. As a
+matter of fact, you can directly set breakpoints at source code lines
+using the command @code{sbp LINE_NO}, e.g.
+
+@example
+MIX > sbp 4
+Breakpoint set at line 7
+MIX >
+@end example
+
+@noindent
+@code{sbp} sets the breakpoint at the first meaningful source code line;
+thus, in the above example we have requested a breakpoint at a line
+which does not correspond to a MIX instruction and the breakpoint is set
+at the first line containing a real instruction after the given one. To
+unset breakpoints, use @code{cbpa ADDRESS} and @code{cbp LINE_NO}, or
+@code{cabp} to remove all currently set breakpoints. You can also set
+conditional breakpoints, i.e., tell @code{mixvm} to interrupt program
+execution whenever a register, a memory cell, the comparison flag or the
+overflow toggle change using the commands @w{@code{sbp[rmco]}}
+(@pxref{Debug commands}).
+
+@cindex @code{psym}
+MIXAL lets you define symbolic constants, either using the @code{EQU}
+pseudoinstruction or starting an instruction line with a label (which
+assigns to the label the value of the current memory address). Each
+MIXAL program has, therefore, an associated symbol table which you can
+inspect using the @code{psym} command. For our hello world sample, you
+will obtain the following output:
+
+@example
+MIX > psym
+START: 3000
+TERM: 19
+MSG: 3002
+MIX >
+@end example
+
+Other useful commands for debugging are @code{strace} (which turns on
+tracing of executed intructions), @code{pbt} (which prints a backtrace
+of executed instructions) and @code{weval} (which evaluates
+w-expressions on the fly). For a complete description of all available
+MIX commands, @xref{mixvm}.
+
+@node Using mixguile, Using Scheme in mixvm and gmixvm, Running the program, Getting started
+@section Using @code{mixguile}
+
+With @code{mixguile} you can run a MIX simulator embedded in a Guile
+shell, that is, using Scheme functions and programs. As with
+@code{mixvm}, @code{mixguile} can be run both in interactive and
+non-interactive modes. The following subsections provide a quick tour on
+using this MIX emulator.
+
+@menu
+* The mixguile shell:: Using the Scheme MIX virtual machine.
+* Additional functions:: Scheme functions accessing the VM.
+* Defining new functions:: Defining your own Scheme functions.
+* Hook functions:: Using command and break hook functions.
+* Scheme scripts::
+@end menu
+
+@node The mixguile shell, Additional functions, Using mixguile, Using mixguile
+@subsection The @code{mixguile} shell
+@cindex Scheme
+@cindex @code{mixguile}
+@cindex REPL
+
+If you simply type
+
+@example
+mixguile @key{RET}
+@end example
+@noindent
+at the command prompt, you'll be presented a Guile shell prompt like
+this
+
+@example
+guile>
+@end example
+@noindent
+At this point, you have entered a Scheme read-eval-print loop (REPL)
+which offers you all the Guile functionality plus a new set of built-in
+procedures to execute and debug MIX programs. Each of the @code{mixvm}
+commands described in the previous sections (and in @pxref{mixvm}) have
+a Scheme function counterpart named after it by prepending the prefix
+@code{mix-} to its name. Thus, to load our hello world program, you can
+simply enter
+
+@example
+guile> (mix-load "hello")
+Program loaded. Start address: 3000
+guile>
+@end example
+@noindent
+and run it using @code{mix-run}:
+
+@example
+guile> (mix-run)
+Running ...
+MIXAL HELLO WORLD
+... done
+Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
+guile>
+@end example
+@noindent
+In the same way, you can execute it step by step using the Scheme
+function @code{mix-next} or set a breakpoint:
+
+@example
+guile> (mix-sbp 4)
+Breakpoint set at line 5
+guile>
+@end example
+@noindent
+or, if you one to peek at a register contents:
+
+@example
+guile> (mix-preg 'A)
+rA: + 00 00 00 00 00 (0000000000)
+guile>
+@end example
+
+You get the idea: you have at your disposal all the @code{mixvm} and
+@code{gmixvm} commands by means of @code{mix-} functions. But, in case
+you are wondering, this is only the beginning. You also have at your
+disposal a whole Scheme interpreter, and you can, for instance, define
+new functions combining the @code{mix-} and all other Scheme
+primitives. In the next sections, you'll find examples of how to take
+advantage of the Guile interpreter.
+
+@node Additional functions, Defining new functions, The mixguile shell, Using mixguile
+@subsection Additional MIX Scheme functions
+
+The @code{mix-} function counterparts of the @code{mixvm} commands don't
+return any value, and are evaluated only for their side-effects
+(possibly including informational messages to the standard output and/or
+error stream). When writting your own Scheme functions to manipulate the
+MIX virtual machine within @code{mixguile} (@pxref{Defining new
+functions}), you'll probably need Scheme functions returning the value
+of the registers, memory cells and so on. Don't worry: @code{mixguile}
+also offers you such functions. For instance, to access the (numerical)
+value of a register you can use @code{mix-reg}:
+
+@example
+guile> (mix-reg 'I2)
+0
+guile>
+@end example
+@noindent
+Note that, unlike @code{(mix-preg 'I2)}, the expression @code{(mix-reg
+'I2)} in the above example evaluates to a Scheme number and does not
+produce any side-effect:
+
+@example
+guile> (number? (mix-reg 'I2))
+#t
+guile> (number? (mix-preg 'I2))
+rI2: + 00 00 (0000)
+#f
+guile>
+@end example
+
+In a similar fashion, you can access the memory contents using
+@code{(mix-cell)}, or the program counter using @code{(mix-loc)}:
+
+@example
+guile> (mix-cell 3000)
+786957541
+guile> (mix-loc)
+3002
+guile>
+@end example
+
+Other functions returning the contents of the virtual machine components
+are @code{mix-cmp} and @code{mix-over}, which eval to the value of the
+comparison flag and the overflow toggle respectively. For a complete
+list of these additional functions, @xref{mixguile}.
+
+In the next section, we'll see a sample of using these functions to
+extend @code{mixguile}'s functionality.
+
+@node Defining new functions, Hook functions, Additional functions, Using mixguile
+@subsection Defining new functions
+@cindex Scheme functions
+
+Scheme is a powerful language, and you can use it inside @code{mixguile}
+to easily extend the MIX interpreter's capabilities. For example, you
+can easily define a function that loads a file, prints its name,
+executes it and, finally, shows the registers contents, all in one shot:
+
+@example
+guile> (define my-load-and-run @key{RET}
+ (lambda (file) @key{RET}
+ (mix-load file) @key{RET}
+ (display "File loaded: ") @key{RET}
+ (mix-pprog) @key{RET}
+ (mix-run) @key{RET}
+ (mix-preg))) @key{RET}
+guile>
+@end example
+@noindent
+and use it to run your programs:
+
+@example
+guile> (my-load-and-run "hello")
+Program loaded. Start address: 3000
+File loaded: hello.mix
+Running ...
+MIXAL HELLO WORLD
+... done
+Elapsed time: 11 /Total program time: 11 (Total uptime: 33)
+rA: + 00 00 00 00 00 (0000000000)
+rX: + 00 00 00 00 00 (0000000000)
+rJ: + 00 00 (0000)
+rI1: + 00 00 (0000) rI2: + 00 00 (0000)
+rI3: + 00 00 (0000) rI4: + 00 00 (0000)
+rI5: + 00 00 (0000) rI6: + 00 00 (0000)
+guile>
+@end example
+
+
+Or, maybe, you want a function which sets a breakpoint at a specified
+line number before executing it:
+
+@example
+guile> (define my-load-and-run-with-bp
+ (lambda (file line)
+ (mix-load file)
+ (mix-sbp line)
+ (mix-run)))
+guile> (my-load-and-run-with-bp "samples/primes" 10)
+Program loaded. Start address: 3000
+Breakpoint set at line 10
+Running ...
+... stopped: breakpoint at line 10 (address 3001)
+Elapsed time: 1 /Total program time: 1 (Total uptime: 45)
+guile>
+@end example
+
+As a third example, the following function loads a program, runs it and
+prints the contents of the memory between the program's start and end
+addresses:
+
+@example
+guile> (define my-run
+ (lambda (file)
+ (mix-load file)
+ (let ((start (mix-loc)))
+ (mix-run)
+ (mix-pmem start (mix-loc)))))
+guile> (my-run "hello")
+Program loaded. Start address: 3000
+Running ...
+MIXAL HELLO WORLD
+... done
+Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
+3000: + 46 58 00 19 37 (0786957541)
+3001: + 00 00 00 02 05 (0000000133)
+3002: + 14 09 27 01 13 (0237350989)
+guile>
+@end example
+
+
+As you can see, the possibilities are virtually unlimited. Of course,
+you don't need to type a function definition each time you start
+@code{mixguile}. You can write it in a file, and load it using Scheme's
+@code{load} function. For instance, you can create a file named, say,
+@file{functions.scm} with your definitions (or any Scheme expression)
+and load it at the @code{mixguile} prompt:
+
+@example
+guile> (load "functions.scm")
+@end example
+
+Alternatively, you can make @code{mixguile} to load it for you. When
+@code{mixguile} starts, it looks for a file named @file{mixguile.scm} in
+your MDK configuration directory (@file{~/.mdk}) and, if it exists,
+loads it before entering the REPL. Therefore, you can copy your
+definitions in that file, or load the @file{functions.scm} file in
+@file{mixguile.scm}.
+
+@node Hook functions, Scheme scripts, Defining new functions, Using mixguile
+@subsection Hook functions
+@cindex hook function
+@cindex pre-hook
+@cindex post-hook
+
+Hooks are functions called before or after a given event occurs. In
+@code{mixguile}, you can define command and break hooks, which are
+associated, respectively, with command execution and program
+interruption events. The following sections give you a tutorial on using
+hook functions within @code{mixguile}.
+
+@menu
+* Command hooks::
+* Break hooks::
+@end menu
+
+@node Command hooks, Break hooks, Hook functions, Hook functions
+@subsubsection Command hooks
+
+In the previous section, we have seen how to extend @code{mixguile}'s
+functionality through the use of user defined functions. Frequently,
+you'll write new functions that improve in some way the workings of a
+built-in @code{mixvm} command, following this pattern:
+
+@enumerate a
+@item
+Prepare the command execution
+@item
+Execute the desired command
+@item
+Perform post execution operations
+@end enumerate
+
+We call the functions executed in step (a) @dfn{pre-hook}s, and those of
+step @dfn{post-hook}s of the given command. @code{mixguile} lets you
+specify pre- and post-hooks for any @code{mixvm} command using the
+@code{mix-add-pre-hook} and @code{mix-add-post-hook} functions, which
+take as arguments a symbol naming the command and a function to be
+executed before (resp. after) the command. In other words,
+@code{mixguile} will execute for you steps (a) and (c) above whenever
+you eval (b). The hook functions must take a single argument, which is a
+string list of the command's arguments. As an example, let us define the
+following hooks for the @code{next} command:
+
+@example
+(define next-pre-hook
+ (lambda (arglist)
+ (mix-slog #f)))
+
+(define next-post-hook
+ (lambda (arglist)
+ (display "Stopped at line ")
+ (display (mix-src-line-no))
+ (display ": ")
+ (display (mix-src-line))
+ (newline)
+ (mix-slog #t)))
+@end example
+@noindent
+In these functions, we are using the function @code{mix-slog} to turn
+off the informational messages produced by the virtual machine, since we
+are providing our own ones in the post hook function. To install these
+hooks, we would write:
+
+@example
+(mix-add-pre-hook 'next next-pre-hook)
+(mix-add-post-hook 'next next-post-hook)
+@end example
+@noindent
+Assuming we have put the above expressions in @code{mixguile}'s
+initialisation file, we would obtain the following results when
+evaluating @code{mix-next}:
+
+@example
+guile> (mix-next)
+MIXAL HELLO WORLD
+Stopped at line 6: HLT
+guile>
+@end example
+
+As a second, more elaborated, example, let's define hooks which print
+the address and contents of a cell being modified using @code{smem}. The
+hook functions could be something like this:
+
+@example
+(define smem-pre-hook
+ (lambda (arglist)
+ (if (eq? (length arglist) 2)
+ (begin
+ (display "Changing address ")
+ (display (car arglist))
+ (newline)
+ (display "Old contents: ")
+ (display (mix-cell (string->number (car arglist))))
+ (newline))
+ (error "Wrong arguments" arglist))))
+
+(define smem-post-hook
+ (lambda (arglist)
+ (if (eq? (length arglist) 2)
+ (begin
+ (display "New contents: ")
+ (display (mix-cell (string->number (car arglist))))
+ (newline)))))
+@end example
+@noindent
+and we can install them using
+
+@example
+(mix-add-pre-hook 'smem smem-pre-hook)
+(mix-add-post-hook 'smem smem-post-hook)
+@end example
+@noindent
+Aferwards, a sample execution of @code{mix-smem} would look like this:
+
+@example
+guile> (mix-smem 2000 100)
+Changing address 2000
+Old contents: 0
+New contents: 100
+guile>
+@end example
+
+@cindex global hook
+
+You can add any number of hooks to a given command. They will be
+executed in the same order as they are registered. You can also define
+global post (pre) hooks, which will be called before (after) any
+@code{mixvm} command is executed. Global hook functions must admit two
+arguments, namely, a string naming the invoked command and a string list
+of its arguments, and they are installed using the Scheme functions
+@code{mix-add-global-pre-hook} and @code{mix-add-global-post-hook}. A
+simple example of global hook would be:
+
+@example
+guile> (define pre-hook
+ (lambda (cmd args)
+ (display cmd)
+ (display " invoked with arguments ")
+ (display args)
+ (newline)))
+guile> (mix-add-global-pre-hook pre-hook)
+ok
+guile> (mix-pmem 120 125)
+pmem invoked with arguments (120-125)
+0120: + 00 00 00 00 00 (0000000000)
+0121: + 00 00 00 00 00 (0000000000)
+0122: + 00 00 00 00 00 (0000000000)
+0123: + 00 00 00 00 00 (0000000000)
+0124: + 00 00 00 00 00 (0000000000)
+0125: + 00 00 00 00 00 (0000000000)
+guile>
+@end example
+
+Note that if you invoke @code{mixvm} commands within a global hook, its
+associated command hooks will be run. Thus, if you have installed both
+the @code{next} hooks described earlier and the global hook above,
+executing @code{mix-next} will yield the following result:
+
+@example
+guile> (mix-next 5)
+next invoked with arguments (5)
+slog invoked with arguments (off)
+MIXAL HELLO WORLD
+Stopped at line 7: MSG ALF "MIXAL"
+slog invoked with arguments (on)
+guile>
+@end example
+
+Adventurous readers may see the above global hook as the beginning of a
+command log utility or a macro recorder that saves your commands for
+replay.
+
+@node Break hooks, , Command hooks, Hook functions
+@subsubsection Break hooks
+
+@cindex break hook
+
+We have seen in the previous section how to associate hooks to command
+execution, but they are not the whole story. You can also associate hook
+functions to program interruption, that is, specify functions that
+should be called every time the execution of a MIX program is stopped
+due to the presence of a breakpoint, either explicit or
+conditional. Break hooks take as arguments the line number and memory
+address at which the break occurred. A simple hook that logs the line
+and address of the breakpoint could be defined as:
+
+@example
+(define break-hook
+ (lambda (line address)
+ (display "Breakpoint encountered at line ")
+ (display line)
+ (display " and address ")
+ (display address)
+ (newline)))
+@end example
+@noindent
+and installed for explicit and conditional breakpoints using
+
+@example
+(mix-add-break-hook break-hook)
+(mix-add-cond-break-hook break-hook)
+@end example
+@noindent
+after that, every time the virtual machine encounters a breakpoint,
+@code{break-code} shall be evaluated for you@footnote{You may have
+noticed that break hooks can be implemented in terms of command hooks
+associated to @code{mix-run} and @code{mix-next}. As a matter of fact,
+they @emph{are} implemented this way: take a look at the file
+@file{@emph{install_dir}/share/mdk/mix-vm-stat.scm} if you are curious.}.
+
+@node Scheme scripts, , Hook functions, Using mixguile
+@subsection Scheme scripts
+@cindex Scheme script
+@cindex non-interactive
+
+Another useful way of using @code{mixguile} is writing executable
+scripts that perform a set of commands for you. This is done using the
+@code{mixguile} switch @code{-s} (being a Guile shell, @code{mixguile}
+accepts all the command options of @code{guile}; type @code{mixguile -h}
+for a list of all available command options). For instance, if you have
+a very useful MIX program @file{foo.mix} which you want to run often,
+you don't have to fire a MIX virtual machine, load and run it every
+time; you can write a Scheme script instead:
+
+@example
+#! /usr/bin/mixguile -s
+!#
+;;; runprimes: execute the primes.mix program
+
+;; load the file you want to run
+(mix-load "../samples/primes")
+;; execute it
+(mix-run)
+;; print the contents of registers
+(mix-pall)
+;; ...
+@end example
+
+Just save the above script to a file named, say, @file{runtest}, make it
+executable (@code{chmod +x runtest}), and, well, execute it from the
+Unix shell:
+
+@example
+$ ./runtest
+Program loaded. Start address: 3000
+Running ...
+... done
+Elapsed time: 190908 /Total program time: 190908 (Total uptime: 190908)
+rA: + 30 30 30 30 30 (0511305630)
+rX: + 30 30 32 32 39 (0511313959)
+rJ: + 47 18 (3026)
+rI1: + 00 00 (0000) rI2: + 55 51 (3571)
+rI3: + 00 19 (0019) rI4: + 31 51 (2035)
+rI5: + 00 00 (0000) rI6: + 00 00 (0000)
+Overflow: F
+Cmp: L
+$
+@end example
+
+Note that this is far more flexible that running programs
+non-interactively using @code{mixvm} (@pxref{Non-interactive mode}), for
+you can execute any combination of commands you want from a Scheme
+script (not just running and dumping the registers). For additional
+@code{mixguile} command line options, see @ref{Invoking mixguile}.
+
+@node Using Scheme in mixvm and gmixvm, , Using mixguile, Getting started
+@section Using Scheme in @code{mixvm} and @code{gmixvm}
+@cindex @code{scmf}
+
+In the previous section (@pxref{Using mixguile}) we have seen how the
+Guile shell @code{mixguile} offers you the possibility of using Scheme
+to manipulate a MIx virtual machine and extend the set of commands
+offered by @code{mixvm} and @code{gmixvm}. This possibility is not
+limited to the @code{mixguile} shell. Actually, both @code{mixvm} and
+@code{gmixvm} incorporate an embedded Guile interpreter, and can
+evaluate Scheme expressions. To evaluate a single-line expression at the
+@code{mixvm} or @code{gmixvm} command prompt, simply write it and press
+return (the command parser will recognise it as a Scheme expression
+because it is parenthesized, and will pass it to the Guile
+interpreter). A sample @code{mixvm} session using Scheme expressions
+could be:
+
+@example
+MIX > load hello
+Program loaded. Start address: 3000
+MIX > (define a (mix-loc))
+MIX > run
+Running ...
+MIXAL HELLO WORLD
+... done
+Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
+MIX > (mix-pmem a)
+3000: + 46 58 00 19 37 (0786957541)
+MIX > (mix-pmem (mix-loc))
+3002: + 14 09 27 01 13 (0237350989)
+MIX >
+@end example
+
+You can also load and evaluate a file, using the @code{scmf}
+command like this:
+
+@example
+MIX> scmf /path/to/file/file.scm
+@end example
+
+Therefore, you have at your disposal all the @code{mixguile} goodies
+described above (new functions, new command definitions, hooks...)
+inside @code{mixvm} and @code{gmixvm}. In other words, these programs
+are extensible using Scheme. See @ref{Using mixguile} for examples of
+how to do it.
+
diff --git a/doc/mdk_index.texi b/doc/mdk_index.texi
new file mode 100644
index 0000000..68f3c48
--- /dev/null
+++ b/doc/mdk_index.texi
@@ -0,0 +1,14 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_index.texi,v 1.7 2004/08/03 13:23:06 jao Exp $
+
+@node Concept Index, Instructions and commands, Copying, Top
+@unnumbered Concept Index
+
+@cindex tail recursion
+@printindex cp
+
diff --git a/doc/mdk_install.texi b/doc/mdk_install.texi
new file mode 100644
index 0000000..08a44e2
--- /dev/null
+++ b/doc/mdk_install.texi
@@ -0,0 +1,287 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2002, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@node Installing MDK, MIX and MIXAL tutorial, Acknowledgments, Top
+@comment node-name, next, previous, up
+@chapter Installing @sc{mdk}
+
+@menu
+* Download::
+* Requirements::
+* Basic installation::
+* Emacs support::
+* Special configure flags::
+* Supported platforms::
+@end menu
+
+@node Download, Requirements, Installing MDK, Installing MDK
+@comment node-name, next, previous, up
+@section Download the source tarball
+
+GNU @sc{mdk} is distributed as a source tarball available for download in
+the following @acronym{URL}s:
+
+@itemize @bullet
+@item
+@url{ftp://ftp.gnu.org/pub/gnu/mdk}
+@item
+@uref{http://www.gnu.org/prep/ftp.html, GNU mirrors}
+@item
+@uref{http://sourceforge.net/project/showfiles.php?group_id=13897}
+@end itemize
+
+The above sites contain the latest stable releases of @sc{mdk}. The
+development branch is available at:
+
+@itemize @bullet
+@item
+@uref{https://savannah.gnu.org/cvs/?group_id=118}
+@end itemize
+
+After you have downloaded the source tarball, unpack it in a directory
+of your choice using the command:
+
+@example
+tar xfvz mdk-X.Y.tar.gz
+@end example
+
+@noindent
+where @var{X.Y} stands for the downloaded version (the current stable
+release being version @value{VERSION}).
+
+@node Requirements, Basic installation, Download, Installing MDK
+@comment node-name, next, previous, up
+@section Requirements
+
+In order to build and install @sc{mdk}, you will need the following
+libraries installed in your system:
+
+@itemize @minus
+@item
+@uref{http://www.gtk.org, GLIB 2.4.0} (required)
+@item
+@uref{http://www.gnu.org/software/flex/flex.html, GNU Flex 2.5} (required)
+@item
+@uref{http://www.gtk.org, GTK 2.4.0} (optional)
+@item
+@uref{http://ftp.gnome.org/pub/GNOME/sources/libglade/2.4/, Libglade
+2.4.0}
+(optional)
+@item
+@uref{http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html, GNU
+Readline}
+(optional)
+@item
+@uref{http://www.gnu.org/software/guile, GNU Libguile 1.6} (optional)
+@end itemize
+
+If present, readline and history are used to provide command completion
+and history management to the command line MIX virtual machine, @code{mixvm}.
+GTK+ and libglade are needed if you want to build the graphical
+interface to the MIX virtual machine, @code{gmixvm}. Finally, if
+libguile is found, the @sc{mdk} utilities will be compiled with Guile
+support and will be extensible using Scheme.
+
+@strong{Please note}: you need both the libraries @emph{and} the
+headers; this means both the library package and the @file{-dev} package
+if you do not compile your libraries yourself (ex: installing
+@file{libgtk2.0-0} and @file{libgtk2.0-0-dev} on Debian).
+
+@node Basic installation, Emacs support, Requirements, Installing MDK
+@comment node-name, next, previous, up
+@section Basic installation
+
+@sc{mdk} uses GNU Autoconf and Automake tools, and, therefore, should
+be built and installed without hassle using the following commands
+inside the source directory:
+
+@example
+./configure
+make
+make install
+@end example
+
+@noindent
+where the last one must be run as root.
+
+The first command, @code{configure}, will setup the makefiles for your
+system. In particular, @code{configure} will look for GTK+ and libglade,
+and, if they are present, will generate the appropiate makefiles for
+building the @code{gmixvm} graphical user interface. Upon completion,
+you should see a message with the configuration results like the
+following:
+
+@example
+*** GNU MDK 1.2 has been successfully configured. ***
+
+Type 'make' to build the following utilities:
+ - mixasm (MIX assembler)
+ - mixvm (MIX virtual machine, with readline support,
+ with guile support)
+ - gmixvm (mixvm GTK+ GUI, with guile support)
+ - mixguile (the mixvm guile shell)
+@end example
+
+@noindent
+where the last lines may be missing if you lack the above mentioned
+libraries.
+
+The next command, @code{make}, will actually build the @sc{mdk} programs
+in the following locations:
+
+@itemize @minus
+@item
+@file{mixutils/mixasm}
+@item
+@file{mixutils/mixvm}
+@item
+@file{mixgtk/gmixvm}
+@item
+@file{mixguile/mixguile}
+@end itemize
+
+You can run these programs from within their directories, but I
+recommend you to install them in proper locations using @code{make
+install} from a root shell.
+
+@node Emacs support, Special configure flags, Basic installation, Installing MDK
+@comment node-name, next, previous, up
+@section Emacs support
+
+@sc{mdk} includes extensive support for Emacs. Upon installation, all
+the elisp code is installed in @file{PREFIX/share/mdk}, where
+@file{PREFIX} stands for your installation root directory (e.g.
+@file{/usr/local}). You can copy the elisp files to a directory that
+is in your load-path, or you can add the above directory to it.
+Assuming that the installing prefix is @file{/usr/local},
+you can do it by adding to your @file{.emacs} file the following line:
+
+@lisp
+(setq load-path (cons "/usr/local/share/mdk" load-path))
+@end lisp
+
+@code{MIXAL} programs can be written using Emacs and the elisp program
+@file{share/mdk/mixal-mode.el}, contributed by @value{PIETER}. It
+provides font locking, interactive help, compiling assistance and
+invocation of the @code{MIX} virtual machine via a new major mode
+called @code{mixal-mode}. To start @code{mixal-mode} automatically
+whenever you edit a @code{MIXAL} source file, add the following lines
+to your @file{.emacs} file:
+
+@lisp
+(autoload 'mixal-mode "mixal-mode" t)
+(add-to-list 'auto-mode-alist '("\\.mixal\\'" . mixal-mode))
+@end lisp
+
+In addition, @code{mixvm} can be run within an Emacs @acronym{GUD}
+buffer using the elisp program @file{share/mdk/mixvm.el}, contributed
+by @value{PHILIP}. @file{mixvm.el} provides an interface between
+@sc{mdk}'s @code{mixvm} and Emacs, via @acronym{GUD}. Place this file
+in your load-path, optionally adding the following line to your
+@file{.emacs} file:
+
+@lisp
+(autoload 'mixvm "mixvm" "mixvm/gud interaction" t)
+@end lisp
+
+
+@node Special configure flags, Supported platforms, Emacs support, Installing MDK
+@comment node-name, next, previous, up
+@section Special configure flags
+
+You can fine-tune the configuration process using the following
+switches with configure:
+
+@defopt @w{--enable-gui[=yes|no]}
+@defoptx --disable-gui
+Enables/disables the build of the MIX virtual machine GUI
+(@code{gmixvm}). If the required libraries are missing
+(@pxref{Requirements}) the configure script with automatically disable
+this feature.
+@end defopt
+
+@defopt @w{--with-guile[=yes|no]}
+@defoptx --without-guile
+Enables/disables the Guile support for @code{mixvm} and @code{gmixvm},
+and the build of @code{mixguile}. If the
+required libraries are missing (@pxref{Requirements}) the configure
+script with automatically disable this feature.
+@end defopt
+
+@defopt @w{--with-readline[=yes|no]}
+@defoptx --without-readline
+Enables/disables the GNU Readline support for @code{mixvm}. If the
+required libraries are missing (@pxref{Requirements}) the configure
+script with automatically disable this feature.
+@end defopt
+
+For additional, boilerplate configure options, see the @file{INSTALL}
+file, or run
+
+@example
+configure --help
+@end example
+
+@node Supported platforms, , Special configure flags, Installing MDK
+@comment node-name, next, previous, up
+@section Supported platforms
+
+GNU MDK has been tested in the following platforms:
+
+@itemize
+@item
+Debian GNU/Linux 2.2, 2.3, 3.0, 3.1, 3.2
+@item
+Redhat GNU/Linux 8.0 (Ronald Cole), 7.0 (Agustin Navarro), 6.2
+(Roberto Ferrero)
+@item
+Mandrake 8.0 (Agustin Navarro)
+@item
+FreeBSD 4.2, 4.3, 4.4, 4.5 (Ying-Chieh Liao), 5.2
+@item
+Solaris 2.8/gcc 2.95.3 (Stephen Ramsay)
+@item
+MS Windows 98 SE/Cygwin 1.1.8-2 (Christoph von
+Nathusius)@footnote{Caveats: Christoph has only tested @code{mixvm} and
+@code{mixasm} on this platform, using @code{gcc} 2.95.3-2, @code{GLIB}
+1.2.10 and @code{GNUreadline} 4.1-2. He has reported missing history
+functionalities on a first try. If you find problems with
+history/readline functionality, please try a newer/manually installed
+readline version.}
+@item
+Mac OS X 10.1.2 (Johan Swanljung)
+@item
+AMD Athlon, GNU/Linux version 2.4.2-2smp (Red Hat 7.1 (Seawolf)) (N.
+H. F. Beebe)
+@item
+Apple PowerPC G3, GNU/Linux 2.2.18-4hpmac (Red Hat Linux/PPC
+2000 Q4) (N. H. F. Beebe)
+@item
+DEC Alpha, GNU/Linux 2.2.19-6.2.1 (Red Hat 6.2) (N. H. F. Beebe)
+@item
+Compaq/DEC Alpha OSF/1 4.0F [ONLY after adding rsync's snprintf()
+implementation] (N. H. F. Beebe)
+@item
+IBM PowerPC AIX 4.2 (N. H. F. Beebe)
+@item
+Intel Pentium III, GNU/Linux 2.4.9-31smp (Red Hat 7.2 (Enigma)) (N. H.
+F. Beebe)
+@item
+SGI Origin 200, IRIX 6.5 (N.
+H. F. Beebe)
+@item
+Sun SPARC, GNU/Linux 2.2.19-6.2.1 (Red Hat 6.2) (N. H. F. Beebe)
+@item
+Sun SPARC, Solaris 2.8 (N. H. F. Beebe)
+@end itemize
+
+@sc{mdk} will probably work on any GNU/Linux or BSD platform. If you
+try it in a platform not listed above, please send a mail to
+@email{jao@@gnu.org, the author}.
+
+
+
+
diff --git a/doc/mdk_intro.texi b/doc/mdk_intro.texi
new file mode 100644
index 0000000..b4ce2ad
--- /dev/null
+++ b/doc/mdk_intro.texi
@@ -0,0 +1,70 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_intro.texi,v 1.8 2004/08/03 13:23:06 jao Exp $
+
+@node Introduction, Acknowledgments, Top, Top
+@comment node-name, next, previous, up
+@unnumbered Introduction
+@cindex Introduction
+
+In his book series @cite{The Art of Computer Programming} (published by
+Addison Wesley), D. Knuth uses an imaginary computer, the MIX, and its
+associated machine-code and assembly languages to ilustrate the
+concepts and algorithms as they are presented.
+
+The MIX's architecture is a simplified version of those found in real
+CISC CPUs, and the MIX assembly language (MIXAL) provides a set of
+primitives that will be very familiar to any person with a minimum
+experience in assembly programming. The MIX/MIXAL definition is powerful
+and complete enough to provide a virtual development platform for
+writing quite complex programs, and close enough to real computers to be
+worth using when learning programming techniques. At any rate, if you
+want to learn or improve your programming skills, a MIX development
+environment would come in handy.
+
+The @sc{mdk} package aims at providing such virtual development
+environment on a GNU box. Thus, @sc{mdk} offers you a set of utilities
+to simulate the MIX computer and to write, compile, run and debug MIXAL
+programs. As of version @value{VERSION}, @sc{mdk} includes
+the following programs:
+
+@table @code
+@item mixasm
+MIXAL assembler. Assembler which translates MIXAL source files into
+programs that can be run (and debugged) by @code{mixvm}, @code{mixguile}
+or @code{gmixvm}.
+@item mixvm
+MIX virtual machine. Emulation of the MIX computer with a @acronym{CLI}.
+@item gmixvm
+A GTK+ GUI for the MIX virtual machine. Provides all of @code{mixvm}
+functionality accessible through a graphical interface.
+@item mixguile
+A Guile shell, with an embedded MIX virtual machine and built-in
+commands to manipulate it using Scheme.
+@item mixal-mode.el
+An Emacs major mode for MIXAL source files editing, providing syntax
+highlighting, documentation lookup and invocation of @code{mixvm}
+within Emacs.
+@item mixvm.el
+This elisp program allows running @code{mixvm} inside an Emacs GUD
+buffer, providing concurrent edition and debugging of MIXAL programs.
+@end table
+
+@code{mixvm} and @code{gmixvm} implement a simulator of the MIX
+computer, giving you a virtual machine for executing and debugging MIX
+programs. These binary programs could be written by hand, but it is
+easier to produce them compiling MIXAL source files, using the MIXAL
+assembler @code{mixasm}. On the other hand, @code{mixguile} offers you
+the possibility of manipulating a MIX virtual machine through a set of
+Scheme functions, so that you can use this programming language to
+interact with the virtual machine. In addition, @code{mixvm} and
+@code{gmixvm} are also able to interpret Scheme scripts (using an
+embedded Guile interpreter), that is, you can use Scheme as an extension
+language to add new functionalities to these programs.
+
+This manual gives you a tutorial of MIX and MIXAL, and a thorough
+description of the use of the @sc{mdk} utilities.
diff --git a/doc/mdk_mixasm.texi b/doc/mdk_mixasm.texi
new file mode 100644
index 0000000..fa144a7
--- /dev/null
+++ b/doc/mdk_mixasm.texi
@@ -0,0 +1,89 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_mixasm.texi,v 1.10 2004/08/05 21:32:46 jao Exp $
+
+@node mixasm, mixvm, Emacs tools, Top
+@comment node-name, next, previous, up
+@chapter @code{mixasm}, the MIXAL assembler
+@cindex @code{mixasm}
+@cindex MIXAL
+@cindex assembler
+
+MIX programs, as executed by @code{mixvm}, are composed of binary
+instructions loaded into the virtual machine memory as MIX
+words. Although you could write your MIX programs directly as a series
+of words in binary format, you have at your disposal a more friendly
+assembly language, MIXAL (@pxref{MIXAL}) which is compiled into binary
+form by @code{mixasm}, the MIXAL assembler included in @sc{mdk}. In this
+chapter, you will find a complete description of @code{mixasm} options.
+
+@menu
+* Invoking mixasm::
+@end menu
+
+@node Invoking mixasm, , mixasm, mixasm
+@comment node-name, next, previous, up
+@section Invoking @code{mixasm}
+
+In its simplest form, @code{mixasm} is invoked with a single argument,
+which is the name of the MIXAL file to be compiled, e.g.
+
+@example
+mixasm hello
+@end example
+
+@noindent
+will compile either @file{hello} or @file{hello.mixal}, producing a
+binary file named @file{hello.mix} if no errors are found.
+
+In addition, @code{mixasm} can be invoked with the following command
+line options (note, that, following GNU's conventions, we provide a long
+option name for each available single letter switch):
+
+@example
+mixasm [-vhulO] [-o OUTPUT_FILE] [--version] [--help] [--usage]
+ [--ndebug] [--output=OUTPUT_FILE] [--list[=LIST_FILE]] file
+@end example
+
+@noindent
+The meaning of these options is as follows:
+
+@defopt -v
+@defoptx --version
+Prints version and copyleft information and exits.
+@end defopt
+
+@defopt -h
+@defoptx --help
+@defoptx -u
+@defoptx --usage
+Prints a summary of available options and exits.
+@end defopt
+
+@defopt -O
+@defoptx --ndebug
+Do not include debugging information in the compiled file, saving
+space but disallowing breakpoint setting at source level and symbol
+table inspection under @code{mixvm}.
+@end defopt
+
+@defopt -o output_file
+@defoptx --output=output_file
+By default, the given source file @var{file.mixal} is compiled into
+@var{file.mix}. You can provide a different name for the output file
+using this option.
+@end defopt
+
+@defopt -l
+@defoptx @w{--list[=list_file]}
+@cindex .mls file
+This option causes @code{mixasm} to produce, in addion to the
+@file{.mix} file, an ASCII file containing a summary of the compilation
+results. The file is named after the MIXAL source file, changing its
+extension to @file{.mls} if no argument is provided; otherwise, the
+listing file is named according to the argument.
+@end defopt
diff --git a/doc/mdk_mixguile.texi b/doc/mdk_mixguile.texi
new file mode 100644
index 0000000..2d6ac65
--- /dev/null
+++ b/doc/mdk_mixguile.texi
@@ -0,0 +1,445 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_mixguile.texi,v 1.5 2004/08/03 13:23:06 jao Exp $
+
+@node mixguile, Problems, gmixvm, Top
+@chapter @code{mixguile}, the Scheme virtual machine
+@cindex @code{mixguile}
+
+This chapter provides a reference to using @code{mixguile} and the
+Scheme function library giving access to the MIX virtual machine in the
+@sc{mdk} emulators (@code{mixguile}, @code{mixvm} and @code{gmixvm}). See
+@ref{Using mixguile} for a tutorial, step by step introduction to
+@code{mixguile} and using Scheme as an extension language for the
+@sc{mdk} MIX virtual machines.
+
+@menu
+* Invoking mixguile:: Command line options.
+* Scheme functions reference:: Scheme functions accessing the VM.
+@end menu
+
+@node Invoking mixguile, Scheme functions reference, mixguile, mixguile
+@section Invoking @code{mixguile}
+@cindex @code{mixguile} options
+
+Invoking @code{mixguile} without arguments will enter the Guile REPL
+(read-eval-print loop) after loading, if it exists, the user's
+initialisation file (@file{~/.mdk/mixguile.scm}).
+
+@code{mixguile} accepts the same command line options than Guile:
+
+@example
+mixguile [-s SCRIPT] [-c EXPR] [-l FILE] [-e FUNCTION] [-qhv]
+ [--help] [--version]
+@end example
+
+The meaning of these options is as follows:
+
+@defopt -h
+@defoptx --help
+Prints usage summary and exits.
+@end defopt
+
+@defopt -v
+@defoptx --version
+Prints version and copyleft information and exits.
+@end defopt
+
+@defopt -s SCRIPT
+Loads Scheme code from @var{script}, evaluates it and exits. This option
+can be used to write executable Scheme scripts, as described in
+@ref{Scheme scripts}.
+@end defopt
+
+@defopt -c EXPR
+Evaluates the given Scheme expression and exits.
+@end defopt
+
+@defopt -l FILE
+Loads the given Scheme file and enters the REPL (read-eval-print loop).
+@end defopt
+
+@defopt -e FUNCTION
+After reading the script, executes the given function using the provided
+command line arguments. For instance, you can write the following Scheme
+script:
+
+@example
+#! /usr/bin/mixguile \
+-e main -s
+!#
+
+;;; execute a given program and print the registers.
+
+(define main
+ (lambda (args)
+ ;; load the file provided as a command line argument
+ (mix-load (cadr args))
+ ;; execute it
+ (mix-run)
+ ;; print the contents of registers
+ (mix-pall)))
+
+@end example
+@noindent
+save it in a file called, say, @file{foo}, make it executable, and run
+it as
+
+@example
+$ ./foo hello
+@end example
+@noindent
+This invocation will cause the evaluation of the @code{main} function
+with a list of command line parameters as its argument (@code{("./foo"
+"hello")} in the above example. Note that command line options to
+mixguile must be written in their own line after the @code{\} symbol.
+@end defopt
+
+@defopt -q
+Do not load user's initialisation file. When @code{mixguile} starts up,
+it looks for a file named @file{mixguile.scm} in the user's @sc{mdk}
+configuration directory (@file{~/.mdk}), and loads it if it exists. This
+option tells @code{mixguile} to skip this initialisation file loading.
+@end defopt
+
+
+@node Scheme functions reference, , Invoking mixguile, mixguile
+@section Scheme functions reference
+
+As we have previously pointed out, @code{mixguile} embeds a MIX virtual
+machine that can be accessed through a set of Scheme functions, that is,
+of a Scheme library. Conversely, @code{mixvm} and @code{gmixvm} contain
+a Guile interpreter, and are able to use this same Scheme library, as
+well as all the other Guile/Scheme primitives and any user defined
+function. Therefore, you have at your disposal a powerful programming
+language, Scheme, to extend the @sc{mdk} virtual machine emulators (see
+@ref{Using Scheme in mixvm and gmixvm} for samples of how to do it).
+
+The following subsections describe available functions the MIX/Scheme
+library.
+
+@menu
+* mixvm wrappers:: Functions invoking mixvm commands.
+* Hooks:: Adding hooks to mixvm commands.
+* Additional VM functions:: Functions accessing the MIX virtual machine.
+@end menu
+
+@node mixvm wrappers, Hooks, Scheme functions reference, Scheme functions reference
+@subsection @code{mixvm} command wrappers
+
+For each of the @code{mixvm} commands listed in @ref{Commands}, there is
+a corresponding Scheme function named by prefixing the command name with
+@code{mix-} (e.g., @code{mix-load}, @code{mix-run} and so on). These
+command wrappers are implemented using a generic command dispatching
+function:
+
+@defun mixvm-cmd command argument
+Dispatchs the given @var{command} to the MIX virtual appending the
+provided @var{argument}. Both @var{command} and @code{argument} must be
+strings. The net result is as writing "@var{command} @var{argument}" at
+the @code{mixvm} or @code{gmixvm} command prompt.
+@end defun
+
+For instance, you can invoke the @code{run} command at the @code{mixvm}
+prompt in three equivalent ways:
+
+@example
+MIX > run hello
+MIX > (mix-run "hello")
+MIX > (mixvm-cmd "run" "hello")
+@end example
+@noindent
+(only the two last forms can be used at the @code{mixguile} prompt or
+inside a Scheme script).
+
+The @code{mix-} functions evaluate to a unspecified value. If you want
+to check the result of the last @code{mixvm} command invocation, use the
+@code{mix-last-result} function:
+
+@defun mix-last-result
+Returns @var{#t} if the last @code{mixvm} command invocation was
+successful, @var{#f} otherwise.
+@end defun
+@noindent
+Using this function, we could improve the script for running a program
+presented in the previous section by adding error checking:
+
+
+@example
+#! /usr/bin/mixguile \
+-e main -s
+!#
+
+;;; Execute a given program and print the registers.
+
+(define main
+ (lambda (args)
+ ;; load the file provided as a command line argument
+ (mix-load (cadr args))
+ ;; execute it if mix-load succeeded
+ (if (mix-last-result) (mix-run))
+ ;; print the contents of registers if the above commands succeded
+ (if (mix-last-result) (mix-pall))))
+@end example
+
+Please, refer to @ref{Commands} for a list of available commands. Given
+the description of a @code{mixvm}, it is straightforward to use its
+Scheme counterpart and, therefore, we shall not give a complete
+description of these functions here. Instead, we will only mention those
+wrappers that exhibit a treatment of their differing from that of their
+command counterpart.
+
+@defun mix-preg [register]
+@defunx mix-sreg register value
+The argument @var{register} of these functions can be either a string or
+a symbol representing the desired register. For instance, the following
+invocations are equivalent:
+
+@example
+(mix-preg 'I1)
+(mix-preg "I1")
+@end example
+@end defun
+
+@defun mix-pmem from [to]
+The command @code{pmem} takes a single argument which can be either a
+cell number or a range of the form @code{FROM-TO}. This function takes
+one argument to ask for a single memory cell contents, or two parameters
+to ask for a range. For instance, the following commands are equivalent:
+
+@example
+MIX > pmem 10-12
+0010: + 00 00 00 00 00 (0000000000)
+0011: + 00 00 00 00 00 (0000000000)
+0012: + 00 00 00 00 00 (0000000000)
+MIX > (mix-pmem 10 12)
+0010: + 00 00 00 00 00 (0000000000)
+0011: + 00 00 00 00 00 (0000000000)
+0012: + 00 00 00 00 00 (0000000000)
+MIX >
+@end example
+@end defun
+
+@defun mix-sover #t|#f
+The command @code{sover} takes as argument either the string @code{T} or
+the string @code{F}, to set, respectively, the overflow toggle to true
+or false. Its Scheme counterpart, @code{mix-sover}, takes as argument
+a Scheme boolean value: @code{#t} (true) or @code{#f}.
+@end defun
+
+For the remaining functions, you simply must take into account that when
+the command arguments are numerical, the corresponding Scheme function
+takes as arguments Scheme number literals. On the other hand, when the
+command argument is a string, the argument of its associated Scheme
+function will be a Scheme string. By way of example, the following
+invocations are pairwise equivalent:
+
+@example
+MIX > load ../samples/hello
+MIX > (mix-load "../samples/hello")
+
+MIX > next 5
+MIX > (mix-next 5)
+@end example
+
+@node Hooks, Additional VM functions, mixvm wrappers, Scheme functions reference
+@subsection Hook functions
+
+Hooks are functions evaluated before or after executing a @code{mixvm}
+command (or its corresponding Scheme function wrapper), or after an
+explicit or conditional breakpoint is found during the execution of a
+MIX program. The following functions let you install hooks:
+
+@defun mix-add-pre-hook command hook
+Adds a function to the list of pre-hooks associated with the give
+@var{command}. @var{command} is a string naming the corresponding @code{mixvm}
+command, and @var{hook} is a function which takes a single argument: a
+string list of the commands arguments. The following scheme code defines
+a simple hook and associates it with the @code{run} command:
+
+@example
+(define run-hook
+ (lambda (args)
+ (display "argument list: ")
+ (display args)
+ (newline)))
+(mix-add-pre-hook "run" run-hook)
+@end example
+
+Pre-hooks are executed, in the order they are added, before invoking the
+corresponding command (or its associated Scheme wrapper function).
+@end defun
+
+@defun mix-add-post-hook command hook
+Adds a function to the list of pre-hooks associated with the give
+@var{command}. The arguments have the same meaning as in
+@code{mix-add-pre-hook}.
+@end defun
+
+@defun mix-add-global-pre-hook hook
+@defunx mix-add-global-post-hook hook
+Global pre/post hooks are executed before/after any @code{mixvm} command
+or function wrapper invocation. In this case, @var{hook} takes two
+arguments: a string with the name of the command being invoked, and a
+string list with its arguments.
+@end defun
+
+@defun mix-add-break-hook hook
+@defunx mix-add-cond-break hook
+Add a hook funtion to be executed when an explicit (resp. conditional)
+breakpoint is encountered during program execution. @var{hook} is a
+function taking two arguments: the source line number where the hook has
+occurred, and the current program counter value. The following code
+shows a simple definition and installation of a break hook:
+
+@example
+(define break-hook
+ (lambda (line address)
+ (display "Breakpoint at line ") (display line)
+ (display " and address ") (display address)
+ (newline)))
+(mix-add-break-hook break-hook)
+@end example
+
+Break hook functions are entirely implemented in Scheme using regular
+post-hooks for the @code{next} and @code{run} commands. If you are
+curious, you can check the Scheme source code at
+@file{@emph{prefix}/share/mdk/mixguile-vm-stat.scm} (where @emph{prefix}
+stands for your root install directory, usualy @code{/usr} or
+@code{/usr/local}.
+@end defun
+
+
+See @ref{Hook functions} for further examples on using hook functions.
+
+
+@node Additional VM functions, , Hooks, Scheme functions reference
+@subsection Additional VM functions
+
+When writing non-trivial Scheme extensions using the MIX/Scheme library,
+you will probably need to evaluate the contents of the virtual machine
+components (registers, memory cells and so on). For instance, you may
+need to store the contents of the @code{A} register in a variable. The
+Scheme functions described so far are of no help: you can print the
+contents of @code{A} using @code{(mix-preg 'A)}, but you cannot define a
+variable containing the contents of @code{A}. To address this kind of
+problems, the MIX/Scheme library provides the following additional
+functions:
+
+@defun mixvm-status
+@defunx mix-vm-status
+Return the current status of the virtual machine, as a number
+(@code{mixvm-status}) or as a symbol (@code{mix-vm-status}). Posible
+return values are:
+@multitable {aamixvmaastatusaa} {aamixvmastatusaaaaaaa} {return valuesaaaaaaaaaaaaaaaaaaaaaaaaaa}
+@item @code{(mixvm-status)} @tab @code{(mix-vm-status)} @tab
+@item 0 @tab MIX_ERROR @tab Loading or execution error
+@item 1 @tab MIX_BREAK @tab Breakpoint encountered
+@item 2 @tab MIX_COND_BREAK @tab Conditional breakpoint
+@item 3 @tab MIX_HALTED @tab Execution terminated
+@item 4 @tab MIX_RUNNING @tab Execution stopped after @code{next}
+@item 5 @tab MIX_LOADED @tab Program successfully loaded
+@item 6 @tab MIX_EMPTY @tab No program loaded
+@end multitable
+@end defun
+
+@defun mix-vm-error?
+@defunx mix-vm-break?
+@defunx mix-vm-cond-break?
+@defunx mix-vm-halted?
+@defunx mix-vm-running?
+@defunx mix-vm-loaded?
+@defunx mix-vm-empty?
+Predicates asking whether the current virtual machine status is
+@code{MIX_ERROR}, @code{MIX_BREAK}, etc.
+@end defun
+
+@defun mix-reg register
+@defunx mix-set-reg! register value
+@code{mix-reg} evaluates to a number which is the contents of the
+specified @var{register}. @code{mix-set-reg} sets the contents of the
+given @var{register} to @var{value}. The register can be specified
+either as a string (@code{"A"}, @code{"X"}, etc.) or as a symbol
+(@code{'A}, @code{'X}, etc.). For instance,
+
+@example
+guile> (mix-reg 'A)
+2341
+guile> (mix-set-reg! "A" 2000)
+ok
+guile> (define reg-a (mix-reg 'A))
+guile> (display reg-a)
+2000
+guile>
+@end example
+@end defun
+
+@defun mix-cell cell_no
+@defunx mix-set-cell! cell_no value
+Evaluate and set the contents of the memory cell number
+@var{cell_no}. Both @var{cell_no} and @var{value} are Scheme numbers.
+@end defun
+
+@defun mix-loc
+Evaluates to the value of the location counter (i.e., the address of the
+next instruction to be executed).
+@end defun
+
+@defun mix-over
+@defunx mix-set-over! #t|#f
+@code{mix-over} evaluates to @code{#t} if the overflow toggle is set,
+and to @code{#f} otherwise. The value of the overflow toggle can be
+modified using @code{mix-set-over!}.
+@end defun
+
+@defun mix-cmp
+@defunx mix-set-cmp! 'L|'E|'G
+Evaluate and set the comparison flag. Possible values are the scheme
+symbols @code{L} (lesser), @code{E} (equal) and @code{G} (greater).
+@end defun
+
+@defun mix-up-time
+Evaluates to the current virtual machine uptime.
+@end defun
+
+@defun mix-lap-time
+Evaluates to the current virtual machine lapsed time, i.e., the time
+elapsed since the last @code{run} or @code{next} command.
+@end defun
+
+@defun mix-prog-time
+Evaluates to the total time spent executing the currently loaded program.
+@end defun
+
+@defun mix-prog-name
+Evaluates to a string containing the basename (without any leading path)
+of the currently loaded MIX program.
+@end defun
+
+@defun mix-prog-path
+Evaluates to a string containing the full path to the currently loaded
+MIX program.
+@end defun
+
+@defun mix-src-path
+Evaluates to a string containing the full path to the source file of the
+currently loaded MIX program.
+@end defun
+
+@defun mix-src-line [lineno]
+@defunx mix-src-line-no
+@code{mix-src-line-no} evaluates to the current source file number
+during the execution of a program. @code{mix-src-line} evaluates to a
+string containing the source file line number @var{lineno}; when
+invoked without argument, it evaluates to @code{(mix-src-line
+(mix-src-line-no))}.
+@end defun
+
+@defun mix-ddir
+Evaluates to a string containing the full path of the current device
+directory.
+@end defun
diff --git a/doc/mdk_mixvm.texi b/doc/mdk_mixvm.texi
new file mode 100644
index 0000000..2e21289
--- /dev/null
+++ b/doc/mdk_mixvm.texi
@@ -0,0 +1,813 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2002, 2003, 2004
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_mixvm.texi,v 1.20 2005/09/19 21:29:42 jao Exp $
+
+@node mixvm, gmixvm, mixasm, Top
+@comment node-name, next, previous, up
+@chapter @code{mixvm}, the MIX computer simulator
+
+@cindex mixvm
+
+This chapter describes @code{mixvm}, the MIX computer
+simulator. @code{mixvm} is a command line interface programme which
+simulates the MIX computer (@pxref{The MIX computer}). It is able
+to run MIXAL programs (@pxref{MIXAL}) previously compiled with the MIX
+assembler (@pxref{mixasm}). The simulator allows inspection of the MIX
+computer components (registers, memory cells, comparison flag and overflow
+toggle), step by step execution of MIX programmes, and breakpoint
+setting to aid you in debugging your code. For a tutorial description of
+@code{mixvm} usage, @xref{Running the program}.
+
+@menu
+* Invocation::
+* Commands:: Commands available in interactive mode.
+* Devices:: MIX block devices implementation.
+@end menu
+
+@node Invocation, Commands, mixvm, mixvm
+@comment node-name, next, previous, up
+@section Invoking @code{mixvm}
+
+@code{mixvm} can be invoked with the following command line options
+(note that, following GNU's conventions, we provide a long option name
+for each available single letter switch):
+
+@example
+mixvm [-vhurdtq] [--version] [--help] [--usage] [--run] [--dump]
+ [--time] [--noinit] [FILE[.mix]]
+@end example
+
+@noindent
+The meaning of these options is as follows:
+
+@defopt -v
+@defoptx --version
+Prints version and copyleft information and exits.
+@end defopt
+
+@defopt -h
+@defoptx --help
+@defoptx -u
+@defoptx --usage
+Prints a summary of available options and exits.
+@end defopt
+
+@defopt -r
+@defoptx --run
+Loads the specified @var{FILE} and executes it. After the program
+execution, @code{mixvm} exits. @var{FILE} must be the name of a binary
+@file{.mix} program compiled with @code{mixasm}. If your program does
+not produce any output, use the @code{-d} flag (see below) to peek at
+the virtual machine's state after execution.
+@end defopt
+
+@defopt -d
+@defoptx --dump
+This option must be used in conjuction with @code{-r}, and tells
+@code{mixvm} to print the value of the virtual machine's registers,
+comparison flag and overflow toggle after executing the program named
+@var{FILE}. See @xref{Non-interactive mode}, for sample usage.
+@end defopt
+
+@defopt -t
+@defoptx --time
+This option must be used in conjuction with @code{-r}, and tells
+@code{mixvm} to print virtual time statistics for the program's
+execution.
+@end defopt
+
+When run without the @code{-r} flag, @code{mixvm} enters its interactive
+mode, showing you a prompt like this one:
+
+@example
+MIX >
+@end example
+
+@noindent
+and waiting for your commands (@pxref{Commands}). If the
+optional @var{FILE} argument is given, the file @file{FILE.mix} will be
+loaded into the virtual machine memory before entering the interactive
+mode.
+
+The first time @code{mixvm} is invoked, a directory named @file{.mdk} is
+created in your home directory. It contains the @code{mixvm}
+configuration file, the command history file and (by default) the block
+devices files (@pxref{Devices}). Before showing you the command prompt,
+@code{mixvm} looks in the @file{~/.mdk} directory for a file named
+@code{mixguile.scm}; if it exists, it is read and evaluated by the
+embedded Guile interpreter (@pxref{Defining new functions}). You can use
+the @code{-q} command line option to skip this file loading:
+
+@defopt -q
+@defoptx --noinit
+Do not load the Guile initialisation file @code{~/.mdk/mixguile.scm} at
+startup.
+@end defopt
+
+@node Commands, Devices, Invocation, mixvm
+@comment node-name, next, previous, up
+@section Interactive commands
+
+You can enter the interactive mode of the MIX virtual machine by simply
+invoking @code{mixvm} without arguments. You will then be greeted by a shell
+prompt@footnote{The default command prompt, @samp{MIX > }, can be
+changed using the @code{prompt} command (@pxref{Configuration commands})}
+
+@example
+MIX >
+@end example
+
+@noindent
+which indicates that a new virtual machine has been initialised and is
+ready to execute your commands. As we have already mentioned, this
+command prompt offers you command line editing facilities which are
+described in the Readline user's manual (chances are that you are
+already familiar with these command line editing capabilities, as they
+are present in many GNU utilities, e.g. the @code{bash}
+shell)@footnote{The readline functionality will be available if you have
+compiled @sc{mdk} with readline support, i.e., if GNU readline is
+installed in your system. This is ofte the case in GNU/Linux and BSD
+systems}. In a nutshell, readline provides command completion using the
+@kbd{TAB} key and command history using the cursor keys. A history file
+containing the last commands typed in previous sessions is stored in the
+@sc{mdk} configuration directory (@file{~/.mdk}).
+
+As a beginner, your best friend will be the @code{help} command, which
+shows you a summary of all available MIX commands and their usage; its
+syntax is as follows:
+
+@deffn {@code{mixvm} command} help [command]
+Prints a short description of the given @var{command} and its usage. If
+@var{command} is omitted, @code{help} prints the short description for
+all available commands.
+@end deffn
+
+@menu
+* File commands:: Loading and executing programs.
+* Debug commands:: Debugging programs.
+* State commands:: Inspecting the virtual machine state.
+* Configuration commands:: Changing and storing mixvm settings.
+* Scheme commands::
+@end menu
+
+@node File commands, Debug commands, Commands, Commands
+@subsection File commands
+
+You have at your disposal a series of commands that let you load and
+execute MIX executable files, as well as manipulate MIXAL source files:
+
+@deffn {file command} load file[.mix]
+This command loads a binary file, @var{file.mix} into the virtual
+machine memory, and positions the program counter at the beginning of
+the loaded program. This address is indicated in the MIXAL source file
+as the operand of the @code{END} pseudoinstruction. Thus, if your
+@file{sample.mixal} source file contains the line:
+
+@example
+ END 3000
+@end example
+
+@noindent
+and you compile it with @code{mixasm} to produce the binary file
+@file{sample.mix}, you will load it into the virtual machine as follows:
+
+@example
+MIX > load sample
+Program loaded. Start address: 3000
+MIX >
+@end example
+
+@end deffn
+
+@deffn {file command} run [file[.mix]]
+When executed without argument, this command initiates or resumes
+execution of instructions from the current program counter
+address. Therefore, issuing this command after a successful @code{load},
+will run the loaded program until either a @code{HLT} instruction or a
+breakpoint is found. If you provide a MIX filename as argument, the
+given file will be loaded (as with @code{load} @var{file}) and
+executed. If @code{run} is invoked again after program execution
+completion (i.e., after the @code{HLT} instruction has been found in a
+previous run), the program counter is repositioned and execution starts
+again from the beginning (as a matter of fact, a @code{load} command
+preserving the currently set breakpoints is issued before resuming
+execution).
+@end deffn
+
+@deffn {file command} edit [file[.mixal]]
+The source file @var{file.mixal} is edited using the editor defined in
+the environment variable @var{MDK_EDITOR}. If this variable is not set,
+the following ones are tried out in order: @var{X_EDITOR}, @var{EDITOR}
+and @var{VISUAL}. If invoked without argument, the source file for the
+currently loaded MIX file is edited. The command used to edit source
+files can also be configured using the @code{sedit} command
+(@pxref{Configuration commands}).
+@end deffn
+
+@deffn {file command} compile file[.mixal]
+The source file @var{file.mixal} is compiled (with debug information
+enabled) using @code{mixasm}. If invoked without argument, the source
+file for the currently loaded MIX file is recompiled. The compilation
+command can be set using the @code{sasm} command (@pxref{Configuration
+commands}).
+@end deffn
+
+@deffn {file command} pprog
+@deffnx {file command} psrc
+Print the path of the currently loaded MIX program and its source file:
+
+@example
+MIX > load ../samples/primes
+Program loaded. Start address: 3000
+MIX > pprog
+../samples/primes.mix
+MIX > psrc
+/home/jao/projects/mdk/gnu/samples/primes.mixal
+MIx>
+@end example
+@end deffn
+
+Finally, you can use the @code{quit} command to exit @code{mixvm}:
+
+@deffn {file command} quit
+Exit @code{mixvm}, saving the current configuration parameters in
+@file{~/.mdk/mixvm.config}.
+@end deffn
+
+
+@node Debug commands, State commands, File commands, Commands
+@subsection Debug commands
+
+Sequential execution of loaded programs can be interrupted using the
+following debug commands:
+
+@deffn {debug command} next [ins_number]
+This command causes the virtual machine to fetch and execute up to
+@var{ins_number} instructions, beginning from the current program
+counter position. Execution is interrupted either when the specified
+number of instructions have been fetched or a breakpoint is found,
+whatever happens first. If run without arguments, one instruction is
+executed. If @code{next} is invoked again after program execution
+completion (i.e., after the @code{HLT} instruction has been found in a
+previous run), the program counter is repositioned and execution starts
+again from the beginning (as a matter of fact, a @code{load} command
+preserving the currently set breakpoints is issued before resuming
+execution).
+@end deffn
+
+@deffn {debug command} sbp line_number
+@deffnx {debug command} cbp line_no
+Sets a breakpoint at the specified source file line number. If the line
+specified corresponds to a command or to a MIXAL pseudoinstruction which
+does not produce a MIX instruction in the binary file (such as
+@code{ORIG} or @code{EQU}) the breakpoint is set at the first source
+code line giving rise to a MIX instruction after the specified
+one. Thus, for our sample @file{hello.mixal} file:
+
+@example
+* (1)
+* hello.mixal: say 'hello world' in MIXAL (2)
+* (3)
+* label ins operand comment (4)
+TERM EQU 19 the MIX console device number (5)
+ ORIG 1000 start address (6)
+START OUT MSG(TERM) output data at address MSG (7)
+...
+@end example
+
+@noindent
+trying to set a breakpoint at line 5, will produce the following result:
+
+@example
+MIX > sbp 5
+Breakpoint set at line 7
+MIX >
+@end example
+
+@noindent
+since line 7 is the first one compiled into a MIX instruction (at
+address 3000).
+
+The command @code{cbp} clears a (previously set) breakpoint at the given
+source file line.
+@end deffn
+
+@deffn {debug command} spba address
+@deffnx {debug command} cbpa address
+Sets a breakpoint at the given memory @var{address}. The argument must
+be a valid MIX memory address, i.e., it must belong into the range
+@w{[0-3999]}. Note that no check is performed to verify that the
+specified address is reachable during program execution. No debug
+information is needed to set a breakpoint by address with @code{sbpa}.
+The command @code{cbpa} clears a (previously set) breakpoint at the
+given memory address.
+@end deffn
+
+@deffn {debug command} sbpr A | X | J | Ii
+@deffnx {debug command} cbpr A | X | J | Ii
+Sets a conditional breakpoint on the specified register change. For
+instance,
+
+@example
+sbpr I1
+@end example
+
+@noindent
+will cause an interruption during program execution whenever the
+contents or register @code{I1} changes. A previously set breakpoint is
+cleared using the @code{cbpr} command.
+@end deffn
+
+@deffn {debug command} sbpm address
+@deffnx {debug command} cbpm address
+Sets a conditional breakpoint on the specified memory cell change. The
+argument must be a valid MIX memory address, i.e., it must belong into
+the range @w{[0-3999]}. For instance,
+
+@example
+sbpm 1000
+@end example
+
+@noindent
+will cause an interruption during program execution whenever the
+contents or of the memory cell number 1000 changes. A previously set
+breakpoint is cleared using the @code{cbpm} command.
+@end deffn
+
+@deffn {debug command} sbpo
+@deffnx {debug command} cbpo
+Sets/clears a conditional breakpoint on overflow toggle change.
+@end deffn
+
+@deffn {debug command} sbpc
+@deffnx {debug command} cbpc
+Sets/clears a conditional breakpoint on comparison flag change.
+@end deffn
+
+@deffn {debug command} cabp
+Clears all currently set breakpoints.
+@end deffn
+
+@deffn {debug command} psym [symbol_name]
+MIXAL programs can define symbolic constants, using either the
+@code{EQU} pseudoinstruction or a label at the beginning of a
+line. Thus, in the program fragment
+
+@example
+VAR EQU 2168
+ ORIG 4000
+START LDA VAR
+@end example
+
+@noindent
+the symbol @code{VAR} stands for the value 2168, while @code{START} is
+assigned the value 4000. The symbol table can be consulted from
+the @code{mixvm} command line using @code{psym} followed by the name of
+the symbol whose contents you are interested in. When run without
+arguments, @code{psym} will print all defined symbols and their values.
+@end deffn
+
+The virtual machine can also show you the instructions it is executing,
+using the following commands:
+
+@deffn {debug command} strace [on|off]
+@code{strace on} enables instruction tracing. When tracing is enabled,
+each time the virtual machine executes an instruction (due to your
+issuing a @code{run} or @code{next} command), it is printed in its
+canonical form (that is, with all expressions evaluated to their
+numerical values) and, if the program was compiled with debug
+information, as it was originally typed in the MIXAL source
+file. Instruction tracing is disabled with @code{strace off}
+command. A typical tracing session could be like this:
+
+@example
+MIX > strace on
+MIX > next
+3000: [OUT 3002,0(2:3)] START OUT MSG(TERM)
+MIXAL HELLO WORLD
+Elapsed time: 1 /Total program time: 1 (Total uptime: 1)
+MIX > next
+3001: [HLT 0,0] HLT
+End of program reached at address 3002
+Elapsed time: 10 /Total program time: 11 (Total uptime: 11)
+MIX > strace off
+MIX >
+@end example
+@noindent
+The executed instruction, as it was translated, is shown between square
+brackets after the memory address, and, following it, you can see the
+actual MIXAL code that was compiled into the executed instruction. The
+tracing behaviour is stored as a configuration parameter in @file{~/.mdk}.
+@end deffn
+
+@deffn {debug command} pline [LINE_NUMBER]
+Prints the requested source line (or the current one if
+@var{line_number} is omitted:
+
+@example
+MIX > load ../samples/hello
+Program loaded. Start address: 3000
+MIX > pline
+Line 5: START OUT MSG(TERM)
+MIX > pline 6
+Line 6: HLT
+MIX >
+@end example
+@end deffn
+
+@deffn {debug command} pbt [INS_NUMBER]
+This command prints a backtrace of executed instructions. Its optional
+argument @var{ins_number} is the number of instructions to print. If it
+is omitted or equals zero, all executed instructions are printed. For
+instance, if you compile and load the following program (@file{bt.mixal}):
+
+@example
+ ORIG 0
+BEG JMP *+1
+ JMP *+1
+FOO JMP BAR
+BAR HLT
+ END BEG
+@end example
+
+@noindent
+you could get the following traces:
+
+@example
+MIX > load bt
+Program loaded. Start address: 0
+MIX > next
+MIX > pbt
+#0 BEG in bt.mixal:2
+MIX > next
+MIX > pbt
+#0 1 in bt.mixal:3
+#1 BEG in bt.mixal:2
+MIX > run
+Running ...
+... done
+MIX > pbt 3
+#0 BAR in bt.mixal:5
+#1 FOO in bt.mixal:4
+#2 1 in bt.mixal:3
+MIX > pbt
+#0 BAR in bt.mixal:5
+#1 FOO in bt.mixal:4
+#2 1 in bt.mixal:3
+#3 BEG in bt.mixal:2
+MIX >
+@end example
+
+Note that the executed instruction trace gives you the label of the
+executed line or, if it has no label, its address.
+@end deffn
+
+As you have probably observed, @code{mixvm} prints timing statistics
+when running programs. This behaviour can be controlled using the
+@code{stime} command (@pxref{Configuration commands}).
+
+@code{mixvm} is also able of evaluating w-expressions
+(@pxref{W-expressions}) using the following command:
+
+@deffn {debug command} weval WEXP
+Evaluates the given w-expression, @var{WEXP}. The w-expression can
+contain any currently defined symbol. For instance:
+
+@example
+MIX > psym START
++ 00 00 00 46 56 (0000003000)
+MIX > weval START(0:1),START(3:4)
++ 56 00 46 56 00 (0939716096)
+MIX >
+@end example
+@end deffn
+
+New symbols can be defined using the @code{ssym} command:
+
+@deffn {debug command} ssym SYM WEXP
+Defines the symbol named @var{SYM} with the value resulting from
+evaluating @var{WEXP}, an w-expression. The newly defined symbol can be
+used in subsequent @code{weval} commands, as part of the expression to
+be evaluated. E.g.,
+
+@example
+MIX > ssym S 2+23*START
++ 00 00 18 19 56 (0000075000)
+MIX > psym S
++ 00 00 18 19 56 (0000075000)
+MIX > weval S(3:4)
++ 00 00 19 56 00 (0000081408)
+MIX >
+@end example
+@end deffn
+
+Finally, if you want to discover which is the decimal value of a MIX
+word expressed as five bytes plus sign, you can use
+
+@deffn {debug command} w2d WORD
+Computes the decimal value of the given word. @var{WORD} must be
+expressed as a sign (+/-) followed by five space-delimited, two-digit
+decimal values representing the five bytes composing the word. The
+reverse operation (showing the word representation of a decimal value)
+can be accomplished with @code{weval}. For instance:
+
+@example
+MIX > w2d - 01 00 00 02 02
+-16777346
+MIX > weval -16777346
+- 01 00 00 02 02 (0016777346)
+MIX >
+@end example
+@end deffn
+
+@node State commands, Configuration commands, Debug commands, Commands
+@subsection State commands
+
+Inspection and modification of the virtual machine state (memory,
+registers, overflow toggle and comparison flag contents) is accomplished
+using the following commands:
+
+@deffn {state command} pstat
+This commands prints the current virtual machine state, which can be one
+of the following:
+@itemize @minus
+@item
+No program loaded
+@item
+Program successfully loaded
+@item
+Execution stopped (@code{next} executed)
+@item
+Execution stopped: breakpoint encountered
+@item
+Execution stopped: conditional breakpoint encountered
+@item
+Program successfully terminated
+@end itemize
+@end deffn
+
+@deffn {state command} pc
+Prints the current value of the program counter, which stores the
+address of the next instruction to be executed in a non-halted program.
+@end deffn
+
+@deffn {state command} sreg A | X | J | I[1-6] value
+@deffnx {state command} preg [A | X | J | I[1-6]]
+@deffnx {state command} pall
+@code{preg} prints the contents of a given MIX register. For instance,
+@w{@code{preg} @var{A}} will print the contents of the A-register. When
+invoked without arguments, all registers shall be printed:
+
+@example
+MIX > preg
+rA: - 00 00 00 00 35 (0000000035)
+rX: + 00 00 00 15 40 (0000001000)
+rJ: + 00 00 (0000)
+rI1: + 00 00 (0000) rI2: + 00 00 (0000)
+rI3: + 00 00 (0000) rI4: + 00 00 (0000)
+rI5: + 00 00 (0000) rI6: + 00 00 (0000)
+MIX >
+@end example
+
+As you can see in the above sample, the contents is printed as the sign
+plus the values of the MIX bytes stored in the register and, between
+parenthesis, the decimal representation of its module.
+
+@code{pall} prints the contents of all registers plus the comparison
+flag and overflow toggle.
+
+Finally, @code{sreg} Sets the contents of the given register to
+@var{value}, expressed as a decimal constant. If @var{value} exceeds the
+maximum value storable in the given register, @code{VALUE mod
+MAXIMU_VALUE} is stored, e.g.
+
+@example
+MIX > sreg I1 1000
+MIX > preg I1
+rI1: + 15 40 (1000)
+MIX > sreg I1 1000000
+MIX > preg I1
+rI1: + 09 00 (0576)
+MIX >
+@end example
+
+@end deffn
+
+
+@deffn {state command} pflags
+@deffnx {state command} scmp E | G | L
+@deffnx {state command} sover F | T
+@code{pflags} prints the value of the comparison flag and overflow
+toggle of the virtual machine, e.g.
+
+@example
+MIX > pflags
+Overflow: F
+Cmp: E
+MIX >
+@end example
+
+@noindent
+The values of the overflow toggle are either @var{F} (false) or @var{T}
+(true), and, for the comparison flag, @var{E}, @var{G}, @var{L} (equal,
+greater, lesser). @code{scmp} and @code{sover} are setters of the
+comparison flag and overflow toggle values.
+@end deffn
+
+@deffn {state command} pmem from[-to]
+@deffnx {state command} smem address value
+@code{pmem} prints the contents of memory cells in the address range
+@w{[@var{FROM}-@var{TO}]}. If the upper limit @var{to} is omitted, only
+the contents of the memory cell with address @var{FROM} is printed, as
+in
+
+@example
+MIX > pmem 3000
+3000: + 46 58 00 19 37 (0786957541)
+MIX >
+@end example
+
+The memory contents is displayed both as the set of five MIX bytes plus
+sign composing the stored MIX word and, between parenthesis, the decimal
+representation of the module of the stored value.
+
+@code{smem} sets the content of the memory cell with address
+@var{address} to @var{value}, expressed as a decimal constant.
+
+@end deffn
+
+@node Configuration commands, Scheme commands, State commands, Commands
+@subsection Configuration commands
+
+This section describes commands that allow you to configure the virtual
+machine behaviour. This configuration is stored in the @sc{mdk}
+directory @file{~/.mdk}.
+
+As you can see in their description, some commands print, as a side
+effect, informational messages to the standard output (e.g. @code{load}
+prints a message telling you the loaded program's start address): these
+messages can be enabled/disabled using @code{slog}:
+
+@deffn {config command} slog on|off
+Turns on/off the logging of informational messages. Note that error
+messages are always displayed, as well as state messages required using
+commands prefixed with @code{p} (@code{preg}, @code{pmem} and the like).
+@end deffn
+
+@deffn {config command} stime on|off
+@deffnx {config command} ptime
+The @code{stime} command (un)sets the printing of timing statistics, and
+@code{ptime} prints their current value:
+
+@example
+MIX > ptime
+Elapsed time: 10 /Total program time: 11 (Total uptime: 11)
+MIX >
+@end example
+@end deffn
+
+@deffn {config command} sedit TEMPLATE
+@deffnx {config command} pedit
+@code{sedit} sets the command to be used to edit MIXAL source files with
+the @code{edit} command. @var{TEMPLATE} must contain the control
+characters @code{%s} to mark the place where the source's file name will
+be inserted. For instance, if you type
+
+@example
+MIX > sedit emacsclient %s
+MIX >
+@end example
+
+issuing the @code{mixvm} command @w{@code{edit foo.mixal}} will invoke
+the operating system command @w{@code{emacsclient foo.mixal}}.
+
+@code{pedit} prints the current value of the edit command template.
+
+@end deffn
+
+@deffn {config command} sasm TEMPLATE
+@deffnx {config command} pasm
+@code{sasm} sets the command to be used to compile MIXAL source files with
+the @code{compile} command. @var{template} must contain the control
+characters @code{%s} to mark the place where the source's file name will
+be inserted. For instance, if you type
+
+@example
+MIX > sasm mixasm -l %s
+MIX >
+@end example
+
+issuing the @code{mixvm} command @w{@code{compile foo.mixal}} will invoke
+the operating system command @w{@code{mixasm -l foo.mixal}}.
+
+@code{pasm} prints the current value of the compile command template.
+
+@end deffn
+
+@deffn {config command} sddir DIRNAME
+@deffnx {config command} pddir
+MIX devices (@pxref{Devices}) are implemented as regular files stored,
+by default, inside @file{~/.mdk}. The @code{sddir} command lets you
+specify an alternative location for storing these device files, while
+@code{pddir} prints the current device directory.
+@end deffn
+
+Finally, you can change the default command prompt, @samp{MIX > },
+using the @code{prompt} command:
+
+@deffn {config command} prompt PROMPT
+Changes the command prompt to @var{prompt}. If you want to include
+white space(s) at the end of the new prompt, bracket @var{prompt} using
+double quotes (e.g., @code{prompt ">> "}).
+@end deffn
+
+@node Scheme commands, , Configuration commands, Commands
+@subsection Scheme commands
+
+If you have compiled @sc{mdk} with @code{libguile} support
+(@pxref{Special configure flags}), @code{mixvm} will start and
+initialise an embedded Guile Scheme interpret when it is invoked. That
+means that you have at your disposal, at @code{mixvm}'s command prompt,
+all the Scheme primitives described in @ref{Using mixguile} and
+@ref{mixguile}, as well as any other function or hook that you have
+defined in the initialisation file @file{~/.mdk/mixguile.scm}. To
+evaluate a Scheme function, simply type it at the @code{mixvm} command
+prompt (see @ref{Using Scheme in mixvm and gmixvm} for a
+sample). Compared to the @code{mixguile} program, this has only one
+limitation: the expressions used in @code{mixvm} cannot span more than
+one line. You can get over this inconvenience writing your multiline
+Scheme expressions in a file and loading it using the @code{scmf}
+command:
+
+@deffn {scheme command} scmf FILE_NAME
+Loads the given Scheme file and evaluates it using the embedded Guile
+interpreter.
+@end deffn
+
+
+@node Devices, , Commands, mixvm
+@section MIX block devices
+
+The MIX computer comes equipped with a set of block devices for
+input-output operations (@pxref{Input-output operators}). @code{mixvm}
+implements these block devices as disk files, with the exception of
+block device no. 19 (typewriter terminal) which is redirected to
+standard input/output. When you request an output operation on any other
+(output) device, a file named according to the following table will be
+created, and the specified MIX words will be
+written to the file in binary form (for binary devices) or in ASCII (for
+char devices). Files corresponding to input block devices should be
+created and filled beforehand to be used by the MIX virtual machine (for
+input-output devices this creation can be accomplished by a MIXAL
+program writing to the device the required data, or, if you prefer, with
+your favourite editor). The device files are stored, by default, in the
+directory @file{~/.mdk}; this location can be changed using the
+@code{mixvm} command @code{devdir} (@pxref{Configuration commands}).
+
+@multitable {the device name} { xx-xx } {filename[x-x].dev} {bin i/o/char }
+@item @emph{Device} @tab @emph{No.} @tab @emph{filename} @tab @emph{type and block size}
+@item Tape @tab 0-7 @tab @file{tape[0-7].dev} @tab bin i/o - 100 words
+@item Disks @tab 8-15 @tab @file{disk[0-7].dev} @tab bin i/o - 100 words
+@item Card reader @tab 16 @tab @file{cardrd.dev} @tab char in - 16 words
+@item Card writer @tab 17 @tab @file{cardwr.dev} @tab char out - 16 words
+@item Line printer @tab 18 @tab @file{printer.dev} @tab char out - 24 words
+@item Terminal @tab 19 @tab @code{stdin/stdout} @tab char i/o - 14 words
+@item Paper tape @tab 20 @tab @file{paper.dev} @tab char in - 14 words
+@end multitable
+
+Devices of type @i{char} are stored as ASCII files, using one line per
+block. For instance, since the card reader has blocks of size 16, that
+is, 80 characters, it will be emulated by an ASCII file consisting of
+lines with length 80. If the reader finds a line with less than the
+required number of characters, it pads the memory with zeroes (MIX
+character 'space') to complete the block size.
+
+Note that the virtual machine automatically converts between the MIX and
+ASCII character encodings, so that you can manipulate char device files
+with any ASCII editor. In addition, the reader is not case-sensitive,
+i.e., it automatically converts lowercase letters to their uppercase
+counterparts (since the MIX character set does not include the former).
+
+The typewriter (device no. 19) lets you use the standard input and
+output in your MIXAL programs. For instance, here is a simple 'echo'
+program:
+
+@example
+* simple echo program
+TERM EQU 19 the typewriter device
+BUF EQU 500 input buffer
+ ORIG 1000
+START IN BUF(TERM) read a block (70 chars)
+ OUT BUF(TERM) write the read chars
+ HLT
+ END START
+@end example
+
+@noindent Input lines longer than 70 characters (14 words) are trimmed.
+On the other hand, if you type less than a block of characters,
+whitespace (MIX character zero) is used as padding.
+
diff --git a/doc/mdk_tut.texi b/doc/mdk_tut.texi
new file mode 100644
index 0000000..0fabe89
--- /dev/null
+++ b/doc/mdk_tut.texi
@@ -0,0 +1,1319 @@
+@c -*-texinfo-*-
+@c This is part of the GNU MDK Reference Manual.
+@c Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+@c Free Software Foundation, Inc.
+@c See the file mdk.texi for copying conditions.
+
+@c $Id: mdk_tut.texi,v 1.14 2005/09/20 00:26:00 jao Exp $
+
+@node MIX and MIXAL tutorial, Getting started, Installing MDK, Top
+@comment node-name, next, previous, up
+@chapter MIX and MIXAL tutorial
+@cindex MIX
+@cindex MIXAL
+
+In the book series @cite{The Art of Computer Programming}, by D. Knuth,
+a virtual computer, the MIX, is used by the author (together with the
+set of binary instructions that the virtual CPU accepts) to illustrate
+the algorithms and skills that every serious programmer should
+master. Like any other real computer, there is a symbolic assembler
+language that can be used to program the MIX: the MIX assembly language,
+or MIXAL for short. In the following subsections you will find a tutorial
+on these topics, which will teach you the basics of the MIX architecture
+and how to program a MIX computer using MIXAL.
+
+@menu
+* The MIX computer:: Architecture and instruction set
+ of the MIX computer.
+* MIXAL:: The MIX assembly language.
+@end menu
+
+@node The MIX computer, MIXAL, MIX and MIXAL tutorial, MIX and MIXAL tutorial
+@comment node-name, next, previous, up
+@section The MIX computer
+
+In this section, you will find a description of the MIX computer,
+its components and instruction set.
+
+@menu
+* MIX architecture::
+* MIX instruction set::
+@end menu
+
+@node MIX architecture, MIX instruction set, The MIX computer, The MIX computer
+@comment node-name, next, previous, up
+@subsection MIX architecture
+@cindex byte
+@cindex MIX byte
+@cindex word
+@cindex MIX word
+@cindex MIX architecture
+@cindex MIX computer
+@cindex register
+@cindex MIX register
+@cindex field specification
+@cindex fspec
+@cindex instruction
+@cindex MIX instruction
+@cindex address
+@cindex memory cell
+@cindex cell
+@cindex memory
+@cindex index
+
+The basic information storage unit in the MIX computer is the
+@dfn{byte}, which stores positive values in the range 0-63 . Note that a
+MIX byte can be then represented as 6 bits, instead of the common 8 bits
+for a @emph{regular} byte. Unless otherwise stated, we shall use the
+word @dfn{byte} to refer to a MIX 6-bit byte.
+
+A MIX @dfn{word} is defined as a set of 5 bytes plus a sign. The bytes
+within a word are numbered from 1 to 5, being byte number one the most
+significant one. The sign is denoted by index 0. Graphically,
+
+@example
+ -----------------------------------------------
+| 0 | 1 | 2 | 3 | 4 | 5 |
+ -----------------------------------------------
+| +/- | byte | byte | byte | byte | byte |
+ -----------------------------------------------
+@end example
+@noindent
+Sample MIX words are @samp{- 12 00 11 01 63} and @samp{+ 12 11 34 43
+00}.
+
+You can refer to subfields within a word using a @dfn{field
+specification} or @dfn{fspec} of the form ``(@var{L}:@var{R})'', where
+@var{L} denotes the first byte, and @var{R} the last byte of the
+subfield.
+When @var{L} is zero, the subfield includes the word's
+sign. An fspec can also be represented as a single value @code{F}, given
+by @code{F = 8*L + R} (thus the fspec @samp{(1:3)}, denoting the first
+three bytes of a word, is represented by the integer 11).
+
+The MIX computer stores information in @dfn{registers}, that can store
+either a word or two bytes and sign (see below), and @dfn{memory cells},
+each one containing a word. Specifically, the MIX computer has 4000
+memory cells with addresses 0 to 3999 (i.e., two bytes are enough to
+address a memory cell) and the following registers:
+
+@cindex rA
+@cindex rX
+@cindex rJ
+@cindex rIn
+@cindex register
+
+@table @asis
+@item @code{rA}
+A register. General purpose register holding a word. Usually its
+contents serves as the operand of arithmetic and storing instructions.
+@item @code{rX}
+X register. General purpose register holding a word. Often it acts as an
+extension or a replacement of @samp{rA}.
+@item @code{rJ}
+J (jump) register. This register stores positive two-byte values,
+usually representing a jump address.
+@item @code{rI1}, @code{rI2}, @code{rI3}, @code{rI4}, @code{rI5}, @code{rI6}
+Index registers. These six registers can store a signed two-byte
+value. Their contents are used as indexing values for the computation of
+effective memory addresses.
+@end table
+
+@cindex @sc{ov}
+@cindex @sc{cm}
+@cindex @code{un}
+@cindex overflow toggle
+@cindex comparison indicator
+@cindex input-output devices
+@noindent
+In addition, the MIX computer contains:
+
+@itemize @minus
+@item
+An @dfn{overflow toggle} (a single bit with values @dfn{on} or
+@dfn{off}). In this manual, this toggle is denoted @sc{ov}.
+@item
+A @dfn{comparison indicator} (having three values: @dfn{EQUAL},
+@dfn{GREATER} or @dfn{LESS}). In this manual, this indicator is denoted
+@sc{cm}, and its possible values are abbreviated as @dfn{E}, @dfn{G} and
+@dfn{L}.
+@item
+Input-output block devices. Each device is labelled as @code{un}, where
+@code{n} runs from 0 to 20. In Knuth's definition, @code{u0} through
+@code{u7} are magnetic tape units, @code{u8} through @code{15} are disks
+and drums, @code{u16} is a card reader, @code{u17} is a card writer,
+@code{u18} is
+a line printer and, @code{u19} is a typewriter terminal, and @code{u20},
+a paper tape. Our implementation maps these devices to disk files,
+except for @code{u19}, which represents the standard output.
+@end itemize
+
+As noted above, the MIX computer communicates with the external world by
+a set of input-output devices which can be ``connected'' to it. The
+computer interchanges information using blocks of words whose length
+depends on the device at hand (@pxref{Devices}). These words are
+interpreted by the device either as binary information (for devices
+0-16), or as representing printable characters (devices 17-20). In the
+last case, each MIX byte is mapped onto a character according to the
+following table:
+
+@multitable {00} {C} {00} {C} {00} {C} {00} {C}
+@item 00 @tab @tab 01 @tab A @tab 02 @tab B @tab 03 @tab C
+@item 04 @tab D @tab 05 @tab E @tab 06 @tab F @tab 07 @tab G
+@item 08 @tab H @tab 09 @tab I @tab 10 @tab ~ @tab 11 @tab J
+@item 12 @tab K @tab 13 @tab L @tab 14 @tab M @tab 15 @tab N
+@item 16 @tab O @tab 17 @tab P @tab 18 @tab Q @tab 19 @tab R
+@item 20 @tab [ @tab 21 @tab # @tab 22 @tab S @tab 23 @tab T
+@item 24 @tab U @tab 25 @tab V @tab 26 @tab W @tab 27 @tab X
+@item 28 @tab Y @tab 29 @tab Z @tab 30 @tab 0 @tab 31 @tab 1
+@item 32 @tab 2 @tab 33 @tab 3 @tab 34 @tab 4 @tab 35 @tab 5
+@item 36 @tab 6 @tab 37 @tab 7 @tab 38 @tab 8 @tab 39 @tab 9
+@item 40 @tab . @tab 41 @tab , @tab 42 @tab ( @tab 43 @tab )
+@item 44 @tab + @tab 45 @tab - @tab 46 @tab * @tab 47 @tab /
+@item 48 @tab = @tab 49 @tab $ @tab 50 @tab < @tab 51 @tab >
+@item 52 @tab @@ @tab 53 @tab ; @tab 54 @tab : @tab 55 @tab '
+@end multitable
+@noindent
+The value 0 represents a whitespace. The characters @code{~}, @code{[} and
+@code{#} correspond to symbols not representable as ASCII characters
+(uppercase delta, sigma and gamma, respectively), and byte values 56-63
+have no associated character.
+
+Finally, the MIX computer features a virtual CPU which controls the
+above components, and which is able to execute a rich set of
+instructions (constituting its machine language, similar to those
+commonly found in real CPUs), including arithmetic, logical, storing,
+comparison and jump instructions. Being a typical von Neumann computer,
+the MIX CPU fetchs binary instructions from memory sequentially (unless
+a jump instruction is found), and stores the address of the next
+instruction to be executed in an internal register called @dfn{location
+counter} (also known as program counter in other architectures).
+
+The next section, @xref{MIX instruction set}, gives a complete description
+of the available MIX binary instructions.
+
+@node MIX instruction set, , MIX architecture, The MIX computer
+@comment node-name, next, previous, up
+@subsection MIX instruction set
+@cindex instruction set
+
+The following subsections fully describe the instruction set of the MIX
+computer. We begin with a description of the structure of binary
+instructions and the notation used to refer to their subfields. The
+remaininig subsections are devoted to describing the actual instructions
+available to the MIX programmer.
+
+@menu
+* Instruction structure::
+* Loading operators::
+* Storing operators::
+* Arithmetic operators::
+* Address transfer operators::
+* Comparison operators::
+* Jump operators::
+* Input-output operators::
+* Conversion operators::
+* Shift operators::
+* Miscellaneous operators::
+* Execution times::
+@end menu
+
+@node Instruction structure, Loading operators, MIX instruction set, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Instruction structure
+
+MIX @dfn{instructions} are codified as words with the following subfield
+structure:
+
+@multitable @columnfractions .15 .20 .65
+@item @emph{Subfield} @tab @emph{fspec} @tab @emph{Description}
+@item ADDRESS @tab (0:2)
+@tab The first two bytes plus sign are the @dfn{address} field. Combined
+with the INDEX field, denotes the memory address to be used by the
+instruction.
+@item INDEX @tab (3:3)
+@tab The third byte is the @dfn{index}, normally used for indexing the
+address@footnote{The actual memory address the instruction refers to, is
+obtained by adding to ADDRESS the value of the @samp{rI} register
+denoted by INDEX.}.
+@item MOD @tab (4:4)
+@tab Byte four is used either as an operation code modifier or as a field
+specification.
+@item OPCODE @tab (5:5)
+@tab The last (least significant) byte in the word denotes the operation
+code.
+@end multitable
+
+@noindent
+or, graphically,
+
+@example
+ ------------------------------------------------
+| 0 | 1 | 2 | 3 | 4 | 5 |
+ ------------------------------------------------
+| ADDRESS | INDEX | MOD | OPCODE |
+ ------------------------------------------------
+@end example
+
+For a given instruction, @samp{M} stands for
+the memory address obtained after indexing the ADDRESS subfield
+(using its INDEX byte), and @samp{V} is the contents of the
+subfield indicated by MOD of the memory cell with address @samp{M}. For
+instance, suppose that we have the following contents of MIX registers
+and memory cells:
+
+@example
+[rI2] = + 00 63
+[31] = - 10 11 00 11 22
+@end example
+@noindent
+where @samp{[n]} denotes the contents of the nth memory cell and
+@samp{[rI2]} the contents of register @samp{rI2}@footnote{In general,
+@samp{[X]} will denote the contents of entity @samp{X}; thus, by
+definition, @w{@samp{V = [M](MOD)}}.}. Let us consider the binary
+instruction @w{@samp{I = - 00 32 02 11 10}}. For this instruction we
+have:
+
+@example
+ADDRESS = - 00 32 = -32
+INDEX = 02 = 2
+MOD = 11 = (1:3)
+OPCODE = 10
+
+M = ADDRESS + [rI2] = -32 + 63 = 31
+V = [M](MOD) = (- 10 11 00 11 22)(1:3) = + 00 00 10 11 00
+@end example
+
+Note that, when computing @samp{V} using a word and an fspec, we apply
+a left padding to the bytes selected by @samp{MOD} to obtain a
+complete word as the result.
+
+In the following subsections, we will
+assign to each MIX instruction a mnemonic, or symbolic name. For
+instance, the mnemonic of @samp{OPCODE} 10 is @samp{LD2}. Thus we can
+rewrite the above instruction as
+
+@example
+LD2 -32,2(1:3)
+@end example
+@noindent
+or, for a generic instruction:
+
+@example
+MNEMONIC ADDRESS,INDEX(MOD)
+@end example
+@noindent
+Some instructions are identified by both the OPCODE and the MOD
+fields. In these cases, the MOD will not appear in the above symbolic
+representation. Also when ADDRESS or INDEX are zero, they can be
+omitted. Finally, MOD defaults to (0:5) (meaning the
+whole word).
+
+@node Loading operators, Storing operators, Instruction structure, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Loading operators
+@cindex loading operators
+
+The following instructions are used to load memory contents into a
+register.
+
+@ftable @code
+@item LDA
+Put in rA the contents of cell no. M.
+OPCODE = 8, MOD = fspec. @code{rA <- V}.
+@item LDX
+Put in rX the contents of cell no. M.
+OPCODE = 15, MOD = fspec. @code{rX <- V}.
+@item LDi
+Put in rIi the contents of cell no. M.
+OPCODE = 8 + i, MOD = fspec. @code{rIi <- V}.
+@item LDAN
+Put in rA the contents of cell no. M, with opposite sign.
+OPCODE = 16, MOD = fspec. @code{rA <- -V}.
+@item LDXN
+Put in rX the contents of cell no. M, with opposite sign.
+OPCODE = 23, MOD = fspec. @code{rX <- -V}.
+@item LDiN
+Put in rIi the contents of cell no. M, with opposite sign.
+OPCODE = 16 + i, MOD = fspec. @code{rIi <- -V}.
+@end ftable
+
+In all the above load instructions the @samp{MOD} field selects the
+bytes of the memory cell with address @samp{M} which are loaded into the
+requisite register (indicated by the @samp{OPCODE}). For instance, the
+word @w{@samp{+ 00 13 01 27 11}} represents the instruction
+
+@example
+LD3 13,1(3:3)
+ ^ ^ ^ ^
+ | | | |
+ | | | --- MOD = 27 = 3*8 + 3
+ | | --- INDEX = 1
+ | --- ADDRESS = 00 13
+ --- OPCODE = 11
+@end example
+Let us suppose that, prior to this instruction execution, the state of
+the MIX computer is the following:
+
+@example
+[rI1] = - 00 01
+[rI3] = + 24 12
+[12] = - 01 02 03 04 05
+@end example
+@noindent
+As, in this case, @w{@samp{M = 13 + [rI1] = 12}}, we have
+
+@example
+V = [M](3:3) = (- 01 02 03 04 05)(3:3)
+ = + 00 00 00 00 03
+@end example
+@noindent
+(note that the specified subfield is left-padded with null bytes to
+complete a word). Hence, the MIX state, after the instruction execution,
+will be
+
+@example
+[rI1] = - 00 01
+[rI3] = + 00 03
+[12] = - 01 02 03 04 05
+@end example
+
+To further illustrate loading operators, the following table shows the
+contents of @samp{rX} after different @samp{LDX} instructions:
+
+@table @samp
+@item LDX 12(0:0) [rX] = - 00 00 00 00 00
+@item LDX 12(0:1) [rX] = - 00 00 00 00 01
+@item LDX 12(3:5) [rX] = + 00 00 03 04 05
+@item LDX 12(3:4) [rX] = + 00 00 00 03 04
+@item LDX 12(0:5) [rX] = - 01 02 03 04 05
+@end table
+
+
+@node Storing operators, Arithmetic operators, Loading operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Storing operators
+@cindex storing operators
+
+The following instructions are the inverse of the load
+operations: they are used to store a subfield of a register
+into a memory location. Here, MOD represents the subfield of the memory
+cell that is to be overwritten with bytes from a register. These bytes
+are taken beginning by the rightmost side of the register.
+
+@ftable @code
+@item STA
+Store rA. OPCODE = 24, MOD = fspec. @code{V <- rA}.
+@item STX
+Store rX. OPCODE = 31, MOD = fspec. @code{V <- rX}.
+@item STi
+Store rIi. OPCODE = 24 + i, MOD = fspec. @code{V <- rIi}.
+@item STJ
+Store rJ. OPCODE = 32, MOD = fspec. @code{V <- rJ}.
+@item STZ
+Store zero. OPCODE = 33, MOD = fspec. @code{V <- 0}.
+@end ftable
+
+By way of example, consider the instruction @samp{STA 1200(2:3)}. It
+causes the MIX to fetch bytes no. 4 and 5 of register A and copy them to
+bytes 2 and 3 of memory cell no. 1200 (remember that, for these
+instructions, MOD specifies a subfield of @emph{the memory
+address}). The other bytes of the memory cell retain their
+values. Thus, if prior to the instruction execution we have
+
+@example
+[1200] = - 20 21 22 23 24
+[rA] = + 01 02 03 04 05
+@end example
+@noindent
+we will end up with
+
+@example
+[1200] = - 20 04 05 23 24
+[rA] = + 01 02 03 04 05
+@end example
+
+As a second example, @samp{ST2 1000(0)} will set the sign of
+@samp{[1000]} to that of @samp{[rI2]}.
+
+@node Arithmetic operators, Address transfer operators, Storing operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Arithmetic operators
+@cindex arithmetic operators
+
+The following instructions perform arithmetic operations between rA and
+rX register and memory contents.
+
+@ftable @code
+@item ADD
+Add and set OV if overflow. OPCODE = 1, MOD = fspec.
+@w{@code{rA <- rA +V}}.
+@item SUB
+Sub and set OV if overflow. OPCODE = 2, MOD = fspec.
+@w{@code{rA <- rA - V}}.
+@item MUL
+Multiply V times rA and store the 10-bytes product in rAX.
+OPCODE = 3, MOD = fspec. @w{@code{rAX <- rA x V}}.
+@item DIV
+rAX is considered a 10-bytes number, and it is divided by V.
+OPCODE = 4, MOD = fspec. @w{@code{rA <- rAX / V}}, @code{rX} <- reminder.
+@end ftable
+
+In all the above instructions, @samp{[rA]} is one of the operands
+of the binary arithmetic operation, the other being @samp{V} (that is,
+the specified subfield of the memory cell with address @samp{M}), padded
+with zero bytes on its left-side to complete a word. In multiplication
+and division, the register @samp{X} comes into play as a right-extension
+of the register @samp{A}, so that we are able to handle 10-byte numbers
+whose more significant bytes are those of @samp{rA} (the sign of this
+10-byte number is that of @samp{rA}: @samp{rX}'s sign is ignored).
+
+Addition and substraction of MIX words can give rise to overflows, since
+the result is stored in a register with room to only 5 bytes (plus
+sign). When this occurs, the operation result modulo @w{1,073,741,823}
+(the maximum value storable in a MIX word) is stored in @samp{rA}, and
+the overflow toggle is set to TRUE.
+
+@node Address transfer operators, Comparison operators, Arithmetic operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Address transfer operators
+@cindex address transfer operators
+
+In these instructions, @samp{M} (the address of the instruction after
+indexing) is used as a number instead of as the address of a memory
+cell. Consequently, @samp{M} can have any valid word value (i.e., it's
+not limited to the 0-3999 range of a memory address).
+
+@ftable @code
+@item ENTA
+Enter @samp{M} in [rA]. OPCODE = 48, MOD = 2. @code{rA <- M}.
+@item ENTX
+Enter @samp{M} in [rX]. OPCODE = 55, MOD = 2. @code{rX <- M}.
+@item ENTi
+Enter @samp{M} in [rIi]. OPCODE = 48 + i, MOD = 2. @code{rIi <- M}.
+@item ENNA
+Enter @samp{-M} in [rA]. OPCODE = 48, MOD = 3. @code{rA <- -M}.
+@item ENNX
+Enter @samp{-M} in [rX]. OPCODE = 55, MOD = 3. @code{rX <- -M}.
+@item ENNi
+Enter @samp{-M} in [rIi]. OPCODE = 48 + i, MOD = 3. @code{rIi <- -M}.
+@item INCA
+Increase [rA] by @samp{M}. OPCODE = 48, MOD = 0. @code{rA <- rA + M}.
+@item INCX
+Increase [rX] by @samp{M}. OPCODE = 55, MOD = 0. @code{rX <- rX + M}.
+@item INCi
+Increase [rIi] by @samp{M}. OPCODE = 48 + i, MOD = 0. @code{rIi <- rIi + M}.
+@item DECA
+Decrease [rA] by @samp{M}. OPCODE = 48, MOD = 1. @code{rA <- rA - M}.
+@item DECX
+Decrease [rX] by @samp{M}. OPCODE = 55, MOD = 1. @code{rX <- rX - M}.
+@item DECi
+Decrease [rIi] by @samp{M}. OPCODE = 48 + i, MaOD = 0. @code{rIi <- rIi - M}.
+@end ftable
+
+In the above instructions, the subfield @samp{ADDRESS} acts as an
+immediate (indexed) operand, and allow us to set directly the contents
+of the MIX registers without an indirection to the memory cells (in a
+real CPU this would mean that they are faster that the previously
+discussed instructions, whose operands are fetched from memory). So, if
+you want to store in @samp{rA} the value -2000 (- 00 00 00 31 16), you
+can use the binary instruction @w{+ 31 16 00 03 48}, or, symbolically,
+
+@example
+ENNA 2000
+@end example
+@noindent
+Used in conjuction with the store operations (@samp{STA}, @samp{STX},
+etc.), these instructions also allow you to set memory cells contents to
+concrete values.
+
+Note that in these address transfer operators, the @samp{MOD} field is
+not a subfield specificator, but serves to define (together with
+@samp{OPCODE}) the concrete operation to be performed.
+
+@node Comparison operators, Jump operators, Address transfer operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Comparison operators
+@cindex comparison operators
+
+So far, we have learned how to move values around between the MIX
+registers and its memory cells, and also how to perform arithmetic
+operations using these values. But, in order to write non-trivial
+programs, other functionalities are needed. One of the most common is
+the ability to compare two values, which, combined with jumps, will
+allow the execution of conditional statements.
+The following instructions compare the value of a register with @samp{V}, and
+set the @sc{cm} indicator to the result of the comparison (i.e. to
+@samp{E}, @samp{G} or @samp{L}, equal, greater or lesser respectively).
+
+@ftable @code
+@item CMPA
+Compare [rA] with V. OPCODE = 56, MOD = fspec.
+@item CMPX
+Compare [rX] with V. OPCODE = 63, MOD = fspec.
+@item CMPi
+Compare [rIi] with V. OPCODE = 56 + i, MOD = fspec.
+@end ftable
+
+As explained above, these instructions modify the value of the MIX
+comparison indicator; but maybe you are asking yourself how do you use
+this value: enter jump operators, in the next subsection.
+
+@node Jump operators, Input-output operators, Comparison operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Jump operators
+@cindex jump operators
+
+The MIX computer has an internal register, called the @dfn{location
+counter}, which stores the address of the next instruction to be fetched
+and executed by the virtual CPU. You cannot directly modify the contents
+of this internal register with a load instruction: after fetching the
+current instruction from memory, it is automatically increased in one
+unit by the MIX. However, there is a set of instructions (which we call
+jump instructions) which can alter the contents of the location counter
+provided some condition is met. When this occurs, the value of the next
+instruction address that would have been fetched in the absence of the
+jump is stored in @samp{rJ} (except for @code{JSJ}), and the location
+counter is set to the value of @samp{M} (so that the next instruction is
+fetched from this new address). Later on, you can return to the point
+when the jump occurred reading the address stored in @samp{rJ}.
+
+The MIX computer provides the following jump instructions:
+With these instructions you force a jump to the specified address. Use
+@samp{JSJ} if you do not care about the return address.
+
+@ftable @code
+@item JMP
+Unconditional jump. OPCODE = 39, MOD = 0.
+@item JSJ
+Unconditional jump, but rJ is not modified. OPCODE = 39, MOD = 1.
+@end ftable
+
+These instructions check the overflow toggle to decide whether to jump
+or not.
+
+@ftable @code
+@item JOV
+Jump if OV is set (and turn it off). OPCODE = 39, MOD = 2.
+@item JNOV
+Jump if OV is not set (and turn it off). OPCODE = 39, MOD = 3.
+@end ftable
+
+In the following instructions, the jump is conditioned to the contents of the
+comparison flag:
+
+@ftable @code
+@item JL
+Jump if @w{@code{[CM] = L}}. OPCODE = 39, MOD = 4.
+@itemx JE
+Jump if @w{@code{[CM] = E}}. OPCODE = 39, MOD = 5.
+@itemx JG
+Jump if @w{@code{[CM] = G}}. OPCODE = 39, MOD = 6.
+@itemx JGE
+Jump if @code{[CM]} does not equal @code{L}. OPCODE = 39, MOD = 7.
+@itemx JNE
+Jump if @code{[CM]} does not equal @code{E}. OPCODE = 39, MOD = 8.
+@itemx JLE
+Jump if @code{[CM]} does not equal @code{G}. OPCODE = 39, MOD = 9.
+@end ftable
+
+You can also jump conditioned to the value stored in the MIX registers,
+using the following instructions:
+
+@ftable @code
+@item JAN
+@itemx JAZ
+@itemx JAP
+@itemx JANN
+@itemx JANZ
+@itemx JANP
+Jump if the content of rA is, respectively, negative, zero, positive,
+non-negative, non-zero or non-positive.
+OPCODE = 40, MOD = 0, 1, 2, 3, 4, 5.
+@item JXN
+@itemx JXZ
+@itemx JXP
+@itemx JXNN
+@itemx JXNZ
+@itemx JXNP
+Jump if the content of rX is, respectively, negative, zero, positive,
+non-negative, non-zero or non-positive.
+OPCODE = 47, MOD = 0, 1, 2, 3, 4, 5.
+@item JiN
+@itemx JiZ
+@itemx JiP
+@itemx JiNN
+@itemx JiNZ
+@itemx JiNP
+Jump if the content of rIi is, respectively, negative, zero, positive,
+non-negative, non-zero or non-positive.
+OPCODE = 40 + i, MOD = 0, 1, 2, 3, 4, 5.
+@end ftable
+
+
+@node Input-output operators, Conversion operators, Jump operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Input-output operators
+@cindex input-output operators
+
+As explained in previous sections (@pxref{MIX architecture}), the MIX
+computer can interact with a series of block devices. To that end, you
+have at your disposal the following instructions:
+
+@ftable @code
+@item IN
+Transfer a block of words from the specified unit to memory, starting at
+address M.
+OPCODE = 36, MOD = I/O unit.
+@item OUT
+Transfer a block of words from memory (starting at address M) to the
+specified unit.
+OPCODE = 37, MOD = I/O unit.
+@item IOC
+Perfom a control operation (given by M) on the specified unit.
+OPCODE = 35, MOD = I/O unit.
+@item JRED
+Jump to M if the specified unit is ready.
+OPCODE = 38, MOD = I/O unit.
+@item JBUS
+Jump to M if the specified unit is busy.
+OPCODE = 34, MOD = I/O unit.
+@end ftable
+@noindent
+In all the above instructions, the @samp{MOD} subfile must be in the
+range 0-20, since it denotes the operation's target device. The
+@samp{IOC} instruction only makes sense for tape devices (@samp{MOD} =
+0-7 or 20): it shifts the read/write pointer by the number of words
+given by @samp{M} (if it equals zero, the tape is rewound)@footnote{In
+Knuth's original definition, there are other control operations
+available, but they do not make sense when implementing the block
+devices as disk files (as we do in @sc{mdk} simulator). For the same
+reason, @sc{mdk} devices are always ready, since all input-output
+operations are performed using synchronous system calls.}.
+
+
+@node Conversion operators, Shift operators, Input-output operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Conversion operators
+@cindex conversion operators
+
+The following instructions convert between numerical values and their
+character representations.
+
+@ftable @code
+@item NUM
+Convert rAX, assumed to contain a character representation of a number,
+to its numerical value and store it in rA.
+OPCODE = 5, MOD = 0.
+@item CHAR
+Convert the number stored in rA to a character representation and store
+it in rAX.
+OPCODE = 5, MOD = 1.
+@end ftable
+@noindent
+Digits are represented in MIX by the range of values 30-39 (digits
+0-9). Thus, if the contents of @samp{rA} and @samp{rX} are, for instance,
+
+@example
+[rA] = + 30 30 31 32 33
+[rX] = + 31 35 39 30 34
+@end example
+@noindent
+the represented number is 0012315904, and @samp{NUM} will store this
+value in @samp{rA} (i.e., we end up with @samp{[rA]} = @w{+ 0 46 62 52
+0} = 12315904).
+
+If any byte in @samp{rA} or @samp{rB} does not belong to the range
+30-39, it is interpreted by @samp{NUM} as the digit obtained by taking
+its value modulo 10. E.g. values 0, 10, 20, 30, 40, 50, 60 all represent the
+digit 0; 2, 12, 22, etc. represent the digit 2, and so on. For
+instance, the number 0012315904 mentioned above could also be
+represented as
+
+@example
+[rA] = + 10 40 31 52 23
+[rX] = + 11 35 49 20 54
+@end example
+
+@samp{CHAR} performs the inverse operation, using only the values 30
+to 39 for representing digits 0-9.
+
+@node Shift operators, Miscellaneous operators, Conversion operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Shift operators
+@cindex shift
+@cindex shift operators
+
+The following instructions perform byte-wise shifts of the contents of
+@samp{rA} and @samp{rX}.
+
+@ftable @code
+@item SLA
+@itemx SRA
+@itemx SLAX
+@itemx SRAX
+@itemx SLC
+@itemx SRC
+Shift rA or rAX left, right, or rAX circularly (see example below)
+left or right. M specifies the number of bytes to be shifted.
+OPCODE = 6, MOD = 0, 1, 2, 3, 4, 5.
+@end ftable
+@noindent
+If we begin with, say, @samp{[rA]} = @w{- 01 02 03 04 05}, we would
+have the following modifications to @samp{rA} contents when performing
+the instructions on the left column:
+
+@multitable {SLA 00} {[rA] = - 00 00 00 00 00}
+@item SLA 2 @tab [rA] = - 03 04 05 00 00
+@item SLA 6 @tab [rA] = - 00 00 00 00 00
+@item SRA 1 @tab [rA] = - 00 01 02 03 04
+@end multitable
+@noindent
+Note that the sign is unaffected by shift operations. On the other
+hand, @samp{SLC}, @samp{SRC}, @samp{SLAX} and @samp{SRAX} treat
+@samp{rA} and @samp{rX} as a single 10-bytes register (ignoring again
+the signs). For instance, if we begin with @samp{[rA]} = @w{+ 01 02 03
+04 05} and @samp{[rX]} = @w{- 06 07 08 09 10}, we would have:
+
+@multitable {SLC 00} {[rA] = - 00 00 00 00 00} {[rA] = - 00 00 00 00 00}
+@item SLC 3 @tab [rA] = + 04 05 06 07 08 @tab [rX] = - 09 10 01 02 03
+@item SLAX 3 @tab [rA] = + 04 05 06 07 08 @tab [rX] = - 09 10 00 00 00
+@item SRC 4 @tab [rA] = + 07 08 09 10 01 @tab [rX] = - 02 03 04 05 06
+@item SRAX 4 @tab [rA] = + 00 00 00 00 01 @tab [rX] = - 02 03 04 05 06
+@end multitable
+
+@node Miscellaneous operators, Execution times, Shift operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Miscellaneous operators
+@cindex miscellaneous operators
+
+Finally, we list in the following table three miscellaneous MIX
+instructions which do not fit in any of the previous subsections:
+
+@ftable @code
+@item MOVE
+Move MOD words from M to the location stored in rI1.
+OPCODE = 7, MOD = no. of words.
+@item NOP
+No operation. OPCODE = 0, MOD = 0.
+@item HLT
+Halt. Stops instruction fetching. OPCODE = 5, MOD = 2.
+@end ftable
+@noindent
+The only effect of executing @samp{NOP} is increasing the location
+counter, while @samp{HLT} usually marks program termination.
+
+@node Execution times, , Miscellaneous operators, MIX instruction set
+@comment node-name, next, previous, up
+@subsubsection Execution times
+
+@cindex exection time
+@cindex time
+
+When writing MIXAL programs (or any kind of programs, for that
+matter), whe shall often be interested in their execution
+time. Loosely speaking, we will interested in the answer to the
+question: how long takes a program to execute? Of course, this
+execution time will be a function of the input size, and the answer to
+our question is commonly given as the asymptotic behaviour as a
+function of the input size. At any rate, to compute this asymptotic
+behaviour, we need a measure of how long execution of a single
+instruction takes in our (virtual) CPU. Therefore, each MIX
+instruction will have an associated execution time, given in arbitrary
+units (in a real computer, the value of this unit will depend on the
+hardware configuration). When our MIX virtual machine executes
+programs, it will (optionally) give you the value of their execution
+time based upon the execution time of each single instruction.
+
+In the following table, the execution times (in the above mentioned
+arbitrary units) of the MIX instructions are given.
+
+@multitable {INSSSS} {01} {INSSSS} {01} {INSSSS} {01} {INSSSS} {01}
+@item @code{NOP} @tab 1 @tab @code{ADD} @tab 2 @tab @code{SUB}
+@tab 2 @tab @code{MUL} @tab 10
+@item @code{DIV} @tab 12 @tab @code{NUM} @tab 10 @tab @code{CHAR}
+@tab 10 @tab @code{HLT} @tab 10
+@item @code{SLx} @tab 2 @tab @code{SRx} @tab 2 @tab @code{LDx}
+@tab 2 @tab @code{STx} @tab 2
+@item @code{JBUS} @tab 1 @tab @code{IOC} @tab 1 @tab @code{IN}
+@tab 1@tab @code{OUT} @tab 1
+@item @code{JRED} @tab 1 @tab @code{Jx} @tab 1 @tab @code{INCx}
+@tab 1 @tab @code{DECx} @tab 1
+@item @code{ENTx} @tab 1 @tab @code{ENNx} @tab 1 @tab @code{CMPx}
+@tab 1 @tab @code{MOVE} @tab 1+2F
+@end multitable
+
+In the above table, 'F' stands for the number of blocks to be moved
+(given by the @code{FSPEC} subfield of the instruction); @code{SLx} and
+@code{SRx} are a short cut for the byte-shifting operations; @code{LDx}
+denote all the loading operations; @code{STx} are the storing
+operations; @code{Jx} stands for all the jump operations, and so on with
+the rest of abbreviations.
+
+@node MIXAL, , The MIX computer, MIX and MIXAL tutorial
+@comment node-name, next, previous, up
+@section MIXAL
+@cindex MIXAL
+@cindex MIX assembly language
+@cindex assembly
+
+In the previous sections we have listed all the available MIX binary
+instructions. As we have shown, each instruction is represented by a
+word which is fetched from memory and executed by the MIX virtual
+CPU. As is the case with real computers, the MIX knows how to decode
+instructions in binary format (the so--called machine language), but a
+human programmer would have a tough time if she were to write her
+programs in machine language. Fortunately, the MIX computer can be
+programmed using an assembly language, MIXAL, which provides a symbolic
+way of writing the binary instructions understood by the imaginary MIX
+computer. If you have used assembler languages before, you will find
+MIXAL a very familiar language. MIXAL source files are translated
+to machine language by a MIX assembler, which produces a binary file (the
+actual MIX program) which can be directly loaded into the MIX memory and
+subsequently executed.
+
+In this section, we describe MIXAL, the MIX assembly language. The
+implementation of the MIX assembler program and MIX computer simulator
+provided by @sc{mdk} are described later on (@pxref{Getting started}).
+
+@menu
+* Basic structure:: Writing basic MIXAL programs.
+* MIXAL directives:: Assembler directives.
+* Expressions:: Evaluation of expressions.
+* W-expressions:: Evaluation of w-expressions.
+* Local symbols:: Special symbol table entries.
+* Literal constants:: Specifying an immediate operand.
+@end menu
+
+@node Basic structure, MIXAL directives, MIXAL, MIXAL
+@comment node-name, next, previous, up
+@subsection Basic program structure
+
+The MIX assembler reads MIXAL files line by line, producing, when
+required, a binary instruction, which is associated to a predefined
+memory address. To keep track of the current address, the assembler
+maintains an internal location counter which is incremented each time an
+instruction is compiled. In addition to MIX instructions, you can
+include in MIXAL file assembly directives (or pseudoinstructions)
+addressed at the assembler itself (for instance, telling it where the
+program starts and ends, or to reposition the location counter; see below).
+
+MIX instructions and assembler directives@footnote{We shall call them,
+collectively, MIXAL instructions.} are written in MIXAL (one per
+source file line) according to the following pattern:
+
+@example
+[LABEL] MNEMONIC [OPERAND] [COMMENT]
+@end example
+
+@noindent
+where @samp{OPERAND} is of the form
+
+@example
+[ADDRESS][,INDEX][(MOD)]
+@end example
+
+Items between square brackets are optional, and
+
+@table @code
+@item LABEL
+is an alphanumeric identifier (a @dfn{symbol}) which gets the current
+value of the location counter, and can be used in subsequent
+expressions,
+@item MNEMONIC
+is a literal denoting the operation code of the instruction
+(e.g. @code{LDA}, @code{STA}; see @pxref{MIX instruction set}) or an
+assembly pseudoinstruction (e.g. @code{ORG}, @code{EQU}),
+@item ADDRESS
+is an expression evaluating to the address subfield of the instruction,
+@item INDEX
+is an expression evaluating to the index subfield of the instruction, which
+defaults to 0 (i.e., no use of indexing) and can only be used when
+@code{ADDRESS} is present,
+@item MOD
+is an expression evaluating to the mod subfield of the instruction. Its
+default value, when omitted, depends on @code{OPCODE},
+@item COMMENT
+any number of spaces after the operand mark the beggining of a comment,
+i.e. any text separated by white space from the operand is ignored by
+the assembler (note that spaces are not allowed within the
+@samp{OPERAND} field).
+@end table
+
+Note that spaces are @emph{not} allowed between the @code{ADDRESS},
+@code{INDEX} and @code{MOD} fields if they are present. White space is
+used to separate the label, operation code and operand parts of the
+instruction@footnote{In fact, Knuth's definition of MIXAL restricts the
+column number at which each of these instruction parts must start. The
+MIXAL assembler included in @sc{mdk}, @code{mixasm}, does not impose
+such restriction.}.
+
+We have already listed the mnemonics associated will each MIX
+instructions; sample MIXAL instructions representing MIX instructions
+are:
+@example
+HERE LDA 2000 HERE represents the current location counter
+ LDX HERE,2(1:3) this is a comment
+ JMP 1234
+@end example
+
+@node MIXAL directives, Expressions, Basic structure, MIXAL
+@comment node-name, next, previous, up
+@subsection MIXAL directives
+
+MIXAL instructions can be either one of the MIX machine instructions
+(@pxref{MIX instruction set}) or one of the following assembly
+pseudoinstructions:
+
+@ftable @code
+@item ORIG
+Sets the value of the memory address to which following instructions
+will be allocated after compilation.
+@item EQU
+Used to define a symbol's value, e.g. @w{@code{SYM EQU 2*200/3}}.
+@item CON
+The value of the given expression is copied directly into the current
+memory address.
+@item ALF
+Takes as operand five characters, constituting the five bytes of a word
+which is copied directly into the current memory address.
+@item END
+Marks the end of the program. Its operand gives the start address for
+program execution.
+@end ftable
+
+The operand of @code{ORIG}, @code{EQU}, @code{CON} and @code{END} can be
+any expression evaluating to a constant MIX word, i.e., either a simple
+MIXAL expression (composed of numbers, symbols and binary operators,
+@pxref{Expressions}) or a w-expression (@pxref{W-expressions}).
+
+All MIXAL programs must contain an @code{END} directive, with a twofold
+end: first, it marks the end of the assembler job, and, in the second
+place, its (mandatory) operand indicates the start address for the
+compiled program (that is, the address at which the virtual MIX machine
+must begin fetching instructions after loading the program). It is also
+very common (although not mandatory) to include at least an @code{ORIG}
+directive to mark the initial value of the assembler's location counter
+(remember that it stores the address associated with each compiled MIX
+instruction). Thus, a minimal MIXAL program would be
+
+@example
+ ORIG 2000 set the initial compilation adress
+ NOP this instruction will be loaded at adress 2000
+ HLT and this one at address 2001
+ END 2000 end of program; start at address 2000
+this line is not parsed by the assembler
+@end example
+@noindent
+The assembler will generate two binary instructions (@code{NOP} (@w{+ 00
+00 00 00 00}) and @code{HLT} (+ 00 00 02 05)), which will be loaded at
+addresses 2000 and 2001. Execution of the program will begin at address
+2000. Every MIXAL program should also include a @code{HLT} instruction,
+which will mark the end of program execution (but not of program
+compilation).
+
+The @code{EQU} directive allows the definition of symbolic names for
+specific values. For instance, we could rewrite the above program as
+follows:
+
+@example
+START EQU 2000
+ ORIG START
+ NOP
+ HLT
+ END START
+@end example
+@noindent
+which would give rise to the same compiled code. Symbolic constants (or
+symbols, for short) can also be implicitly defined placing them in the
+@code{LABEL} field of a MIXAL instruction: in this case, the assembler
+assigns to the symbol the value of the location counter before compiling
+the line. Hence, a third way of writing our trivial program is
+
+@example
+ ORIG 2000
+START NOP
+ HLT
+ END START
+@end example
+
+The @code{CON} directive allows you to directly specify the contents of
+the memory address pointed by the location counter. For instance, when
+the assembler encounters the following code snippet
+
+@example
+ ORIG 1150
+ CON -1823473
+@end example
+@noindent
+it will assign to the memory cell number 1150 the contents @w{- 00 06 61
+11 49} (which corresponds to the decimal value -1823473).
+
+Finally, the @code{ALF} directive let's you specify the memory contents
+as a set of five (optionally quoted) characters, which are translated by
+the assembler to their byte values, conforming in that way the binary
+word that is to be stored in the corresponding memory cell. This
+directive comes in handy when you need to store printable messages in a
+memory address, as in the following example @footnote{In the original
+MIXAL definition, the @code{ALF} argument is not quoted. You can write
+the operand (as the @code{ADDRESS} field) without quotes, but, in this
+case, you must follow the alignment rules of the original MIXAL
+definition (namely, the @code{ADDRESS} must start at column 17).}:
+
+@example
+ OUT MSG MSG is not yet defined here (future reference)
+MSG ALF "THIS " MSG gets defined here
+ ALF "IS A "
+ ALF "MESSA"
+ ALF "GE. "
+@end example
+@noindent
+The above snippet also shows the use of a @dfn{future reference}, that
+is, the usage of a symbol (@code{MSG} in the example) prior of its actual
+definition. The MIXAL assembler is able to handle future references
+subject to some limitations which are described in the following section
+(@pxref{Expressions}).
+
+@cindex comments
+
+Any line starting with an asterisk is treated as a comment and ignored
+by the assembler.
+
+@example
+* This is a comment: this line is ignored.
+ * This line is an error: * must be in column 1.
+@end example
+
+As noted in the previous section, comments can also be located after the
+@code{OPERAND} field of an instruction, separated from it by white
+space, as in
+
+@example
+LABEL LDA 100 This is also a comment
+@end example
+
+@node Expressions, W-expressions, MIXAL directives, MIXAL
+@comment node-name, next, previous, up
+@subsection Expressions
+@cindex operator
+@cindex binary operator
+@cindex unary operator
+The @code{ADDRESS}, @code{INDEX} and @code{MOD} fields of a MIXAL
+instruction can be expressions, formed by numbers, identifiers and
+binary operators (@code{+ - * / // :}). @code{+} and @code{-} can also
+be used as unary operators. Operator precedence is from left to right:
+there is no other operator precedence rule, and parentheses cannot be
+used for grouping. A stand-alone asterisk denotes the current memory
+location; thus, for instance,
+
+@example
+ 4+2**
+@end example
+
+@noindent
+evaluates to 6 (4 plus 2) times the current memory location. White space
+is not allowed within expressions.
+
+The special binary operator @code{:} has the same meaning as in fspecs,
+i.e.,
+
+@example
+A:B = 8*A + B
+@end example
+@noindent
+while @code{A//B} stands for the quotient of the ten-byte number @w{@code{A} 00
+00 00 00 00} (that is, A right-padded with 5 null bytes or, what amounts
+to the same, multiplied by 64 to the fifth power) divided by
+@code{B}. Sample expressions are:
+
+@example
+18-8*3 = 30
+14/3 = 4
+1+3:11 = 4:11 = 43
+1//64 = (01 00 00 00 00 00)/(00 00 00 01 00) = (01 00 00 00 00)
+@end example
+@noindent
+Note that all MIXAL expressions evaluate to a MIX word (by definition).
+
+All symbols appearing within an expression must be previously defined. Future
+references are only allowed when appearing standalone (or modified by
+an unary operator) in the @code{ADDRESS} part of a MIXAL instruction,
+e.g.
+
+@example
+* OK: stand alone future reference
+ STA -S1(1:5)
+* ERROR: future reference in expression
+ LDX 2-S1
+S1 LD1 2000
+@end example
+
+@node W-expressions, Local symbols, Expressions, MIXAL
+@comment node-name, next, previous, up
+@subsection W-expressions
+@cindex w-expressions
+
+Besides expressions, as described above (@pxref{Expressions}), the MIXAL
+assembler is able to handle the so called @dfn{w-expressions} as the
+operands of the directives @code{ORIG}, @code{EQU}, @code{CON} and
+@code{END} (@pxref{MIXAL directives}). The general form of a
+w-expression is the following:
+
+@example
+ WEXP = EXP[(EXP)][,WEXP]
+@end example
+@noindent
+where @code{EXP} stands for an expression and square brackets denote
+optional items. Thus, a w-expression is made by an expression, followed
+by an optional expression between parenthesis, followed by any number
+of similar constructs separated by commas. Sample w-expressions are:
+
+@example
+2000
+235(3)
+S1+3(S2),3000
+S1,S2(3:5),23
+@end example
+
+W-expressions are evaluated from left to right as follows:
+
+@itemize
+@item
+Start with an accumulated result @samp{w} equal to 0.
+@item
+Take the first expression of the comma-separated list and evaluate
+it. For instance, if the w-expression is @samp{S1+2(2:4),2000(S2)}, we
+evaluate first @samp{S1+2}; let's suppose that @samp{S1} equals
+265230: then @samp{S1+2 = 265232 = + 00 01 00 48 16}.
+@item
+Evaluate the expression within parenthesis, reducing it to an f-spec
+of the form @samp{L:R}. In our previous example, the expression
+between parenthesis already has the desired form: 2:4.
+@item
+Substitute the bytes of the accumulated result @samp{w} designated by
+the f-spec using those of the previous expression value. In our sample,
+@samp{w = + 00 00 00 00 00}, and we must substitute bytes 2, 3 and 4 of
+@samp{w} using values from 265232. We need 3 bytes, and we take the
+least significant ones: 00, 48, and 16, and insert them in positions
+2, 3 and 4 of @samp{w}, obtaining @samp{w = + 00 00 48 16 00}.
+@item
+Repeat this operation with the remaining terms, acting on the new
+value of @samp{w}. In our example, if, say, @samp{S2 = 1:1}, we must
+substitute the first byte of @samp{w} using one byte (the least
+significant) from 2000, that is, 16 (since 2000 = + 00 00 00 31 16)
+and, therefore, we obtain @samp{w = + 16 00 48 16 00}; summing up, we
+have obtained @samp{265232(1:4),2000(1:1) = + 16 00 48 16 00 =
+268633088}.
+@end itemize
+
+As a second example, in the w-expression
+@example
+1(1:2),66(4:5)
+@end example
+@noindent
+we first take two bytes from 1 (00 and 01) and store them as bytes 1 and
+2 of the result (obtaining @w{@samp{+ 00 01 00 00 00}}) and, afterwards,
+take two bytes from 66 (01 and 02) and store them as bytes 4 and 5 of
+the result, obtaining @w{@samp{+ 00 01 00 01 02}} (262210). The process
+is repeated for each new comma-separated example. For instance:
+
+@example
+1(1:1),2(2:2),3(3:3),4(4:4) = 01 02 03 04 00
+@end example
+
+As stated before, w-expressions can only appear as the operands of MIXAL
+directives taking a constant value (@code{ORIG}, @code{EQU}, @code{CON}
+and @code{END}). Future references are @emph{not} allowed within
+w-expressions (i.e., all symbols appearing in a w-expression must be
+defined before it is used).
+
+@node Local symbols, Literal constants, W-expressions, MIXAL
+@comment node-name, next, previous, up
+@subsection Local symbols
+@cindex local symbols
+
+Besides user defined symbols, MIXAL programmers can use the so called
+@dfn{local symbols}, which are symbols of the form @code{[1-9][HBF]}. A
+local symbol @code{nB} refers to the address of the last previous
+occurrence of @code{nH} as a label, while @code{nF} refers to the next
+@code{nH} occurrence. Unlike user defined symbols, @code{nH} can appear
+multiple times in the @code{LABEL} part of different MIXAL
+instructions. The following code shows an instance of local symbols'
+usage:
+
+@example
+* line 1
+1H LDA 100
+* line 2: 1B refers to address of line 1, 3F refers to address of line 4
+ STA 3F,2(1B//2)
+* line 3: redefinition of 1H
+1H STZ
+* line 4: 1B refers to address of line 3
+3H JMP 1B
+@end example
+
+Note that a @code{B} local symbol never refers to a definition in its
+own line, that is, in the following program:
+
+@example
+ ORIG 1999
+ST NOP
+3H EQU 69
+3H ENTA 3B local symbol 3B refers to 3H in previous line
+ HLT
+ END ST
+@end example
+@noindent
+the contents of @samp{rA} is set to 69 and @emph{not} to 2001. An
+specially tricky case occurs when using local symbols in conjunction
+with @code{ORIG} pseudoinstructions. To wit@footnote{The author wants to
+thank Philip E. King for pointing these two special cases of local
+symbol usage to him.},
+
+@example
+ ORIG 1999
+ST NOP
+3H CON 10
+ ENT1 *
+ LDA 3B
+** rI1 is 2001, rA is 10. So far so good!
+3H ORIG 3B+1000
+** at this point 3H equals 2003
+** and the location counter equals 3000.
+ ENT2 *
+ LDX 3B
+** rI2 contains 3000, rX contains 2003.
+ HLT
+ END ST
+@end example
+
+@node Literal constants, , Local symbols, MIXAL
+@comment node-name, next, previous, up
+@subsection Literal constants
+@cindex literal constants
+
+MIXAL allows the introduction of @dfn{literal constants}, which are
+automatically stored in memory addresses after the end of the program by
+the assembler. Literal constants are denoted as @code{=wexp=}, where
+@code{wexp} is a w-expression (@pxref{W-expressions}). For instance, the
+code
+
+@example
+L EQU 5
+ LDA =20-L=
+@end example
+
+causes the assembler to add after the program's end an instruction
+with contents 15 (@samp{20-L}), and to assemble the above code as the
+instruction @w{@code{ LDA a}}, where @code{a} stands for the address
+in which the value 15 is stored. In other words, the compiled code is
+equivalent to the following:
+
+@example
+L EQU 5
+ LDA a
+@dots{}
+a CON 20-L
+ END start
+@end example
+
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..db3f35f
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,17 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2001 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+EXTRA_DIST = getopt_long.c getopt.h
+
+noinst_LIBRARIES = libreplace.a
+libreplace_a_SOURCES =
+libreplace_a_LIBADD = @LIBOBJS@ \ No newline at end of file
diff --git a/lib/getopt.h b/lib/getopt.h
new file mode 100644
index 0000000..4ac33b7
--- /dev/null
+++ b/lib/getopt.h
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+ Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/lib/getopt_long.c b/lib/getopt_long.c
new file mode 100644
index 0000000..8abb3ac
--- /dev/null
+++ b/lib/getopt_long.c
@@ -0,0 +1,1086 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
+ Free Software Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+ When compiling libc, the _ macro is predefined. */
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+ is valid for the getopt call we must make sure that the ARGV passed
+ to getopt is that one passed to the process. */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+ /* XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+ original_argc = argc;
+ original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#ifdef _LIBC
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#ifdef _LIBC
+ if (posixly_correct == NULL
+ && argc == original_argc && argv == original_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#ifdef _LIBC
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+
+
+#endif /* TEST */
diff --git a/mdk.spec b/mdk.spec
new file mode 100644
index 0000000..356ddb5
--- /dev/null
+++ b/mdk.spec
@@ -0,0 +1,142 @@
+%define name mdk
+%define docname mdk-doc
+%define version 0.4.2
+%define release 1
+%define serial 2
+#%define prefix /opt/mdk-0.3.1/usr
+%define prefix /usr
+#%define infodirdir %{prefix}/etc/
+%define infodirdir /etc
+Summary: MIX Development Kit
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Serial: %{serial}
+Copyright: GPL
+Group: Development/Languages
+Url: http://www.gnu.org/software/mdk/mdk.html
+Vendor: Jose A. Ortega Ruiz <jao@gnu.org>
+Source0: http://download.sourcegorge.net/mdk/%{name}-%{version}.tar.gz
+Source1: http://download.sourcegorge.net/mdk/%{docname}-%{version}.tar.gz
+#Patch0: patch-mdk-0.3
+Packager: Agustin Navarro <anp@cantv.net>
+BuildRoot: /var/tmp/%{name}-%{version}-root
+#DocDir: %{prefix}/share/doc/mdk-0.3.1
+
+
+%description
+MDK stands for MIX Development Kit, and provides tools for developing
+and executing, in a MIX virtual machine, MIXAL programs.
+
+The MIX is Donald Knuth's mythical computer, described in the first
+volume of The Art of Computer Programming, which is programmed using
+MIXAL, the MIX assembly language.
+
+MDK includes a MIXAL assembler (mixasm) and a MIX virtual machine
+(mixvm) with a command line interface. In case you are an Emacs guy,
+you can try doc/mixvm.el, which allows running mixvm inside an Emacs
+GUD buffer.
+
+Using these interfaces, you can debug your MIXAL programs at source
+code level, and read/modify the contents of all the components of the
+MIX computer (including block devices, which are simultated using the
+file system).
+
+
+%package gtk
+Summary: MIX Development Kit GTK GUI Interface to mixvm
+Group: Development/Languages
+
+%description gtk
+MDK stands for MIX Development Kit, and provides tools for developing
+and executing, in a MIX virtual machine, MIXAL programs.
+
+The MIX is Donald Knuth's mythical computer, described in the first
+volume of The Art of Computer Programming, which is programmed using
+MIXAL, the MIX assembly language.
+
+A GTK+ GUI to mixvm, called gmixvm, is provided
+
+Using these interfaces, you can debug your MIXAL programs at source
+code level, and read/modify the contents of all the components of the
+MIX computer (including block devices, which are simultated using the
+file system).
+
+
+%package doc
+Summary: MIX Development Kit HTML Documentation
+Group: Development/Languages
+
+%description doc
+MDK stands for MIX Development Kit, and provides tools for developing
+and executing, in a MIX virtual machine, MIXAL programs.
+
+This pakage includes the HTML Documentation
+
+
+%prep
+
+%setup -q
+%setup -D -T -b 1
+
+#%patch0 -p1
+
+CFLAGS=$RPM_OPT_FLAGS \
+ ./configure --prefix=%{prefix} --infodir='${prefix}/share/info'
+
+%build
+make
+#make html
+
+%install
+[ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
+make -e prefix=$RPM_BUILD_ROOT%{prefix} install
+
+%clean
+[ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
+
+%post
+/sbin/install-info %{prefix}/share/info/mdk.info.gz %{infodirdir}/info-dir
+
+%files
+%defattr(-,root,root)
+%doc AUTHORS ChangeLog COPYING README NEWS TODO THANKS INSTALL
+%doc samples
+%doc misc/mixvm.el
+%{prefix}/bin/mixasm
+%{prefix}/bin/mixvm
+%{prefix}/share/info/*
+
+%files gtk
+%defattr(-,root,root)
+%{prefix}/share/mdk
+%{prefix}/bin/gmixvm
+
+%files doc
+%defattr(-,root,root)
+%doc ../%{docname}-%{version}/img ../%{docname}-%{version}/manual
+
+
+%changelog
+* Sun Aug 19 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to mdk-0.4
+
+* Sun Jul 22 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to mdk-0.4
+
+* Thu Jun 21 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to mdk-0.3.5
+
+* Tue Jun 12 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to mdk-0.3.4
+
+* Sat Jun 09 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to mdk-0.3.3
+
+* Thu May 16 2001 Agustin Navarro <anp@cantv.net>
+- Upgrade to 0.3.2
+
+* Fri Mar 30 2001 Agustin Navarro <anp@cantv.net>
+- Initial Rpm Release
+
+
diff --git a/misc/Makefile.am b/misc/Makefile.am
new file mode 100644
index 0000000..f703ba0
--- /dev/null
+++ b/misc/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+EXTRA_DIST = mixvm.el mixal-mode.el
+
+pkgdata_DATA = mixvm.el mixal-mode.el
+
diff --git a/misc/mixal-mode.el b/misc/mixal-mode.el
new file mode 100644
index 0000000..638947a
--- /dev/null
+++ b/misc/mixal-mode.el
@@ -0,0 +1,1321 @@
+;;; mixal-mode.el --- Major mode for the mix asm language.
+
+;; Copyright (C) 2003, 2005 Free Software Foundation
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be
+;; useful, but WITHOUT ANY WARRANTY; without even the implied
+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+;; PURPOSE. See the GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public
+;; License along with this program; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301 USA
+
+;; Author: Pieter E.J. Pareit <pieter.pareit@skynet.be>
+;; Maintainer: Pieter E.J. Pareit <pieter.pareit@skynet.be>
+;; Created: 09 Nov 2002
+;; Version: 0.1
+;; Keywords: Knuth mix mixal asm mixvm "The Art Of Computer Programming"
+
+;;; Commentary:
+;; Major mode for the mix asm language.
+;; The mix asm language is described in "The Art Of Computer Programming".
+;;
+;; For optimal use, also use GNU MDK. Compiling needs mixasm, running
+;; and debugging needs mixvm and mixvm.el from GNU MDK. You can get
+;; GNU MDK from `https://savannah.gnu.org/projects/mdk/' and
+;; `ftp://ftp.gnu.org/pub/gnu/mdk'.
+;;
+;; To use this mode, place the following in your .emacs file:
+;; `(load-file "/PATH-TO-FILE/mixal-mode.el")'.
+;; When you load a file with the extension .mixal the mode will be started
+;; automatic. If you want to start the mode manual, use `M-x mixal-mode'.
+;; Font locking will work, the behavior of tabs is the same as emacs
+;; default behavior. You can compile a source file with `C-c c' you can
+;; run a compiled file with `C-c r' or run it in debug mode with `C-c d'.
+;; You can get more information about a particular operation code by using
+;; mixal-describe-operation-code or `C-h o'.
+;;
+;; Have fun.
+
+;;; History:
+;; Version 0.2:
+;; 06/04/05: mixasm no longer needs -g option
+;; fontlocking of comments works in all? cases now
+;; added some more mixal-operation-codes
+;; Version 0.1:
+;; Version 0.1.1:
+;; 22/11/02: bugfix in fontlocking, needed to add a '-' to the regex.
+;; 19/11/02: completed implementing mixal-describe-operation-code.
+;; 13/11/02: implemented compile, mixal-run and mixal-debug.
+;; 10/11/02: implemented font-locking and syntax table.
+;; 09/11/02: started mixal-mode.
+
+;;; Code:
+
+;;; Key map
+(defvar mixal-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-cc" 'compile)
+ (define-key map "\C-cr" 'mixal-run)
+ (define-key map "\C-cd" 'mixal-debug)
+ (define-key map "\C-ho" 'mixal-describe-operation-code)
+ map)
+ "Keymap for `mixal-mode'.")
+; (makunbound 'mixal-mode-map)
+
+;;; Syntax table
+(defvar mixal-mode-syntax-table
+ (let ((st (make-syntax-table)))
+ ; (modify-syntax-entry ?* "<" st) we need to do a bit more to make
+ ; (modify-syntax-entry ?\n ">" st) fontlocking for comments work
+ st)
+ "Syntax table for `dot-mode'.")
+
+(defvar mixal-font-lock-label-face 'font-lock-variable-name-face
+ "Face name to use for label names.
+Default value is that of `font-lock-variable-name-face', but you can modify
+its value.")
+
+(defvar mixal-font-lock-operation-code-face 'font-lock-keyword-face
+ "Face name to use for operation code names.
+Default value is that of `font-lock-keyword-face', but you can modify its
+value.")
+
+(defvar mixal-font-lock-assembly-pseudoinstruction-face 'font-lock-builtin-face
+ "Face name to use for assembly pseudoinstruction names.
+Default value is that of `font-lock-builtin-face', but you can modify its
+value.")
+
+(defvar mixal-operation-codes
+ '("NOP" "ADD" "FADD" "SUB" "FSUB" "MUL" "FMUL" "DIV" "FDIV" "NUM" "CHAR"
+ "HLT" "SLA" "SRA" "SLAX" "SRAX" "SLC" "SRC" "MOVE" "LDA" "LD1" "LD2" "LD3"
+ "LD4" "LD5" "LD6" "LDX" "LDAN" "LD1N" "LD2N" "LD3N" "LD4N" "LD5N" "LD6N"
+ "LDXN" "STA" "ST1" "ST2" "ST3" "ST4" "ST5" "ST6" "STX" "STJ" "STZ" "JBUS"
+ "IOC" "IN" "OUT" "JRAD" "JMP" "JSJ" "JOV" "JNOV"
+ "JL" "JE" "JG" "JGE" "JNE" "JLE"
+ "JAN" "J1N" "J2N" "J3N" "J4N" "J5N" "J6N" "JXN"
+ "JAZ" "J1Z" "J2Z" "J3Z" "J4Z" "J5Z" "J6Z" "JXZ"
+ "JAP" "J1P" "J2P" "J3P" "J4P" "J5P" "J6P" "JXP"
+ "JANN" "J1NN" "J2NN" "J3NN" "J4NN" "J5NN" "J6NN" "JXNN"
+ "JANZ" "J1NZ" "J2NZ" "J3NZ" "J4NZ" "J5NZ" "J6NZ" "JXNZ"
+ "JANP" "J1NP" "J2NP" "J3NP" "J4NP" "J5NP" "J6NP" "JXNP"
+ "INCA" "DECA" "ENTA" "ENNA" "INC1" "DEC1" "ENT1" "ENN1"
+ "INC2" "DEC2" "ENT2" "ENN2" "INC3" "DEC3" "ENT3" "ENN3" "INC4" "DEC4"
+ "ENT4" "ENN4" "INC5" "DEC5" "ENT5" "ENN5" "INC6" "DEC6" "ENT6" "ENN6"
+ "INCX" "DECX" "ENTX" "ENNX" "CMPA" "FCMP" "CMP1" "CMP2" "CMP3" "CMP4"
+ "CMP5" "CMP6" "CMPX")
+ "List of possible operation codes as strings.")
+; (makunbound 'mixal-operation-codes)
+
+(defvar mixal-assembly-pseudoinstructions
+ '("ORIG" "EQU" "CON" "ALF" "END")
+ "List of possible assembly pseudoinstructions")
+
+;;; Font-locking:
+(defvar mixal-font-lock-keywords
+ `(("^\\([A-Z0-9a-z]+\\).*$"
+ (1 mixal-font-lock-label-face))
+ (,(regexp-opt mixal-operation-codes 'words)
+ . mixal-font-lock-operation-code-face)
+ (,(regexp-opt
+ mixal-assembly-pseudoinstructions 'words)
+ . mixal-font-lock-assembly-pseudoinstruction-face)
+ ("^[A-Z0-9a-z]*[ \t]+[A-ZO-9a-z]+[ \t]+\\(=.*=\\).*$"
+ (1 font-lock-constant-face))
+ ("^[A-Z0-9a-z]*[ \t]+[A-Z0-9a-z]+[ \t]+[A-Z0-9a-z,():+-\\*=\" ]*[\t]+\\(.*\\)$"
+ (1 font-lock-comment-face))
+ ("^\\*.*$" . font-lock-comment-face))
+ "Keyword highlighting specification for `mixal-mode'.")
+; (makunbound 'mixal-font-lock-keywords)
+
+;;;; Compilation
+;; Output from mixasm is compatible with default behavior of emacs,
+;; I just added a key (C-cc) and modified the make-command.
+
+;;;; Indentation
+;; Tabs works well by default.
+
+;;;; Describe
+(defvar mixal-operation-codes-alist '()
+ "Alist that contains all the possible operation codes for mix.
+Each elt has the form (OP-CODE GROUP FULL-NAME C-BYTE F-BYTE DESCRIPTION EXECUTION-TIME)
+Where OP-CODE is the text of the opcode as an symbol, FULL NAME is the human readable name
+as a string, C-BYTE is the operation code telling what operation is to be performed, F-BYTE holds
+an modification of the operation code which can be a symbol or a number, DESCRIPTION contains
+an string with a description about the operation code and EXECUTION-TIME holds info
+about the time it takes, number or string")
+; (makunbound 'mixal-operation-codes-alist)
+
+(defun mixal-add-operation-code (op-code group full-name C-byte F-byte description execution-time)
+ "Add an operation code to the list that contains information about possible op code's."
+ (setq mixal-operation-codes-alist (cons (list op-code group full-name C-byte F-byte
+ description execution-time)
+ mixal-operation-codes-alist )))
+
+;; now add each operation code
+
+(mixal-add-operation-code
+ 'LDA 'loading "load A" 8 'field
+ "Put in rA the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word."
+ 2)
+
+(mixal-add-operation-code
+ 'LDX 'loading "load X" 15 'field
+ "Put in rX the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word."
+ 2)
+
+(mixal-add-operation-code
+ 'LD1 'loading "load I1" (+ 8 1) 'field
+ "Put in rI1 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD2 'loading "load I2" (+ 8 2) 'field
+ "Put in rI2 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD3 'loading "load I3" (+ 8 3) 'field
+ "Put in rI3 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD4 'loading "load I4" (+ 8 4) 'field
+ "Put in rI4 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD5 'loading "load I5" (+ 8 5) 'field
+ "Put in rI5 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD6 'loading "load I6" (+ 8 6) 'field
+ "Put in rI6 the contents of cell no. M.
+Uses a + when there is no sign in subfield. Subfield is left padded with
+zeros to make a word. Index registers only have 2 bytes and a sign, Trying
+to set anything more that that will result in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LDAN 'loading "load A negative" 16 'field
+ "Put in rA the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word."
+ 2)
+
+(mixal-add-operation-code
+ 'LDXN 'loading "load X negative" 23 'field
+ "Put in rX the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word."
+ 2)
+
+(mixal-add-operation-code
+ 'LD1N 'loading "load I1 negative" (+ 16 1) 'field
+ "Put in rI1 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD2N 'loading "load I2 negative" (+ 16 2) 'field
+ "Put in rI2 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD3N 'loading "load I3 negative" (+ 16 3) 'field
+ "Put in rI3 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD4N 'loading "load I4 negative" (+ 16 4) 'field
+ "Put in rI4 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD5N 'loading "load I5 negative" (+ 16 5) 'field
+ "Put in rI5 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'LD6N 'loading "load I6 negative" (+ 16 6) 'field
+ "Put in rI6 the contents of cell no. M, with opposite sign.
+Uses a + when there is no sign in subfield, otherwise use the opposite sign.
+Subfield is left padded with zeros to make a word. Index registers only
+have 2 bytes and a sign, Trying to set anything more that that will result
+in undefined behavior."
+ 2)
+
+(mixal-add-operation-code
+ 'STA 'storing "store A" 24 'field
+ "Store in cell Nr. M the contents of rA.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield."
+ 2)
+
+(mixal-add-operation-code
+ 'STX 'storing "store X" 31 'field
+ "Store in cell Nr. M the contents of rX.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield."
+ 2)
+
+(mixal-add-operation-code
+ 'ST1 'storing "store I1" (+ 24 1) 'field
+ "Store in cell Nr. M the contents of rI1.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'ST2 'storing "store I2" (+ 24 2) 'field
+ "Store in cell Nr. M the contents of rI2.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'ST3 'storing "store I3" (+ 24 3) 'field
+ "Store in cell Nr. M the contents of rI3.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'ST4 'storing "store I4" (+ 24 4) 'field
+ "Store in cell Nr. M the contents of rI4.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'ST5 'storing "store I5" (+ 24 5) 'field
+ "Store in cell Nr. M the contents of rI5.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'ST6 'storing "store I6" (+ 24 6) 'field
+ "Store in cell Nr. M the contents of rI6.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The
+sign of the memory cell is not changed, unless it is part of the subfield.
+Because index registers only have 2 bytes and a sign, the rest of the bytes
+are assumed to be 0."
+ 2)
+
+(mixal-add-operation-code
+ 'STJ 'storing "store J" 32 'field
+ "Store in cell Nr. M the contents of rJ.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with bytes from a register. These
+bytes are taken beginning by the rightmost side of the register. The sign
+of rJ is always +, sign of the memory cell is not changed, unless it is
+part of the subfield. The default field for STJ is (0:2)."
+ 2)
+
+(mixal-add-operation-code
+ 'STZ 'storing "store zero" 33 'field
+ "Store in cell Nr. M '+ 0'.
+The modification of the operation code represents the subfield of the
+memory cell that is to be overwritten with zeros."
+ 2)
+
+(mixal-add-operation-code
+ 'ADD 'arithmetic "add" 1 'field
+ "Add to A the contents of cell Nr. M.
+Subfield is padded with zero to make a word.
+If the result is to large, the operation result modulo 1,073,741,823 (the
+maximum value storable in a MIX word) is stored in `rA', and the overflow
+toggle is set to TRUE."
+ 2)
+
+(mixal-add-operation-code
+ 'SUB 'arithmetic "subtract" 2 'field
+ "Subtract to A the contents of cell Nr. M.
+Subfield is padded with zero to make a word.
+If the result is to large, the operation result modulo 1,073,741,823 (the
+maximum value storable in a MIX word) is stored in `rA', and the overflow
+toggle is set to TRUE."
+ 2)
+
+(mixal-add-operation-code
+ 'MUL 'arithmetic "multiply" 3 'field
+ "Multiplies the contents of cell Nr. M with A, result is 10 bytes and stored in rA and rX.
+The sign is + if the sign of rA and cell M where the same, otherwise, it is -"
+ 10)
+
+(mixal-add-operation-code
+ 'DIV 'arithmetic "divide" 4 'field
+ "Both rA and rX are taken together and divided by cell Nr. M, quotient is placed in rA, remainder in rX.
+The sign is taken from rA, and after the divide the sign of rA is set to + when
+both the sign of rA and M where the same. Divide by zero and overflow of rA result
+in undefined behavior."
+ 12)
+
+(mixal-add-operation-code
+ 'ENTA 'address-transfer "enter A" 48 2
+ "Literal value is stored in rA.
+Indexed, stores value of index in rA."
+ 1)
+
+(mixal-add-operation-code
+ 'ENTX 'address-transfer "enter X" 55 2
+ "Literal value is stored in rX.
+Indexed, stores value of index in rX."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT1 'address-transfer "Enter rI1" (+ 48 1) 2
+ "Literal value is stored in rI1.
+Indexed, stores value of index in rI1."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT2 'address-transfer "Enter rI2" (+ 48 2) 2
+ "Literal value is stored in rI2.
+Indexed, stores value of index in rI2."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT3 'address-transfer "Enter rI3" (+ 48 3) 2
+ "Literal value is stored in rI3.
+Indexed, stores value of index in rI3."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT4 'address-transfer "Enter rI4" (+ 48 4) 2
+ "Literal value is stored in rI4.
+Indexed, stores value of index in rI4."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT5 'address-transfer "Enter rI5" (+ 48 5) 2
+ "Literal value is stored in rI5.
+Indexed, stores value of index in rI5."
+ 1)
+
+(mixal-add-operation-code
+ 'ENT6 'address-transfer "Enter rI6" (+ 48 6) 2
+ "Literal value is stored in rI6.
+Indexed, stores value of index in rI6."
+ 1)
+
+(mixal-add-operation-code
+ 'ENNA 'address-transfer "enter negative A" 48 3
+ "Literal value is stored in rA with opposite sign.
+Indexed, stores value of index in rA with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENNX 'address-transfer "enter negative X" 55 3
+ "Literal value is stored in rX with opposite sign.
+Indexed, stores value of index in rX with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN1 'address-transfer "Enter negative rI1" (+ 48 1) 3
+ "Literal value is stored in rI1 with opposite sign.
+Indexed, stores value of index in rI1 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN2 'address-transfer "Enter negative rI2" (+ 48 2) 3
+ "Literal value is stored in rI2 with opposite sign.
+Indexed, stores value of index in rI2 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN3 'address-transfer "Enter negative rI3" (+ 48 3) 3
+ "Literal value is stored in rI3 with opposite sign.
+Indexed, stores value of index in rI3 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN4 'address-transfer "Enter negative rI4" (+ 48 4) 3
+ "Literal value is stored in rI4 with opposite sign.
+Indexed, stores value of index in rI4 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN5 'address-transfer "Enter negative rI5" (+ 48 5) 3
+ "Literal value is stored in rI5 with opposite sign.
+Indexed, stores value of index in rI5 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'ENN6 'address-transfer "Enter negative rI6" (+ 48 6) 3
+ "Literal value is stored in rI6 with opposite sign.
+Indexed, stores value of index in rI6 with opposite sign."
+ 1)
+
+(mixal-add-operation-code
+ 'INCA 'address-transfer "increase A" 48 0
+ "Increase register A with the literal value of M.
+On overflow the overflow toggle is set."
+ 1)
+
+(mixal-add-operation-code
+ 'INCX 'address-transfer "increase X" 55 0
+ "Increase register X with the literal value of M.
+On overflow the overflow toggle is set."
+ 1)
+
+(mixal-add-operation-code
+ 'INC1 'address-transfer "increase I1" (+ 48 1) 0
+ "Increase register I1 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'INC2 'address-transfer "increase I2" (+ 48 2) 0
+ "Increase register I2 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'INC3 'address-transfer "increase I3" (+ 48 3) 0
+ "Increase register I3 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'INC4 'address-transfer "increase I4" (+ 48 4) 0
+ "Increase register I4 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'INC5 'address-transfer "increase I5" (+ 48 5) 0
+ "Increase register I5 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'INC6 'address-transfer "increase I6" (+ 48 6) 0
+ "Increase register I6 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DECA 'address-transfer "decrease A" 48 1
+ "Decrease register A with the literal value of M.
+On overflow the overflow toggle is set."
+ 1)
+
+(mixal-add-operation-code
+ 'DECX 'address-transfer "decrease X" 55 1
+ "Decrease register X with the literal value of M.
+On overflow the overflow toggle is set."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC1 'address-transfer "decrease I1" (+ 48 1) 1
+ "Decrease register I1 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC2 'address-transfer "decrease I2" (+ 48 2) 1
+ "Decrease register I2 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC3 'address-transfer "decrease I3" (+ 48 3) 1
+ "Decrease register I3 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC4 'address-transfer "decrease I4" (+ 48 4) 1
+ "Decrease register I4 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC5 'address-transfer "decrease I5" (+ 48 5) 1
+ "Decrease register I5 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'DEC6 'address-transfer "decrease I6" (+ 48 6) 1
+ "Decrease register I6 with the literal value of M.
+The result is undefined when the result does not fit in
+2 bytes."
+ 1)
+
+(mixal-add-operation-code
+ 'CMPA 'comparison "compare A" 56 'field
+ "Compare contents of A with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMPX 'comparison "compare X" 63 'field
+ "Compare contents of rX with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP1 'comparison "compare I1" (+ 56 1) 'field
+ "Compare contents of rI1 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP2 'comparison "compare I2" (+ 56 2) 'field
+ "Compare contents of rI2 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP3 'comparison "compare I3" (+ 56 3) 'field
+ "Compare contents of rI3 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP4 'comparison "compare I4" (+ 56 4) 'field
+ "Compare contents of rI4 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP5 'comparison "compare I5" (+ 56 5) 'field
+ "Compare contents of rI5 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+
+(mixal-add-operation-code
+ 'CMP6 'comparison "compare I6" (+ 56 6) 'field
+ "Compare contents of rI6 with contents of M.
+The field specifier works on both fields. The comparison indicator
+is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
+have a value of 0."
+ 2)
+
+(mixal-add-operation-code
+ 'JMP 'jump "jump" 39 0
+ "Unconditional jump.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'JSJ 'jump "jump, save J" 39 1
+ "Unconditional jump, but rJ is not modified."
+ 1)
+
+(mixal-add-operation-code
+ 'JOV 'jump "jump on overflow" 39 2
+ "Jump if OV is set (and turn it off).
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'JNOV 'jump "Jump on no overflow" 39 3
+ "Jump if OV is not set (and turn it off).
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'JL 'jump "Jump on less" 39 4
+ "Jump if '[CM] = L'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JE 'jump "Jump on equal" 39 5
+ "Jump if '[CM] = E'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JG 'jump "Jump on greater" 39 6
+ "Jump if '[CM] = G'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JGE 'jump "Jump on not less" 39 7
+ "Jump if '[CM]' does not equal 'L'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JNE 'jump "Jump on not equal" 39 8
+ "Jump if '[CM]' does not equal 'E'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JLE 'jump "Jump on not greater" 39 9
+ "Jump if '[CM]' does not equal 'G'.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'JAN 'jump "jump A negative" 40 0
+ "Jump if the content of rA is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JAZ 'jump "jump A zero" 40 1
+ "Jump if the content of rA is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JAP 'jump "jump A positive" 40 2
+ "Jump if the content of rA is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JANN 'jump "jump A non-negative" 40 3
+ "Jump if the content of rA is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JANZ 'jump "jump A non-zero" 40 4
+ "Jump if the content of rA is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JANP 'jump "jump A non-positive" 40 5
+ "Jump if the content of rA is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'JXN 'jump "jump X negative" 47 0
+ "Jump if the content of rX is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JXZ 'jump "jump X zero" 47 1
+ "Jump if the content of rX is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JXP 'jump "jump X positive" 47 2
+ "Jump if the content of rX is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JXNN 'jump "jump X non-negative" 47 3
+ "Jump if the content of rX is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JXNZ 'jump "jump X non-zero" 47 4
+ "Jump if the content of rX is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JXNP 'jump "jump X non-positive" 47 5
+ "Jump if the content of rX is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'J1N 'jump "jump I1 negative" (+ 40 1) 0
+ "Jump if the content of rI1 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J1Z 'jump "jump I1 zero" (+ 40 1) 1
+ "Jump if the content of rI1 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J1P 'jump "jump I1 positive" (+ 40 1) 2
+ "Jump if the content of rI1 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J1NN 'jump "jump I1 non-negative" (+ 40 1) 3
+ "Jump if the content of rI1 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J1NZ 'jump "jump I1 non-zero" (+ 40 1) 4
+ "Jump if the content of rI1 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J1NP 'jump "jump I1 non-positive" (+ 40 1) 5
+ "Jump if the content of rI1 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'J2N 'jump "jump I2 negative" (+ 40 1) 0
+ "Jump if the content of rI2 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J2Z 'jump "jump I2 zero" (+ 40 1) 1
+ "Jump if the content of rI2 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J2P 'jump "jump I2 positive" (+ 40 1) 2
+ "Jump if the content of rI2 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J2NN 'jump "jump I2 non-negative" (+ 40 1) 3
+ "Jump if the content of rI2 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J2NZ 'jump "jump I2 non-zero" (+ 40 1) 4
+ "Jump if the content of rI2 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J2NP 'jump "jump I2 non-positive" (+ 40 1) 5
+ "Jump if the content of rI2 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3N 'jump "jump I3 negative" (+ 40 1) 0
+ "Jump if the content of rI3 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3Z 'jump "jump I3 zero" (+ 40 1) 1
+ "Jump if the content of rI3 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3P 'jump "jump I3 positive" (+ 40 1) 2
+ "Jump if the content of rI3 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3NN 'jump "jump I3 non-negative" (+ 40 1) 3
+ "Jump if the content of rI3 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3NZ 'jump "jump I3 non-zero" (+ 40 1) 4
+ "Jump if the content of rI3 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J3NP 'jump "jump I3 non-positive" (+ 40 1) 5
+ "Jump if the content of rI3 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4N 'jump "jump I4 negative" (+ 40 1) 0
+ "Jump if the content of rI4 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4Z 'jump "jump I4 zero" (+ 40 1) 1
+ "Jump if the content of rI4 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4P 'jump "jump I4 positive" (+ 40 1) 2
+ "Jump if the content of rI4 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4NN 'jump "jump I4 non-negative" (+ 40 1) 3
+ "Jump if the content of rI4 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4NZ 'jump "jump I4 non-zero" (+ 40 1) 4
+ "Jump if the content of rI4 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J4NP 'jump "jump I4 non-positive" (+ 40 1) 5
+ "Jump if the content of rI4 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5N 'jump "jump I5 negative" (+ 40 1) 0
+ "Jump if the content of rI5 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5Z 'jump "jump I5 zero" (+ 40 1) 1
+ "Jump if the content of rI5 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5P 'jump "jump I5 positive" (+ 40 1) 2
+ "Jump if the content of rI5 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5NN 'jump "jump I5 non-negative" (+ 40 1) 3
+ "Jump if the content of rI5 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5NZ 'jump "jump I5 non-zero" (+ 40 1) 4
+ "Jump if the content of rI5 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J5NP 'jump "jump I5 non-positive" (+ 40 1) 5
+ "Jump if the content of rI5 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6N 'jump "jump I6 negative" (+ 40 1) 0
+ "Jump if the content of rI6 is negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6Z 'jump "jump I6 zero" (+ 40 1) 1
+ "Jump if the content of rI6 is zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6P 'jump "jump I6 positive" (+ 40 1) 2
+ "Jump if the content of rI6 is positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6NN 'jump "jump I6 non-negative" (+ 40 1) 3
+ "Jump if the content of rI6 is non-negative.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6NZ 'jump "jump I6 non-zero" (+ 40 1) 4
+ "Jump if the content of rI6 is non-zero.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+
+(mixal-add-operation-code
+ 'J6NP 'jump "jump I6 non-positive" (+ 40 1) 5
+ "Jump if the content of rI6 is non-positive.
+Register J is set to the value of the next instruction that would have
+been executed when there was no jump."
+ 1)
+
+(mixal-add-operation-code
+ 'SLA 'miscellaneous "shift left A" 6 0
+ "Shift to A, M bytes left.
+Hero's will be added to the right."
+ 2)
+
+
+(mixal-add-operation-code
+ 'SRA 'miscellaneous "shift right A" 6 1
+ "Shift to A, M bytes right.
+Zeros will be added to the left."
+ 2)
+
+
+(mixal-add-operation-code
+ 'SLAX 'miscellaneous "shift left AX" 6 2
+ "Shift AX, M bytes left.
+Zeros will be added to the right."
+ 2)
+
+
+
+(mixal-add-operation-code
+ 'SRAX 'miscellaneous "shift right AX" 6 3
+ "Shift AX, M bytes right.
+Zeros will be added to the left."
+ 2)
+
+
+(mixal-add-operation-code
+ 'SLC 'miscellaneous "shift left AX circularly" 6 4
+ "Shift AX, M bytes left circularly.
+The bytes that fall off to the left will be added to the right."
+ 2)
+
+
+(mixal-add-operation-code
+ 'SRC 'miscellaneous "shift right AX circularly" 6 4
+ "Shift AX, M bytes right circularly.
+The bytes that fall off to the right will be added to the left."
+ 2)
+
+(mixal-add-operation-code
+ 'MOVE 'miscellaneous "move" 7 'number
+ "Move MOD words from M to the location stored in rI1."
+ '(+ 1 (* 2 number)))
+
+(mixal-add-operation-code
+ 'NOP 'miscellaneous "no operation" 0 'ignored
+ "No operation, M and F are not used by the machine."
+ 1)
+
+(mixal-add-operation-code
+ 'HLT 'miscellaneous "halt" 5 2
+ "Halt.
+Stop instruction fetching."
+ 1)
+
+(mixal-add-operation-code
+ 'IN 'input-output "input" 36 'unit
+ "Transfer a block of words from the specified unit to memory.
+The transfer starts at address M."
+ 1)
+
+(mixal-add-operation-code
+ 'OUT 'input-output "output" 37 'unit
+ "Transfer a block of words from memory.
+The transfer starts at address M to the specified unit."
+ 1)
+
+(mixal-add-operation-code
+ 'IOC 'input-output "input-output control" 35 'unit
+ "Perform a control operation.
+The control operation is given by M on the specified unit."
+ 1)
+
+(mixal-add-operation-code
+ 'JRED 'input-output "jump ready" 38 'unit
+ "Jump to M if the specified unit is ready."
+ 1)
+
+
+(mixal-add-operation-code
+ 'JBUS 'input-output "jump busy" 34 'unit
+ "Jump to M if the specified unit is busy."
+ 1)
+
+(mixal-add-operation-code
+ 'NUM 'conversion "convert to numeric" 5 0
+ "Convert rAX to its numerical value and store it in rA.
+the register rAX is assumed to contain a character representation of
+a number."
+ 10)
+
+(mixal-add-operation-code
+ 'CHAR 'conversion "convert to characters" 5 1
+ "Convert the number stored in rA to a character representation.
+The converted character representation is stored in rAX."
+ 10)
+
+(defvar mixal-describe-operation-code-history nil
+ "History list for describe operation code.")
+
+(defun mixal-describe-operation-code (&optional op-code)
+ "Display the full documentation of OP-CODE."
+ (interactive)
+ ;; we like to provide completition and history, so do it ourself (interactive "?bla")?
+ (unless op-code
+ (let* ((completion-ignore-case t)
+ ;; we already have a list, but it is not in the right format
+ ;; transform it to a valid table so completition can use it
+ (table (mapcar '(lambda (elm)
+ (cons (symbol-name (car elm)) nil))
+ mixal-operation-codes-alist))
+ ;; prompt is different depending on we are close to a valid op-code
+ (have-default (member (current-word) mixal-operation-codes))
+ (prompt (concat "Describe operation code "
+ (if have-default
+ (concat "(default " (current-word) "): ")
+ ": "))))
+ ;; as the operation code to the user
+ (setq op-code (completing-read prompt table nil t nil
+ 'mixal-describe-operation-code-history
+ (current-word)))))
+ ;; get the info on the op-code and output it to the help buffer
+ (let ((op-code-help (assq (intern-soft op-code) mixal-operation-codes-alist)))
+ (when op-code-help
+ (with-output-to-temp-buffer (buffer-name (get-buffer-create "*Help*"))
+ (princ op-code) (princ " is an mix operation code\n\n")
+ (princ (nth 5 op-code-help)) (terpri) (terpri)
+ (princ " group: ") (princ (nth 1 op-code-help)) (terpri)
+ (princ " nice name: ") (princ (nth 2 op-code-help)) (terpri)
+ (princ " OPCODE / C: ") (princ (nth 3 op-code-help)) (terpri)
+ (princ " MOD / F: ") (princ (nth 4 op-code-help)) (terpri)
+ (princ " time: ") (princ (nth 6 op-code-help)) (terpri)))))
+
+;;;; Running
+(defun mixal-run ()
+ "Run's mixal file in current buffer, assumes that file has been compiled"
+ (interactive)
+ (mixvm (concat "mixvm -r -t -d "
+ (file-name-sans-extension (buffer-file-name)))))
+
+(defun mixal-debug ()
+ "Starts mixvm for debugging, assumes that file has been compiled with debugging support"
+ (interactive)
+ (mixvm (concat "mixvm "
+ (file-name-sans-extension (buffer-file-name)))))
+
+;;;###autoload
+(define-derived-mode mixal-mode fundamental-mode "mixal"
+ "Major mode for the mixal asm language.
+\\{mixal-mode-map}"
+ (set (make-local-variable 'comment-start) "*")
+ (set (make-local-variable 'comment-start-skip) "*")
+ (set (make-local-variable 'font-lock-defaults) '(mixal-font-lock-keywords))
+; might add an indent function in the future
+; (set (make-local-variable 'indent-line-function) 'mixal-indent-line)
+ (set (make-local-variable 'compile-command) (concat "mixasm "
+ buffer-file-name))
+ ;; mixasm will do strange when there is no final newline,
+ ;; let emacs ensure that it is always there
+ (set (make-local-variable 'require-final-newline) t))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.mixal\\'" . mixal-mode))
+
+(provide 'mixal-mode)
+;;; mixal-mode.el ends here
diff --git a/misc/mixvm.el b/misc/mixvm.el
new file mode 100644
index 0000000..c437dfd
--- /dev/null
+++ b/misc/mixvm.el
@@ -0,0 +1,158 @@
+;;; mixvm.el --- mdk's mixvm / Emacs gud interaction
+;; Copyright (C) 2001 Free Software Foundation, Inc.
+
+;; Author: Philip Ellis King <pking@pdq.net>
+;; Maintainer: Philip Ellis King <pking@pdq.net>
+;; Created: 12 Feb 2001
+;; Version: 0.2
+;; Keywords: tools
+
+
+;;; Commentary:
+;; mixvm.el provides an interface between mdk's mixvm and Emacs,
+;; via gud. Place this file in your load-path, optionally adding
+;; the following line to your .emacs file:
+;; (autoload 'mixvm "mixvm" "mixvm/gud interaction" t)
+;; Initiate a mdk/gud session with the command mixvm, gud will
+;; reflect the current line in the source file buffer.
+
+;; (mixvm.el is based on a study of gdb, perldb, and pdb as found
+;; in gud.el, and rubydb3x.el distributed with the source code to
+;; the Ruby language.
+
+;;; Change Log:
+;; Version 0.2
+;; Initial release
+
+
+;;; Code:
+(require 'gud)
+(provide 'mixvm)
+
+;;; History of argument lists passed to mixvm.
+(defvar gud-mixvm-history nil)
+
+;; rubydb3x provided good examples of xemacs/emacs
+;; compatibility (not interested at the moment)
+(defun gud-mixvm-massage-args (file args)
+ (cons "--emacs" args))
+
+;; There's no guarantee that Emacs will hand the filter the entire
+;; marker at once; it could be broken up across several strings. We
+;; might even receive a big chunk with several markers in it. If we
+;; receive a chunk of text which looks like it might contain the
+;; beginning of a marker, we save it here between calls to the
+;; filter.
+(defvar gud-mixvm-marker-acc "")
+(make-variable-buffer-local 'gud-mixvm-marker-acc)
+
+(defun gud-mixvm-marker-filter (string)
+ (setq gud-mixvm-marker-acc (concat gud-mixvm-marker-acc string))
+ (let ((output ""))
+
+ ;; Process all the complete markers in this chunk.
+ (while (string-match "\032\032mixvm:\\([^:]+\\):\\([0-9]+\\)"
+ gud-mixvm-marker-acc)
+ (setq
+
+ ;; Extract the frame position from the marker.
+ gud-last-frame
+ (cons (substring gud-mixvm-marker-acc (match-beginning 1) (match-end 1))
+ (string-to-int (substring gud-mixvm-marker-acc
+ (match-beginning 2)
+ (match-end 2))))
+
+ ;; Append any text before the marker to the output we're going
+ ;; to return - we don't include the marker in this text.
+ output (concat output
+ (substring gud-mixvm-marker-acc 0 (match-beginning 0)))
+
+ ;; Set the accumulator to the remaining text.
+ gud-mixvm-marker-acc (substring gud-mixvm-marker-acc (match-end 0))))
+
+ ;; Does the remaining text look like it might end with the
+ ;; beginning of another marker? If it does, then keep it in
+ ;; gud-mixvm-marker-acc until we receive the rest of it. Since we
+ ;; know the full marker regexp above failed, it's pretty simple to
+ ;; test for marker starts.
+ ;; (note: \\' matches the end of the string (Perl's '$'))
+ (if (string-match "\032.*\\'" gud-mixvm-marker-acc)
+ (progn
+ ;; Everything before the potential marker start can be output.
+ (setq output (concat output (substring gud-mixvm-marker-acc
+ 0 (match-beginning 0))))
+
+ ;; Everything after, we save, to combine with later input.
+ (setq gud-mixvm-marker-acc
+ (substring gud-mixvm-marker-acc (match-beginning 0))))
+
+ (setq output (concat output gud-mixvm-marker-acc)
+ gud-mixvm-marker-acc ""))
+
+ output))
+
+;; See gdb for more comprehensive example
+;; pek: it bugs me that this is run for EVERY interactive
+;; mixvm command, should we cache some info somewhere?
+(defun gud-mixvm-find-file (file)
+ (save-excursion
+ (let* ((buf (find-file-noselect file)))
+ (set-buffer buf)
+ (when (boundp 'gud-make-debug-menu)
+ (gud-make-debug-menu))
+ buf)))
+
+
+(defvar mixvm-minibuffer-local-map nil
+ "Keymap for minibuffer prompting of mixvm startup command.")
+(if mixvm-minibuffer-local-map
+ ()
+ (setq mixvm-minibuffer-local-map (copy-keymap minibuffer-local-map))
+ (define-key
+ mixvm-minibuffer-local-map "\C-i" 'comint-dynamic-complete-filename))
+
+
+(defcustom gud-mixvm-command-name "mixvm"
+ "File name for executing the mixvm debugger.
+This should be an executable on your path, or an absolute file name."
+ :type 'string
+ :group 'gud)
+
+
+;;;###autoload
+(defun mixvm (command-line)
+ "Run mixvm on program FILE in buffer `*gud-FILE*'.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger."
+ (interactive
+ (list (read-from-minibuffer "Run mixvm (like this): "
+ (if (consp gud-mixvm-history)
+ (car gud-mixvm-history)
+ (concat gud-mixvm-command-name " "))
+ mixvm-minibuffer-local-map nil
+ '(gud-mixvm-history . 1))))
+
+ (gud-common-init command-line 'gud-mixvm-massage-args
+ 'gud-mixvm-marker-filter 'gud-mixvm-find-file)
+
+ (gud-def gud-break "sbp %l" "\C-b" "Set breakpoint at current line.")
+ (gud-def gud-remove "cbp %l" "\C-d" "Remove breakpoint at current line")
+ (gud-def gud-step "next" "\C-s" "Step one source line with display.")
+ (gud-def gud-next "next" "\C-n" "Step one line.")
+ (gud-def gud-stepi "next" "\C-i" "Step one line.")
+ (gud-def gud-cont "run" "\C-r" "Continue with display.")
+ (gud-def gud-finish "run" "\C-f" "Finish executing current function.")
+ (gud-def gud-print "weval %e" "\C-p" "Evaluate expression at point.")
+; (gud-def gud-up "up" "<" "Up one stack frame.")
+; (gud-def gud-down "down" ">" "Down one stack frame.")
+; ;; Is this right?
+; (gud-def gud-statement "! %e" "\C-e" "Execute Python statement at point.")
+
+; (local-set-key [menu-bar debug finish] '("Finish Function" . gud-finish))
+; (local-set-key [menu-bar debug up] '("Up Stack" . gud-up))
+; (local-set-key [menu-bar debug down] '("Down Stack" . gud-down))
+ (setq comint-prompt-regexp "^MIX > ")
+ (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
+ (run-hooks 'mixvm-mode-hook))
+
+;;; mixvm.el ends here
diff --git a/mixgtk/Makefile.am b/mixgtk/Makefile.am
new file mode 100644
index 0000000..60adf8d
--- /dev/null
+++ b/mixgtk/Makefile.am
@@ -0,0 +1,47 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.19 2005/09/18 21:49:40 jao Exp $
+
+EXTRA_DIST = mixgtk.glade
+
+if MAKE_GUILE
+GUILED = -DMAKE_GUILE
+else
+GUILED =
+endif
+
+if MAKE_GUI
+
+pkgdata_DATA = mixgtk.glade
+
+INCLUDES = -I$(includedir) -I$(top_srcdir) \
+ -DGLADE_FILE=\""$(pkgdatadir)/mixgtk.glade"\"\
+ -DLOCAL_GLADE_FILE=\""$(srcdir)/mixgtk.glade"\"\
+ $(GUILED)
+LDADD = $(top_builddir)/mixlib/libmix.a $(top_builddir)/lib/libreplace.a\
+ $(top_builddir)/mixguile/libmixguile.a $(INTLLIBS)
+
+AM_LDFLAGS = -Wl,--export-dynamic
+bin_PROGRAMS = gmixvm
+gmixvm_SOURCES = gmixvm.c mixgtk.h mixgtk.c \
+ mixgtk_config.h mixgtk_config.c \
+ mixgtk_gen_handlers.h mixgtk_gen_handlers.c \
+ mixgtk_cmd_dispatcher.h mixgtk_cmd_dispatcher.c \
+ mixgtk_widgets.h mixgtk_widgets.c \
+ mixgtk_device.h mixgtk_device.c \
+ mixgtk_mixvm.h mixgtk_mixvm.c \
+ mixgtk_mixal.h mixgtk_mixal.c \
+ mixgtk_input.h mixgtk_input.c \
+ mixgtk_fontsel.h mixgtk_fontsel.c \
+ mixgtk_wm.h mixgtk_wm.c
+endif
diff --git a/mixgtk/gmixvm.c b/mixgtk/gmixvm.c
new file mode 100644
index 0000000..150c891
--- /dev/null
+++ b/mixgtk/gmixvm.c
@@ -0,0 +1,124 @@
+/* -*-c-*- -------------- gmixvm.c :
+ * Main function of the mix gtk front-end
+ * ------------------------------------------------------------------
+ * $Id: gmixvm.c,v 1.6 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mixgtk.h"
+
+static gboolean initfile_ = TRUE;
+
+#ifdef MAKE_GUILE
+# include <mixguile/mixguile.h>
+# include "mixgtk_cmd_dispatcher.h"
+static void
+inner_main_ (int argc, char *argv[])
+{
+ mixgtk_init (argc, argv);
+ mixguile_set_cmd_dispatcher (mixgtk_cmd_dispatcher_get_mix_dispatcher ());
+ mixguile_load_bootstrap (initfile_);
+ mixgtk_main ();
+ mixgtk_release ();
+}
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+#else
+# include <lib/getopt.h>
+#endif /* HAVE_GETOPT_LONG */
+
+enum {
+ VER_OPT = 'v',
+ NOINIT_OPT = 'q',
+ HELP_OPT = 'h',
+ USAGE_OPT = 'u'
+};
+
+static const char *options_ = "vqhu";
+
+static struct option long_options_[] =
+{
+ {"version", no_argument, 0, VER_OPT},
+ {"help", no_argument, 0, HELP_OPT},
+ {"usage", no_argument, 0, USAGE_OPT},
+ {"noinit", no_argument, 0, NOINIT_OPT},
+ {0, 0, 0, 0}
+};
+
+static void print_usage_ (const gchar *prog)
+{
+ static const char *usage_ =
+ "Usage: %s [-vhuq] [--version] [--help] [--usage] [--noinit]\n";
+ fprintf (stderr, usage_, prog);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+
+ const char *prog_name = argv[0];
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ while (1)
+ {
+ c = getopt_long (argc, argv, options_, long_options_, (int*)0);
+
+ /* Detect the end of the options. */
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case VER_OPT:
+ mix_print_license (_("gmixvm, GTK MIX virtual machine"));
+ return EXIT_SUCCESS;
+ case NOINIT_OPT:
+ initfile_ = FALSE;
+ break;
+ case HELP_OPT:
+ case USAGE_OPT:
+ print_usage_ (prog_name);
+ return EXIT_SUCCESS;
+ case '?':
+ print_usage_ (prog_name);
+ return EXIT_FAILURE;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+#ifdef MAKE_GUILE
+ mixguile_enter (argc, argv, inner_main_);
+#else
+ if (!mixgtk_init (argc, argv)) return EXIT_FAILURE;
+ mixgtk_main ();
+ mixgtk_release ();
+#endif
+
+ return EXIT_SUCCESS;
+}
diff --git a/mixgtk/mixgtk.c b/mixgtk/mixgtk.c
new file mode 100644
index 0000000..eddb528
--- /dev/null
+++ b/mixgtk/mixgtk.c
@@ -0,0 +1,79 @@
+/* -*-c-*- -------------- mixgtk.c :
+ * Main functions of the mix gtk front-end
+ * ------------------------------------------------------------------
+ * $Id: mixgtk.c,v 1.19 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mixgtk_widgets.h"
+
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk_input.h"
+#include "mixgtk_config.h"
+#include "mixgtk_wm.h"
+#include "mixgtk.h"
+
+/* initialise the app */
+gboolean
+mixgtk_init (int argc, char *argv[])
+{
+ mix_init_lib ();
+
+ gtk_init (&argc, &argv);
+
+ if (!mixgtk_config_load ())
+ {
+ g_error (_("Unable to load gmixvm configuration"));
+ }
+
+ if (!mixgtk_widget_factory_init ())
+ {
+ g_error (_("Unable to initialise application: missing glade file"));
+ return FALSE;
+ }
+
+ if (!mixgtk_wm_init ())
+ {
+ g_error (_("Unable to initialise application\n"));
+ return FALSE;
+ }
+
+ mixgtk_input_init ();
+
+ return TRUE;
+}
+
+/* main loop */
+void
+mixgtk_main (void)
+{
+ gtk_main ();
+}
+
+/* clean up */
+void
+mixgtk_release (void)
+{
+ if (mixgtk_config_is_autosave ()) mixgtk_config_save ();
+ mix_vm_cmd_dispatcher_delete (mixgtk_cmd_dispatcher_get_mix_dispatcher ());
+ mix_release_lib ();
+}
diff --git a/mixgtk/mixgtk.glade b/mixgtk/mixgtk.glade
new file mode 100644
index 0000000..f16f441
--- /dev/null
+++ b/mixgtk/mixgtk.glade
@@ -0,0 +1,3913 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="main_window">
+ <property name="title" translatable="yes">gmixvm</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">650</property>
+ <property name="default_height">550</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="role">gmixvm-main</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+
+ <child>
+ <widget class="GtkVBox" id="main_vbox">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="mainmenubar">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="file">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="file_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="file_open">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Load a MIX file</property>
+ <property name="label" translatable="yes">_Load...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_file_open_activate"/>
+ <accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image432">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="edit">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Edit a MIXAL source file</property>
+ <property name="label" translatable="yes">_Edit...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_file_edit_activate"/>
+ <accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image433">
+ <property name="visible">True</property>
+ <property name="stock">gtk-justify-fill</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="compile">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Compile a MIXAL source file</property>
+ <property name="label" translatable="yes">_Compile...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_file_compile_activate"/>
+ <accelerator key="B" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image434">
+ <property name="visible">True</property>
+ <property name="stock">gtk-execute</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="file_exit">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Exit application</property>
+ <property name="label" translatable="yes">E_xit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_file_exit_activate"/>
+ <accelerator key="Q" modifiers="GDK_CONTROL_MASK | GDK_MOD1_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image435">
+ <property name="visible">True</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="debug">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">De_bug</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="debug_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="debug_run">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Run program</property>
+ <property name="label" translatable="yes">_Run</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_debug_run_activate"/>
+ <accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image436">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-forward</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="debug_next">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Execute next instruction</property>
+ <property name="label" translatable="yes">_Next</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_debug_next_activate"/>
+ <accelerator key="N" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image437">
+ <property name="visible">True</property>
+ <property name="stock">gtk-goto-last</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="clear_breakpoints">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Clear all set breakpoints</property>
+ <property name="label" translatable="yes">_Clear breakpoints</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_clear_breakpoints_activate"/>
+ <accelerator key="C" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image438">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="symbols">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show the symbol table</property>
+ <property name="label" translatable="yes">_Symbols...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_symbols_activate"/>
+ <accelerator key="Y" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image439">
+ <property name="visible">True</property>
+ <property name="stock">gtk-index</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="view1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Vie_w</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="view1_menu">
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_toolbars">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Toolbars</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id=" ">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Detached windows</property>
+ <property name="use_underline">True</property>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image440">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dnd-multiple</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenu" id=" _menu">
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="detach_vm">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Virtual machine</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="detach_source">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Source</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="detach_dev">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Devices</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="settings2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_ettings</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="settings2_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="fonts1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Change _font</property>
+ <property name="use_underline">True</property>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image441">
+ <property name="visible">True</property>
+ <property name="stock">gtk-select-font</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenu" id="fonts1_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="mix">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Virtual machine</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_mix_font_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="mixal">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Source</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_mixal_font_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="command_prompt">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Command _prompt</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_prompt_font_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="command_log">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Command l_og</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_log_font_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="devices">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Devices</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_devices_font_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="symbol_list">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Symbol _list</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_symbols_font_activate" last_modification_time="Sun, 04 Jul 2004 23:03:55 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator4">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="all_fonts">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Change all fonts at once</property>
+ <property name="label" translatable="yes">_All</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_all_fonts_activate" last_modification_time="Sat, 03 Jul 2004 00:34:07 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="device_output1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Change format of binary devices output</property>
+ <property name="label" translatable="yes">_Device output...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_devform_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image442">
+ <property name="visible">True</property>
+ <property name="stock">gtk-zoom-100</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="devices_dir">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">De_vices dir...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_devdir_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image443">
+ <property name="visible">True</property>
+ <property name="stock">gtk-home</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="external_programs1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">E_xternal programs...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_external_programs_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image444">
+ <property name="visible">True</property>
+ <property name="stock">gtk-preferences</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator3">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="save">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Save current settings</property>
+ <property name="label" translatable="yes">_Save</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_save_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image445">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="save_on_exit">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Toogle save settings on exit</property>
+ <property name="label" translatable="yes">Save on _exit</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="toggled" handler="on_save_on_exit_toggle"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="help">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="help_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="about">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image446">
+ <property name="visible">True</property>
+ <property name="stock">gtk-help</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHandleBox" id="tb_handle">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <property name="handle_position">GTK_POS_LEFT</property>
+ <property name="snap_edge">GTK_POS_TOP</property>
+
+ <child>
+ <widget class="GtkToolbar" id="main_toolbar">
+ <property name="visible">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">True</property>
+
+ <child>
+ <widget class="GtkToolButton" id="load_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Load MIX program</property>
+ <property name="label" translatable="yes">Open</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-open</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_file_open_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="compile_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Compile MIXAL source</property>
+ <property name="label" translatable="yes">Compile</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-execute</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_file_compile_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="edit_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Edit MIXAL source</property>
+ <property name="label" translatable="yes">Edit</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-justify-fill</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_file_edit_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="run_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Run</property>
+ <property name="label" translatable="yes">Run</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-go-forward</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_debug_run_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="step_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Next</property>
+ <property name="label" translatable="yes">Next</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-goto-last</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_debug_next_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="clear_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Clear breakpoints</property>
+ <property name="label" translatable="yes">Clear</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-clear</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_clear_breakpoints_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="symbols_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Symbol table</property>
+ <property name="label" translatable="yes">Symbols</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-index</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_symbols_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem2">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button28">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Device directory</property>
+ <property name="label" translatable="yes">Devdir</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-home</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <signal name="clicked" handler="on_devdir_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button30">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Output format</property>
+ <property name="label" translatable="yes">Format</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-zoom-100</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <signal name="clicked" handler="on_devform_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button31">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">External programs</property>
+ <property name="label" translatable="yes">Programs</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-properties</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <signal name="clicked" handler="on_external_programs_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem8">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="dettach_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Detach window</property>
+ <property name="label" translatable="yes">Detach</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-dnd-multiple</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <signal name="clicked" handler="on_detach_clicked" last_modification_time="Tue, 29 Jun 2004 22:14:37 GMT"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="attach_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Attach all windows</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-dnd</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_attach_all_clicked" last_modification_time="Thu, 01 Jul 2004 22:00:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVPaned" id="main_panel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">1</property>
+
+ <child>
+ <widget class="GtkNotebook" id="main_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ </widget>
+ <packing>
+ <property name="shrink">False</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="prompt_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="mixlog_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTextView" id="command_log">
+ <property name="visible">True</property>
+ <property name="editable">False</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_WORD</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">3</property>
+ <property name="right_margin">4</property>
+ <property name="indent">0</property>
+ <property name="text" translatable="yes"></property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="command_prompt">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Enter MIXVM command here</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <signal name="key_press_event" handler="on_command_prompt_key_press_event" after="yes"/>
+ <signal name="activate" handler="on_command_prompt_activate" last_modification_time="Sat, 19 Jun 2004 00:00:22 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkStatusbar" id="main_statusbar">
+ <property name="visible">True</property>
+ <property name="has_resize_grip">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="word_dialog">
+ <property name="title" translatable="yes">Enter value</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area5">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="word_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ <signal name="clicked" handler="on_word_cancel_clicked" last_modification_time="Thu, 01 Jul 2004 22:25:09 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="word_reset">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-clear</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">False</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_word_reset_clicked" last_modification_time="Thu, 01 Jul 2004 22:28:00 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="word_ok">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ <signal name="clicked" handler="on_word_ok_clicked" last_modification_time="Thu, 01 Jul 2004 22:26:25 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFixed" id="word_layout">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkEntry" id="word_decimal">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">28</property>
+ <signal name="changed" handler="on_word_dec_changed" after="yes" last_modification_time="Sun, 20 Jun 2004 23:47:46 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">88</property>
+ <property name="y">64</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_b2">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">2</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">3</property>
+ <signal name="changed" handler="on_word_byte_changed" last_modification_time="Sun, 20 Jun 2004 23:20:10 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">144</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_b3">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">2</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">3</property>
+ <signal name="changed" handler="on_word_byte_changed" last_modification_time="Sun, 20 Jun 2004 23:20:28 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">176</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_b4">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">2</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">3</property>
+ <signal name="changed" handler="on_word_byte_changed" last_modification_time="Sun, 20 Jun 2004 23:20:57 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">208</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_b5">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">2</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">3</property>
+ <signal name="changed" handler="on_word_byte_changed" last_modification_time="Sun, 20 Jun 2004 23:21:18 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">238</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_b1">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">2</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">3</property>
+ <signal name="changed" handler="on_word_byte_changed" last_modification_time="Sun, 20 Jun 2004 23:19:50 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">112</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="word_sign">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">1</property>
+ <property name="text" translatable="yes">+</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">2</property>
+ <signal name="changed" handler="on_word_sign_changed" last_modification_time="Sun, 20 Jun 2004 23:19:23 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">88</property>
+ <property name="y">32</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label60">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Decimal</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">14</property>
+ <property name="y">68</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label61">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Bytes</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">15</property>
+ <property name="y">36</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="word_label">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Enter value</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">112</property>
+ <property name="y">8</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="about_dialog">
+ <property name="title" translatable="yes">MDK</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="modal">True</property>
+ <property name="default_width">250</property>
+ <property name="default_height">150</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child>
+ <widget class="GtkLayout" id="layout1">
+ <property name="visible">True</property>
+ <property name="width">250</property>
+ <property name="height">150</property>
+ <property name="hadjustment">0 0 250 0 225 250</property>
+ <property name="vadjustment">0 0 150 0 135 150</property>
+
+ <child>
+ <widget class="GtkLabel" id="label222">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">GNU MIX Development Kit</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">56</property>
+ <property name="y">24</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="version_label">
+ <property name="width_request">52</property>
+ <property name="height_request">16</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label223</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">96</property>
+ <property name="y">48</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label224">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> Copyright (C) 2001, 2002, 2003 , 2004
+Free Software Foundation, Inc.
+
+Please, send bug reports to
+bug-mdk@gnu.org</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">24</property>
+ <property name="y">80</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="goto_dialog">
+ <property name="title" translatable="yes">Go to memory cell</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox6">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area6">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="goto_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="goto_ok">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label225">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Go to address:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="goto_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">10</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkFontSelectionDialog" id="fontsel_dialog">
+ <property name="border_width">4</property>
+ <property name="title" translatable="yes">Select Font</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="cancel_button">
+ <widget class="GtkButton" id="cancel_button1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+
+ <child internal-child="apply_button">
+ <widget class="GtkButton" id="apply_button1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+
+ <child internal-child="ok_button">
+ <widget class="GtkButton" id="ok_button1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+
+ <child internal-child="font_selection">
+ <widget class="GtkFontSelection" id="fontselection1">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="preview_text" translatable="yes">abcdefghijk ABCDEFGHIJK</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="devform_dialog">
+ <property name="title" translatable="yes">Device output format</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="default_width">320</property>
+ <property name="default_height">140</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox8">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area8">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button37">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button38">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-apply</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-10</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button39">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFixed" id="fixed2">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkButton" id="devset_button">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Set all devices to current format</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">S_et all</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_devset_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="x">233</property>
+ <property name="y">31</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label232">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Device</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">24</property>
+ <property name="y">10</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label233">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Format</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">24</property>
+ <property name="y">38</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBoxEntry" id="dev_combo">
+ <property name="width_request">183</property>
+ <property name="height_request">25</property>
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">tape0
+tape1
+tape2
+tape3
+tape4
+tape5
+tape6
+tape7
+disk0
+disk1
+disk2
+disk3
+disk4
+disk5
+disk6
+disk7</property>
+ <signal name="changed" handler="on_dev_combo_changed" last_modification_time="Wed, 23 Jun 2004 11:34:16 GMT"/>
+ </widget>
+ <packing>
+ <property name="x">90</property>
+ <property name="y">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="wordradio">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show output as MIX words</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Word</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="x">89</property>
+ <property name="y">34</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="decradio">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show output as decimal numbers</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Decimal</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">wordradio</property>
+ <signal name="toggled" handler="on_decradio_toggled"/>
+ </widget>
+ <packing>
+ <property name="x">154</property>
+ <property name="y">34</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="external_dialog">
+ <property name="title" translatable="yes">External programs</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox9">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area9">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button40">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button41">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFixed" id="fixed3">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkEntry" id="editor_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes">xterm -e vi %s</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="x">256</property>
+ <property name="y">12</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label234">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Editor command (e.g xterm -e vi %s)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">8</property>
+ <property name="y">15</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFixed" id="fixed4">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkEntry" id="mixasm_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes">mixasm %s</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="x">255</property>
+ <property name="y">4</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label235">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">MIX sssembler command (e.g. mixasm %s)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="x">8</property>
+ <property name="y">8</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="symbols_dialog">
+ <property name="title" translatable="yes">Symbol table</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">245</property>
+ <property name="default_height">265</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_symbol_ok_clicked"/>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox36">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image57">
+ <property name="visible">True</property>
+ <property name="stock">gtk-close</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1437">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Close</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow26">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="symbols_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">True</property>
+ <property name="enable_search">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="mixal_window">
+ <property name="title" translatable="yes">MIXAL source</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">570</property>
+ <property name="default_height">225</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHandleBox" id="tb_handle">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <property name="handle_position">GTK_POS_LEFT</property>
+ <property name="snap_edge">GTK_POS_TOP</property>
+
+ <child>
+ <widget class="GtkToolbar" id="mixal_toolbar">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">True</property>
+
+ <child>
+ <widget class="GtkToolButton" id="button14">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Run</property>
+ <property name="label" translatable="yes">Run</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-go-forward</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_debug_run_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button15">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Next</property>
+ <property name="label" translatable="yes">Step</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-goto-last</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_debug_next_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button16">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Clear breakpoints</property>
+ <property name="label" translatable="yes">Clear</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-clear</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_clear_breakpoints_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button18">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Symbol table</property>
+ <property name="label" translatable="yes">Symbols</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-index</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_symbols_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem7">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button22">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Source code font</property>
+ <property name="label" translatable="yes">Font</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-select-font</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_mixal_font_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem10">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="attach_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Attach window</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-dnd</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="mixal_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkStatusbar" id="mixal_statusbar">
+ <property name="visible">True</property>
+ <property name="has_resize_grip">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="devices_window">
+ <property name="title" translatable="yes">Devices</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">550</property>
+ <property name="default_height">250</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <signal name="delete_event" handler="on_window_hide"/>
+ <signal name="destroy_event" handler="on_window_hide"/>
+ <signal name="destroy" handler="on_window_hide"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHandleBox" id="tb_handle">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <property name="handle_position">GTK_POS_LEFT</property>
+ <property name="snap_edge">GTK_POS_TOP</property>
+
+ <child>
+ <widget class="GtkToolbar" id="devices_toolbar">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">True</property>
+
+ <child>
+ <widget class="GtkToolButton" id="devdir_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Device directory</property>
+ <property name="label" translatable="yes">Directory</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-home</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_devdir_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="output_button">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Output format</property>
+ <property name="label" translatable="yes">Output</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-zoom-100</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_devform_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem11">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="button21">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Output font</property>
+ <property name="label" translatable="yes">Font</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-select-font</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_devices_font_activate"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem12">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="attach_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-dnd</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="dev_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="devdir_dialog">
+ <property name="title" translatable="yes">Devices directory</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <signal name="destroy_event" handler="gtk_widget_hide"/>
+ <signal name="destroy" handler="gtk_widget_hide"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox11">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area11">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="devdir_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ <signal name="clicked" handler="on_devdir_cancel_clicked" last_modification_time="Tue, 22 Jun 2004 22:16:53 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="devdir_ok">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ <signal name="clicked" handler="on_devdir_ok_clicked" last_modification_time="Tue, 22 Jun 2004 22:18:04 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="border_width">25</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">11</property>
+
+ <child>
+ <widget class="GtkLabel" id="label239">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Directory</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="devdir_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="devdir_browse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-open</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_devdir_browse_clicked"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="mixvm_window">
+ <property name="title" translatable="yes">Virtual machine</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">640</property>
+ <property name="default_height">268</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox8">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHandleBox" id="tb_handle">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <property name="handle_position">GTK_POS_LEFT</property>
+ <property name="snap_edge">GTK_POS_TOP</property>
+
+ <child>
+ <widget class="GtkToolbar" id="mixvm_toolbar">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">True</property>
+
+ <child>
+ <widget class="GtkToolButton" id="toolbutton2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Font</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-select-font</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <signal name="clicked" handler="on_mix_font_activate" last_modification_time="Wed, 30 Jun 2004 16:06:57 GMT"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem9">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="attach_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-dnd</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="mixvm_container">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="mixvm_widget">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="border_width">1</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">1</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame3">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="border_width">8</property>
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">6</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">11</property>
+
+ <child>
+ <widget class="GtkLabel" id="label97">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">A</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label100">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I1</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label101">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I2</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rA_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">19</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI1_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI2_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label98">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">X</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label102">
+ <property name="width_request">16</property>
+ <property name="height_request">16</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I3</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label103">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I4</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label104">
+ <property name="width_request">16</property>
+ <property name="height_request">16</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I5</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label105">
+ <property name="width_request">16</property>
+ <property name="height_request">16</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">I6</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label99">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">J</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rX_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">19</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI4_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="right_attach">6</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI5_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="right_attach">6</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI6_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="right_attach">6</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="rI3_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox22">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="rJ_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">9</property>
+ <signal name="button_press_event" handler="on_register_click"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label264">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Registers </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame5">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox6">
+ <property name="border_width">1</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkRadioButton" id="greater_radio">
+ <property name="border_width">2</property>
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Greater</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">G</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_cmp_g_toggled"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="equal_radio">
+ <property name="border_width">2</property>
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Equal</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">E</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">greater_radio</property>
+ <signal name="toggled" handler="on_cmp_e_toggled"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="lesser_radio">
+ <property name="border_width">2</property>
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Lesser</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">L</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">greater_radio</property>
+ <signal name="toggled" handler="on_cmp_l_toggled"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVSeparator" id="vseparator9">
+ <property name="height_request">7</property>
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="over_toggle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Overflow</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_overflow_toggled" last_modification_time="Mon, 21 Jun 2004 11:44:04 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label266">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Flags </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame6">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">1</property>
+
+ <child>
+ <widget class="GtkEntry" id="loc_entry">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">4</property>
+ <property name="text" translatable="yes">0</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">6</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="loc_arrow">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">View loc address</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_loc_arrow_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">1</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1323">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Location </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame2">
+ <property name="border_width">2</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkLabel" id="label258">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Uptime:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="uptime_label">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">00000000</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">5</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label260">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Elapsed:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="elapsed_label">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">000000</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">5</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label261">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Program:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="program_label">
+ <property name="width_request">0</property>
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">000000</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">5</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label263">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Times </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame4">
+ <property name="border_width">7</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="memory_scroll">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="memory_cells">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label265">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Memory </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1414">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">MIX Virtual Machine </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">2</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="input_dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">MIX Console input</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+ <signal name="destroy_event" handler="gtk_widget_hide" last_modification_time="Wed, 23 Jun 2004 20:54:59 GMT"/>
+ <signal name="close" handler="gtk_widget_hide" last_modification_time="Wed, 23 Jun 2004 20:55:16 GMT"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox12">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area12">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label1438">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Enter up to 70 characters</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="input_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">70</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">70</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/mixgtk/mixgtk.gladep b/mixgtk/mixgtk.gladep
new file mode 100644
index 0000000..40a311a
--- /dev/null
+++ b/mixgtk/mixgtk.gladep
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+ <name>Mixgtk</name>
+ <program_name>mixgtk</program_name>
+ <pixmaps_directory>.</pixmaps_directory>
+ <gnome_support>FALSE</gnome_support>
+</glade-project>
diff --git a/mixgtk/mixgtk.h b/mixgtk/mixgtk.h
new file mode 100644
index 0000000..913c245
--- /dev/null
+++ b/mixgtk/mixgtk.h
@@ -0,0 +1,49 @@
+/* -*-c-*- ---------------- mixgtk.h :
+ * Gmixvm initialisation and cleanup functions
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <2001-04-29 12:06:48 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_H
+#define MIXGTK_H
+
+#include <gtk/gtk.h>
+#include <mixlib/mix.h>
+
+/* the app files directory */
+#define MIXGTK_FILES_DIR ".mdk"
+
+/* initialise the app */
+extern gboolean
+mixgtk_init (int argc, char *argv[]);
+
+/* enter the main mixgtk loop */
+extern void
+mixgtk_main (void);
+
+/* clean up */
+extern void
+mixgtk_release (void);
+
+
+
+#endif /* MIXGTK_H */
+
diff --git a/mixgtk/mixgtk_cmd_dispatcher.c b/mixgtk/mixgtk_cmd_dispatcher.c
new file mode 100644
index 0000000..dbb2909
--- /dev/null
+++ b/mixgtk/mixgtk_cmd_dispatcher.c
@@ -0,0 +1,547 @@
+/* -*-c-*- -------------- mixgtk_cmd_dispatcher.c :
+ * Implementation of the functions declared in mixgtk_cmd_dispatcher.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_cmd_dispatcher.c,v 1.24 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <mixlib/mix.h>
+
+#ifdef HAVE_LIBHISTORY
+# include <readline/history.h>
+#endif
+
+#ifdef MAKE_GUILE
+# include <mixguile/mixguile.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
+#include <mixlib/mix_vm_command.h>
+#include "mixgtk_mixvm.h"
+#include "mixgtk_mixal.h"
+#include "mixgtk_fontsel.h"
+#include "mixgtk_config.h"
+#include "mixgtk_cmd_dispatcher.h"
+
+
+/* a mix vm command dispatcher */
+typedef struct mixgtk_dispatch_
+{
+ mix_vm_cmd_dispatcher_t *dispatcher; /* the underlying cmd dispatcher */
+ FILE *out; /* the dispatcher's output file */
+ int fildes[2]; /* pipe for communication with the dispatcher */
+ GtkWidget *prompt; /* the command prompt widget */
+ GtkWidget *log; /* the dispatcher's messages echo area */
+ GtkWidget *status; /* the status bar widget */
+ guint context; /* context of the status bar messages */
+ gchar *last_file;
+} mixgtk_dispatch_data_t;
+
+static struct mixgtk_dispatch_ dis_data_ = {NULL};
+
+static GtkWidget *ext_dlg_ = NULL;
+static GtkWidget *ed_entry_ = NULL;
+static GtkWidget *asm_entry_ = NULL;
+
+static const gchar *ED_NAME_ = "editor_entry";
+static const gchar *ASM_NAME_ = "mixasm_entry";
+
+static const gchar *TITLE_FORMAT_ = "gmixvm - %s";
+
+static void
+log_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd)
+{
+ GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dis->log));
+ GtkTextIter end;
+
+ gtk_text_buffer_get_end_iter (buf, &end);
+ gtk_text_buffer_place_cursor (buf, &end);
+ gtk_text_buffer_insert_at_cursor (buf, "MIX> ", -1);
+ gtk_text_buffer_insert_at_cursor (buf, cmd, -1);
+ gtk_text_buffer_insert_at_cursor (buf, "\n", -1);
+
+#ifdef HAVE_LIBHISTORY
+ add_history ((char *)cmd);
+/* history_search ((char *)cmd, 0); */
+ history_set_pos (history_base + history_length - 1);
+#endif
+}
+
+static void
+flush_log_ (mixgtk_dispatch_data_t *dis)
+{
+ enum {BLKSIZE = 100};
+ static gchar BUFFER[BLKSIZE];
+
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dis->log));
+ GtkTextMark *mark;
+ GtkTextIter end;
+ ssize_t k;
+
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_place_cursor (buffer, &end);
+
+ fflush (dis->out);
+ while ((k = read (dis->fildes[0], BUFFER, BLKSIZE)) != 0)
+ {
+ if (k == -1 && errno != EINTR) break;
+ if (k != -1)
+ gtk_text_buffer_insert_at_cursor (buffer, BUFFER, k);
+ }
+
+ mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (dis->log), mark, 0,
+ TRUE, 0, 0);
+}
+
+/* hooks */
+static void
+global_post_hook_ (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd, const gchar *arg, gpointer data)
+{
+ flush_log_ ((mixgtk_dispatch_data_t *)data);
+ mixgtk_mixvm_update_vm_widgets ();
+}
+
+static void
+load_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ static glong id = -1;
+
+ if (mix_vm_cmd_dispatcher_get_last_result (dis))
+ {
+ GtkWindow *mainw =
+ GTK_WINDOW (mixgtk_widget_factory_get_dialog (MIXGTK_MAIN));
+
+ if (dis_data_.last_file) g_free (dis_data_.last_file);
+ dis_data_.last_file = g_strdup_printf (TITLE_FORMAT_, arg);
+ gtk_window_set_title (mainw, dis_data_.last_file);
+
+ mixgtk_mixal_load_file ();
+ mixgtk_mixal_update ();
+ mixgtk_mixal_update_bp_all ();
+
+ if (id != -1)
+ gtk_statusbar_remove (GTK_STATUSBAR (dis_data_.status),
+ dis_data_.context, (guint)id);
+ id =
+ gtk_statusbar_push (GTK_STATUSBAR (dis_data_.status), dis_data_.context,
+ dis_data_.last_file);
+ }
+}
+
+static void
+run_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ mixgtk_mixal_update ();
+}
+
+static void
+next_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ mixgtk_mixal_update ();
+}
+
+static void
+linebp_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ if (arg && strlen (arg)) mixgtk_mixal_update_bp_at_line (atoi (arg));
+}
+
+static void
+addrbp_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ if (arg && strlen (arg)) mixgtk_mixal_update_bp_at_address (atoi (arg));
+}
+
+static void
+allbp_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
+ gpointer data)
+{
+ mixgtk_mixal_update_bp_all ();
+}
+
+
+static void
+install_hooks_ (void)
+{
+ mix_vm_cmd_dispatcher_global_post_hook (dis_data_.dispatcher,
+ global_post_hook_,
+ (gpointer)(&dis_data_));
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_LOAD, load_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_RUN, run_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_NEXT, next_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_SBP, linebp_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_CBP, linebp_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_SBPA, addrbp_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_CBPA, addrbp_post_hook_,
+ NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
+ MIX_CMD_CABP, allbp_post_hook_,
+ NULL);
+}
+
+/* configuration stuff */
+static const gchar *EDITOR_KEY_ = "Editor";
+static const gchar *MIXASM_KEY_ = "Mixasm";
+
+static void
+read_config_ (void)
+{
+ const gchar *editor = mixgtk_config_get (EDITOR_KEY_);
+ const gchar *assem = mixgtk_config_get (MIXASM_KEY_);
+
+ if (!editor)
+ {
+ static const gchar *ENV[] = {"MDK_EDITOR", "X_EDITOR", NULL};
+ gchar *edit = NULL;
+ int k = 0;
+ while (!edit && ENV[k]) edit = getenv (ENV[k++]);
+ if (edit) edit = g_strconcat (edit, " %s", NULL);
+ else edit = g_strdup ("xterm -e vi %s");
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, edit);
+ g_free (edit);
+ }
+ else
+ {
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, editor);
+ }
+ if (!assem) assem = "mixasm %s";
+ mix_vm_cmd_dispatcher_set_assembler (dis_data_.dispatcher, assem);
+
+}
+
+void
+on_external_programs_activate ()
+{
+ if (!ext_dlg_)
+ {
+ ext_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_EXTERNPROG_DIALOG);
+ g_return_if_fail (ext_dlg_ != NULL);
+ ed_entry_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_EXTERNPROG_DIALOG, ED_NAME_);
+ g_assert (ed_entry_);
+ asm_entry_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_EXTERNPROG_DIALOG, ASM_NAME_);
+ g_assert (asm_entry_);
+ }
+ gtk_entry_set_text (GTK_ENTRY (ed_entry_),
+ mix_vm_cmd_dispatcher_get_editor (dis_data_.dispatcher));
+ gtk_entry_set_text (GTK_ENTRY (asm_entry_),
+ mix_vm_cmd_dispatcher_get_assembler
+ (dis_data_.dispatcher));
+ gtk_widget_show (ext_dlg_);
+ if (gtk_dialog_run (GTK_DIALOG (ext_dlg_)) == GTK_RESPONSE_OK)
+ {
+ const gchar *value = gtk_entry_get_text (GTK_ENTRY (ed_entry_));
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, value);
+ mixgtk_config_update (EDITOR_KEY_, value);
+ value = gtk_entry_get_text (GTK_ENTRY (asm_entry_));
+ mix_vm_cmd_dispatcher_set_assembler (dis_data_.dispatcher, value);
+ mixgtk_config_update (MIXASM_KEY_, value);
+ }
+
+ gtk_widget_hide (ext_dlg_);
+}
+
+/* initialise the command dispatcher */
+gboolean
+mixgtk_cmd_dispatcher_init (mixgtk_dialog_id_t top)
+{
+ static gboolean restart = FALSE;
+ gchar *text = NULL;
+
+ ext_dlg_ = NULL;
+ ed_entry_ = NULL;
+ asm_entry_ = NULL;
+
+ dis_data_.prompt =
+ mixgtk_widget_factory_get (top, MIXGTK_WIDGET_PROMPT);
+ g_return_val_if_fail (dis_data_.prompt != NULL, FALSE);
+
+ if (dis_data_.log)
+ text = gtk_editable_get_chars (GTK_EDITABLE (dis_data_.log), 0, -1);
+
+ dis_data_.log =
+ mixgtk_widget_factory_get (top, MIXGTK_WIDGET_LOG);
+
+ g_return_val_if_fail (dis_data_.log != NULL, FALSE);
+
+ if (text)
+ {
+ gtk_text_buffer_insert_at_cursor
+ (gtk_text_view_get_buffer (GTK_TEXT_VIEW (dis_data_.log)), text, -1);
+ g_free (text);
+ }
+
+ if (!dis_data_.dispatcher)
+ {
+ static const gchar *HISTORY_FILE = "gmixvm.history";
+ static gint HISTORY_SIZE = 100;
+ mix_config_t *config = mixgtk_config_get_mix_config ();
+
+ int r = pipe (dis_data_.fildes);
+ g_return_val_if_fail (r == 0, FALSE);
+ /* connect stdout/stderr to the pipe's write end */
+ if (dup2 (dis_data_.fildes[1], STDOUT_FILENO) == -1
+ || dup2 (dis_data_.fildes[1], STDOUT_FILENO) == -1)
+ return FALSE;
+ dis_data_.out = fdopen (dis_data_.fildes[1], "w");
+ g_return_val_if_fail (dis_data_.out != NULL, FALSE);
+ r = fcntl (dis_data_.fildes[0], F_GETFL, 0);
+ g_return_val_if_fail (r != -1, FALSE);
+ r |= O_NONBLOCK;
+ r = fcntl(dis_data_.fildes[0], F_SETFL, r);
+ g_return_val_if_fail (r != -1, FALSE);
+
+ if (!mix_config_get_history_file (config))
+ mix_config_set_history_file (config, HISTORY_FILE);
+ if (mix_config_get_history_size (config) == 0)
+ mix_config_set_history_size (config, HISTORY_SIZE);
+
+ dis_data_.dispatcher =
+ mix_vm_cmd_dispatcher_new_with_config (dis_data_.out,
+ dis_data_.out,
+ config);
+ mix_vm_cmd_dispatcher_print_time (dis_data_.dispatcher, FALSE);
+
+ install_hooks_ ();
+ }
+
+ dis_data_.status =
+ mixgtk_widget_factory_get (MIXGTK_MAIN, MIXGTK_WIDGET_STATUSBAR);
+ g_return_val_if_fail (dis_data_.status != NULL, FALSE);
+ dis_data_.context = gtk_statusbar_get_context_id (GTK_STATUSBAR
+ (dis_data_.status),
+ "cmd_dis_context");
+ if (!restart) read_config_ ();
+ if (dis_data_.last_file)
+ gtk_window_set_title
+ (GTK_WINDOW (mixgtk_widget_factory_get_dialog (MIXGTK_MAIN)),
+ dis_data_.last_file);
+
+ mixgtk_fontsel_set_font (MIX_FONT_LOG, dis_data_.log);
+ mixgtk_fontsel_set_font (MIX_FONT_PROMPT, dis_data_.prompt);
+
+ restart = TRUE;
+ return TRUE;
+}
+
+/* dispatch an externally provided command */
+#ifdef MAKE_GUILE
+static gboolean
+try_guile_ (const gchar *command)
+{
+ if (command && command[0] == '(' && command[strlen (command) - 1] == ')')
+ {
+ mixguile_interpret_command (command);
+ return TRUE;
+ }
+ return FALSE;
+}
+#else
+# define try_guile_(ignored) FALSE
+#endif
+
+void
+mixgtk_cmd_dispatcher_dispatch (const gchar *command)
+{
+ GtkWidget *entry = dis_data_.prompt;
+ g_return_if_fail (command != NULL);
+ g_assert (entry != NULL);
+ gtk_entry_set_text (GTK_ENTRY (entry), command);
+ log_command_ (&dis_data_, command);
+ if (!try_guile_ (command))
+ mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, command);
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+}
+
+/* get times */
+void
+mixgtk_cmd_dispatcher_get_times (gint *uptime, gint *progtime, gint *laptime)
+{
+ if (uptime != NULL)
+ *uptime = mix_vm_cmd_dispatcher_get_uptime (dis_data_.dispatcher);
+ if (progtime != NULL)
+ *progtime = mix_vm_cmd_dispatcher_get_progtime (dis_data_.dispatcher);
+ if (laptime != NULL)
+ *laptime = mix_vm_cmd_dispatcher_get_laptime (dis_data_.dispatcher);
+}
+
+/* get the underlying vm */
+mix_vm_t *
+mixgtk_cmd_dispatcher_get_vm (void)
+{
+ return (mix_vm_t *) mix_vm_cmd_dispatcher_get_vm (dis_data_.dispatcher);
+}
+
+/* get the current source file */
+const gchar *
+mixgtk_cmd_dispatcher_get_src_path (void)
+{
+ return mix_vm_cmd_dispatcher_get_src_file_path (dis_data_.dispatcher);
+}
+
+/* get the mix cmd dispatcher */
+mix_vm_cmd_dispatcher_t *
+mixgtk_cmd_dispatcher_get_mix_dispatcher (void)
+{
+ return dis_data_.dispatcher;
+}
+
+/* process commands */
+void
+complete_command_ (void)
+{
+ GtkEntry *entry = GTK_ENTRY (dis_data_.prompt);
+ gchar *prefix = NULL;
+ const gchar *text = gtk_entry_get_text (entry);
+ const GList *cmds =
+ mix_vm_cmd_dispatcher_complete (dis_data_.dispatcher, text, &prefix);
+
+ if (prefix != NULL)
+ {
+ GtkTextBuffer *buf =
+ gtk_text_view_get_buffer (GTK_TEXT_VIEW (dis_data_.log));
+
+ gtk_entry_set_text (entry, prefix);
+ if (g_list_length ((GList *)cmds) > 1)
+ {
+ static gchar BUFFER[25];
+ gint k = 0;
+ gtk_text_buffer_insert_at_cursor (buf, "Completions:\n", -1);
+ while (cmds)
+ {
+ g_snprintf (BUFFER, 25, "%-12s", (const char*)cmds->data);
+ ++k;
+ gtk_text_buffer_insert_at_cursor (buf, BUFFER, -1);
+ if (k%5 == 0)
+ gtk_text_buffer_insert_at_cursor (buf, "\n", -1);
+
+ cmds = cmds->next;
+ }
+ if (k%5 != 0)
+ gtk_text_buffer_insert_at_cursor (buf, "\n", -1);
+ }
+ else
+ {
+ gint pos = strlen (prefix);
+ gtk_editable_insert_text (GTK_EDITABLE (entry), " ", 1, &pos);
+ }
+ flush_log_ (&dis_data_);
+ g_free (prefix);
+ }
+}
+
+int
+on_command_prompt_key_press_event (GtkEntry *w, GdkEventKey *e, gpointer d)
+{
+ guint key = e->keyval;
+ gboolean result = FALSE;
+
+#ifdef HAVE_LIBHISTORY
+ HIST_ENTRY *entry = NULL;
+ if (key == GDK_Up)
+ {
+ entry = previous_history ();
+ if (entry && entry->line)
+ gtk_entry_set_text (w, entry->line);
+ result = TRUE;
+ }
+ if (key == GDK_Down)
+ {
+ entry = next_history ();
+ if (entry && entry->line)
+ gtk_entry_set_text (w, entry->line);
+ result = TRUE;
+ }
+#endif
+
+ if (key == GDK_Tab)
+ {
+ complete_command_ ();
+ result = TRUE;
+ }
+
+ if (result) gtk_editable_set_position (GTK_EDITABLE (w), -1);
+
+ return result;
+}
+
+void
+on_command_prompt_activate (GtkEntry *prompt, gpointer data)
+{
+ gchar *text =
+ g_strstrip (gtk_editable_get_chars (GTK_EDITABLE (prompt), 0, -1));
+ if (text && *text)
+ {
+ log_command_ (&dis_data_, text);
+ if (!try_guile_ (text))
+ mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
+ gtk_entry_set_text (prompt, "");
+ }
+ g_free (text);
+}
+
+void
+on_log_font_activate ()
+{
+ GtkWidget *w[] = { dis_data_.log };
+ mixgtk_fontsel_query_font (MIX_FONT_LOG, w, 1);
+}
+
+void
+on_prompt_font_activate ()
+{
+ GtkWidget *w[] = { dis_data_.prompt };
+ mixgtk_fontsel_query_font (MIX_FONT_PROMPT, w, 1);
+}
+
+void
+mixgtk_cmd_dispatcher_update_fonts (void)
+{
+ mixgtk_fontsel_set_font (MIX_FONT_LOG, dis_data_.log);
+ mixgtk_fontsel_set_font (MIX_FONT_PROMPT, dis_data_.prompt);
+}
diff --git a/mixgtk/mixgtk_cmd_dispatcher.h b/mixgtk/mixgtk_cmd_dispatcher.h
new file mode 100644
index 0000000..25ca240
--- /dev/null
+++ b/mixgtk/mixgtk_cmd_dispatcher.h
@@ -0,0 +1,61 @@
+/* -*-c-*- ---------------- mixgtk_cmd_dispatcher.h :
+ * functions to access the command dispatcher
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_cmd_dispatcher.h,v 1.6 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_CMD_DISPATCHER_H
+#define MIXGTK_CMD_DISPATCHER_H
+
+#include <mixlib/mix_vm.h>
+#include <mixlib/mix_vm_command.h>
+#include "mixgtk_widgets.h"
+
+/* initialise the command dispatcher */
+extern gboolean
+mixgtk_cmd_dispatcher_init (mixgtk_dialog_id_t top);
+
+extern void
+mixgtk_cmd_dispatcher_update_fonts (void);
+
+/* dispatch an externally provided command */
+extern void
+mixgtk_cmd_dispatcher_dispatch (const gchar *command);
+
+/* get times */
+extern void
+mixgtk_cmd_dispatcher_get_times (gint *uptime, gint *progtime, gint *laptime);
+
+/* get the underlying vm */
+extern mix_vm_t *
+mixgtk_cmd_dispatcher_get_vm (void);
+
+/* get the current source file */
+extern const gchar *
+mixgtk_cmd_dispatcher_get_src_path (void);
+
+/* get the mix cmd dispatcher */
+extern mix_vm_cmd_dispatcher_t *
+mixgtk_cmd_dispatcher_get_mix_dispatcher (void);
+
+
+#endif /* MIXGTK_CMD_DISPATCHER_H */
+
diff --git a/mixgtk/mixgtk_config.c b/mixgtk/mixgtk_config.c
new file mode 100644
index 0000000..275d182
--- /dev/null
+++ b/mixgtk/mixgtk_config.c
@@ -0,0 +1,113 @@
+/* -*-c-*- -------------- mixgtk_config.c :
+ * Implementation of the functions declared in mixgtk_config.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_config.c,v 1.10 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "mixgtk.h"
+#include "mixgtk_config.h"
+
+static const gchar *MIXGTK_CONFIG_FILE_ = "gmixvm.config";
+static const gchar *SHOW_TB_KEY = "Toolbars";
+static const gchar *TB_YES = "Yes";
+static const gchar *TB_NO = "No";
+
+static mix_config_t *config_ = NULL;
+
+/* load configuration */
+gboolean
+mixgtk_config_load (void)
+{
+ if (config_ == NULL)
+ {
+ gchar *cdir = g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S,
+ MIXGTK_FILES_DIR, NULL);
+ config_ = mix_config_new (cdir, MIXGTK_CONFIG_FILE_);
+ g_free (cdir);
+ }
+ return (config_ != NULL);
+}
+
+/* get mixlib config */
+mix_config_t *
+mixgtk_config_get_mix_config (void)
+{
+ return config_;
+}
+
+/* autosave state */
+gboolean
+mixgtk_config_is_autosave (void)
+{
+ return mix_config_is_autosave (config_);
+}
+
+void
+mixgtk_config_set_autosave (gboolean autosave)
+{
+ mix_config_set_autosave (config_, autosave);
+}
+
+/* update config item */
+void
+mixgtk_config_update (const gchar *key, const gchar *value)
+{
+ mix_config_update (config_, key, value);
+}
+
+/* get config item */
+const gchar *
+mixgtk_config_get (const gchar *key)
+{
+ return mix_config_get (config_, key);
+}
+
+void
+mixgtk_config_remove (const char *key)
+{
+ mix_config_remove (config_, key);
+}
+
+/* save configuration */
+void
+mixgtk_config_save (void)
+{
+ mix_config_save (config_);
+}
+
+gboolean
+mixgtk_config_show_toolbars (void)
+{
+ const gchar *show = mixgtk_config_get (SHOW_TB_KEY);
+ return (!show || !strcmp (show, TB_YES));
+}
+
+void
+mixgtk_config_set_show_toolbars (gboolean show)
+{
+ mixgtk_config_update (SHOW_TB_KEY, show? TB_YES : TB_NO);
+}
diff --git a/mixgtk/mixgtk_config.h b/mixgtk/mixgtk_config.h
new file mode 100644
index 0000000..7c3f548
--- /dev/null
+++ b/mixgtk/mixgtk_config.h
@@ -0,0 +1,70 @@
+/* -*-c-*- ---------------- mixgtk_config.h :
+ * Configuration functions declarations.
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_config.h,v 1.7 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_CONFIG_H
+#define MIXGTK_CONFIG_H
+
+#include <mixlib/mix.h>
+#include <mixlib/mix_config.h>
+
+/* load configuration */
+extern gboolean
+mixgtk_config_load (void);
+
+/* get mix config */
+extern mix_config_t *
+mixgtk_config_get_mix_config (void);
+
+/* autosave state */
+extern gboolean
+mixgtk_config_is_autosave (void);
+
+extern void
+mixgtk_config_set_autosave (gboolean autosave);
+
+/* update config item */
+extern void
+mixgtk_config_update (const gchar *key, const gchar *value);
+
+/* get config item */
+extern const gchar *
+mixgtk_config_get (const gchar *key);
+
+/* remove config item */
+extern void
+mixgtk_config_remove (const gchar *key);
+
+/* save configuration */
+extern void
+mixgtk_config_save (void);
+
+/* shared config params */
+extern gboolean
+mixgtk_config_show_toolbars (void);
+
+extern void
+mixgtk_config_set_show_toolbars (gboolean show);
+
+#endif /* MIXGTK_CONFIG_H */
+
diff --git a/mixgtk/mixgtk_device.c b/mixgtk/mixgtk_device.c
new file mode 100644
index 0000000..203933c
--- /dev/null
+++ b/mixgtk/mixgtk_device.c
@@ -0,0 +1,625 @@
+/* -*-c-*- ---------------- mixgtk_device.c :
+ * actual types for mixgtk devices
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_device.c,v 1.26 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mixlib/mix_vm_command.h>
+#include <mixlib/xmix_device.h>
+
+#include "mixgtk.h"
+#include "mixgtk_gen_handlers.h"
+#include "mixgtk_widgets.h"
+#include "mixgtk_fontsel.h"
+#include "mixgtk_config.h"
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk_device.h"
+
+#define BIN_DEV_COL_ 5
+
+static const gchar *DEV_FORMAT_KEY_ = "Device.format";
+
+/* device container */
+static GtkNotebook *dev_nb_ = NULL;
+/* devdir dialog */
+static GtkWidget *devdir_dlg_ = NULL;
+static GtkEntry *devdir_entry_ = NULL;
+/* terminal input dialog */
+static GtkWidget *input_dlg_ = NULL;
+static GtkEntry *input_dlg_entry_ = NULL;
+
+/** configuration stuff */
+#define LAST_BIN_DEV_ mix_dev_DISK_7
+static GtkWidget *devdlg_ = NULL;
+static GtkWidget *dtoggle_ = NULL;
+static GtkWidget *wtoggle_ = NULL;
+static GtkWidget *combo_ = NULL;
+
+/* virtual machine */
+static mix_vm_t *vm_ = NULL;
+/* dec settings */
+static gint32 decs_ = 0;
+static gint32 new_decs_ = 0;
+
+/* macros manipulating dec settings */
+#define IS_DEC(flags,type) (((flags) >> (type)) & 1)
+#define SET_DEC(flags,type) ((flags) |= (1<<(type)))
+#define CLEAR_DEC(flags,type) ((flags) &= ~(1<<(type)))
+
+/* a mixgtk device */
+struct mixgtk_device_t
+{
+ mix_device_t device;
+ GtkWidget *widget;
+ GtkWidget *scroll;
+};
+
+struct mixgtk_bin_device_t
+{
+ struct mixgtk_device_t gtk_device;
+ guint last_insert;
+ GtkListStore *store;
+ gboolean dec;
+};
+
+/* callbacks for output devices */
+static void
+write_char_ (struct mixgtk_device_t *dev, const mix_word_t *block)
+{
+ enum {MAX_BLOCK = 16, BUFF_SIZE = MAX_BLOCK * 5 + 2};
+ static gchar BUFFER[BUFF_SIZE];
+
+ guint k, j;
+ GtkTextIter end;
+ GtkTextBuffer *buffer;
+ GtkTextMark *mark;
+
+ for (k = 0; k < SIZES_[dev->device.type]; k++)
+ for (j = 1; j < 6; j++)
+ {
+ mix_char_t ch = mix_word_get_byte (block[k], j);
+ BUFFER[5 * k + j - 1] = mix_char_to_ascii (ch);
+ }
+
+ BUFFER[5 * k] = '\n';
+ BUFFER[5 * k + 1] = '\0';
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dev->widget));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_place_cursor (buffer, &end);
+ gtk_text_buffer_insert_at_cursor (buffer, BUFFER, -1);
+ mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (dev->widget), mark, 0,
+ TRUE, 0, 0);
+}
+
+static const gchar *
+get_word_string_ (mix_word_t w, gboolean dec)
+{
+ enum {BUFF_SIZE = 17};
+ static gchar BUFFER[BUFF_SIZE] = { 0 };
+ if (dec)
+ g_snprintf (BUFFER, BUFF_SIZE, "%s%011ld",
+ mix_word_is_negative (w)? "-" : "+",
+ mix_word_magnitude (w));
+ else
+ mix_word_print_to_buffer (w, BUFFER);
+ return BUFFER;
+}
+
+static void
+write_bin_ (struct mixgtk_bin_device_t *dev, const mix_word_t *block)
+{
+ guint k, col;
+ gboolean dec = FALSE;
+ size_t len;
+
+ GtkTreeView *view = GTK_TREE_VIEW (dev->gtk_device.widget);
+ GtkListStore *store = dev->store;
+ GtkTreeIter iter;
+
+ g_assert (view);
+ g_assert (store);
+
+ dec = IS_DEC(decs_, dev->gtk_device.device.type);
+
+ for (k = 0, len = SIZES_[dev->gtk_device.device.type];
+ k < len; k += BIN_DEV_COL_)
+ {
+ gtk_list_store_append (store, &iter);
+ for (col = 0; col < BIN_DEV_COL_; ++col)
+ gtk_list_store_set (store, &iter,
+ col, get_word_string_ (block[k + col], dec),
+ col + BIN_DEV_COL_, (guint)block[k + col],
+ -1);
+ dev->last_insert++;
+ }
+}
+
+static gboolean
+write_ (mix_device_t *dev, const mix_word_t *block)
+{
+ struct mixgtk_device_t *gtkdev = (struct mixgtk_device_t *) dev;
+
+ if (dev->type != mix_dev_CONSOLE && !(DEF_DEV_VTABLE_->write)(dev, block))
+ return FALSE;
+
+ if (MODES_[dev->type] == mix_dev_CHAR) write_char_ (gtkdev, block);
+ else write_bin_ ((struct mixgtk_bin_device_t *)gtkdev, block);
+
+ gtk_notebook_set_current_page (dev_nb_,
+ gtk_notebook_page_num (dev_nb_,
+ gtkdev->scroll));
+
+ return TRUE;
+}
+
+static gboolean
+read_cons_ (mix_word_t *block)
+{
+ gchar *text;
+ size_t i, j;
+
+ if (input_dlg_ == NULL)
+ {
+ input_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_INPUT_DIALOG);
+ g_assert (input_dlg_);
+ input_dlg_entry_ = GTK_ENTRY (mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_INPUT_DIALOG, "input_entry"));
+ g_assert (input_dlg_entry_);
+ }
+
+ gtk_entry_set_text (input_dlg_entry_, "");
+ gtk_dialog_run (GTK_DIALOG (input_dlg_));
+ gtk_widget_hide (input_dlg_);
+ text = g_strdup_printf ("%-70s", gtk_entry_get_text (input_dlg_entry_));
+ for (i = 0; i < 70; ++i)
+ for (j = 0; j < 5; ++j)
+ mix_word_set_byte (block + i, j + 1,
+ mix_char_to_byte
+ (mix_ascii_to_char (text[5 * i + j])));
+ g_free (text);
+ return TRUE;
+}
+
+static gboolean
+read_ (mix_device_t *dev, mix_word_t *block)
+{
+ struct mixgtk_device_t *gtkdev = (struct mixgtk_device_t *) dev;
+
+ if (dev->type == mix_dev_CONSOLE && !read_cons_ (block)) return FALSE;
+
+ if (dev->type != mix_dev_CONSOLE && !(DEF_DEV_VTABLE_->read)(dev, block))
+ return FALSE;
+
+ if (MODES_[dev->type] == mix_dev_CHAR) write_char_ (gtkdev, block);
+ else write_bin_ ((struct mixgtk_bin_device_t *)gtkdev, block);
+
+ gtk_notebook_set_current_page (dev_nb_,
+ gtk_notebook_page_num (dev_nb_,
+ gtkdev->scroll));
+ return TRUE;
+}
+
+static gboolean
+ioc_ (mix_device_t *dev, mix_short_t cmd)
+{
+ return (DEF_DEV_VTABLE_->ioc)(dev, cmd);
+}
+
+static gboolean
+busy_ (const mix_device_t *dev)
+{
+ return (DEF_DEV_VTABLE_->busy)(dev);
+}
+
+static void
+destroy_ (mix_device_t *dev)
+{
+ struct mixgtk_device_t *gtkdev = (struct mixgtk_device_t *)dev;
+ if (MODES_[dev->type] == mix_dev_BIN) {
+ struct mixgtk_bin_device_t * bdev = (struct mixgtk_bin_device_t *)dev;
+ gtk_list_store_clear (bdev->store);
+ g_object_unref ((gpointer)bdev->store);
+ }
+ (DEF_DEV_VTABLE_->destroy) (dev);
+ gtk_notebook_remove_page (dev_nb_,
+ gtk_notebook_page_num (dev_nb_,
+ gtkdev->scroll));
+}
+
+static mix_device_vtable_t MIXGTK_VTABLE_ = {
+ write_, read_, ioc_, busy_, destroy_
+};
+
+/* create the gui part of the device */
+static void
+mixgtk_device_construct_gui_ (struct mixgtk_device_t *dev)
+{
+ GtkWidget *label = gtk_label_new (DEF_NAMES_[dev->device.type]);
+
+ g_assert (label);
+
+ dev->scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dev->scroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ if (MODES_[dev->device.type] == mix_dev_CHAR)
+ {
+ dev->widget = gtk_text_view_new ();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (dev->widget), FALSE);
+ }
+ else
+ {
+ gint k;
+ struct mixgtk_bin_device_t *bindev = (struct mixgtk_bin_device_t *)dev;
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+ GType *types = g_new (GType, BIN_DEV_COL_ * 2);
+
+ for (k = 0; k < BIN_DEV_COL_; ++k)
+ {
+ types[k] = G_TYPE_STRING;
+ types[k + BIN_DEV_COL_] = G_TYPE_UINT;
+ }
+
+ bindev->store = gtk_list_store_newv (BIN_DEV_COL_ * 2, types);
+
+ dev->widget =
+ gtk_tree_view_new_with_model (GTK_TREE_MODEL (bindev->store));
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dev->widget), FALSE);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dev->widget), TRUE);
+
+ for (k = 0; k < BIN_DEV_COL_; ++k)
+ {
+ gtk_tree_view_append_column
+ (GTK_TREE_VIEW (dev->widget),
+ gtk_tree_view_column_new_with_attributes ("", renderer,
+ "text", k, NULL));
+ }
+
+
+ g_free (types);
+ }
+
+ g_assert (dev->widget);
+ gtk_container_add (GTK_CONTAINER (dev->scroll), dev->widget);
+ mixgtk_fontsel_set_font (MIX_FONT_DEVICES, dev->widget);
+ gtk_notebook_append_page (dev_nb_, dev->scroll, label);
+ gtk_widget_show (label);
+ gtk_widget_show (dev->scroll);
+ gtk_widget_show (dev->widget);
+}
+
+static void
+redraw_bin_device_ (struct mixgtk_bin_device_t *dev)
+{
+ if (dev != NULL)
+ {
+ GtkTreeModel *store = GTK_TREE_MODEL (dev->store);
+ GtkTreeIter iter;
+ gboolean valid;
+
+ g_assert (store);
+
+ valid =
+ gtk_tree_model_get_iter_first (store, &iter);
+
+ while (valid)
+ {
+ gint k;
+ guint word;
+
+ for (k = 0; k < BIN_DEV_COL_; ++k)
+ {
+ gtk_tree_model_get (store, &iter, k + BIN_DEV_COL_, &word, -1);
+ gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+ k, get_word_string_ ((mix_word_t)word,
+ dev->dec),
+ -1);
+ }
+ valid = gtk_tree_model_iter_next (store, &iter);
+ }
+ gtk_widget_queue_draw (((struct mixgtk_device_t *)dev)->widget);
+ }
+}
+
+
+/* create a new mixgtk device */
+static mix_device_t *
+mixgtk_device_new_ (mix_device_type_t type)
+{
+ struct mixgtk_device_t *dev = NULL;
+
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+
+ if (MODES_[type] == mix_dev_CHAR)
+ {
+ dev = g_new (struct mixgtk_device_t, 1);
+ }
+ else
+ {
+ dev = (struct mixgtk_device_t *) g_new (struct mixgtk_bin_device_t, 1);
+ ((struct mixgtk_bin_device_t *)dev)->last_insert = 0;
+ }
+
+ construct_device_ (&dev->device, type);
+
+ dev->device.vtable = &MIXGTK_VTABLE_;
+
+ mixgtk_device_construct_gui_ (dev);
+
+ return (mix_device_t *)dev;
+}
+
+/* init default devices */
+GtkWidget *
+mixgtk_device_init (mix_vm_t *vm)
+{
+ g_assert (vm != NULL);
+
+ vm_ = vm;
+ devdlg_ = NULL;
+ devdir_dlg_ = NULL;
+ devdir_entry_ = NULL;
+ input_dlg_ = NULL;
+ dtoggle_ = NULL;
+ wtoggle_ = NULL;
+ combo_ = NULL;
+
+ if (dev_nb_ == NULL)
+ {
+ mix_vm_set_device_factory (vm, mixgtk_device_new_);
+
+ /* read format configuration */
+ if (mixgtk_config_get (DEV_FORMAT_KEY_))
+ decs_ = atoi (mixgtk_config_get (DEV_FORMAT_KEY_));
+
+ dev_nb_ = GTK_NOTEBOOK (gtk_notebook_new ());
+ gtk_notebook_set_tab_pos (dev_nb_, GTK_POS_RIGHT);
+ gtk_notebook_set_scrollable (dev_nb_, FALSE);
+ }
+
+ mixgtk_fontsel_set_font (MIX_FONT_DEVICES, GTK_WIDGET (dev_nb_));
+
+ return GTK_WIDGET (dev_nb_);
+}
+
+void
+mixgtk_device_set_format (mix_device_type_t dev, gboolean dec)
+{
+ gboolean changed;
+
+ g_return_if_fail (dev < mix_dev_INVALID);
+
+ changed = (dec && !IS_DEC (decs_, dev)) || (!dec && IS_DEC (decs_, dev));
+
+ if (changed && (MODES_[dev] == mix_dev_BIN))
+ {
+ struct mixgtk_bin_device_t *gdev =
+ (struct mixgtk_bin_device_t *) mix_vm_get_device (vm_, dev);
+
+ if (gdev != NULL)
+ {
+ if (dec) SET_DEC (decs_, dev); else CLEAR_DEC (decs_, dev);
+ gdev->dec = !(gdev->dec);
+ redraw_bin_device_ (gdev);
+ }
+ }
+}
+
+
+static mix_device_type_t
+get_device_idx_ (void)
+{
+ int k;
+ const gchar *name = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (combo_)->child));
+ for (k = 0; k <= LAST_BIN_DEV_; ++k)
+ if (!strcmp (name, DEF_NAMES_[k])) break;
+ return k;
+}
+
+static void
+init_devform_ (void)
+{
+ devdlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_DEVFORM_DIALOG);
+ g_assert (devdlg_);
+ dtoggle_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "decradio");
+ g_assert (dtoggle_);
+ wtoggle_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "wordradio");
+ g_assert (wtoggle_);
+ combo_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "dev_combo");
+ g_assert (combo_);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_BIN (combo_)->child), FALSE);
+}
+
+void
+on_dev_combo_changed ()
+{
+ mix_device_type_t dev = get_device_idx_ ();
+ if (dev <= LAST_BIN_DEV_)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dtoggle_),
+ IS_DEC (new_decs_, dev));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wtoggle_),
+ !IS_DEC (new_decs_, dev));
+ }
+}
+
+void
+on_devform_activate ()
+{
+ gint result = GTK_RESPONSE_APPLY;
+
+ if (!devdlg_) init_devform_ ();
+ new_decs_ = decs_;
+
+ while (result == GTK_RESPONSE_APPLY)
+ {
+ //on_dev_combo_changed ();
+ result = gtk_dialog_run (GTK_DIALOG (devdlg_));
+ if (result != GTK_RESPONSE_CANCEL)
+ {
+ int k;
+ gchar value[20];
+ for (k = 0; k <= LAST_BIN_DEV_; ++k)
+ mixgtk_device_set_format (k, IS_DEC (new_decs_, k));
+ decs_ = new_decs_;
+ g_snprintf (value, 20, "%d", decs_);
+ mixgtk_config_update (DEV_FORMAT_KEY_, value);
+ }
+ }
+
+ gtk_widget_hide (devdlg_);
+}
+
+void
+on_decradio_toggled (GtkToggleButton *button)
+{
+ if (gtk_toggle_button_get_active (button))
+ SET_DEC (new_decs_, get_device_idx_ ());
+ else
+ CLEAR_DEC (new_decs_, get_device_idx_ ());
+}
+
+void
+on_devset_button_clicked ()
+{
+ static gint32 ON = 0xffff, OFF = 0;
+ new_decs_ = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dtoggle_)))?
+ ON : OFF;
+}
+
+void
+on_devdir_activate ()
+{
+ static const gchar *DEVDIR_ENTRY_NAME = "devdir_entry";
+ if (devdir_dlg_ == NULL)
+ {
+ devdir_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_DEVDIR_DIALOG);
+ g_assert (devdir_dlg_);
+ devdir_entry_ = GTK_ENTRY
+ (mixgtk_widget_factory_get_child_by_name (MIXGTK_DEVDIR_DIALOG,
+ DEVDIR_ENTRY_NAME));
+ g_assert (devdir_entry_);
+ }
+ gtk_entry_set_text (devdir_entry_, mix_device_get_dir ());
+ gtk_widget_show (devdir_dlg_);
+}
+
+void
+on_devdir_browse_clicked ()
+{
+ GtkWidget *dialog;
+ const gchar *current = gtk_entry_get_text (devdir_entry_);
+
+ dialog =
+ gtk_file_chooser_dialog_new (_("Devices folder"),
+ GTK_WINDOW (devdir_dlg_),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if (current != NULL)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), current);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ char *filename
+ = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ gtk_entry_set_text (devdir_entry_, filename);
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+void
+on_devdir_cancel_clicked ()
+{
+ gtk_widget_hide (devdir_dlg_);
+}
+
+void
+on_devdir_ok_clicked ()
+{
+ const gchar *dirname = gtk_entry_get_text (devdir_entry_);
+ gchar *cmd = g_strconcat (mix_vm_command_to_string (MIX_CMD_SDDIR),
+ " ", dirname, NULL);
+ gtk_widget_hide (devdir_dlg_);
+ mixgtk_cmd_dispatcher_dispatch (cmd);
+ g_free (cmd);
+}
+
+
+
+/* fonts */
+static GtkWidget **
+font_widgets_ (gint * n)
+{
+ gint no = gtk_notebook_get_n_pages (dev_nb_);
+ GtkWidget **w = g_new (GtkWidget *, no + 1);
+ gint k, j;
+
+ for (k = 0, j = 0; k < no && j < mix_dev_INVALID; ++j)
+ {
+ struct mixgtk_device_t * dev =
+ (struct mixgtk_device_t *) mix_vm_get_device (vm_, j);
+ if (dev != NULL) w[k++] = dev->widget;
+ }
+
+ g_assert (k == no);
+ w[k] = GTK_WIDGET (dev_nb_);
+
+ if (n) *n = no;
+
+ return w;
+}
+
+void
+on_devices_font_activate ()
+{
+ gint no = 0;
+ GtkWidget **w = font_widgets_ (&no);
+ mixgtk_fontsel_query_font (MIX_FONT_DEVICES, w, no + 1);
+ g_free (w);
+}
+
+void
+mixgtk_device_update_fonts (void)
+{
+ gint k, n = 0;
+ GtkWidget **w = font_widgets_ (&n);
+
+ g_assert (n >= 0);
+
+ for (k = 0; k < n; ++k)
+ mixgtk_fontsel_set_font (MIX_FONT_DEVICES, w[k]);
+}
diff --git a/mixgtk/mixgtk_device.h b/mixgtk/mixgtk_device.h
new file mode 100644
index 0000000..69859f3
--- /dev/null
+++ b/mixgtk/mixgtk_device.h
@@ -0,0 +1,45 @@
+/* -*-c-*- ---------------- mixgtk_device.h :
+ * Block devices used by mixgtk
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/03/04 23:43:59 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_DEVICE_H
+#define MIXGTK_DEVICE_H
+
+#include <gtk/gtk.h>
+#include <mixlib/mix_vm.h>
+#include <mixlib/mix_device.h>
+
+/* init default devices */
+extern GtkWidget *
+mixgtk_device_init (mix_vm_t *vm);
+
+extern void
+mixgtk_device_update_fonts (void);
+
+/* change the output format of a device */
+extern void
+mixgtk_device_set_format (mix_device_type_t dev, gboolean dec);
+
+
+#endif /* MIXGTK_DEVICE_H */
+
diff --git a/mixgtk/mixgtk_fontsel.c b/mixgtk/mixgtk_fontsel.c
new file mode 100644
index 0000000..e88793b
--- /dev/null
+++ b/mixgtk/mixgtk_fontsel.c
@@ -0,0 +1,142 @@
+/* -*-c-*- -------------- mixgtk_fontsel.c :
+ * Implementation of the functions declared in mixgtk_fontsel.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_fontsel.c,v 1.19 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <mixlib/mix.h>
+#include "mixgtk_widgets.h"
+#include "mixgtk_config.h"
+#include "mixgtk_mixvm.h"
+#include "mixgtk_mixal.h"
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk_device.h"
+#include "mixgtk_fontsel.h"
+
+static GtkFontSelectionDialog *fontsel_dialog_ = NULL;
+
+static const gchar *keys_[MIX_FONT_NO] = {
+ "MIX.font", "Prompt.font", "Log.font", "MIXAL.font", "Devices.font",
+ "Symbols.font", "Default.font"
+};
+
+
+/* initialise the font selection dialog */
+static void
+init_fontsel_ (void)
+{
+ fontsel_dialog_ =
+ GTK_FONT_SELECTION_DIALOG
+ (mixgtk_widget_factory_get_dialog (MIXGTK_FONTSEL_DIALOG));
+ g_assert (fontsel_dialog_ != NULL);
+}
+
+void
+mixgtk_fontsel_set_font (mixgtk_font_t f, GtkWidget *w)
+{
+ const gchar *font;
+ PangoFontDescription *font_desc;
+
+ if (f >= MIX_FONT_NO || w == NULL) return;
+
+ font = mixgtk_config_get (keys_[f]);
+ if (!font)
+ {
+ mixgtk_config_update (keys_[f], "Monospace 10");
+ font = mixgtk_config_get (keys_[f]);
+ g_assert (font);
+ }
+
+ font_desc = pango_font_description_from_string (font);
+
+ if (font_desc)
+ {
+ gtk_widget_modify_font (w, font_desc);
+ gtk_widget_queue_draw (w);
+ pango_font_description_free (font_desc);
+ }
+ else
+ mixgtk_config_remove (keys_[f]);
+
+}
+
+gboolean
+mixgtk_fontsel_query_font (mixgtk_font_t f, GtkWidget **w, size_t no)
+{
+ gint result = GTK_RESPONSE_APPLY;
+ const gchar *current;
+ gboolean ret = FALSE;
+
+ if (f >= MIX_FONT_NO) return FALSE;
+ if (!fontsel_dialog_) init_fontsel_ ();
+
+ current = mixgtk_config_get (keys_[f]);
+ gtk_font_selection_dialog_set_font_name (fontsel_dialog_,
+ current? current : "Monospace 10");
+
+ while (result == GTK_RESPONSE_APPLY)
+ {
+ result = gtk_dialog_run (GTK_DIALOG (fontsel_dialog_));
+ if (result != GTK_RESPONSE_CANCEL)
+ {
+ gint k;
+ mixgtk_config_update
+ (keys_[f],
+ gtk_font_selection_dialog_get_font_name (fontsel_dialog_));
+ for (k = 0; k < no; ++k)
+ mixgtk_fontsel_set_font (f, w[k]);
+ ret = TRUE;
+ }
+ }
+ gtk_widget_hide (GTK_WIDGET (fontsel_dialog_));
+ return ret;
+}
+
+void
+on_all_fonts_activate (void)
+{
+ gint result = GTK_RESPONSE_APPLY;
+ const gchar *current;
+
+ if (!fontsel_dialog_) init_fontsel_ ();
+
+ current = mixgtk_config_get (keys_[MIX_FONT_DEFAULT]);
+ gtk_font_selection_dialog_set_font_name (fontsel_dialog_,
+ current? current : "Monospace");
+
+ while (result == GTK_RESPONSE_APPLY)
+ {
+ result = gtk_dialog_run (GTK_DIALOG (fontsel_dialog_));
+ if (result != GTK_RESPONSE_CANCEL)
+ {
+ gint k;
+ current = gtk_font_selection_dialog_get_font_name (fontsel_dialog_);
+
+ for (k = 0; k < MIX_FONT_NO; ++k)
+ mixgtk_config_update (keys_[k], current);
+
+ mixgtk_mixal_update_fonts ();
+ mixgtk_mixvm_update_fonts ();
+ mixgtk_device_update_fonts ();
+ mixgtk_cmd_dispatcher_update_fonts ();
+ }
+ }
+ gtk_widget_hide (GTK_WIDGET (fontsel_dialog_));
+}
diff --git a/mixgtk/mixgtk_fontsel.h b/mixgtk/mixgtk_fontsel.h
new file mode 100644
index 0000000..2228ed6
--- /dev/null
+++ b/mixgtk/mixgtk_fontsel.h
@@ -0,0 +1,51 @@
+/* -*-c-*- ---------------- mixgtk_fontsel.h :
+ * Functions for handling font selection.
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_fontsel.h,v 1.8 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_FONTSEL_H
+#define MIXGTK_FONTSEL_H
+
+#include <glib.h>
+#include "mixgtk_widgets.h"
+
+typedef enum {
+ MIX_FONT_MIXVM,
+ MIX_FONT_LOG,
+ MIX_FONT_PROMPT,
+ MIX_FONT_MIXAL,
+ MIX_FONT_DEVICES,
+ MIX_FONT_SYMBOLS,
+ MIX_FONT_DEFAULT,
+ MIX_FONT_NO
+} mixgtk_font_t;
+
+/* configured fonts */
+extern void
+mixgtk_fontsel_set_font (mixgtk_font_t f, GtkWidget *w);
+
+extern gboolean
+mixgtk_fontsel_query_font (mixgtk_font_t f, GtkWidget **ws, size_t no);
+
+
+#endif /* MIXGTK_FONTSEL_H */
+
diff --git a/mixgtk/mixgtk_gen_handlers.c b/mixgtk/mixgtk_gen_handlers.c
new file mode 100644
index 0000000..151feac
--- /dev/null
+++ b/mixgtk/mixgtk_gen_handlers.c
@@ -0,0 +1,165 @@
+/* -*-c-*- -------------- mixgtk_gen_handlers.c :
+ * Implementation of the functions declared in mixgtk_gen_handlers.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_gen_handlers.c,v 1.10 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <mixlib/mix_vm_command.h>
+#include "mixgtk_gen_handlers.h"
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk_config.h"
+
+/* grab a file with an externally provided callback */
+void
+mixgtk_get_file (file_callback_t callback,
+ const gchar *title,
+ const gchar *pattern,
+ const gchar *def_file)
+{
+ if (callback != NULL)
+ {
+ GtkWidget *dialog;
+
+ dialog =
+ gtk_file_chooser_dialog_new (title,
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if (pattern != NULL)
+ {
+ GtkFileFilter *filter = gtk_file_filter_new ();
+ gtk_file_filter_add_pattern (filter, pattern);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
+ }
+
+ if (def_file != NULL)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), def_file);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ char *filename;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ callback (filename);
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (dialog);
+ }
+}
+
+/* exec prompt command */
+static void
+exec_cmd_ (mix_vm_command_t cmd, const gchar *arg)
+{
+ gchar *command;
+ if (arg)
+ command = g_strdup_printf ("%s %s",
+ mix_vm_command_to_string (cmd),
+ arg);
+ else
+ command = g_strdup (mix_vm_command_to_string (cmd));
+ mixgtk_cmd_dispatcher_dispatch (command);
+ g_free (command);
+}
+
+/* load mix binary */
+static void
+open_cb_ (const gchar *file)
+{
+ if (file)
+ exec_cmd_ (MIX_CMD_LOAD, file);
+}
+
+void
+on_file_open_activate (GtkWidget *w, gpointer data)
+{
+ mixgtk_get_file (open_cb_, _("Load MIX program..."), "*.mix", NULL);
+}
+
+/* edit mixal source */
+static void
+edit_cb_ (const gchar *file)
+{
+ exec_cmd_ (MIX_CMD_EDIT, file);
+}
+
+void
+on_file_edit_activate (GtkWidget *w, gpointer data)
+{
+ mixgtk_get_file (edit_cb_, _("Edit MIXAL source file..."), "*.mixal",
+ mixgtk_cmd_dispatcher_get_src_path ());
+}
+
+/* compile mixal source */
+static void
+compile_cb_ (const gchar *file)
+{
+ exec_cmd_ (MIX_CMD_COMPILE, file);
+}
+
+void
+on_file_compile_activate (GtkWidget *w, gpointer data)
+{
+ mixgtk_get_file (compile_cb_, _("Compile MIXAL source file..."), "*.mixal",
+ mixgtk_cmd_dispatcher_get_src_path ());
+}
+
+void
+on_debug_run_activate (GtkWidget *w, gpointer p)
+{
+ mixgtk_cmd_dispatcher_dispatch (mix_vm_command_to_string (MIX_CMD_RUN));
+}
+
+void
+on_debug_next_activate (GtkWidget *w, gpointer p)
+{
+ mixgtk_cmd_dispatcher_dispatch (mix_vm_command_to_string (MIX_CMD_NEXT));
+}
+
+
+void
+on_file_exit_activate (GtkWidget *w, gpointer data)
+{
+ gtk_main_quit ();
+}
+
+void
+on_clear_breakpoints_activate (GtkWidget *w, gpointer data)
+{
+ mixgtk_cmd_dispatcher_dispatch (mix_vm_command_to_string (MIX_CMD_CABP));
+}
+
+void
+on_save_on_exit_toggle (GtkWidget *w, gpointer data)
+{
+ mixgtk_config_set_autosave (GTK_CHECK_MENU_ITEM (w)->active);
+}
+
+void
+on_save_activate (GtkWidget *w, gpointer data)
+{
+ mixgtk_config_save ();
+}
+
+
diff --git a/mixgtk/mixgtk_gen_handlers.h b/mixgtk/mixgtk_gen_handlers.h
new file mode 100644
index 0000000..c82c195
--- /dev/null
+++ b/mixgtk/mixgtk_gen_handlers.h
@@ -0,0 +1,62 @@
+/* -*-c-*- ---------------- mixgtk_gen_handlers.h :
+ * general signal handlers declarations
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_gen_handlers.h,v 1.7 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_GEN_HANDLERS_H
+#define MIXGTK_GEN_HANDLERS_H
+
+#include <gtk/gtk.h>
+
+extern void
+on_main_window_destroy (GtkWidget *w, gpointer data);
+
+extern void
+on_file_open_activate (GtkWidget *w, gpointer data);
+
+extern void
+on_file_exit_activate (GtkWidget *w, gpointer data);
+
+extern void
+on_file_edit_activate (GtkWidget *w, gpointer data);
+
+extern void
+on_file_compile_activate (GtkWidget *w, gpointer data);
+
+extern void
+on_clear_breakpoints_activate (GtkWidget *w, gpointer data);
+
+extern void
+on_save_on_exit_toggle (GtkWidget *w, gpointer data);
+
+extern void
+on_save_activate (GtkWidget *w, gpointer data);
+
+typedef void (*file_callback_t)(const gchar *file);
+
+extern void
+mixgtk_get_file (file_callback_t callback, const gchar *title,
+ const gchar *pattern, const gchar *def_file);
+
+
+#endif /* MIXGTK_GEN_HANDLERS_H */
+
diff --git a/mixgtk/mixgtk_input.c b/mixgtk/mixgtk_input.c
new file mode 100644
index 0000000..238fadd
--- /dev/null
+++ b/mixgtk/mixgtk_input.c
@@ -0,0 +1,233 @@
+/* -*-c-*- -------------- mixgtk_input.c :
+ * Implementation of the functions declared in mixgtk_input.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_input.c,v 1.7 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mixgtk_widgets.h"
+#include "mixgtk_input.h"
+
+enum {
+ MSG_, SIGN_, B1_, B2_, B3_, B4_, B5_, DEC_, RESET_, OK_, SIZE_
+};
+
+static const gchar *WGT_NAMES_[SIZE_] = {
+ "word_label", "word_sign", "word_b1", "word_b2", "word_b3",
+ "word_b4", "word_b5", "word_decimal", "word_reset", "word_ok"
+};
+
+static GtkDialog *dialog_ = NULL;
+static GtkWidget *childs_[SIZE_];
+static input_callback_t callback_;
+static gpointer data_;
+
+
+static void init_dialog_ (void);
+static void set_word_ (mix_word_t word);
+
+
+/* init */
+void
+mixgtk_input_init (void)
+{
+ dialog_ = NULL;
+}
+
+/* get a word */
+void
+mixgtk_input_word (const gchar *message, mix_word_t def,
+ input_callback_t cb, gpointer data)
+{
+ if (!dialog_) init_dialog_ ();
+ gtk_label_set_text (GTK_LABEL (childs_[MSG_]), message);
+ set_word_ (def);
+ callback_ = cb;
+ data_ = data;
+ gtk_widget_show (childs_[B1_]);
+ gtk_widget_show (childs_[B2_]);
+ gtk_widget_show (childs_[B3_]);
+ gtk_widget_show (GTK_WIDGET (dialog_));
+}
+
+/* get a short */
+void
+mixgtk_input_short (const gchar *message, mix_short_t def,
+ input_callback_t cb, gpointer data)
+{
+ if (!dialog_) init_dialog_ ();
+ gtk_label_set_text (GTK_LABEL (childs_[MSG_]), message);
+ set_word_ (mix_word_to_short_fast (def));
+ callback_ = cb;
+ data_ = data;
+ gtk_widget_show (GTK_WIDGET (dialog_));
+ gtk_widget_hide (childs_[B1_]);
+ gtk_widget_hide (childs_[B2_]);
+ gtk_widget_hide (childs_[B3_]);
+}
+
+#include <gdk/gdkkeysyms.h>
+
+/* dec and bytes input handler */
+void
+on_word_dec_changed (GtkEditable *dec, gpointer *data)
+{
+ gchar *txt = gtk_editable_get_chars (dec, 0, -1);
+
+ if (strlen (txt) > 0)
+ {
+ gint val = atoi (txt);
+ set_word_ (mix_word_new (val));
+ }
+ g_free (txt);
+}
+
+void
+on_word_byte_changed (GtkEditable *byte, gpointer *data)
+{
+ gchar *txt = gtk_editable_get_chars (byte, 0, 2);
+
+ if (strlen (txt) > 0)
+ {
+ mix_byte_t bytes[5];
+ gint k;
+ const gchar *s;
+ mix_word_t w;
+
+ for (k = 0; k < 5; ++k)
+ {
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (childs_[B1_ + k]));
+ bytes[k] = mix_byte_new (atoi (text));
+ }
+ w = mix_bytes_to_word (bytes, 5);
+ s = gtk_entry_get_text (GTK_ENTRY (childs_[SIGN_]));
+ if (s && s[0] == '-') mix_word_reverse_sign (w);
+ set_word_ (w);
+ }
+ g_free (txt);
+}
+
+void
+on_word_sign_changed (GtkEditable *sign, gpointer *data)
+{
+ gchar *txt = gtk_editable_get_chars (sign, 0, 1);
+
+ if (strlen (txt) > 0)
+ {
+ gint pos = 0;
+ mix_word_t w =
+ mix_word_new (atoi (gtk_entry_get_text (GTK_ENTRY (childs_[DEC_]))));
+
+ g_signal_handlers_block_by_func (GTK_OBJECT (sign),
+ on_word_sign_changed, data);
+
+ if (txt[0] != '+' && txt[0] != '-') txt[0] = '+';
+ gtk_editable_delete_text (sign, 0, 1);
+ gtk_editable_insert_text (sign, txt, 1, &pos);
+
+ g_signal_handlers_unblock_by_func (GTK_OBJECT (sign),
+ on_word_sign_changed, data);
+ set_word_ (txt[0] == '-' ? mix_word_negative (w) : w);
+ }
+ g_free (txt);
+}
+
+void
+on_word_ok_clicked (GtkWidget *widget, gpointer *data)
+{
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (childs_[DEC_]));
+ mix_word_t w = mix_word_new (atoi (text));
+ if (w == MIX_WORD_ZERO)
+ {
+ const gchar *sign = gtk_entry_get_text (GTK_ENTRY (childs_[SIGN_]));
+ if (sign && sign[0] == '-') mix_word_reverse_sign (w);
+ }
+ callback_ (w, data_);
+ gtk_widget_hide (GTK_WIDGET (dialog_));
+}
+
+void
+on_word_cancel_clicked (GtkWidget *widget, gpointer *data)
+{
+ gtk_widget_hide (GTK_WIDGET (dialog_));
+}
+
+void
+on_word_reset_clicked (GtkWidget *w, gpointer *data)
+{
+ set_word_ (MIX_WORD_ZERO);
+}
+
+static void
+init_dialog_ (void)
+{
+ gint k;
+
+ dialog_ = GTK_DIALOG (mixgtk_widget_factory_get_dialog (MIXGTK_WORD_DIALOG));
+ g_assert (dialog_ != NULL);
+ for (k = 0; k < SIZE_; ++k)
+ {
+ childs_[k] = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_WORD_DIALOG, WGT_NAMES_[k]);
+ g_assert (childs_[k] != NULL);
+ }
+}
+
+static void
+set_word_ (mix_word_t word)
+{
+ enum {SIZE = 50};
+ static gchar BUFFER[SIZE] = {0};
+ gint k;
+ gint val = mix_word_magnitude (word);
+ gboolean neg = mix_word_is_negative (word);
+ g_snprintf (BUFFER, SIZE, "%s%d", neg ? "-" : "", val);
+
+
+ g_signal_handlers_block_by_func (GTK_OBJECT (childs_[DEC_]),
+ on_word_dec_changed, NULL);
+ g_signal_handlers_block_by_func (GTK_OBJECT (childs_[SIGN_]),
+ on_word_sign_changed, NULL);
+ for (k = B1_; k <= B5_; ++k)
+ g_signal_handlers_block_by_func (GTK_OBJECT (childs_[k]),
+ on_word_byte_changed, NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (childs_[DEC_]), BUFFER);
+ gtk_entry_set_text (GTK_ENTRY (childs_[SIGN_]), neg ? "-" : "+");
+
+ for (k = 1; k < 6; ++k)
+ {
+ mix_byte_t b = mix_word_get_byte (word, k);
+ g_snprintf (BUFFER, SIZE, "%d", (int)b);
+ gtk_entry_set_text (GTK_ENTRY (childs_[SIGN_ + k]), BUFFER);
+ }
+
+ for (k = B1_; k <= B5_; ++k)
+ g_signal_handlers_unblock_by_func (GTK_OBJECT (childs_[k]),
+ on_word_byte_changed, NULL);
+ g_signal_handlers_unblock_by_func (GTK_OBJECT (childs_[DEC_]),
+ on_word_dec_changed, NULL);
+ g_signal_handlers_unblock_by_func (GTK_OBJECT (childs_[SIGN_]),
+ on_word_sign_changed, NULL);
+}
+
diff --git a/mixgtk/mixgtk_input.h b/mixgtk/mixgtk_input.h
new file mode 100644
index 0000000..924e90b
--- /dev/null
+++ b/mixgtk/mixgtk_input.h
@@ -0,0 +1,49 @@
+/* -*-c-*- ---------------- mixgtk_input.h :
+ * Declaration of functions for user input
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/03/12 23:35:14 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_INPUT_H
+#define MIXGTK_INPUT_H
+
+#include <mixlib/mix_types.h>
+
+/* callback function type */
+typedef void (*input_callback_t)(mix_word_t result, gpointer data);
+
+/* init */
+extern void
+mixgtk_input_init (void);
+
+/* get a word */
+extern void
+mixgtk_input_word (const gchar *message, mix_word_t def,
+ input_callback_t cb, gpointer data);
+
+/* get a short */
+extern void
+mixgtk_input_short (const gchar *message, mix_short_t def,
+ input_callback_t cb, gpointer data );
+
+
+#endif /* MIXGTK_INPUT_H */
+
diff --git a/mixgtk/mixgtk_mixal.c b/mixgtk/mixgtk_mixal.c
new file mode 100644
index 0000000..50d09a7
--- /dev/null
+++ b/mixgtk/mixgtk_mixal.c
@@ -0,0 +1,580 @@
+/* -*-c-*- -------------- mixgtk_mixal.c :
+ * Implementation of the functions declared in mixgtk_mixal.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_mixal.c,v 1.22 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "mixgtk_widgets.h"
+#include "mixgtk_config.h"
+#include "mixgtk_fontsel.h"
+#include "mixgtk_mixal.h"
+
+static mix_vm_t *vm_ = NULL;
+static GtkTreeView *clist_ = NULL;
+static GtkListStore *clist_store_ = NULL;
+
+static gulong lineno_;
+static GtkStatusbar *status_ = NULL;
+static gint status_context_ = 0;
+static GPtrArray *tips_text_ = NULL;
+
+static GtkWidget *symbols_dlg_ = NULL;
+static GtkTreeView *symbols_view_ = NULL;
+static GtkListStore *symbols_store_ = NULL;
+static const gchar *SYMBOLS_VIEW_NAME_ = "symbols_view";
+
+static const gchar *bp_stock_id_ = NULL;
+static const gchar *pc_stock_id_ = NULL;
+static const guint bp_stock_size_ = GTK_ICON_SIZE_MENU;
+
+enum {
+ CLIST_BP_ID_COL,
+ CLIST_BP_SIZE_COL,
+ CLIST_ADDRESS_COL,
+ CLIST_BYTECODE_COL,
+ CLIST_CODE_COL,
+ CLIST_ADDRESS_NO_COL,
+ CLIST_LINE_NO_COL,
+ CLIST_COL_NO
+};
+
+enum {
+ SYMBOLS_NAME_COL,
+ SYMBOLS_VALUE_COL,
+ SYMBOLS_WORD_COL,
+ SYMBOLS_COL_NO
+};
+
+
+static gboolean
+mixal_event_ (GtkWidget *w, GdkEvent *event, gpointer data);
+
+
+static void
+init_symbols_ (void)
+{
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+
+ symbols_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_SYMBOLS_DIALOG);
+ g_assert (symbols_dlg_);
+ symbols_view_ = GTK_TREE_VIEW
+ (mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_SYMBOLS_DIALOG, SYMBOLS_VIEW_NAME_));
+ g_assert (symbols_view_);
+
+ mixgtk_fontsel_set_font (MIX_FONT_SYMBOLS, GTK_WIDGET (symbols_view_));
+
+ symbols_store_ = gtk_list_store_new (SYMBOLS_COL_NO,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (symbols_store_),
+ SYMBOLS_NAME_COL,
+ GTK_SORT_ASCENDING);
+
+ gtk_tree_view_set_model (symbols_view_, GTK_TREE_MODEL (symbols_store_));
+ g_object_unref (G_OBJECT (symbols_store_));
+ gtk_tree_view_append_column
+ (symbols_view_,
+ gtk_tree_view_column_new_with_attributes ("Name", renderer,
+ "text", SYMBOLS_NAME_COL,
+ NULL));
+ gtk_tree_view_append_column
+ (symbols_view_,
+ gtk_tree_view_column_new_with_attributes ("Value", renderer,
+ "text", SYMBOLS_VALUE_COL,
+ NULL));
+ gtk_tree_view_append_column
+ (symbols_view_,
+ gtk_tree_view_column_new_with_attributes ("", renderer,
+ "text", SYMBOLS_WORD_COL,
+ NULL));
+}
+
+static void
+insert_symbol_ (gpointer symbol, gpointer value, gpointer data)
+{
+ enum {DEC_SIZE = 25, WORD_SIZE = 20};
+ static gchar DEC[DEC_SIZE], WORD[WORD_SIZE];
+
+ GtkTreeIter iter;
+
+ mix_word_t w = (mix_word_t)GPOINTER_TO_INT (value);
+ g_snprintf (DEC, DEC_SIZE, "%s%ld",
+ mix_word_is_negative (w)? "-" : "+",
+ mix_word_magnitude (w));
+ mix_word_print_to_buffer (w, WORD);
+
+ gtk_list_store_append (symbols_store_, &iter);
+ gtk_list_store_set (symbols_store_, &iter,
+ SYMBOLS_NAME_COL, (const gchar*)symbol,
+ SYMBOLS_VALUE_COL, DEC,
+ SYMBOLS_WORD_COL, WORD,
+ -1);
+}
+
+static void
+fill_symbols_ (const mix_symbol_table_t *table)
+{
+ if (symbols_view_)
+ gtk_list_store_clear (symbols_store_);
+ else
+ init_symbols_ ();
+
+ mix_symbol_table_foreach (((mix_symbol_table_t *)table),
+ insert_symbol_, NULL);
+}
+
+static void
+init_clist_ (void)
+{
+ GtkStockItem item;
+
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+ GtkCellRenderer *bprenderer = gtk_cell_renderer_pixbuf_new ();
+
+ clist_ = GTK_TREE_VIEW (gtk_tree_view_new ());
+
+ clist_store_ = gtk_list_store_new (CLIST_COL_NO,
+ G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ gtk_tree_view_set_model (clist_, GTK_TREE_MODEL (clist_store_));
+ g_object_unref (G_OBJECT (clist_store_));
+ gtk_tree_view_set_rules_hint (clist_, TRUE);
+
+ gtk_tree_view_append_column
+ (clist_,
+ gtk_tree_view_column_new_with_attributes ("", bprenderer,
+ "stock-id", CLIST_BP_ID_COL,
+ "stock-size", CLIST_BP_SIZE_COL,
+ NULL));
+ gtk_tree_view_append_column
+ (clist_,
+ gtk_tree_view_column_new_with_attributes ("Address", renderer,
+ "text", CLIST_ADDRESS_COL,
+ NULL));
+ gtk_tree_view_append_column
+ (clist_,
+ gtk_tree_view_column_new_with_attributes ("Bytecode", renderer,
+ "text", CLIST_BYTECODE_COL,
+ NULL));
+ gtk_tree_view_append_column
+ (clist_,
+ gtk_tree_view_column_new_with_attributes ("Source", renderer,
+ "text", CLIST_CODE_COL,
+ NULL));
+
+ if (gtk_stock_lookup (GTK_STOCK_STOP, &item))
+ {
+ bp_stock_id_ = item.stock_id;
+ }
+
+ if (gtk_stock_lookup (GTK_STOCK_GO_FORWARD, &item))
+ {
+ pc_stock_id_ = item.stock_id;
+ }
+
+ symbols_dlg_ = NULL;
+ symbols_view_ = NULL;
+
+ g_signal_connect (G_OBJECT (clist_), "event",
+ G_CALLBACK (mixal_event_), NULL);
+
+
+ mixgtk_fontsel_set_font (MIX_FONT_MIXAL, GTK_WIDGET (clist_));
+
+ gtk_widget_show (GTK_WIDGET (clist_));
+
+}
+
+
+/* initialise the mixal widgets */
+GtkWidget *
+mixgtk_mixal_init (mix_vm_t *vm)
+{
+ if (vm != NULL) vm_ = vm;
+
+ if (vm_ == NULL) return FALSE;
+
+ if (clist_ == NULL) init_clist_ ();
+
+ status_ = NULL;
+
+ return GTK_WIDGET (clist_);
+}
+
+void
+mixgtk_mixal_reparent (GtkStatusbar *status)
+{
+ g_assert (status != NULL);
+ mixgtk_mixal_pop_status ();
+ status_ = status;
+ status_context_ = gtk_statusbar_get_context_id (status_, "MIXAL status");
+}
+
+void
+mixgtk_mixal_update_fonts (void)
+{
+ mixgtk_fontsel_set_font (MIX_FONT_MIXAL, GTK_WIDGET (clist_));
+ mixgtk_fontsel_set_font (MIX_FONT_SYMBOLS, GTK_WIDGET (symbols_view_));
+}
+
+void
+mixgtk_mixal_pop_status (void)
+{
+ if (status_ != NULL)
+ gtk_statusbar_pop (status_, status_context_);
+}
+
+/* load the corresponding mixal file */
+static void
+update_tips_ (const mix_symbol_table_t *table,
+ const gchar *line)
+{
+ enum {SIZE = 256};
+ static gchar BUFFER[256];
+ static const gchar *DELIMITERS = " /+*=-()\t,:\n";
+ if (line)
+ {
+ guint k = 0;
+ gchar *tip = g_strdup ("");
+ gchar *new_tip;
+ gchar **tokens;
+ gchar *text = g_strdup (line);
+ text = g_strdelimit (text, DELIMITERS, ' ');
+ tokens = g_strsplit (g_strstrip (text), " ", -1);
+ while (tokens[k])
+ {
+ if (mix_symbol_table_is_defined (table, tokens[k]))
+ {
+ mix_word_t val = mix_symbol_table_value (table, tokens[k]);
+ g_snprintf (BUFFER, SIZE, "[ %s = %s%ld ]", tokens[k],
+ mix_word_is_negative (val)? "-" : "+",
+ mix_word_magnitude (val));
+ new_tip = g_strconcat (tip, " ", BUFFER, NULL);
+ g_free (tip);
+ tip = new_tip;
+ }
+ ++k;
+ }
+ g_ptr_array_add (tips_text_, (gpointer)tip);
+ g_strfreev (tokens);
+ g_free (text);
+ }
+}
+
+void
+mixgtk_mixal_load_file (void)
+{
+ enum {ADDR_SIZE = 20, CONT_SIZE = 200, WORD_SIZE = 20};
+ static gchar ADDR[ADDR_SIZE], CONT[CONT_SIZE], WORD[WORD_SIZE];
+
+ const mix_src_file_t *file;
+ GtkTreeIter iter;
+
+ g_assert (vm_);
+ g_assert (clist_);
+
+ gtk_list_store_clear (clist_store_);
+ if (tips_text_)
+ {
+ g_ptr_array_free (tips_text_, TRUE);
+ tips_text_ = NULL;
+ }
+
+ file = mix_vm_get_src_file (vm_);
+ if (file != NULL)
+ {
+ gint k;
+
+ mix_address_t addr;
+ const mix_symbol_table_t *table = mix_vm_get_symbol_table (vm_);
+
+ if (table) tips_text_ = g_ptr_array_new ();
+
+ lineno_ = mix_src_file_get_line_no (file);
+
+ for (k = 0; k < lineno_; ++k)
+ {
+ gchar *line =
+ g_strchomp ((gchar *)mix_src_file_get_line (file, k + 1));
+
+ g_snprintf (CONT, CONT_SIZE, " %03d: %s", k + 1, line);
+ addr = mix_vm_get_lineno_address (vm_, k + 1);
+ if (addr != MIX_VM_CELL_NO)
+ {
+ g_snprintf (ADDR, ADDR_SIZE, "%04d", mix_short_magnitude (addr));
+ mix_word_print_to_buffer (mix_vm_get_addr_contents (vm_, addr),
+ WORD);
+ }
+ else
+ {
+ g_snprintf (ADDR, ADDR_SIZE, _("N/A"));
+ g_snprintf (WORD, WORD_SIZE, _("N/A"));
+ }
+ gtk_list_store_append (clist_store_, &iter);
+ gtk_list_store_set (clist_store_, &iter,
+ CLIST_ADDRESS_NO_COL, mix_short_magnitude (addr),
+ CLIST_LINE_NO_COL, k + 1,
+ CLIST_ADDRESS_COL, ADDR,
+ CLIST_CODE_COL, CONT,
+ CLIST_BYTECODE_COL, WORD,
+ CLIST_BP_SIZE_COL, bp_stock_size_,
+ -1);
+ if (table) update_tips_ (table, line);
+ }
+ if (table) fill_symbols_ (table);
+ }
+ else
+ {
+ lineno_ = 0;
+ gtk_list_store_append (clist_store_, &iter);
+ gtk_list_store_set (clist_store_, &iter,
+ CLIST_ADDRESS_NO_COL, MIX_VM_CELL_NO,
+ CLIST_LINE_NO_COL, 0,
+ CLIST_ADDRESS_COL, "",
+ CLIST_CODE_COL, _("Source not available"),
+ CLIST_BYTECODE_COL, "",
+ -1);
+ }
+}
+
+
+/* update the widgets */
+static gint
+find_address_ (gint address)
+{
+ GtkTreeIter iter;
+ gint addr;
+ gint row = 0;
+ gboolean valid =
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (clist_store_), &iter);
+
+ while (valid)
+ {
+ ++row;
+ gtk_tree_model_get (GTK_TREE_MODEL (clist_store_), &iter,
+ CLIST_ADDRESS_NO_COL, &addr, -1);
+ if (addr == address) return row;
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (clist_store_), &iter);
+ }
+ return 0;
+}
+
+static void
+update_bp_ (gint row)
+{
+ if (row > 0)
+ {
+ GtkTreePath *path = gtk_tree_path_new_from_indices (row - 1, -1);
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (clist_store_), &iter, path))
+ {
+ gint address;
+ const gchar *id = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (clist_store_), &iter,
+ CLIST_ADDRESS_NO_COL, &address, -1);
+ if (mix_vm_has_breakpoint_at_address (vm_, address))
+ id = bp_stock_id_;
+ else if (address ==
+ (gint) mix_short_magnitude (mix_vm_get_prog_count (vm_)))
+ id = pc_stock_id_;
+
+ gtk_list_store_set (clist_store_, &iter, CLIST_BP_ID_COL, id, -1);
+ }
+ gtk_tree_path_free (path);
+ }
+}
+
+static void
+select_row_ (gint row)
+{
+ static gint previous = 0;
+
+ if (row > 0 && previous != row)
+ {
+ GtkTreePath *path = gtk_tree_path_new_from_indices (row - 1, -1);
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (clist_store_), &iter, path))
+ {
+ gtk_list_store_set (clist_store_, &iter,
+ CLIST_BP_ID_COL, pc_stock_id_,
+ -1);
+ update_bp_ (previous);
+ previous = row;
+ gtk_tree_view_scroll_to_cell (clist_, path, NULL, FALSE, 0.3, 0);
+ }
+ gtk_tree_path_free (path);
+ }
+}
+
+void
+mixgtk_mixal_update (void)
+{
+ gint addr = 0;
+
+ g_assert (vm_);
+
+ addr = (gint) mix_short_magnitude (mix_vm_get_prog_count (vm_));
+ select_row_ (find_address_ (addr));
+}
+
+/* breakpoints */
+void
+mixgtk_mixal_update_bp_at_address (guint addr)
+{
+ update_bp_ (find_address_ ((gint)addr));
+}
+
+void
+mixgtk_mixal_update_bp_at_line (guint line)
+{
+ update_bp_ ((gint)line);
+}
+
+void
+mixgtk_mixal_update_bp_all (void)
+{
+ gint k;
+ for (k = 1; k <= lineno_; ++k) update_bp_ (k);
+ mixgtk_mixal_update ();
+}
+
+/* callbacks */
+static void
+mixal_row_clicked_ (GtkTreeIter *iter)
+{
+
+ gint addr = MIX_VM_CELL_NO;
+ gtk_tree_model_get (GTK_TREE_MODEL (clist_store_),
+ iter, CLIST_ADDRESS_NO_COL, &addr, -1);
+
+ if (addr < MIX_VM_CELL_NO)
+ {
+ gboolean isset = mix_vm_has_breakpoint_at_address (vm_, addr);
+ if (isset)
+ mix_vm_clear_breakpoint_address (vm_, addr);
+ else
+ mix_vm_set_breakpoint_address (vm_, addr);
+ update_bp_ (find_address_ (addr));
+ }
+}
+
+static void
+mixal_motion_ (GtkTreeIter *iter)
+{
+ static gint last_row = 0;
+ static guint last_message = 0;
+
+ gint row = last_row;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (clist_store_), iter,
+ CLIST_LINE_NO_COL, &row, -1);
+
+ if (row > 0 && row != last_row && tips_text_)
+ {
+ const gchar *msg = NULL;
+ last_row = row;
+ if (last_message)
+ gtk_statusbar_remove (status_, status_context_, last_message);
+ msg = (const gchar *)g_ptr_array_index (tips_text_, row - 1);
+ if (msg)
+ last_message = gtk_statusbar_push (status_, status_context_, msg);
+ else
+ last_message = 0;
+ }
+}
+
+static gboolean
+mixal_event_ (GtkWidget *w, GdkEvent *event, gpointer data)
+{
+ GdkEventType type = event->type;
+ if ((type == GDK_BUTTON_PRESS || type == GDK_MOTION_NOTIFY)
+ && (gtk_tree_view_get_bin_window (clist_) == event->any.window))
+ {
+ gdouble x = (type == GDK_BUTTON_PRESS)? event->button.x : event->motion.x;
+ gdouble y = (type == GDK_BUTTON_PRESS)? event->button.y : event->motion.y;
+ GtkTreeIter iter;
+ GtkTreePath *path = NULL;
+ GtkTreeViewColumn *col = NULL;
+ if (gtk_tree_view_get_path_at_pos (clist_, x, y, &path, &col, NULL, NULL)
+ && gtk_tree_model_get_iter (GTK_TREE_MODEL (clist_store_),
+ &iter, path))
+ {
+ if (type == GDK_BUTTON_PRESS) mixal_row_clicked_ (&iter);
+ else mixal_motion_ (&iter);
+ }
+ if (path) gtk_tree_path_free (path);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+on_symbol_ok_clicked ()
+{
+ gtk_widget_hide (symbols_dlg_);
+}
+
+void
+on_symbols_activate ()
+{
+ if (!symbols_dlg_) init_symbols_ ();
+ gtk_widget_show (symbols_dlg_);
+}
+
+void
+on_mixal_leave_notify_event ()
+{
+ if (status_ != NULL) gtk_statusbar_pop (status_, status_context_);
+}
+
+void
+on_mixal_font_activate ()
+{
+ GtkWidget *w[] = { GTK_WIDGET (clist_) };
+ mixgtk_fontsel_query_font (MIX_FONT_MIXAL, w, 1);
+}
+
+void
+on_symbols_font_activate ()
+{
+ if (symbols_view_ != NULL)
+ {
+ GtkWidget *w[] = { GTK_WIDGET (symbols_view_) };
+ mixgtk_fontsel_query_font (MIX_FONT_SYMBOLS, w, 1);
+ }
+ else
+ mixgtk_fontsel_query_font (MIX_FONT_SYMBOLS, NULL, 0);
+}
diff --git a/mixgtk/mixgtk_mixal.h b/mixgtk/mixgtk_mixal.h
new file mode 100644
index 0000000..1afe9a0
--- /dev/null
+++ b/mixgtk/mixgtk_mixal.h
@@ -0,0 +1,66 @@
+/* -*-c-*- ---------------- mixgtk_mixal.h :
+ * Declarations for functions displaying the mixal source file
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_mixal.h,v 1.8 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_MIXAL_H
+#define MIXGTK_MIXAL_H
+
+#include <gtk/gtk.h>
+#include <mixlib/mix_vm.h>
+#include "mixgtk_widgets.h"
+
+
+/* initialise the mixal widget */
+extern GtkWidget *
+mixgtk_mixal_init (mix_vm_t *vm);
+
+extern void
+mixgtk_mixal_reparent (GtkStatusbar *stat);
+
+/* load the corresponding mixal file */
+extern void
+mixgtk_mixal_load_file (void);
+
+/* update the widget */
+extern void
+mixgtk_mixal_update (void);
+
+extern void
+mixgtk_mixal_update_fonts (void);
+
+extern void
+mixgtk_mixal_pop_status (void);
+
+/* breakpoints */
+extern void
+mixgtk_mixal_update_bp_at_address (guint addr);
+
+extern void
+mixgtk_mixal_update_bp_at_line (guint line);
+
+extern void
+mixgtk_mixal_update_bp_all (void);
+
+
+#endif /* MIXGTK_MIXAL_H */
+
diff --git a/mixgtk/mixgtk_mixvm.c b/mixgtk/mixgtk_mixvm.c
new file mode 100644
index 0000000..cc74e27
--- /dev/null
+++ b/mixgtk/mixgtk_mixvm.c
@@ -0,0 +1,529 @@
+/* -*-c-*- -------------- mixgtk_mixvm.c :
+ * Implementation of the functions declared in mixgtk_mixvm.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_mixvm.c,v 1.16 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <mixlib/xmix_vm.h>
+#include "mixgtk_widgets.h"
+#include "mixgtk_fontsel.h"
+#include "mixgtk_mixvm.h"
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk_input.h"
+
+
+/* Local variables */
+
+#define REGISTER_NO_ (MIXGTK_WIDGET_rI6 - MIXGTK_WIDGET_rA + 1)
+
+static GtkEntry *reg_entries_[REGISTER_NO_];
+static GtkTooltips *tips_ = NULL;
+static GtkEntry *loc_entry_;
+static GtkWidget *goto_ = NULL;
+static GtkEntry *goto_entry_ = NULL;
+static GtkToggleButton *over_button_;
+static GtkToggleButton *cmp_buttons_[3];
+static GtkTreeView *memory_;
+static GtkListStore *mem_store_;
+static GtkLabel *laptime_;
+static GtkLabel *progtime_;
+static GtkLabel *uptime_;
+static mix_vm_t *vm_;
+
+
+/* Static function prototypes */
+static void init_goto_ (void);
+static void update_register_ (mixgtk_widget_id_t reg);
+static gboolean init_mem_ (void);
+
+
+enum {
+ MEM_ADDRESS_COL,
+ MEM_CONTENTS_COL,
+ MEM_COL_NO
+};
+
+
+/* initialise the mixvm widgets */
+gboolean
+mixgtk_mixvm_init (mix_vm_t *vm)
+{
+ int k;
+
+ g_assert (vm != NULL);
+
+ vm_ = vm;
+
+ if (!tips_) tips_ = gtk_tooltips_new ();
+
+ for (k = 0; k < REGISTER_NO_; ++k)
+ {
+ reg_entries_[k] =
+ GTK_ENTRY (mixgtk_widget_factory_get(MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_rA + k));
+ g_assert (reg_entries_[k] != NULL);
+ mixgtk_fontsel_set_font (MIX_FONT_MIXVM,
+ GTK_WIDGET (reg_entries_[k]));
+ }
+
+ loc_entry_ =
+ GTK_ENTRY (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_LOC));
+ g_assert (loc_entry_ != NULL);
+ mixgtk_fontsel_set_font (MIX_FONT_MIXVM, GTK_WIDGET (loc_entry_));
+
+ uptime_ =
+ GTK_LABEL (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_UPTIME));
+ g_assert (uptime_ != NULL);
+
+ progtime_ =
+ GTK_LABEL (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_PROGTIME));
+ g_assert (progtime_ != NULL);
+
+ laptime_ =
+ GTK_LABEL (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_LAPTIME));
+ g_assert (laptime_ != NULL);
+
+ over_button_ =
+ GTK_TOGGLE_BUTTON
+ (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG, MIXGTK_WIDGET_OVER));
+ g_assert (over_button_ != NULL);
+
+ for (k = 0; k < 3; ++k)
+ {
+ cmp_buttons_[k] = GTK_TOGGLE_BUTTON
+ (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_CMP_L +k));
+ g_assert (cmp_buttons_[k] != NULL);
+ }
+ init_mem_ ();
+
+ return TRUE;
+}
+
+static GtkWidget **
+text_widgets_ (gint *n)
+{
+ static GtkWidget *w[REGISTER_NO_ + 2] = { NULL};
+
+ if (w[0] == NULL)
+ {
+ gint k;
+ w[0] = GTK_WIDGET (loc_entry_);
+ w[1] = GTK_WIDGET (memory_);
+ for (k = 0; k < REGISTER_NO_; ++k)
+ w[k + 2] = GTK_WIDGET (reg_entries_[k]);
+ };
+
+ if (n) *n = REGISTER_NO_ + 2;
+
+ return w;
+}
+
+void
+mixgtk_mixvm_update_fonts (void)
+{
+ gint k, n = 0;
+ GtkWidget **w = text_widgets_ (&n);
+ for (k = 0; k < n; ++k)
+ mixgtk_fontsel_set_font (MIX_FONT_MIXVM, w[k]);
+}
+
+/* update register widgets */
+void
+mixgtk_mixvm_update_registers (void)
+{
+ gint k;
+ for (k = MIXGTK_WIDGET_rA; k <= MIXGTK_WIDGET_rI6; ++k)
+ update_register_ (k);
+}
+
+/* update the overflow toggle */
+void
+mixgtk_mixvm_update_over_toggle (void)
+{
+ g_assert (over_button_);
+ gtk_toggle_button_set_active (over_button_,
+ mix_vm_get_overflow (vm_));
+}
+
+/* update the comparison flag */
+void
+mixgtk_mixvm_update_cmp (void)
+{
+ gint toggle;
+
+ g_assert (cmp_buttons_);
+
+ toggle = mix_vm_get_cmpflag (vm_);
+ gtk_toggle_button_set_active (cmp_buttons_[toggle], TRUE);
+}
+
+
+/* update the memory cells */
+void
+mixgtk_mixvm_update_cells (void)
+{
+ static gchar BUFFER[20];
+ GtkTreeIter iter;
+ gboolean valid =
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (mem_store_), &iter);
+ gint k = 0;
+
+ while (valid)
+ {
+ mix_word_print_to_buffer (mix_vm_get_addr_contents (vm_, k++), BUFFER);
+ gtk_list_store_set (mem_store_, &iter, MEM_CONTENTS_COL, BUFFER, -1);
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (mem_store_), &iter);
+ }
+}
+
+void
+mixgtk_mixvm_update_cells_to_address (gint address)
+{
+ GtkTreePath *path = gtk_tree_path_new_from_indices (address, -1);
+
+ if (address >= MIX_VM_CELL_NO) return;
+ gtk_tree_view_scroll_to_cell (memory_, path, NULL, TRUE, 0, 0);
+ gtk_tree_path_free (path);
+}
+
+/* update the loc pointer */
+void
+mixgtk_mixvm_update_loc (void)
+{
+ enum {SIZE = 10 };
+ static gchar BUFFER[SIZE];
+ mix_short_t locval;
+
+ g_assert (loc_entry_);
+
+ locval = mix_vm_get_prog_count (vm_);
+ g_snprintf (BUFFER, SIZE, "%04d", mix_short_magnitude (locval));
+ gtk_entry_set_text (loc_entry_, BUFFER);
+}
+
+/* update times */
+void
+mixgtk_mixvm_update_times (void)
+{
+ enum {SIZE = 20 };
+ static gchar BUFFER[SIZE];
+ gint uptime, progtime, laptime;
+
+ g_assert (uptime_ && progtime_ && laptime_);
+ mixgtk_cmd_dispatcher_get_times (&uptime, &progtime, &laptime);
+ g_snprintf (BUFFER, SIZE, "%d", uptime);
+ gtk_label_set_text (uptime_, BUFFER);
+ g_snprintf (BUFFER, SIZE, "%d", progtime);
+ gtk_label_set_text (progtime_, BUFFER);
+ g_snprintf (BUFFER, SIZE, "%d", laptime);
+ gtk_label_set_text (laptime_, BUFFER);
+}
+
+
+/* update all mixvm widgets */
+void
+mixgtk_mixvm_update_vm_widgets (void)
+{
+ mixgtk_mixvm_update_registers ();
+ mixgtk_mixvm_update_loc ();
+ mixgtk_mixvm_update_over_toggle ();
+ mixgtk_mixvm_update_cmp ();
+ mixgtk_mixvm_update_cells ();
+ mixgtk_mixvm_update_times ();
+}
+
+
+/* update cmp flag */
+void
+on_cmp_e_toggled (GtkWidget *widget, gpointer data)
+{
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ mix_vm_set_cmpflag (vm_, mix_EQ);
+}
+
+void
+on_cmp_l_toggled (GtkWidget *widget, gpointer data)
+{
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ mix_vm_set_cmpflag (vm_, mix_LESS);
+}
+
+void
+on_cmp_g_toggled (GtkWidget *widget, gpointer data)
+{
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ mix_vm_set_cmpflag (vm_, mix_GREAT);
+}
+
+void
+on_overflow_toggled (GtkWidget *widget, gpointer data)
+{
+ mix_vm_set_overflow (vm_, GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+void
+on_loc_arrow_clicked (GtkWidget *widget, gpointer data)
+{
+ gint address = mix_short_magnitude (mix_vm_get_prog_count (vm_));
+ mixgtk_mixvm_update_cells_to_address (address);
+}
+
+static void
+register_AX_ (mix_word_t w, gpointer reg)
+{
+ gint k = GPOINTER_TO_INT (reg);
+ if (k == 0)
+ mix_vm_set_rA (vm_, w);
+ else
+ mix_vm_set_rX (vm_, w);
+ update_register_ (MIXGTK_WIDGET_rA + k);
+}
+
+static void
+register_j_ (mix_word_t w, gpointer data)
+{
+ if (mix_word_is_negative (w)) mix_word_reverse_sign (w);
+ mix_vm_set_rJ (vm_, mix_word_to_short_fast (w));
+ update_register_ (MIXGTK_WIDGET_rJ);
+}
+
+static void
+register_i_ (mix_word_t w, gpointer reg)
+{
+ mix_vm_set_rI (vm_, GPOINTER_TO_INT (reg), mix_word_to_short_fast (w));
+ update_register_ (MIXGTK_WIDGET_rI1 - 1 + GPOINTER_TO_INT (reg));
+}
+
+gboolean
+on_register_click (GtkWidget *w, GdkEvent *e, gpointer data)
+{
+ enum {SIZE = 20};
+ static gchar BUFFER[SIZE];
+ gint k;
+
+ if (w == GTK_WIDGET (reg_entries_[0]))
+ mixgtk_input_word (_("Register A"), mix_vm_get_rA (vm_),
+ register_AX_, GINT_TO_POINTER (0));
+ else if (w == GTK_WIDGET (reg_entries_[1]))
+ mixgtk_input_word (_("Register X"), mix_vm_get_rX (vm_),
+ register_AX_, GINT_TO_POINTER(1));
+ else if (w == GTK_WIDGET (reg_entries_[2]))
+ mixgtk_input_short (_("Register J"), mix_vm_get_rJ (vm_),
+ register_j_, NULL);
+ else for (k = 1; k < 7; ++k)
+ {
+ if (w == GTK_WIDGET (reg_entries_[2 + k]))
+ {
+ g_snprintf (BUFFER, SIZE, _("Register I%d"), k);
+ mixgtk_input_short (BUFFER, mix_vm_get_rI (vm_, k),
+ register_i_, GINT_TO_POINTER (k));
+ break;
+ }
+ }
+ return TRUE;
+}
+
+static void
+mem_cell_ (mix_word_t w, gpointer a)
+{
+ mix_short_t addr = mix_short_new (GPOINTER_TO_INT (a));
+ mix_vm_set_addr_contents (vm_, addr, w);
+ mixgtk_mixvm_update_cells ();
+}
+
+void
+on_mix_font_activate (void)
+{
+ gint n;
+ GtkWidget **w = text_widgets_ (&n);
+ mixgtk_fontsel_query_font (MIX_FONT_MIXVM, w, n);
+}
+
+
+
+/* static functions */
+static void
+init_goto_ (void)
+{
+ goto_ = mixgtk_widget_factory_get_dialog (MIXGTK_GOTO_DIALOG);
+ g_assert (goto_ != NULL);
+ goto_entry_ =
+ GTK_ENTRY (mixgtk_widget_factory_get (MIXGTK_GOTO_DIALOG,
+ MIXGTK_WIDGET_GOTO_ENTRY));
+ g_assert (goto_entry_ != NULL);
+}
+
+static void
+update_register_ (mixgtk_widget_id_t reg)
+{
+ static gchar BUFFER[20];
+ mix_word_t tipval = MIX_WORD_ZERO;
+ switch (reg)
+ {
+ case MIXGTK_WIDGET_rA:
+ tipval = mix_vm_get_rA (vm_);
+ mix_word_print_to_buffer (tipval, BUFFER);
+ break;
+ case MIXGTK_WIDGET_rX:
+ tipval = mix_vm_get_rX (vm_);
+ mix_word_print_to_buffer (tipval, BUFFER);
+ break;
+ case MIXGTK_WIDGET_rJ:
+ tipval = mix_short_to_word_fast (mix_vm_get_rJ (vm_));
+ mix_short_print_to_buffer (mix_vm_get_rJ (vm_), BUFFER);
+ break;
+ case MIXGTK_WIDGET_rI1:
+ case MIXGTK_WIDGET_rI2:
+ case MIXGTK_WIDGET_rI3:
+ case MIXGTK_WIDGET_rI4:
+ case MIXGTK_WIDGET_rI5:
+ case MIXGTK_WIDGET_rI6:
+ {
+ gint k = reg - MIXGTK_WIDGET_rI1 + 1;
+ tipval = mix_short_to_word_fast (mix_vm_get_rI (vm_, k));
+ mix_short_print_to_buffer (mix_vm_get_rI (vm_, k), BUFFER);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ gtk_entry_set_text (reg_entries_[reg - MIXGTK_WIDGET_rA], BUFFER);
+ g_snprintf (BUFFER, 20, "%s%ld", mix_word_is_negative (tipval)? "-" : "",
+ mix_word_magnitude (tipval));
+ gtk_tooltips_set_tip (tips_,
+ GTK_WIDGET (reg_entries_[reg - MIXGTK_WIDGET_rA]),
+ BUFFER, NULL);
+
+}
+
+
+static void
+cells_clicked_ (GtkTreeViewColumn* col, gpointer data)
+{
+ if (!goto_) init_goto_ ();
+ if (gtk_dialog_run (GTK_DIALOG (goto_)) == GTK_RESPONSE_OK)
+ {
+ const gchar *txt = gtk_entry_get_text (goto_entry_);
+ mix_short_t addr = mix_short_new (atoi (txt));
+ if (addr < MIX_VM_CELL_NO)
+ mixgtk_mixvm_update_cells_to_address (addr);
+ }
+ gtk_widget_hide (goto_);
+}
+
+static gboolean
+cont_clicked_ (GtkWidget *w, GdkEvent *event, gpointer data)
+{
+ enum {SIZE = 30};
+ static gchar BUFFER[SIZE];
+
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (memory_));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gint addr;
+
+ gtk_tree_model_get (model, &iter, MEM_ADDRESS_COL, &addr, -1);
+ g_snprintf (BUFFER, SIZE, _("Memory cell no. %d"), addr);
+ mixgtk_input_word
+ (BUFFER,
+ mix_vm_get_addr_contents (vm_, mix_short_new (addr)),
+ mem_cell_, GINT_TO_POINTER (addr));
+ }
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+init_mem_ (void)
+{
+ gint k;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *col;
+
+ /* model */
+
+ mem_store_ = gtk_list_store_new (MEM_COL_NO, G_TYPE_INT, G_TYPE_STRING);
+
+ g_assert (mem_store_);
+
+ for (k = 0; k< MIX_VM_CELL_NO; ++k)
+ {
+ gtk_list_store_append (mem_store_, &iter);
+ gtk_list_store_set (mem_store_, &iter,
+ MEM_ADDRESS_COL, k,
+ MEM_CONTENTS_COL, "+ 00 00 00 00 00",
+ -1);
+ }
+
+ /* view */
+
+ renderer = gtk_cell_renderer_text_new ();
+ memory_ =
+ GTK_TREE_VIEW (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_CELLS));
+
+ g_assert (memory_);
+ g_assert (renderer);
+
+ gtk_tree_view_set_model (memory_, GTK_TREE_MODEL (mem_store_));
+ gtk_tree_view_set_headers_clickable (memory_, TRUE);
+ g_object_unref (G_OBJECT (mem_store_));
+
+ col = gtk_tree_view_column_new_with_attributes ("Address", renderer,
+ "text", 0, NULL);
+ gtk_tree_view_column_set_clickable (col, TRUE);
+ g_signal_connect (G_OBJECT (col), "clicked",
+ G_CALLBACK (cells_clicked_), NULL);
+
+ gtk_tree_view_append_column (memory_, col);
+
+
+ col = gtk_tree_view_column_new_with_attributes ("Contents", renderer,
+ "text", 1, NULL);
+ gtk_tree_view_column_set_clickable (col, TRUE);
+ g_signal_connect (G_OBJECT (col), "clicked",
+ G_CALLBACK (cont_clicked_), NULL);
+
+ gtk_tree_view_append_column (memory_, col);
+
+ g_signal_connect (G_OBJECT (memory_), "event-after",
+ G_CALLBACK (cont_clicked_), NULL);
+
+ mixgtk_fontsel_set_font (MIX_FONT_MIXVM, GTK_WIDGET (memory_));
+
+ return TRUE;
+}
+
diff --git a/mixgtk/mixgtk_mixvm.h b/mixgtk/mixgtk_mixvm.h
new file mode 100644
index 0000000..79a8d72
--- /dev/null
+++ b/mixgtk/mixgtk_mixvm.h
@@ -0,0 +1,72 @@
+/* -*-c-*- ---------------- mixgtk_mixvm.h :
+ * Functions dealing with the mixvm widgets
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_mixvm.h,v 1.6 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_MIXVM_H
+#define MIXGTK_MIXVM_H
+
+#include <mixlib/mix_vm.h>
+#include "mixgtk.h"
+#include "mixgtk_widgets.h"
+
+/* initialise the mixvm widgets */
+extern gboolean
+mixgtk_mixvm_init (mix_vm_t *vm);
+
+extern void
+mixgtk_mixvm_update_fonts (void);
+
+/* update register widgets */
+extern void
+mixgtk_mixvm_update_registers (void);
+
+/* update the overflow toggle */
+extern void
+mixgtk_mixvm_update_over_toggle (void);
+
+/* update the comparison flag */
+extern void
+mixgtk_mixvm_update_cmp (void);
+
+/* update the memory cells */
+extern void
+mixgtk_mixvm_update_cells (void);
+
+extern void
+mixgtk_mixvm_update_cells_to_address (gint address);
+
+/* update the loc pointer */
+extern void
+mixgtk_mixvm_update_loc (void);
+
+/* update times */
+extern void
+mixgtk_mixvm_update_times (void);
+
+/* update all mixvm widgets */
+extern void
+mixgtk_mixvm_update_vm_widgets (void);
+
+
+#endif /* MIXGTK_MIXVM_H */
+
diff --git a/mixgtk/mixgtk_widgets.c b/mixgtk/mixgtk_widgets.c
new file mode 100644
index 0000000..724b578
--- /dev/null
+++ b/mixgtk/mixgtk_widgets.c
@@ -0,0 +1,153 @@
+/* -*-c-*- -------------- mixgtk_widgets.c :
+ * Implementation of the functions declared in mixgtk_widgets.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "2001-04-29 14:32:17 jao"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <unistd.h>
+#include <glade/glade.h>
+#include <mixlib/mix.h>
+#include "mixgtk_config.h"
+#include "mixgtk_widgets.h"
+
+/* dialog names */
+static const gchar * dnames_[] = {
+ "main_window",
+ "mixvm_window",
+ "mixal_window",
+ "devices_window",
+ "word_dialog",
+ "about_dialog",
+ "goto_dialog",
+ "fontsel_dialog",
+ "devform_dialog",
+ "external_dialog",
+ "symbols_dialog",
+ "input_dialog",
+ "devdir_dialog"
+};
+
+#define DLG_NO_ (sizeof (dnames_) / sizeof(dnames_[0]))
+
+/* widget names */
+static const gchar *names_[] = {
+ "main_statusbar",
+ "attach_button",
+ "main_notebook",
+ "mixvm_widget",
+ "mixvm_container",
+ "command_prompt",
+ "command_log",
+ "dev_container",
+ "mixal_container",
+ "mixal_statusbar",
+ "rA_entry",
+ "rX_entry",
+ "rJ_entry",
+ "rI1_entry",
+ "rI2_entry",
+ "rI3_entry",
+ "rI4_entry",
+ "rI5_entry",
+ "rI6_entry",
+ "lesser_radio",
+ "equal_radio",
+ "greater_radio",
+ "over_toggle",
+ "memory_cells",
+ "elapsed_label",
+ "program_label",
+ "uptime_label",
+ "devices_container",
+ "loc_entry",
+ "goto_entry",
+ NULL
+};
+
+#define WIDGET_NO_ (sizeof (names_) / sizeof (names_[0]))
+
+/* the glade specs */
+static GladeXML *xml_[DLG_NO_] = {NULL};
+
+/* the xml file name */
+static const gchar *file_ = NULL;
+
+static void init_xml_ (mixgtk_dialog_id_t dlg)
+{
+ xml_[dlg] = glade_xml_new (file_, dnames_[dlg], NULL);
+ glade_xml_signal_autoconnect (xml_[dlg]);
+ g_assert (xml_[dlg] != NULL);
+}
+
+/* create a new factory from an xml glade file */
+gboolean
+mixgtk_widget_factory_init (void)
+{
+ if (!file_)
+ {
+ const gchar *glade_file = GLADE_FILE;
+ glade_init ();
+ if (access (glade_file, R_OK)) {
+ if (access (LOCAL_GLADE_FILE, R_OK)) return FALSE;
+ glade_file = LOCAL_GLADE_FILE;
+ }
+ file_ = g_strdup (glade_file);
+ }
+ else
+ {
+ gint k;
+ for (k = 0; k < DLG_NO_; ++k) if (xml_[k]) xml_[k] = NULL;
+ }
+
+ init_xml_ (MIXGTK_MAIN);
+ return TRUE;
+}
+
+/* get a widget */
+GtkWidget *
+mixgtk_widget_factory_get (mixgtk_dialog_id_t dlg, mixgtk_widget_id_t widget)
+{
+ g_assert (widget < WIDGET_NO_);
+
+ return mixgtk_widget_factory_get_child_by_name (dlg, names_[widget]);
+}
+
+
+GtkWidget *
+mixgtk_widget_factory_get_dialog (mixgtk_dialog_id_t dlg)
+{
+ g_assert (dlg < DLG_NO_);
+
+ if (!xml_[dlg]) init_xml_ (dlg);
+ return glade_xml_get_widget (xml_[dlg], dnames_[dlg]);
+}
+
+GtkWidget *
+mixgtk_widget_factory_get_child_by_name (mixgtk_dialog_id_t dlg,
+ const gchar *name)
+{
+ g_assert (dlg < DLG_NO_);
+ g_assert (name != NULL);
+ if (!xml_[dlg]) init_xml_ (dlg);
+ return glade_xml_get_widget (xml_[dlg], name);
+}
+
+
diff --git a/mixgtk/mixgtk_widgets.h b/mixgtk/mixgtk_widgets.h
new file mode 100644
index 0000000..720f962
--- /dev/null
+++ b/mixgtk/mixgtk_widgets.h
@@ -0,0 +1,102 @@
+/* -*-c-*- ---------------- mixgtk_widgets.h :
+ * glade-based factory of mixvm widgets
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_widgets.h,v 1.15 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_WIDGETS_H
+#define MIXGTK_WIDGETS_H
+
+#include <gtk/gtk.h>
+#include <mixlib/mix_vm.h>
+
+/* enumeration of gmixvm dialogs */
+typedef enum {
+ MIXGTK_MAIN, /* main app window */
+ MIXGTK_MIXVM_DIALOG, /* mixvm dialog */
+ MIXGTK_MIXAL_DIALOG, /* mixal dialog */
+ MIXGTK_DEVICES_DIALOG, /* devices dialog */
+ MIXGTK_WORD_DIALOG, /* input dialog for a mix word */
+ MIXGTK_ABOUT_DIALOG,
+ MIXGTK_GOTO_DIALOG,
+ MIXGTK_FONTSEL_DIALOG, /* font selection dialog */
+ MIXGTK_DEVFORM_DIALOG, /* device format config dialog */
+ MIXGTK_EXTERNPROG_DIALOG, /* external programs dialog */
+ MIXGTK_SYMBOLS_DIALOG, /* symbol table dialog */
+ MIXGTK_INPUT_DIALOG, /* console input dialog */
+ MIXGTK_DEVDIR_DIALOG /* devices directory chooser */
+} mixgtk_dialog_id_t;
+
+/* enumeration of mixvm widget ids */
+typedef enum {
+ MIXGTK_WIDGET_STATUSBAR,
+ MIXGTK_WIDGET_ATTACH_BUTTON,
+ MIXGTK_WIDGET_NOTEBOOK, /* the notebook */
+ MIXGTK_WIDGET_MIXVM, /* virtual machine */
+ MIXGTK_WIDGET_MIXVM_CONTAINER,
+ MIXGTK_WIDGET_PROMPT, /* command prompt */
+ MIXGTK_WIDGET_LOG, /* command output */
+ MIXGTK_WIDGET_DEV_CONTAINER,
+ MIXGTK_WIDGET_MIXAL_CONTAINER,
+ MIXGTK_WIDGET_MIXAL_STATUSBAR,
+ MIXGTK_WIDGET_rA,
+ MIXGTK_WIDGET_rX,
+ MIXGTK_WIDGET_rJ,
+ MIXGTK_WIDGET_rI1,
+ MIXGTK_WIDGET_rI2,
+ MIXGTK_WIDGET_rI3,
+ MIXGTK_WIDGET_rI4,
+ MIXGTK_WIDGET_rI5,
+ MIXGTK_WIDGET_rI6,
+ MIXGTK_WIDGET_CMP_L,
+ MIXGTK_WIDGET_CMP_E,
+ MIXGTK_WIDGET_CMP_G,
+ MIXGTK_WIDGET_OVER,
+ MIXGTK_WIDGET_CELLS,
+ MIXGTK_WIDGET_LAPTIME,
+ MIXGTK_WIDGET_PROGTIME,
+ MIXGTK_WIDGET_UPTIME,
+ MIXGTK_WIDGET_DEVICES,
+ MIXGTK_WIDGET_LOC,
+ MIXGTK_WIDGET_GOTO_ENTRY,
+ MIXGTK_WIDGET_NONE
+} mixgtk_widget_id_t;
+
+
+/* create a new factory from an xml glade file */
+extern gboolean
+mixgtk_widget_factory_init (void);
+
+/* get a dialog */
+extern GtkWidget *
+mixgtk_widget_factory_get_dialog (mixgtk_dialog_id_t dlg);
+
+/* get a widget */
+extern GtkWidget *
+mixgtk_widget_factory_get (mixgtk_dialog_id_t dlg, mixgtk_widget_id_t widget);
+
+/* Get a widget by name */
+extern GtkWidget *
+mixgtk_widget_factory_get_child_by_name (mixgtk_dialog_id_t dlg,
+ const gchar *name);
+
+#endif /* MIXGTK_WIDGETS_H */
+
diff --git a/mixgtk/mixgtk_wm.c b/mixgtk/mixgtk_wm.c
new file mode 100644
index 0000000..7821d0e
--- /dev/null
+++ b/mixgtk/mixgtk_wm.c
@@ -0,0 +1,573 @@
+/* -*-c-*- -------------- mixgtk_wm.c :
+ * Implementation of the functions declared in mixgtk_wm.h
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_wm.c,v 1.12 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+
+#include "mixgtk_wm.h"
+
+#include "mixgtk_widgets.h"
+#include "mixgtk_config.h"
+#include "mixgtk_device.h"
+#include "mixgtk_mixvm.h"
+#include "mixgtk_mixal.h"
+#include "mixgtk_widgets.h"
+#include "mixgtk_cmd_dispatcher.h"
+#include "mixgtk.h"
+
+
+typedef struct window_info_t_
+{
+ mixgtk_dialog_id_t dialog;
+ GtkWidget *widget;
+ GtkCheckMenuItem *menu;
+ const gchar *menu_name;
+ const gchar *config_key;
+ gboolean detached;
+ void (*detach) (void);
+ void (*attach) (void);
+} window_info_t_;
+
+static const gchar *DETACH_YES_ = "Yes";
+static const gchar *DETACH_NO_ = "No";
+static GtkWidget *about_ = NULL;
+
+static GtkContainer *mixvm_container_ = NULL;
+static GtkContainer *mixal_container_ = NULL;
+static GtkContainer *dev_container_ = NULL;
+
+static const gchar *TB_MENU_NAME_ = "show_toolbars";
+static GtkCheckMenuItem *tb_menu_ = NULL;
+static GtkNotebook *notebook_ = NULL;
+
+static mix_vm_t *vm_ = NULL;
+
+static void init_info_ (void);
+static void init_notebook_ (void);
+static void init_dispatcher_ (void);
+static void init_mixvm_ (void);
+static void init_mixal_ (void);
+static void init_dev_ (void);
+static void init_signals_ (void);
+static void init_visibility_ (void);
+static void init_tb_ (void);
+static void init_about_ (void);
+static void init_autosave_ (void);
+static void show_toolbars_ (gboolean show);
+static void add_page_ (GtkWidget *w, mixgtk_window_id_t id);
+static void mixvm_attach_ (void);
+static void mixvm_detach_ (void);
+static void mixal_attach_ (void);
+static void mixal_detach_ (void);
+static void dev_attach_ (void);
+static void dev_detach_ (void);
+static void on_nb_switch_ (GtkNotebook *notebook, GtkWidget *page,
+ guint page_num, gpointer user_data);
+
+static window_info_t_ infos_[] = {
+ {MIXGTK_MIXVM_DIALOG, NULL, NULL, "detach_vm", "MIX.detach",
+ FALSE, mixvm_detach_, mixvm_attach_},
+ {MIXGTK_MIXAL_DIALOG, NULL, NULL, "detach_source", "MIXAL.detach",
+ FALSE, mixal_detach_, mixal_attach_},
+ {MIXGTK_DEVICES_DIALOG, NULL, NULL, "detach_dev", "Devices.detach",
+ FALSE, dev_detach_, dev_attach_}
+};
+
+static size_t INF_NO_ = sizeof (infos_) / sizeof (infos_[0]);
+
+
+gboolean
+mixgtk_wm_init (void)
+{
+ gint k;
+
+ init_info_ ();
+ init_notebook_ ();
+ init_dispatcher_ ();
+ init_mixvm_ ();
+ init_mixal_ ();
+ init_dev_ ();
+
+ for (k = 0; k < INF_NO_; ++k)
+ {
+ if (infos_[k].detached)
+ mixgtk_wm_detach_window (k);
+ else
+ mixgtk_wm_attach_window (k);
+ }
+
+ init_tb_ ();
+ init_about_ ();
+ init_autosave_ ();
+ init_visibility_ ();
+ init_signals_ ();
+
+ return TRUE;
+}
+
+void
+mixgtk_wm_detach_window (mixgtk_window_id_t w)
+{
+ if (w < INF_NO_)
+ {
+ (*(infos_[w].detach)) ();
+ infos_[w].detached = TRUE;
+ gtk_check_menu_item_set_active (infos_[w].menu, TRUE);
+ mixgtk_config_update (infos_[w].config_key, DETACH_YES_);
+ if (infos_[w].widget != NULL) gtk_widget_show (infos_[w].widget);
+ if (gtk_notebook_get_n_pages (notebook_) < 1)
+ gtk_widget_hide (GTK_WIDGET (notebook_));
+ gtk_widget_show (mixgtk_widget_factory_get_dialog (infos_[w].dialog));
+ }
+}
+
+void
+mixgtk_wm_attach_window (mixgtk_window_id_t w)
+{
+ if (w < INF_NO_)
+ {
+ gint page = gtk_notebook_page_num (notebook_, infos_[w].widget);
+
+ gtk_widget_hide (mixgtk_widget_factory_get_dialog (infos_[w].dialog));
+
+ if (page < 0) (*(infos_[w].attach)) ();
+
+ infos_[w].detached = FALSE;
+ gtk_check_menu_item_set_active (infos_[w].menu, FALSE);
+ mixgtk_config_update (infos_[w].config_key, DETACH_NO_);
+ if (gtk_notebook_get_n_pages (notebook_) == 1)
+ gtk_widget_show (GTK_WIDGET (notebook_));
+ }
+}
+
+
+
+/* callbacks */
+void
+on_detach_clicked (GtkWidget *ignored)
+{
+ gint page = gtk_notebook_get_current_page (notebook_);
+ if (page >= 0)
+ {
+ gint k;
+ GtkWidget *w = gtk_notebook_get_nth_page (notebook_, page);
+
+ for (k = 0; k < INF_NO_; ++k)
+ if (infos_[k].widget == w) mixgtk_wm_detach_window (k);
+ }
+}
+
+void
+on_attach_all_clicked ()
+{
+ gint k;
+ for (k = INF_NO_; k > 0; --k)
+ if (infos_[k - 1].detached) mixgtk_wm_attach_window (k - 1);
+}
+
+void
+on_attach_toggled (GtkCheckMenuItem *item)
+{
+ gint k;
+ for (k = 0; k < INF_NO_; ++k)
+ if (item == infos_[k].menu) break;
+ g_return_if_fail (k < INF_NO_);
+ if (item->active) mixgtk_wm_detach_window (k);
+ else mixgtk_wm_attach_window (k);
+ mixgtk_config_update (infos_[k].config_key,
+ (item->active)? DETACH_YES_ : DETACH_NO_);
+}
+
+void
+on_window_hide (GtkWidget *w)
+{
+ gint k;
+ for (k = 0; k < INF_NO_; ++k)
+ if (w == mixgtk_widget_factory_get_dialog (infos_[k].dialog)) break;
+ g_return_if_fail (k < INF_NO_);
+ mixgtk_wm_attach_window (k);
+}
+
+void
+on_show_toolbars_toggled (GtkCheckMenuItem *item)
+{
+ if (item->active != mixgtk_config_show_toolbars ())
+ show_toolbars_ (item->active);
+}
+
+void
+on_widget_attach (GtkWidget *ign, gpointer id)
+{
+ mixgtk_wm_attach_window (GPOINTER_TO_INT (id));
+}
+
+
+/* about box */
+void
+on_about_activate (GtkWidget *w, gpointer data)
+{
+ if (!about_) init_about_ ();
+ gtk_widget_show (about_);
+}
+
+
+static void
+init_info_ (void)
+{
+ gint k;
+ for (k = 0; k < INF_NO_; ++k)
+ {
+ const gchar *txt;
+
+ infos_[k].menu =
+ GTK_CHECK_MENU_ITEM
+ (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN,
+ infos_[k].menu_name));
+ g_assert (infos_[k].menu != NULL);
+ txt = mixgtk_config_get (infos_[k].config_key);
+ infos_[k].detached = txt && !g_ascii_strcasecmp (txt, DETACH_YES_);
+ }
+}
+
+static void
+init_notebook_ (void)
+{
+ notebook_ =
+ GTK_NOTEBOOK (mixgtk_widget_factory_get (MIXGTK_MAIN,
+ MIXGTK_WIDGET_NOTEBOOK));
+ g_assert (notebook_ != NULL);
+ gtk_widget_show (GTK_WIDGET (notebook_));
+}
+
+static void
+add_page_ (GtkWidget *page, mixgtk_window_id_t id)
+{
+ static const gchar *LABELS[] = {
+ N_("_Virtual machine"), N_("_Source"), N_("_Devices")
+ };
+
+ gint p = 0;
+
+ g_assert (page != NULL);
+ g_assert (id < INF_NO_);
+ g_assert (notebook_ != NULL);
+
+ if (id > MIXGTK_MIXVM_WINDOW)
+ {
+ if (id == MIXGTK_DEVICES_WINDOW)
+ p = gtk_notebook_get_n_pages (notebook_);
+ else
+ p = infos_[MIXGTK_MIXVM_WINDOW].detached ? 0 : 1;
+ }
+
+ gtk_notebook_insert_page (notebook_, page,
+ gtk_label_new_with_mnemonic (LABELS[id]),
+ p);
+ gtk_notebook_set_current_page (notebook_, p);
+ gtk_widget_show (page);
+ gtk_widget_show (GTK_WIDGET (notebook_));
+}
+
+static void
+init_signals_ (void)
+{
+ gint k;
+ for (k = 0; k < INF_NO_; ++k)
+ {
+ GObject *dialog =
+ G_OBJECT (mixgtk_widget_factory_get_dialog (infos_[k].dialog));
+
+ GObject *button =
+ G_OBJECT (mixgtk_widget_factory_get (infos_[k].dialog,
+ MIXGTK_WIDGET_ATTACH_BUTTON));
+
+ g_assert (dialog != NULL);
+ g_assert (button != NULL);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (on_widget_attach), GINT_TO_POINTER (k));
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (on_window_hide), NULL);
+ g_signal_connect (dialog, "destroy_event",
+ G_CALLBACK (on_window_hide), NULL);
+ g_signal_connect (dialog, "delete_event",
+ G_CALLBACK (on_window_hide), NULL);
+ g_signal_connect (G_OBJECT (infos_[k].menu), "toggled",
+ G_CALLBACK (on_attach_toggled), NULL);
+ }
+
+}
+
+static void
+init_visibility_ (void)
+{
+ gint k;
+ for (k = 0; k < INF_NO_; ++k)
+ if (infos_[k].detached)
+ gtk_widget_show (mixgtk_widget_factory_get_dialog (infos_[k].dialog));
+
+ if (gtk_notebook_get_n_pages (notebook_) > 0)
+ gtk_notebook_set_current_page (notebook_, 0);
+
+ gtk_widget_show (mixgtk_widget_factory_get_dialog (MIXGTK_MAIN));
+}
+
+static void
+init_dispatcher_ (void)
+{
+ if (!mixgtk_cmd_dispatcher_init (MIXGTK_MAIN))
+ g_assert (FALSE);
+ vm_ = mixgtk_cmd_dispatcher_get_vm ();
+ g_assert (vm_ != NULL);
+}
+
+static void
+init_mixvm_ (void)
+{
+ GtkContainer *vm =
+ GTK_CONTAINER
+ (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG, MIXGTK_WIDGET_MIXVM));
+
+ mixvm_container_ =
+ GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG,
+ MIXGTK_WIDGET_MIXVM_CONTAINER));
+
+ g_assert (mixvm_container_ != NULL);
+
+ g_assert (vm != NULL);
+ g_object_ref (G_OBJECT (vm));
+ infos_[MIXGTK_MIXVM_WINDOW].widget = GTK_WIDGET (vm);
+
+ mixgtk_mixvm_init (vm_);
+ mixgtk_mixvm_update_vm_widgets ();
+
+ gtk_widget_show (GTK_WIDGET (vm));
+
+}
+
+static void
+init_mixal_ (void)
+{
+ GtkWidget *page = gtk_scrolled_window_new (NULL, NULL);
+ GtkWidget *mixal = mixgtk_mixal_init (vm_);
+
+ g_assert (page != NULL);
+ g_assert (mixal != NULL);
+
+ g_object_ref (page);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_container_add (GTK_CONTAINER (page), mixal);
+
+ infos_[MIXGTK_MIXAL_WINDOW].widget = page;
+
+ mixal_container_ =
+ GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_MIXAL_DIALOG,
+ MIXGTK_WIDGET_MIXAL_CONTAINER));
+
+ g_assert (mixal_container_ != NULL);
+
+ gtk_container_add (mixal_container_, page);
+
+ gtk_widget_show (mixal);
+ gtk_widget_show (page);
+ gtk_widget_show (GTK_WIDGET (mixal_container_));
+}
+
+static void
+init_dev_ (void)
+{
+ GtkWidget *page = gtk_scrolled_window_new (NULL, NULL);
+ GtkWidget *devs = mixgtk_device_init (vm_);
+
+ g_assert (page != NULL);
+ g_assert (devs != NULL);
+
+ g_object_ref (page);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (page), devs);
+
+ infos_[MIXGTK_DEVICES_WINDOW].widget = page;
+
+ dev_container_ =
+ GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_DEVICES_DIALOG,
+ MIXGTK_WIDGET_DEV_CONTAINER));
+
+ g_assert (dev_container_ != NULL);
+
+ gtk_container_add (dev_container_, page);
+
+ gtk_widget_show (devs);
+ gtk_widget_show (page);
+}
+
+static void
+init_tb_ (void)
+{
+ tb_menu_ = GTK_CHECK_MENU_ITEM
+ (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN,
+ TB_MENU_NAME_));
+ g_assert (tb_menu_ != NULL);
+
+ gtk_check_menu_item_set_active (tb_menu_, mixgtk_config_show_toolbars ());
+ show_toolbars_ (mixgtk_config_show_toolbars ());
+
+ g_signal_connect (G_OBJECT (tb_menu_), "toggled",
+ G_CALLBACK (on_show_toolbars_toggled), NULL);
+}
+
+static void
+show_toolbars_ (gboolean show)
+{
+ static const gchar *HANDLE_NAME = "tb_handle";
+
+ int k;
+
+ GtkWidget *handle =
+ mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, HANDLE_NAME);
+
+ if (show)
+ gtk_widget_show (handle);
+ else
+ gtk_widget_hide (handle);
+
+ for (k = 0; k < INF_NO_; ++k)
+ {
+ GtkWidget *hd =
+ mixgtk_widget_factory_get_child_by_name (infos_[k].dialog, HANDLE_NAME);
+ if (show) gtk_widget_show (hd); else gtk_widget_hide (hd);
+ }
+
+ mixgtk_config_set_show_toolbars (show);
+}
+
+static void
+init_autosave_ (void)
+{
+#define AUTOSAVE_ITEM_ "save_on_exit"
+
+ GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM
+ (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, AUTOSAVE_ITEM_));
+ if (item)
+ {
+ gtk_check_menu_item_set_active (item, mixgtk_config_is_autosave ());
+ }
+}
+
+static void
+init_about_ (void)
+{
+#define VERSION_LABEL_ "version_label"
+#define GPL_TEXT_ "gpl_text"
+ GtkWidget *label;
+ about_ = mixgtk_widget_factory_get_dialog (MIXGTK_ABOUT_DIALOG);
+ g_assert (about_ != NULL);
+ label = mixgtk_widget_factory_get_child_by_name (MIXGTK_ABOUT_DIALOG,
+ VERSION_LABEL_);
+ g_assert (label != NULL);
+ gtk_label_set_text (GTK_LABEL (label), VERSION);
+ gtk_widget_show (label);
+}
+
+static void
+mixvm_attach_ (void)
+{
+ gtk_container_remove (mixvm_container_, infos_[MIXGTK_MIXVM_WINDOW].widget);
+ add_page_ (infos_[MIXGTK_MIXVM_WINDOW].widget, MIXGTK_MIXVM_WINDOW);
+}
+
+static void
+mixvm_detach_ (void)
+{
+ gtk_widget_reparent (infos_[MIXGTK_MIXVM_WINDOW].widget,
+ GTK_WIDGET (mixvm_container_));
+}
+
+static void
+mixal_attach_ (void)
+{
+ static GtkStatusbar *stat = NULL;
+
+ if (stat == NULL)
+ {
+ stat =
+ GTK_STATUSBAR
+ (mixgtk_widget_factory_get (MIXGTK_MAIN, MIXGTK_WIDGET_STATUSBAR));
+ g_assert (stat);
+
+ g_signal_connect (G_OBJECT (notebook_), "switch-page",
+ G_CALLBACK (on_nb_switch_), NULL);
+ }
+
+ mixgtk_mixal_reparent (stat);
+ gtk_container_remove (mixal_container_, infos_[MIXGTK_MIXAL_WINDOW].widget);
+ add_page_ (infos_[MIXGTK_MIXAL_WINDOW].widget, MIXGTK_MIXAL_WINDOW);
+}
+
+static void
+mixal_detach_ (void)
+{
+ static GtkStatusbar *stat = NULL;
+
+ if (stat == NULL)
+ {
+ stat =
+ GTK_STATUSBAR
+ (mixgtk_widget_factory_get (MIXGTK_MIXAL_DIALOG,
+ MIXGTK_WIDGET_MIXAL_STATUSBAR));
+ g_assert (stat);
+ }
+
+ mixgtk_mixal_reparent (stat);
+ gtk_widget_reparent (infos_[MIXGTK_MIXAL_WINDOW].widget,
+ GTK_WIDGET (mixal_container_));
+}
+
+static void
+dev_attach_ (void)
+{
+ gtk_container_remove (dev_container_, infos_[MIXGTK_DEVICES_WINDOW].widget);
+ add_page_ (infos_[MIXGTK_DEVICES_WINDOW].widget, MIXGTK_DEVICES_WINDOW);
+}
+
+static void
+dev_detach_ (void)
+{
+ gtk_widget_reparent (infos_[MIXGTK_DEVICES_WINDOW].widget,
+ GTK_WIDGET (dev_container_));
+}
+
+static void
+on_nb_switch_ (GtkNotebook *notebook, GtkWidget *page,
+ guint page_num, gpointer user_data)
+{
+ if (!(infos_[MIXGTK_MIXAL_WINDOW].detached)
+ && (page != infos_[MIXGTK_MIXAL_WINDOW].widget))
+ mixgtk_mixal_pop_status ();
+}
+
+
diff --git a/mixgtk/mixgtk_wm.h b/mixgtk/mixgtk_wm.h
new file mode 100644
index 0000000..878eca6
--- /dev/null
+++ b/mixgtk/mixgtk_wm.h
@@ -0,0 +1,46 @@
+/* -*-c-*- ---------------- mixgtk_wm.h :
+ * Functions for window management
+ * ------------------------------------------------------------------
+ * $Id: mixgtk_wm.h,v 1.5 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGTK_WM_H
+#define MIXGTK_WM_H
+
+#include "mixgtk.h"
+
+typedef enum {
+ MIXGTK_MIXVM_WINDOW,
+ MIXGTK_MIXAL_WINDOW,
+ MIXGTK_DEVICES_WINDOW
+} mixgtk_window_id_t;
+
+extern gboolean
+mixgtk_wm_init (void);
+
+extern void
+mixgtk_wm_attach_window (mixgtk_window_id_t w);
+
+extern void
+mixgtk_wm_detach_window (mixgtk_window_id_t w);
+
+#endif /* MIXGTK_WM_H */
+
diff --git a/mixguile/Makefile.am b/mixguile/Makefile.am
new file mode 100644
index 0000000..cdafcba
--- /dev/null
+++ b/mixguile/Makefile.am
@@ -0,0 +1,43 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2001 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.6 2001/09/30 20:29:30 jao Exp $
+
+SCM_FILES = mixguile.scm mixguile-commands.scm mixguile-vm-stat.scm
+EXTRA_DIST = $(SCM_FILES)
+
+noinst_LIBRARIES = libmixguile.a
+
+if MAKE_GUILE
+
+SCM_PATHS = -DSCM_FILE=\""$(pkgdatadir)/mixguile.scm"\"\
+ -DLOCAL_SCM_FILE=\"mixguile.scm\"
+
+pkgdata_DATA = $(SCM_FILES)
+INCLUDES = -I$(includedir) -I$(top_srcdir) $(SCM_PATHS)
+libmixguile_a_INCLUDES = -I$(includedir) -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"libmixguile\"
+libmixguile_a_SOURCES = mixguile.h mixguile.c \
+ mixguile_cmd_dispatcher.h mixguile_cmd_dispatcher.c \
+ xmixguile_cmd_dispatcher.h xmixguile_cmd_dispatcher.c
+
+bin_PROGRAMS = mixguile
+mixguile_LDADD = $(top_builddir)/mixlib/libmix.a \
+ $(top_builddir)/lib/libreplace.a \
+ $(top_builddir)/mixguile/libmixguile.a $(INTLLIBS)
+mixguile_SOURCES = mixguile_main.c
+
+else
+
+libmixguile_a_SOURCES =
+
+endif
diff --git a/mixguile/mixguile-commands.scm b/mixguile/mixguile-commands.scm
new file mode 100644
index 0000000..bc1aeb2
--- /dev/null
+++ b/mixguile/mixguile-commands.scm
@@ -0,0 +1,254 @@
+;; -*-scheme-*- -------------- mixguile-commands.scm :
+; mixvm commands implementation using the mixvm-cmd primitive
+; ------------------------------------------------------------------
+; $Id: mixguile-commands.scm,v 1.5 2005/09/20 19:43:14 jao Exp $
+; ------------------------------------------------------------------
+; Copyright (C) 2001 Free Software Foundation, Inc.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+;;
+
+;; auxiliar functions for argument conversion
+(define argsym->string
+ (lambda (arg)
+ (cond ((symbol? arg) (symbol->string arg))
+ ((string? arg) arg)
+ (else (error "Wrong argument type" arg)))))
+
+(define argnsym->string
+ (lambda (arg)
+ (cond ((null? arg) "")
+ ((pair? arg) (argsym->string (car arg)))
+ (else (argsym->string arg)))))
+
+(define argnum->string
+ (lambda (arg)
+ (cond ((number? arg) (number->string arg))
+ ((string? arg) arg)
+ (else (error "Wrong argument type" arg)))))
+
+(define argnnum->string
+ (lambda (arg)
+ (cond ((null? arg) "")
+ ((pair? arg) (argnum->string (car arg)))
+ (else (argnum->string arg)))))
+
+;;; mixvm commands
+
+; preg
+(define mix-preg
+ (lambda (. reg)
+ (mixvm-cmd "preg" (argnsym->string reg))))
+
+; sreg
+(define mix-sreg
+ (lambda (reg val) (mixvm-cmd "sreg" (string-append (argsym->string reg)
+ " "
+ (argnum->string val)))))
+
+; pmem
+(define mix-pmem
+ (lambda (from . to)
+ (cond ((null? to) (mixvm-cmd "pmem" (argnum->string from)))
+ (else (mixvm-cmd "pmem"
+ (string-append (argnum->string from)
+ "-"
+ (argnnum->string to)))))))
+
+; smem
+(define mix-smem
+ (lambda (cell val) (mixvm-cmd "smem" (string-append (argnum->string cell)
+ " "
+ (argnum->string val)))))
+
+; pall
+(define mix-pall (lambda () (mixvm-cmd "pall" "")))
+
+; pc
+(define mix-pc (lambda () (mixvm-cmd "pc" "")))
+
+; pflags
+(define mix-pflags (lambda () (mixvm-cmd "pflags" "")))
+
+; sover
+(define mix-sover
+ (lambda (val)
+ (mixvm-cmd "sover" (if val "T" "F"))))
+
+; psym
+(define mix-psym
+ (lambda (. sym)
+ (mixvm-cmd "psym" (argnsym->string sym))))
+
+; ssym
+(define mix-ssym
+ (lambda (sym value)
+ (mixvm-cmd "ssym"
+ (string-append
+ (argsym->string sym) " " (argnum->string value)))))
+
+; run
+(define mix-run
+ (lambda (. file)
+ (mixvm-cmd "run" (argnsym->string file))))
+
+; next
+(define mix-next
+ (lambda (. no)
+ (mixvm-cmd "next" (argnnum->string no))))
+
+; load
+(define mix-load
+ (lambda (file)
+ (mixvm-cmd "load" (argsym->string file))))
+
+; pstat
+(define mix-pstat (lambda () (mixvm-cmd "pstat" "")))
+
+; compile
+(define mix-compile
+ (lambda (. file)
+ (mixvm-cmd "compile" (argnsym->string file))))
+
+; devdir
+(define mix-sddir
+ (lambda (dir)
+ (mixvm-cmd "sddir" dir)))
+
+(define mix-pddir (lambda () (mixvm-cmd "pddir" "")))
+
+; edit
+(define mix-edit
+ (lambda (. file)
+ (mixvm-cmd "edit" (argnsym->string file))))
+
+; help
+(define mix-help
+ (lambda (. cmd)
+ (mixvm-cmd "help" (argnsym->string cmd))))
+
+; pasm
+(define mix-pasm (lambda () (mixvm-cmd "pasm" "")))
+
+; sasm
+(define mix-sasm
+ (lambda (path)
+ (mixvm-cmd "sasm" (argsym->string path))))
+
+; pedit
+(define mix-pedit (lambda () (mixvm-cmd "pedit" "")))
+
+; sedit
+(define mix-sedit
+ (lambda (path)
+ (mixvm-cmd "sedit" (argsym->string path))))
+
+; sbp
+(define mix-sbp
+ (lambda (line)
+ (mixvm-cmd "sbp" (argnum->string line))))
+
+; sbp
+(define mix-pline
+ (lambda (. no)
+ (mixvm-cmd "pline" (argnnum->string no))))
+
+; cbp
+(define mix-cbp
+ (lambda (line)
+ (mixvm-cmd "cbp" (argnum->string line))))
+
+; sbpa
+(define mix-sbpa
+ (lambda (addr)
+ (mixvm-cmd "sbpa" (argnum->string addr))))
+
+; cbpa
+(define mix-cbpa
+ (lambda (addr)
+ (mixvm-cmd "cbpa" (argnum->string addr))))
+
+
+; sbpc
+(define mix-sbpc (lambda () (mixvm-cmd "sbpc" "")))
+
+; cbpc
+(define mix-cbpc (lambda () (mixvm-cmd "cbpc" "")))
+
+; sbpo
+(define mix-sbpo (lambda () (mixvm-cmd "sbpo" "")))
+
+; cbpo
+(define mix-cbpo (lambda () (mixvm-cmd "cbpo" "")))
+
+; sbpm
+(define mix-sbpm
+ (lambda (cell)
+ (mixvm-cmd "sbpm" (argnum->string cell))))
+
+; cbpm
+(define mix-cbpm
+ (lambda (cell)
+ (mixvm-cmd "cbpm" (argnum->string cell))))
+
+; sbpr
+(define mix-sbpr
+ (lambda (reg)
+ (mixvm-cmd "sbpr" (argsym->string reg))))
+
+; cbpr
+(define mix-cbpr
+ (lambda (reg)
+ (mixvm-cmd "cbpr" (argsym->string reg))))
+
+; pbt
+(define mix-pbt
+ (lambda (. num)
+ (mixvm-cmd "pbt" (argnnum->string num))))
+
+; timing
+(define mix-stime
+ (lambda (on)
+ (mixvm-cmd "stime" (if on "on" "off"))))
+
+(define mix-ptime (lambda () (mixvm-cmd "ptime" "")))
+
+; timing
+(define mix-strace
+ (lambda (on)
+ (mixvm-cmd "strace" (if on "on" "off"))))
+
+; logging
+(define mix-slog
+ (lambda (on)
+ (mixvm-cmd "slog" (if on "on" "off"))))
+
+; w2d
+(define mix-w2d
+ (lambda (w)
+ (mixvm-cmd "w2d" w)));
+
+; weval
+(define mix-weval
+ (lambda (exp)
+ (mixvm-cmd "weval" (argsym->string exp))))
+
+; pprog
+(define mix-pprog (lambda () (mixvm-cmd "pprog" "")))
+
+; sprog
+(define mix-psrc (lambda () (mixvm-cmd "psrc" "")))
+
diff --git a/mixguile/mixguile-vm-stat.scm b/mixguile/mixguile-vm-stat.scm
new file mode 100644
index 0000000..1887b4c
--- /dev/null
+++ b/mixguile/mixguile-vm-stat.scm
@@ -0,0 +1,71 @@
+;; -*-scheme-*- -------------- mixguile-vm-stat.scm :
+; mixvm status functions
+; ------------------------------------------------------------------
+; $Id: mixguile-vm-stat.scm,v 1.4 2005/09/20 19:43:14 jao Exp $
+; ------------------------------------------------------------------
+; Copyright (C) 2001 Free Software Foundation, Inc.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+;;
+
+;; possible status index
+(define mix-status-values (vector 'MIX_ERROR
+ 'MIX_BREAK
+ 'MIX_COND_BREAK
+ 'MIX_HALTED
+ 'MIX_RUNNING
+ 'MIX_LOADED
+ 'MIX_EMPTY))
+;; return status as a simbol
+(define mix-vm-status (lambda () (vector-ref mix-status-values (mixvm-status))))
+
+;; check for a given status
+(define mix-vm-status?
+ (lambda (status) (eq? status (mix-vm-status))))
+
+;; predicates for each possible status
+(define mix-vm-error? (lambda () (mix-vm-status? 'MIX_ERROR)))
+(define mix-vm-break? (lambda () (mix-vm-status? 'MIX_BREAK)))
+(define mix-vm-cond-break? (lambda () (mix-vm-status? 'MIX_COND_BREAK)))
+(define mix-vm-halted? (lambda () (mix-vm-status? 'MIX_HALTED)))
+(define mix-vm-running? (lambda () (mix-vm-status? 'MIX_RUNNING)))
+(define mix-vm-loaded? (lambda () (mix-vm-status? 'MIX_LOADED)))
+(define mix-vm-empty? (lambda () (mix-vm-status? 'MIX_EMPTY)))
+
+
+;; define hooks on break conditions
+
+(define mix-make-conditional-hook
+ (lambda (test hook)
+ (lambda (arglist)
+ (if (test) (hook (mix-src-line-no) (mix-loc))))))
+
+(define mix-add-run-next-hook
+ (lambda (hook)
+ (mix-add-post-hook 'run hook)
+ (mix-add-post-hook 'next hook)))
+
+
+(define mix-add-break-hook
+ (lambda (hook)
+ (mix-add-run-next-hook (mix-make-conditional-hook mix-vm-break? hook))))
+
+(define mix-add-cond-break-hook
+ (lambda (hook)
+ (mix-add-run-next-hook (mix-make-conditional-hook
+ mix-vm-cond-break? hook))))
+
+
diff --git a/mixguile/mixguile.c b/mixguile/mixguile.c
new file mode 100644
index 0000000..f37424f
--- /dev/null
+++ b/mixguile/mixguile.c
@@ -0,0 +1,124 @@
+/* -*-c-*- -------------- mixguile.c :
+ * Implementation of the functions declared in mixguile.h
+ * ------------------------------------------------------------------
+ * $Id: mixguile.c,v 1.8 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <unistd.h>
+
+#include <mixlib/mix_config.h>
+#include "mixguile_cmd_dispatcher.h"
+#include "mixguile.h"
+
+static mixguile_cmd_dispatcher_t *dispatcher_ = NULL;
+static mix_vm_cmd_dispatcher_t *vm_dispatcher_ = NULL;
+static main_func_t main_fun_;
+static gboolean init_file_;
+
+/* do local initialisation and enter the user provided main */
+
+static void
+real_main_ (int argc, char *argv[])
+{
+ if (vm_dispatcher_)
+ {
+ mixguile_set_cmd_dispatcher (vm_dispatcher_);
+ mixguile_load_bootstrap (init_file_);
+ }
+ (*main_fun_)(argc, argv);
+}
+
+/*
+ initialise the guile command dispatcher and enter the provided
+ main function.
+*/
+void
+mixguile_init (int argc, char *argv[], gboolean initfile,
+ main_func_t main_fun,
+ mix_vm_cmd_dispatcher_t *dis)
+{
+ main_fun_ = main_fun;
+ vm_dispatcher_ = dis;
+ init_file_ = initfile;
+ gh_enter (argc, argv, real_main_);
+}
+
+/* load bootstrap file */
+void
+mixguile_load_bootstrap (gboolean loadlocal)
+{
+ const gchar *scmfile = SCM_FILE;
+ gchar *lscmfile = g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S,
+ MIX_CONFIG_DIR, G_DIR_SEPARATOR_S,
+ LOCAL_SCM_FILE, NULL);
+
+ if (access (scmfile, R_OK) && access ((scmfile = LOCAL_SCM_FILE), R_OK))
+ {
+ g_warning (_("mixguile bootstrap file %s not found\n"), SCM_FILE);
+ scmfile = NULL;
+ }
+ else
+ mixguile_interpret_file (scmfile);
+
+ if (loadlocal && !access (lscmfile, R_OK))
+ {
+ mixguile_interpret_file (lscmfile);
+ }
+
+ g_free (lscmfile);
+}
+
+/* enter the guile repl */
+void
+mixguile_enter_repl (int argc, char *argv[])
+{
+ gh_repl (argc, argv);
+}
+
+/* set the command dispatcher */
+void
+mixguile_set_cmd_dispatcher (mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ if (dispatcher_) mixguile_cmd_dispatcher_delete (dispatcher_);
+ vm_dispatcher_ = dis;
+ dispatcher_ = mixguile_cmd_dispatcher_new (dis);
+ g_assert (dispatcher_);
+}
+
+/* access the mixguile comand dispatcher */
+mix_vm_cmd_dispatcher_t *
+mixguile_get_cmd_dispatcher (void)
+{
+ return mixguile_cmd_dispatcher_get_vm_dispatcher (dispatcher_);
+}
+
+/* execute a string or file using the guile interpreter */
+void
+mixguile_interpret_file (const gchar *path)
+{
+ mixguile_cmd_dispatcher_interpret_file (dispatcher_, path);
+}
+
+void
+mixguile_interpret_command (const gchar *command)
+{
+ mixguile_cmd_dispatcher_interpret_command (dispatcher_, command);
+}
diff --git a/mixguile/mixguile.h b/mixguile/mixguile.h
new file mode 100644
index 0000000..c2ef492
--- /dev/null
+++ b/mixguile/mixguile.h
@@ -0,0 +1,72 @@
+/* -*-c-*- ---------------- mixguile.h :
+ * Interface to the mixguile interpreter.
+ * ------------------------------------------------------------------
+ * $Id: mixguile.h,v 1.6 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGUILE_H
+#define MIXGUILE_H
+
+#include <mixlib/mix.h>
+#include <mixlib/mix_vm_command.h>
+#include <guile/gh.h>
+
+/* the main function type */
+typedef void (*main_func_t) (int argc, char *argv[]);
+
+
+/* enter and do the initialisation manually inside the guile world */
+#define mixguile_enter(argc,argv,main_fun) gh_enter (argc, argv, main_fun)
+
+/* load mixguile startup file */
+extern void
+mixguile_load_bootstrap (gboolean localinit);
+
+/*
+ initialise the guile command dispatcher and enter the provided
+ main function.
+*/
+extern void
+mixguile_init (int argc, char *argv[], gboolean initfile, main_func_t main_fun,
+ mix_vm_cmd_dispatcher_t *dis);
+
+/* set the command dispatcher */
+extern void
+mixguile_set_cmd_dispatcher (mix_vm_cmd_dispatcher_t *dis);
+
+/* enter the guile repl */
+extern void
+mixguile_enter_repl (int argc, char *argv[]);
+
+/* access the comand dispatcher */
+extern mix_vm_cmd_dispatcher_t *
+mixguile_get_cmd_dispatcher (void);
+
+/* execute a string or file using the guile interpreter */
+extern void
+mixguile_interpret_file (const gchar *path);
+
+extern void
+mixguile_interpret_command (const gchar *command);
+
+
+#endif /* MIXGUILE_H */
+
diff --git a/mixguile/mixguile.scm b/mixguile/mixguile.scm
new file mode 100644
index 0000000..4e7dcbe
--- /dev/null
+++ b/mixguile/mixguile.scm
@@ -0,0 +1,25 @@
+;; -*-scheme-*- -------------- mixguile.scm :
+; mixguile bootstrap file
+; ------------------------------------------------------------------
+; Last change: Time-stamp: "01/09/05 01:05:29 jao"
+; ------------------------------------------------------------------
+; Copyright (C) 2001 Free Software Foundation, Inc.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+;;
+
+(load "mixguile-commands.scm")
+(load "mixguile-vm-stat.scm")
diff --git a/mixguile/mixguile_cmd_dispatcher.c b/mixguile/mixguile_cmd_dispatcher.c
new file mode 100644
index 0000000..2cc243b
--- /dev/null
+++ b/mixguile/mixguile_cmd_dispatcher.c
@@ -0,0 +1,122 @@
+/* -*-c-*- -------------- mixguile_cmd_dispatcher.c :
+ * Implementation of the functions declared in mixguile_cmd_dispatcher.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/08/22 02:29:34 jao"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <guile/gh.h>
+#include "mixguile.h"
+#include "xmixguile_cmd_dispatcher.h"
+
+#define SCM_CMD "scm"
+#define SCMF_CMD "scmf"
+
+/*local commands */
+static gboolean
+cmd_scm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ (void) gh_eval_str_with_catch ((char *)arg, scm_handle_by_message_noexit);
+ return TRUE;
+}
+
+static gboolean
+cmd_scmf_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ (void) gh_eval_file_with_catch ((char *)arg, scm_handle_by_message_noexit);
+ return TRUE;
+}
+
+static mix_vm_command_info_t commands_[] = {
+ { SCM_CMD, cmd_scm_, N_("Eval Scheme command using Guile"), "scm COMMAND"},
+ { SCMF_CMD, cmd_scmf_, N_("Eval Scheme file using Guile"), "scm PATH"},
+ {NULL}
+};
+
+/* create/destroy cmd dispatcher */
+mixguile_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_new (mix_vm_cmd_dispatcher_t *dis)
+{
+ static gboolean REGISTERED = FALSE;
+ mixguile_cmd_dispatcher_t *result = NULL;
+ int k = 0;
+
+ g_return_val_if_fail (dis != NULL, NULL);
+
+ if (!REGISTERED)
+ {
+ register_scm_commands_ (DEFAULT_SCM_COMMANDS_);
+ REGISTERED = TRUE;
+ }
+
+ result = g_new (mixguile_cmd_dispatcher_t, 1);
+ result->dispatcher = dis;
+
+ while (commands_[k].name)
+ {
+ mix_vm_cmd_dispatcher_register_new (dis, commands_ + k);
+ ++k;
+ }
+
+ register_cmd_dispatcher_ (result);
+
+ return result;
+}
+
+
+void
+mixguile_cmd_dispatcher_delete (mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ mix_vm_cmd_dispatcher_delete (dis->dispatcher);
+}
+
+/* get the underlying vm dispatcher */
+mix_vm_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_get_vm_dispatcher (const mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->dispatcher;
+}
+
+void
+mixguile_cmd_dispatcher_interpret_file (mixguile_cmd_dispatcher_t *dis,
+ const gchar *path)
+{
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (path != NULL);
+ mix_vm_cmd_dispatcher_dispatch_split_text (dis->dispatcher,
+ SCMF_CMD, path);
+}
+
+void
+mixguile_cmd_dispatcher_interpret_command (mixguile_cmd_dispatcher_t *dis,
+ const gchar *command)
+{
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (command != NULL);
+ mix_vm_cmd_dispatcher_dispatch_split_text (dis->dispatcher,
+ SCM_CMD, command);
+}
+
diff --git a/mixguile/mixguile_cmd_dispatcher.h b/mixguile/mixguile_cmd_dispatcher.h
new file mode 100644
index 0000000..1b10510
--- /dev/null
+++ b/mixguile/mixguile_cmd_dispatcher.h
@@ -0,0 +1,57 @@
+/* -*-c-*- ---------------- mixguile_cmd_dispatcher.h :
+ * Command dispatcher with guile support
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/08/22 01:15:23 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXGUILE_CMD_DISPATCHER_H
+#define MIXGUILE_CMD_DISPATCHER_H
+
+#include <mixlib/mix.h>
+#include <mixlib/mix_vm_command.h>
+
+/* the guile command dispatcher type */
+typedef struct mixguile_cmd_dispatcher_t mixguile_cmd_dispatcher_t;
+
+/* create/destroy cmd dispatcher */
+extern mixguile_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_new (mix_vm_cmd_dispatcher_t *dis);
+
+extern void
+mixguile_cmd_dispatcher_delete (mixguile_cmd_dispatcher_t *dis);
+
+/* get the underlying vm dispatcher */
+extern mix_vm_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_get_vm_dispatcher (const
+ mixguile_cmd_dispatcher_t *disp);
+
+/* interpret commands from file or string */
+extern void
+mixguile_cmd_dispatcher_interpret_file (mixguile_cmd_dispatcher_t *dis,
+ const gchar *path);
+
+extern void
+mixguile_cmd_dispatcher_interpret_command (mixguile_cmd_dispatcher_t *dis,
+ const gchar *command);
+
+
+#endif /* MIXGUILE_CMD_DISPATCHER_H */
+
diff --git a/mixguile/mixguile_main.c b/mixguile/mixguile_main.c
new file mode 100644
index 0000000..22e65be
--- /dev/null
+++ b/mixguile/mixguile_main.c
@@ -0,0 +1,94 @@
+/* -*-c-*- -------------- mixguile_main.c :
+ * Main function for mixguile, the MIX Guile shell
+ * ------------------------------------------------------------------
+ * $Id: mixguile_main.c,v 1.6 2005/09/20 19:43:14 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "mixguile.h"
+
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+#else
+# include <lib/getopt.h>
+#endif /* HAVE_GETOPT_LONG */
+
+enum {
+ VER_OPT = 'v',
+ NOINIT_OPT = 'q',
+};
+
+static const char *options_ = "vq";
+
+static struct option long_options_[] =
+{
+ {"version", no_argument, 0, VER_OPT},
+ {0, 0, 0, 0}
+};
+
+int
+main (int argc, char *argv[])
+{
+ const gchar *CONFIG_FILE = "mixvm.config";
+ mix_config_t *config;
+ mix_vm_cmd_dispatcher_t *dis;
+ int c;
+
+ gboolean initfile = TRUE;
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ /* prevent getopt printing a message for unknown options (stored in optopt) */
+ opterr = 0;
+
+ while (1)
+ {
+ c = getopt_long (argc, argv, options_, long_options_, (int*)0);
+
+ /* Detect the end of the options. */
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case VER_OPT:
+ mix_print_license ("mixguile, Scheme MIX Virtual Machine");
+ return EXIT_SUCCESS;
+ case NOINIT_OPT:
+ initfile = FALSE;
+ break;
+ default:
+ /* let guile try to understand the option */
+ break;
+ }
+ }
+
+ mix_init_lib ();
+
+ config = mix_config_new (NULL, CONFIG_FILE);
+ dis = mix_vm_cmd_dispatcher_new_with_config (stdout, stderr, config);
+ mixguile_init (argc, argv, initfile, mixguile_enter_repl, dis);
+
+ return EXIT_SUCCESS; /* never reached */
+}
diff --git a/mixguile/xmixguile_cmd_dispatcher.c b/mixguile/xmixguile_cmd_dispatcher.c
new file mode 100644
index 0000000..2ccd19c
--- /dev/null
+++ b/mixguile/xmixguile_cmd_dispatcher.c
@@ -0,0 +1,558 @@
+/* -*-c-*- -------------- xmixguile_cmd_dispatcher.c :
+ * Implementation of the functions declared in xmixguile_cmd_dispatcher.h
+ * ------------------------------------------------------------------
+ * $Id: xmixguile_cmd_dispatcher.c,v 1.14 2005/09/20 19:50:26 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+
+#include <mixlib/mix.h>
+#include <guile/gh.h>
+
+#include "xmixguile_cmd_dispatcher.h"
+
+/* cmd dispatcher for use within the scm commands */
+static mixguile_cmd_dispatcher_t *dispatcher_;
+static mix_vm_cmd_dispatcher_t *vm_dispatcher_;
+static mix_vm_t *vm_;
+
+/* register a NULL-terminated list of scm commands */
+void
+register_scm_commands_ (const scm_command_t *commands)
+{
+ int k = 0;
+ g_return_if_fail (commands != NULL);
+ while (commands[k].name)
+ {
+ gh_new_procedure (commands[k].name, commands[k].func,
+ commands[k].argno, commands[k].opt_argno,
+ commands[k].restp);
+ ++k;
+ }
+}
+
+/* register the mixvm cmd dispatcher to use with commands */
+void
+register_cmd_dispatcher_ (mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ dispatcher_ = dis;
+ vm_dispatcher_ = mixguile_cmd_dispatcher_get_vm_dispatcher (dis);
+ vm_ = (mix_vm_t *) mix_vm_cmd_dispatcher_get_vm (vm_dispatcher_);
+}
+
+/* commands */
+static SCM
+mixvm_cmd_ (SCM cmd, SCM arg)
+{
+ char *com = NULL, *argu = NULL;
+ unsigned int len;
+ gboolean result;
+
+ SCM_ASSERT (SCM_STRINGP (cmd) || SCM_SYMBOLP (cmd),
+ cmd, SCM_ARG1, "mixvm-cmd");
+ SCM_ASSERT (SCM_STRINGP (arg) || SCM_SYMBOLP (arg),
+ arg, SCM_ARG2, "mixvm-cmd");
+
+ SCM_DEFER_INTS;
+ com = gh_scm2newstr (cmd, &len);
+ argu = gh_scm2newstr (arg, &len);
+ result = mix_vm_cmd_dispatcher_dispatch (vm_dispatcher_,
+ mix_vm_command_from_string (com),
+ argu);
+ g_free (com);
+ g_free (argu);
+
+ SCM_ALLOW_INTS;
+
+ return SCM_UNSPECIFIED;
+}
+
+static SCM
+mixvm_status_ (void)
+{
+ return gh_long2scm (mix_vm_get_run_status (vm_));
+}
+
+static SCM
+mix_last_result_ (void)
+{
+ return gh_bool2scm (mix_vm_cmd_dispatcher_get_last_result (vm_dispatcher_));
+}
+
+static long
+word_to_long_ (mix_word_t word)
+{
+ long result = mix_word_magnitude (word);
+ return mix_word_is_negative (word) ? -result : result;
+}
+
+static long
+short_to_long_ (mix_short_t s)
+{
+ long result = mix_short_magnitude (s);
+ return mix_short_is_negative (s) ? -result : result;
+}
+
+static SCM
+mix_reg_ (SCM reg)
+{
+ char *regis;
+ unsigned int len;
+ long val = MIX_WORD_MAX + 1;
+
+ SCM_ASSERT (SCM_STRINGP (reg) || SCM_SYMBOLP (reg), reg, SCM_ARG1, "mix-reg");
+
+ SCM_DEFER_INTS;
+ if (SCM_SYMBOLP (reg)) reg = scm_symbol_to_string (reg);
+ regis = gh_scm2newstr (reg, &len);
+ switch (regis[0])
+ {
+ case 'A':
+ val = word_to_long_ (mix_vm_get_rA (vm_)); break;
+ case 'X':
+ val = word_to_long_ (mix_vm_get_rX (vm_)); break;
+ case 'J':
+ val = short_to_long_ (mix_vm_get_rJ (vm_)); break;
+ case 'I':
+ {
+ int i = regis[1] - '0';
+ if (i > 0 && i < 7) val = short_to_long_ (mix_vm_get_rI (vm_, i));
+ }
+ break;
+ default:
+ break;
+ }
+ g_free (regis);
+
+ SCM_ALLOW_INTS;
+
+ SCM_ASSERT (val <= MIX_WORD_MAX, reg, SCM_ARG1, "mix-reg");
+
+ return gh_long2scm (val);
+}
+
+static SCM
+mix_set_reg_ (SCM reg, SCM value)
+{
+ char *regis;
+ unsigned int len;
+ long val;
+ gboolean result = TRUE;
+
+ SCM_ASSERT (SCM_STRINGP (reg) || SCM_SYMBOLP (reg), reg, SCM_ARG1,
+ "mix-set-reg!");
+ SCM_ASSERT (SCM_NUMBERP (value), value, SCM_ARG2, "mix-set-reg!");
+
+ SCM_DEFER_INTS;
+ if (SCM_SYMBOLP (reg)) reg = scm_symbol_to_string (reg);
+ regis = gh_scm2newstr (reg, &len);
+ val = gh_scm2long (value);
+ switch (regis[0])
+ {
+ case 'A':
+ mix_vm_set_rA (vm_, mix_word_new (val)); break;
+ case 'X':
+ mix_vm_set_rX (vm_, mix_word_new (val)); break;
+ case 'J':
+ mix_vm_set_rJ (vm_, mix_short_new (val)); break;
+ case 'I':
+ {
+ int i = regis[1] - '0';
+ if (i > 0 && i < 7) mix_vm_set_rI (vm_, i, mix_short_new (val));
+ else result = FALSE;
+ }
+ break;
+ default:
+ result = FALSE; break;
+ }
+ g_free (regis);
+
+ SCM_ALLOW_INTS;
+
+ SCM_ASSERT (result, reg, SCM_ARG1, "mix-set-reg!");
+
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_cell_ (SCM no)
+{
+ int cell;
+ long result;
+
+ SCM_ASSERT (SCM_NUMBERP (no), no, SCM_ARG1, "mix-cell");
+ cell = gh_scm2int (no);
+ SCM_ASSERT (cell < MIX_VM_CELL_NO, no, SCM_ARG1, "mix-cell");
+ result = word_to_long_ (mix_vm_get_addr_contents (vm_, cell));
+ return gh_long2scm (result);
+}
+
+static SCM
+mix_set_cell_ (SCM no, SCM val)
+{
+ int cell;
+ long result;
+
+ SCM_ASSERT (SCM_NUMBERP (no), no, SCM_ARG1, "mix-set-cell!");
+ SCM_ASSERT (SCM_NUMBERP (val), no, SCM_ARG2, "mix-set-cell!");
+ cell = gh_scm2int (no);
+ SCM_ASSERT (cell < MIX_VM_CELL_NO, no, SCM_ARG1, "mix-set-cell!");
+ result = gh_scm2long (val);
+ mix_vm_set_addr_contents (vm_, cell, mix_word_new (result));
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_over_ (void)
+{
+ return gh_bool2scm (mix_vm_get_overflow (vm_));
+}
+
+static SCM
+mix_set_over_ (SCM over)
+{
+ mix_vm_set_overflow (vm_, gh_scm2bool (over));
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_loc_ (void)
+{
+ return gh_long2scm (mix_vm_get_prog_count (vm_));
+}
+
+static SCM
+mix_cmp_ (void)
+{
+ gchar *result = NULL;
+ switch (mix_vm_get_cmpflag (vm_))
+ {
+ case mix_LESS: result = "L"; break;
+ case mix_EQ: result = "E"; break;
+ case mix_GREAT: result = "G"; break;
+ default: g_assert_not_reached ();
+ }
+ return gh_symbol2scm (result);
+}
+
+static SCM
+mix_set_cmp_ (SCM value)
+{
+ gchar *val = NULL;
+ unsigned int len;
+ mix_cmpflag_t result = -1;
+
+ SCM_ASSERT (SCM_STRINGP (value) || SCM_SYMBOLP (value), value, SCM_ARG1,
+ "mix-set-cmp!");
+
+ SCM_DEFER_INTS;
+ val = gh_scm2newstr (value, &len);
+ if (strlen (val) == 1)
+ {
+ switch (val[0])
+ {
+ case 'L': result = mix_LESS; break;
+ case 'E': result = mix_EQ; break;
+ case 'G': result = mix_GREAT; break;
+ default: break;
+ }
+ }
+ g_free (val);
+ SCM_ALLOW_INTS;
+ SCM_ASSERT (result != -1, value, SCM_ARG1, "mix-set-cmp!");
+ mix_vm_set_cmpflag (vm_, result);
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_src_name_ (void)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_src_file_path (vm_dispatcher_);
+ return gh_str02scm (path? g_path_get_basename (path) : "");
+}
+
+static SCM
+mix_src_path_ (void)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_src_file_path (vm_dispatcher_);
+ return gh_str02scm (path? (char *)path : "");
+}
+
+static SCM
+mix_prog_name_ (void)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_program_path (vm_dispatcher_);
+ return gh_str02scm (path? g_path_get_basename (path) : "");
+}
+
+static SCM
+mix_prog_path_ (void)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_program_path (vm_dispatcher_);
+ return gh_str02scm (path? (char *)path : "");
+}
+
+static SCM
+mix_ddir_ (void)
+{
+ return gh_str02scm ((char *)mix_device_get_dir ());
+}
+
+static SCM
+mix_uptime_ (void)
+{
+ return gh_long2scm (mix_vm_cmd_dispatcher_get_uptime (vm_dispatcher_));
+}
+
+static SCM
+mix_progtime_ (void)
+{
+ return gh_long2scm (mix_vm_cmd_dispatcher_get_progtime (vm_dispatcher_));
+}
+
+static SCM
+mix_laptime_ (void)
+{
+ return gh_long2scm (mix_vm_cmd_dispatcher_get_laptime (vm_dispatcher_));
+}
+
+static SCM
+mix_src_line_ (SCM opt)
+{
+ gulong no = 0;
+ const gchar *line = "";
+ if (opt != SCM_UNDEFINED)
+ {
+ SCM_ASSERT (SCM_NUMBERP (opt), opt, SCM_ARG1, "mix-src-line");
+ no = gh_scm2long (opt);
+ }
+ else
+ no = mix_vm_cmd_dispatcher_get_src_file_lineno (vm_dispatcher_);
+
+ SCM_ASSERT (line >= 0, opt, SCM_ARG1, "mix-src-line");
+
+ if (no > 0)
+ line = mix_vm_cmd_dispatcher_get_src_file_line (vm_dispatcher_, no, FALSE);
+
+ return gh_str02scm ((char *)line);
+}
+
+static SCM
+mix_src_line_no_ (void)
+{
+ return
+ gh_long2scm (mix_vm_cmd_dispatcher_get_src_file_lineno (vm_dispatcher_));
+}
+
+/* ----- hook functions ---- */
+
+/* auxiliar arg list maker */
+static SCM
+make_arg_list_ (const gchar *arg)
+{
+ gchar **arglist = g_strsplit (arg, " ", -1);
+ SCM argument = gh_list (SCM_UNDEFINED, SCM_EOL);
+ if (arglist && arglist[0])
+ {
+ int k = 0;
+ while (arglist[k])
+ argument = gh_cons (gh_str02scm (arglist[k++]), argument);
+ argument = gh_reverse (argument);
+ }
+ g_strfreev (arglist);
+ return argument;
+}
+
+/* command hook auxiliar functions and types */
+/*
+static SCM
+hook_error_handler_ (void *data, SCM tag, SCM args){}
+*/
+typedef struct
+{
+ SCM function;
+ SCM args;
+} hook_data_t;
+
+static SCM
+hook_catch_body_ (void *data)
+{
+ hook_data_t *h = (hook_data_t *)data;
+ return gh_call1 (h->function, h->args);
+}
+
+static void
+scm_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg, gpointer data)
+{
+ hook_data_t h;
+ h.function = (SCM) data;
+
+ g_assert (gh_procedure_p (h.function));
+
+ h.args = make_arg_list_ (arg);
+ g_assert (gh_list_p (h.args));
+
+ gh_catch (SCM_BOOL_T, hook_catch_body_, &h,
+ scm_handle_by_message_noexit, dis);
+}
+
+/* global hook auxiliar functions and types */
+typedef struct
+{
+ SCM function;
+ SCM cmd;
+ SCM args;
+} global_hook_data_t;
+
+static SCM
+global_hook_catch_body_ (void *data)
+{
+ global_hook_data_t *h = (global_hook_data_t *)data;
+ return gh_call2 (h->function, h->cmd, h->args);
+}
+
+static void
+scm_global_hook_ (mix_vm_cmd_dispatcher_t *dis, mix_vm_command_t cmd,
+ const gchar *arg, gpointer data)
+{
+ global_hook_data_t h;
+ h.function = (SCM) data;
+ h.cmd = gh_str02scm ((char *)mix_vm_command_to_string (cmd));
+ h.args = make_arg_list_ (arg);
+ gh_catch (SCM_BOOL_T, global_hook_catch_body_, &h,
+ scm_handle_by_message_noexit, NULL);
+}
+
+static SCM
+define_hook_procedure_ (SCM function)
+{
+ enum {BUFF_SIZE = 128};
+ static gchar BUFFER[BUFF_SIZE];
+ static const gchar *PATTERN = "____mix__hook__%d____";
+ static int K = 0;
+ g_snprintf (BUFFER, BUFF_SIZE, PATTERN, K++);
+ /* gh_define (name, val) returns a pair: (symbol . symbol-value) */
+ return gh_cdr (gh_define ((char *)BUFFER, function));
+}
+
+static SCM
+mix_add_hook_ (SCM cmd, SCM function, gboolean pre)
+{
+ gchar *cmdstr = NULL;
+ mix_vm_command_t command;
+ unsigned int len;
+ const gchar *fun = pre? "mix-add-pre-hook" : "mix-add-post-hook";
+
+ SCM_ASSERT (SCM_STRINGP (cmd) || SCM_SYMBOLP (cmd), cmd, SCM_ARG1, fun);
+ SCM_ASSERT (gh_procedure_p (function), function, SCM_ARG2, fun);
+ SCM_DEFER_INTS;
+ cmdstr = gh_scm2newstr (cmd, &len);
+ command = mix_vm_command_from_string (cmdstr);
+ g_free (cmdstr);
+ SCM_ALLOW_INTS;
+ SCM_ASSERT (command != MIX_CMD_INVALID, cmd, SCM_ARG1, fun);
+ SCM_DEFER_INTS;
+ if (pre)
+ mix_vm_cmd_dispatcher_pre_hook (vm_dispatcher_, command, scm_hook_,
+ (gpointer)
+ define_hook_procedure_ (function));
+ else
+ mix_vm_cmd_dispatcher_post_hook (vm_dispatcher_, command, scm_hook_,
+ (gpointer)
+ define_hook_procedure_ (function));
+ SCM_ALLOW_INTS;
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_add_global_hook_ (SCM function, gboolean pre)
+{
+ const gchar *fun =
+ pre? "mix-add-global-pre-hook" : "mix-add-global-post-hook";
+
+ SCM_ASSERT (gh_procedure_p (function), function, SCM_ARG1, fun);
+ SCM_DEFER_INTS;
+ if (pre)
+ mix_vm_cmd_dispatcher_global_pre_hook (vm_dispatcher_, scm_global_hook_,
+ (gpointer)
+ define_hook_procedure_ (function));
+ else
+ mix_vm_cmd_dispatcher_global_post_hook (vm_dispatcher_, scm_global_hook_,
+ (gpointer)
+ define_hook_procedure_ (function));
+ SCM_ALLOW_INTS;
+ return gh_symbol2scm ("ok");
+}
+
+static SCM
+mix_add_pre_hook_ (SCM cmd, SCM function)
+{
+ return mix_add_hook_ (cmd, function, TRUE);
+}
+
+static SCM
+mix_add_post_hook_ (SCM cmd, SCM function)
+{
+ return mix_add_hook_ (cmd, function, FALSE);
+}
+
+static SCM
+mix_add_global_pre_hook_ (SCM function)
+{
+ return mix_add_global_hook_ (function, TRUE);
+}
+
+static SCM
+mix_add_global_post_hook_ (SCM function)
+{
+ return mix_add_global_hook_ (function, FALSE);
+}
+
+/* NULL-terminated list of available scm commands */
+const scm_command_t DEFAULT_SCM_COMMANDS_[] = {
+ {"mixvm-cmd", mixvm_cmd_, 2, 0, 0},
+ {"mixvm-status", mixvm_status_, 0, 0, 0},
+ {"mix-last-result", mix_last_result_, 0, 0, 0},
+ {"mix-reg", mix_reg_, 1, 0, 0},
+ {"mix-set-reg!", mix_set_reg_, 2, 0, 0},
+ {"mix-cell", mix_cell_, 1, 0, 0},
+ {"mix-set-cell!", mix_set_cell_, 2, 0, 0},
+ {"mix-over", mix_over_, 0, 0, 0},
+ {"mix-loc", mix_loc_, 0, 0, 0},
+ {"mix-set-over!", mix_set_over_, 1, 0, 0},
+ {"mix-cmp", mix_cmp_, 0, 0, 0},
+ {"mix-up-time", mix_uptime_, 0, 0, 0},
+ {"mix-lap-time", mix_laptime_, 0, 0, 0},
+ {"mix-prog-time", mix_progtime_, 0, 0, 0},
+ {"mix-prog-name", mix_prog_name_, 0, 0, 0},
+ {"mix-prog-path", mix_prog_path_, 0, 0, 0},
+ {"mix-src-name", mix_src_name_, 0, 0, 0},
+ {"mix-src-path", mix_src_path_, 0, 0, 0},
+ {"mix-src-line-no", mix_src_line_no_, 0, 0, 0},
+ {"mix-src-line", mix_src_line_, 0, 1, 0},
+ {"mix-ddir", mix_ddir_, 0, 0, 0},
+ {"mix-set-cmp!", mix_set_cmp_, 1, 0, 0},
+ {"mix-add-pre-hook", mix_add_pre_hook_, 2, 0, 0},
+ {"mix-add-post-hook", mix_add_post_hook_, 2, 0, 0},
+ {"mix-add-global-pre-hook", mix_add_global_pre_hook_, 1, 0, 0},
+ {"mix-add-global-post-hook", mix_add_global_post_hook_, 1, 0, 0},
+ {NULL}
+};
diff --git a/mixguile/xmixguile_cmd_dispatcher.h b/mixguile/xmixguile_cmd_dispatcher.h
new file mode 100644
index 0000000..f7ef756
--- /dev/null
+++ b/mixguile/xmixguile_cmd_dispatcher.h
@@ -0,0 +1,67 @@
+/* -*-c-*- ---------------- xmixguile_cmd_dispatcher.h :
+ * Internal declarations for mixguile_cmd_dispatcher_t
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/08/22 01:11:20 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIXGUILE_CMD_DISPATCHER_H
+#define XMIXGUILE_CMD_DISPATCHER_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <guile/gh.h>
+#include "mixguile_cmd_dispatcher.h"
+
+/* the cmd dispatcher type */
+struct mixguile_cmd_dispatcher_t
+{
+ mix_vm_cmd_dispatcher_t *dispatcher;
+};
+
+/* scm commands types */
+/* prototype of a function implementing a new scm function */
+typedef SCM (*scm_func_t) ();
+
+/* record for a new scm command */
+typedef struct scm_command_t
+{
+ gchar *name; /* name of the scheme command */
+ scm_func_t func; /* implementation of the command */
+ int argno; /* no. of arguments */
+ int opt_argno; /* no. of optional arguments */
+ int restp; /* if 1, receive a list of remaining args */
+} scm_command_t;
+
+/* NULL-terminated list of available scm commands */
+extern const scm_command_t DEFAULT_SCM_COMMANDS_[];
+
+/* register a NULL-terminated list of scm commands */
+extern void
+register_scm_commands_ (const scm_command_t *commands);
+
+/* register the mixvm cmd dispatcher to use with commands */
+extern void
+register_cmd_dispatcher_ (mixguile_cmd_dispatcher_t *dis);
+
+
+#endif /* XMIXGUILE_CMD_DISPATCHER_H */
+
diff --git a/mixlib/Makefile.am b/mixlib/Makefile.am
new file mode 100644
index 0000000..b925ff5
--- /dev/null
+++ b/mixlib/Makefile.am
@@ -0,0 +1,42 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.6 2002/12/08 01:36:49 jao Exp $
+
+SUBDIRS = testsuite
+INCLUDES = -I$(includedir) -I$(top_srcdir) -DG_LOG_DOMAIN=\"libmix\"
+
+noinst_LIBRARIES = libmix.a
+libmix_a_SOURCES = gettext.h mix.h mix.c \
+ mix_types.h mix_types.c \
+ mix_ins.h mix_ins.c \
+ mix_vm.h mix_vm.c xmix_vm.h xmix_vm.c \
+ mix_vm_dump.h mix_vm_dump.c \
+ mix_io.h mix_io.c xmix_io.h xmix_io.c \
+ mix_symbol_table.h mix_symbol_table.c \
+ mix_file.h mix_file.c \
+ mix_code_file.h mix_code_file.c \
+ mix_parser.h xmix_parser.h mix_parser.c mix_scanner.l \
+ mix_device.h mix_device.c xmix_device.h xmix_device.c \
+ mix_eval.h mix_eval.c xmix_eval.h mix_eval_scanner.l \
+ mix_src_file.c mix_src_file.h \
+ mix_vm_clock.c mix_vm_clock.h \
+ mix_vm_command.c mix_vm_command.h \
+ xmix_vm_command.c xmix_vm_command.h \
+ xmix_vm_handlers.h xmix_vm_handlers.c \
+ mix_config.c mix_config.h \
+ mix_predicate.c mix_predicate.h \
+ mix_predicate_list.c mix_predicate_list.h
+
+
+
+
diff --git a/mixlib/gettext.h b/mixlib/gettext.h
new file mode 100644
index 0000000..fa3622f
--- /dev/null
+++ b/mixlib/gettext.h
@@ -0,0 +1,69 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+# define gettext(Msgid) ((const char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
+# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+#endif /* _LIBGETTEXT_H */
diff --git a/mixlib/mix.c b/mixlib/mix.c
new file mode 100644
index 0000000..3578a57
--- /dev/null
+++ b/mixlib/mix.c
@@ -0,0 +1,99 @@
+/* -*-c-*- -------------- mix.c :
+ * Implementation of the functions declared in mix.h
+ * ------------------------------------------------------------------
+ * $Id: mix.c,v 1.6 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+
+
+#include "mix_types.h"
+#include "mix_ins.h"
+#include "mix_code_file.h"
+#include "mix.h"
+
+
+/* This function must be called before using the library */
+void
+mix_init_lib(void)
+{
+ mix_init_types ();
+ mix_init_ins ();
+ mix_code_file_set_defext (MIX_CODE_DEFEXT);
+}
+
+
+/* This function must be called for deallocating the lib resources
+ when it is no longer in use
+*/
+void
+mix_release_lib (void)
+{
+ /* clean the user defined code file extension (if any) */
+ mix_code_file_set_defext (NULL);
+ mix_release_ins ();
+}
+
+const char *MIX_GPL_LICENSE =
+"Copyright (C) 2001 Free Software Foundation, Inc.\n"
+"There is NO warranty. You may redistribute this software\n"
+"under the terms of the GNU General Public License.\n"
+"For more information about these matters, see the files named COPYING.\n";
+
+void
+mix_print_license (const gchar *program)
+{
+ fprintf (stderr, _("%s (GNU MDK %s)\n\n"),
+ program, VERSION);
+ fprintf (stderr, MIX_GPL_LICENSE);
+}
+
+/* check dir, and create it if it doesn't exist */
+gboolean
+mix_stat_dir (const gchar *dirname, const gchar *alias)
+{
+ struct stat statbuf;
+
+ g_return_val_if_fail (dirname != NULL, FALSE);
+ if (alias == NULL) alias = "";
+
+ if (stat (dirname, &statbuf) == -1)
+ {
+ if (errno != ENOENT || mkdir (dirname, S_IRWXU | S_IRWXG | S_IRWXO))
+ {
+ g_warning (_("Error creating %s dir %s: %s"),
+ alias, dirname, strerror (errno));
+ return FALSE;
+ }
+ stat (dirname, &statbuf);
+ }
+
+ if (!(statbuf.st_mode & S_IFDIR))
+ {
+ g_warning (_("Error setting %s dir: %s is not a directory"),
+ alias, dirname);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/mixlib/mix.h b/mixlib/mix.h
new file mode 100644
index 0000000..6a3fd1d
--- /dev/null
+++ b/mixlib/mix.h
@@ -0,0 +1,78 @@
+/* -*-c-*- ---------------- mix.h :
+ * Initialisation of the mix library
+ * ------------------------------------------------------------------
+ * $Id: mix.h,v 1.7 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_H
+#define MIX_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#else
+# warning "config.h not found, package misconfigured."
+# define PACKAGE "mdk"
+# define VERSION "0.0"
+#endif
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+/*
+#ifdef HAVE_GETTEXT
+# include <libintl.h>
+# define gettext_noop(String) (String)
+#else
+# include <intl/libgettext.h>
+#endif
+*/
+#include "gettext.h"
+
+#define _(String) gettext (String)
+#define N_(String) gettext_noop (String)
+
+#include <glib.h>
+
+/* This function must be called before using the library */
+extern void
+mix_init_lib (void);
+
+/* This function must be called for deallocating the lib resources
+ when it is no longer in use
+*/
+extern void
+mix_release_lib (void);
+
+
+extern const char *MIX_GPL_LICENSE;
+
+extern void
+mix_print_license (const gchar *program);
+
+
+/* check dir, and create it if it doesn't exist */
+extern gboolean
+mix_stat_dir (const gchar *dirname, const gchar *alias);
+
+
+#endif /* MIX_H */
+
diff --git a/mixlib/mix_code_file.c b/mixlib/mix_code_file.c
new file mode 100644
index 0000000..ab67812
--- /dev/null
+++ b/mixlib/mix_code_file.c
@@ -0,0 +1,330 @@
+/* -*-c-*- -------------- mix_code_file.c :
+ * Implementation of the functions declared in mix_code_file.h
+ * ------------------------------------------------------------------
+ * $Id: mix_code_file.c,v 1.6 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+
+#include "mix.h"
+#include "xmix_io.h"
+#include "mix_code_file.h"
+
+/* mix_code_file_t type */
+static const gint32 SIGNATURE_ = 0xDEADBEEF; /* release files */
+static const gint32 SIGNATURE_D_ = 0xBEEFDEAD; /* debug files */
+
+#define IS_DEBUG_(file) ((file)->header.signature == SIGNATURE_D_)
+#define IS_RELEASE_(file) ((file)->header.signature == SIGNATURE_)
+
+
+typedef struct mix_cfheader_t mix_cfheader_t;
+struct mix_cfheader_t
+{
+ gint32 signature;
+ gint mj_ver;
+ gint mn_ver;
+ gint16 start;
+ size_t path_len;
+};
+
+struct mix_code_file_t
+{
+ mix_file_t *file; /* the underlying disk file */
+ mix_address_t address; /* current address while reading */
+ mix_cfheader_t header; /* file header */
+ gchar *source_path; /* variable length part of the header*/
+ mix_symbol_table_t *symbol_table; /* code files with debug info fill it*/
+};
+
+#define to_io_(cf) MIX_IOCHANNEL (cf->file)
+
+/* Code files are lists of tagged words. A MIX_INS_TAG_ denotes
+ * that the word is an instruction, whose address is the next to
+ * the previous instruction's one, while a MIX_ADDR_TAG_ indicates
+ * that the word is a new address origin for the next instructions.
+ * The tags are stored as bit patterns in bit 31 of the mix word.
+ */
+#define MIX_ADDR_TAG_ (MIX_WORD_SIGN_BIT<<1)
+
+#define is_ins_(word) (((word)&MIX_ADDR_TAG_) == MIX_WORD_ZERO)
+#define is_addr_(word) (((word)&MIX_ADDR_TAG_) == MIX_ADDR_TAG_)
+#define tag_ins_(word) (word)
+#define tag_addr_(word) ((word)|MIX_ADDR_TAG_)
+#define extract_ins_(tagged) (tagged)
+#define extract_addr_(tagged) ((tagged)&MIX_SHORT_MAX)
+
+/* mix code files have a default extension (.mix) which is customizable */
+static const gchar *DEFEXT_ = NULL;
+
+const gchar *
+mix_code_file_get_defext (void)
+{
+ return DEFEXT_;
+}
+
+gboolean
+mix_code_file_set_defext (const gchar *ext)
+{
+ if (DEFEXT_ != NULL) g_free ((void *)DEFEXT_);
+ DEFEXT_ = (ext != NULL)? g_strdup (ext):NULL;
+ return (DEFEXT_ != NULL || ext == NULL);
+}
+
+/* create/destroy code files for read or write */
+static mix_code_file_t *
+mix_code_file_new_ (const gchar *name, mix_fmode_t mode)
+{
+ mix_code_file_t *result = g_new (mix_code_file_t, 1);
+ if ( result != NULL )
+ {
+ result->file = mix_file_new_with_def_ext (name, mode, DEFEXT_);
+ result->address = MIX_SHORT_ZERO;
+ result->source_path = NULL;
+ result->symbol_table = NULL;
+ }
+ if ( result != NULL && result->file == NULL )
+ {
+ g_free (result);
+ result = NULL;
+ }
+ return result;
+}
+
+mix_code_file_t *
+mix_code_file_new_read (const gchar *name)
+{
+ mix_code_file_t *result = mix_code_file_new_ (name, mix_io_READ);
+ mix_cfheader_t *header;
+ FILE *file;
+ gboolean check;
+
+ if ( result == NULL )
+ return NULL;
+
+ file = mix_file_to_FILE (result->file);
+ header = &(result->header);
+ check = fread (header, sizeof (mix_cfheader_t), 1, file)
+ && (IS_RELEASE_ (result) || IS_DEBUG_ (result));
+
+ if ( check )
+ {
+ gint major, minor;
+ sscanf (VERSION, "%d.%d", &major, &minor);
+ check = header->mj_ver == major && header->mn_ver <= minor;
+ }
+
+ if ( check )
+ {/* get source path */
+ result->source_path = g_strnfill (1 + header->path_len, '\0');
+ check = result->source_path != NULL
+ && fgets (result->source_path, 1 + header->path_len, file) != NULL;
+ }
+
+ if ( check && IS_DEBUG_ (result) )
+ {/* read symbol table */
+ result->symbol_table = mix_symbol_table_new_from_file (file);
+ check = result->symbol_table != NULL;
+ }
+
+ if ( !check )
+ {
+ mix_code_file_delete (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+mix_code_file_t *
+mix_code_file_new_write(const gchar *name, mix_address_t addr,
+ const gchar *source_path, gboolean debug,
+ const mix_symbol_table_t *table)
+{
+ mix_code_file_t *result;
+ FILE *file;
+ gboolean check;
+
+ result = mix_code_file_new_ (name, mix_io_WRITE);
+ if ( result == NULL || ( file = mix_file_to_FILE (result->file) ) == NULL )
+ return NULL;
+ else if ( source_path != NULL )
+ {
+ result->source_path = g_strdup (source_path/*, MAX_PATH_LEN_*/);
+ if ( result->source_path == NULL )
+ {
+ mix_code_file_delete (result);
+ return NULL;
+ }
+ }
+ else
+ result->source_path = NULL;
+
+ result->header.signature = debug? SIGNATURE_D_:SIGNATURE_;
+ sscanf (VERSION, "%d.%d", &result->header.mj_ver, &result->header.mn_ver);
+ result->header.start = (gint16) addr;
+ result->header.path_len = strlen (result->source_path);
+ check = write_data_ (to_io_ (result), &result->header, 1);
+ if ( check && result->source_path != NULL )
+ check = fputs (result->source_path, file) != EOF;
+ if ( check && debug )
+ mix_symbol_table_print (table, MIX_SYM_LINE, file, TRUE);
+ if ( !check )
+ {
+ mix_code_file_delete (result);
+ return NULL;
+ }
+ return result;
+}
+
+void
+mix_code_file_delete (mix_code_file_t *file)
+{
+ g_return_if_fail (file != NULL);
+ mix_file_delete (file->file);
+ if (file->source_path) g_free (file->source_path);
+ g_free (file);
+}
+
+/* get general parameters from a code file */
+gboolean
+mix_code_file_is_debug (const mix_code_file_t *file)
+{
+ return (file != NULL) && IS_DEBUG_ (file);
+}
+
+gint
+mix_code_file_major_version (const mix_code_file_t *file)
+{
+ g_return_val_if_fail (file != NULL, 0);
+ return file->header.mj_ver;
+}
+
+gint
+mix_code_file_minor_version (const mix_code_file_t *file)
+{
+ g_return_val_if_fail (file != NULL, 0);
+ return file->header.mn_ver;
+}
+
+mix_address_t
+mix_code_file_get_start_addr (const mix_code_file_t *file)
+{
+ g_return_val_if_fail (file != NULL, MIX_SHORT_ZERO);
+ return mix_short_new (file->header.start);
+}
+
+mix_symbol_table_t *
+mix_code_file_get_symbol_table(mix_code_file_t *file)
+{
+ mix_symbol_table_t *result = NULL;
+ g_return_val_if_fail (file != NULL, NULL);
+ result = file->symbol_table;
+ file->symbol_table = NULL;
+ return result;
+}
+
+/* read instructions from a code file */
+gboolean
+mix_code_file_is_eof (mix_code_file_t *file)
+{
+ return is_eof_ (to_io_ (file));
+}
+
+gboolean
+mix_code_file_get_ins (mix_code_file_t *file, mix_ins_desc_t *desc)
+{
+ mix_word_t next;
+ g_return_val_if_fail (file != NULL, FALSE);
+ g_return_val_if_fail (desc != NULL, FALSE);
+ while (TRUE)
+ {
+ if ( ! mix_io_read_word_array (to_io_ (file), &next, 1) ) return FALSE;
+ if ( is_addr_ (next) )
+ file->address = extract_addr_ (next);
+ else if ( is_ins_ (next) )
+ {
+ desc->ins = extract_ins_ (next);
+ desc->address = (file->address)++;
+ if ( IS_DEBUG_ (file) )
+ {
+ mix_short_t lineno;
+ if ( !mix_io_read_short_array (to_io_ (file), &lineno, 1) )
+ return FALSE;
+ desc->lineno = mix_short_magnitude (lineno);
+ }
+ else
+ desc->lineno = 0;
+ return TRUE;
+ }
+ else
+ {
+ g_assert_not_reached ();
+ return FALSE;
+ }
+ };
+}
+
+/* Write instructions to a code file */
+gboolean
+mix_code_file_write_ins (mix_code_file_t *file, const mix_ins_desc_t *desc)
+{
+ g_return_val_if_fail (desc != NULL, FALSE);
+ return ( mix_code_file_set_address (file, desc->address) &&
+ mix_code_file_write_next_ins (file, desc->ins, desc->lineno) );
+}
+
+gboolean
+mix_code_file_write_next_ins (mix_code_file_t *file, mix_word_t ins,
+ guint lineno)
+{
+ g_return_val_if_fail (file != NULL, FALSE);
+ if ( mix_io_write_word (to_io_ (file), tag_ins_ (ins))
+ && ( IS_RELEASE_ (file)
+ || mix_io_write_short (to_io_ (file), mix_short_new (lineno)) )
+ )
+ {
+ ++(file->address);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+gboolean
+mix_code_file_set_address (mix_code_file_t *file, mix_address_t address)
+{
+ g_return_val_if_fail(file != NULL, FALSE);
+ if ( file->address != address ) {
+ if ( !mix_io_write_word (to_io_ (file),
+ tag_addr_ (mix_short_to_word_fast (address))) )
+ return FALSE;
+ file->address = address;
+ }
+ return TRUE;
+}
+
+/* get details about the source file */
+const gchar *
+mix_code_file_get_source_path (const mix_code_file_t *file)
+{
+ g_return_val_if_fail (file != NULL, NULL);
+ return file->source_path;
+}
diff --git a/mixlib/mix_code_file.h b/mixlib/mix_code_file.h
new file mode 100644
index 0000000..84b89fb
--- /dev/null
+++ b/mixlib/mix_code_file.h
@@ -0,0 +1,106 @@
+/* -*-c-*- ---------------- mix_code_file.h :
+ * Declaration of mix_code_file_t, a file containing compiled mix
+ * instructions.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_CODE_FILE_H
+#define MIX_CODE_FILE_H
+
+#include "mix_file.h"
+#include "mix_ins.h"
+#include "mix_symbol_table.h"
+
+/* mix_code_file_t type */
+typedef struct mix_code_file_t mix_code_file_t;
+
+/* instructions are loaded at specific memory addresses and related to
+ source line numbers
+*/
+typedef struct mix_ins_desc_t mix_ins_desc_t;
+struct mix_ins_desc_t
+{
+ mix_word_t ins; /* a mix instruction coded into a word */
+ mix_address_t address; /* the address of this instruction */
+ guint lineno; /* source file line no. */
+};
+
+/* mix code files have a default extension (.mix) which is customizable */
+extern const gchar *
+mix_code_file_get_defext(void);
+
+extern gboolean
+mix_code_file_set_defext(const gchar *ext);
+
+/* create/destroy code files for read or write */
+/* if -name- does not end with defext, it is automatically appended */
+extern mix_code_file_t *
+mix_code_file_new_read(const gchar *name);
+
+/* open a code file for write with/out debug information */
+extern mix_code_file_t *
+mix_code_file_new_write(const gchar *name, mix_address_t start,
+ const gchar *source_path, gboolean debug,
+ const mix_symbol_table_t *table);
+
+extern void
+mix_code_file_delete(mix_code_file_t *file);
+
+/* get general parameters from a code file */
+extern gboolean
+mix_code_file_is_debug(const mix_code_file_t *file);
+
+extern gint
+mix_code_file_major_version(const mix_code_file_t *file);
+
+extern gint
+mix_code_file_minor_version(const mix_code_file_t *file);
+
+extern mix_address_t
+mix_code_file_get_start_addr(const mix_code_file_t *file);
+
+extern mix_symbol_table_t *
+mix_code_file_get_symbol_table(mix_code_file_t *file);
+
+/* read instructions from a code file */
+extern gboolean
+mix_code_file_is_eof(mix_code_file_t *file);
+
+extern gboolean
+mix_code_file_get_ins(mix_code_file_t *file, mix_ins_desc_t *desc);
+
+/* write instructions to a code file */
+extern gboolean
+mix_code_file_write_ins(mix_code_file_t *file, const mix_ins_desc_t *desc);
+
+extern gboolean
+mix_code_file_write_next_ins(mix_code_file_t *file, mix_word_t ins,
+ guint lineno);
+
+extern gboolean
+mix_code_file_set_address(mix_code_file_t *file, mix_address_t address);
+
+/* get details about the source file */
+extern const gchar *
+mix_code_file_get_source_path (const mix_code_file_t *file);
+
+
+#endif /* MIX_CODE_FILE_H */
+
diff --git a/mixlib/mix_config.c b/mixlib/mix_config.c
new file mode 100644
index 0000000..694b18b
--- /dev/null
+++ b/mixlib/mix_config.c
@@ -0,0 +1,298 @@
+/* -*-c-*- -------------- mix_config.c :
+ * Implementation of the functions declared in mix_config.h
+ * ------------------------------------------------------------------
+ * $Id: mix_config.c,v 1.12 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "mix_config.h"
+
+const gchar *MIX_CONFIG_DIR = ".mdk";
+
+static const gchar COMMENT_PREFIX_ = '#';
+static const gchar *AUTOSAVE_KEY_ = "Autosave";
+static const gchar *AUTOSAVE_YES_ = "True";
+static const gchar *AUTOSAVE_NO_ = "False";
+static const gchar *DEVICES_KEY_ = "Devices.dir";
+static const gchar *HISTORY_KEY_ = "History.file";
+static const gchar *HISTORY_SIZE_KEY_ = "History.size";
+
+/* the config type */
+struct mix_config_t
+{
+ gchar *filename; /* full path to configuration file */
+ gboolean autosave; /* whether save on destroy */
+ GHashTable *items; /* configuration items */
+};
+
+/* create a new config handler, giving the dir and name of the config file */
+mix_config_t *
+mix_config_new (const gchar *dirname, const gchar *filename)
+{
+ static const gchar *DEF_DIRNAME_ = NULL;
+ static const gchar *DEF_FILENAME_ = "config";
+
+ const gchar *autosave;
+ FILE *f;
+ mix_config_t *result = NULL;
+
+ if (DEF_DIRNAME_ == NULL)
+ DEF_DIRNAME_ = g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S,
+ MIX_CONFIG_DIR, NULL);
+
+ if (dirname == NULL) dirname = DEF_DIRNAME_;
+ if (filename == NULL) filename = DEF_FILENAME_;
+
+ if (!mix_stat_dir (dirname, "configuration")) return NULL;
+
+ result = g_new (mix_config_t, 1);
+ result->filename = g_strdup_printf ("%s/%s", dirname, filename);
+ result->items = g_hash_table_new (g_str_hash, g_str_equal);
+
+ f = fopen (result->filename, "r");
+ if (f != NULL)
+ {
+ enum {LEN = 256};
+ gchar buffer[LEN];
+ gchar *line = buffer;
+ while (!feof (f))
+ {
+ line = fgets (line, LEN, f);
+ if (line) line = g_strstrip (line);
+ if (line && line[0] != COMMENT_PREFIX_)
+ {
+ gchar **vals = g_strsplit (line, "=", 2);
+ g_hash_table_insert (result->items,
+ (gpointer) g_strstrip (vals[0]),
+ (gpointer) g_strstrip (vals[1]));
+ }
+ }
+ fclose (f);
+ }
+
+ autosave = mix_config_get (result, AUTOSAVE_KEY_);
+ result->autosave = autosave && !g_ascii_strcasecmp (autosave, AUTOSAVE_YES_);
+
+ return result;
+}
+
+/* delete a config handler, saving the configuration if needed */
+void
+mix_config_delete (mix_config_t *config)
+{
+ g_return_if_fail (config != NULL);
+ if (mix_config_is_autosave (config)) mix_config_save (config);
+ g_free (config->filename);
+ g_hash_table_destroy (config->items);
+ g_free (config);
+}
+
+/* get the config filename */
+const gchar *
+mix_config_get_filename (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ return config->filename;
+}
+
+/* get a config item's value from its key */
+const gchar *
+mix_config_get (const mix_config_t *config, const gchar *key)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ return (const gchar*)g_hash_table_lookup (config->items, key);
+}
+
+gint
+mix_config_get_integer (const mix_config_t *config, const gchar *key)
+{
+ const gchar *val;
+ g_return_val_if_fail (config != NULL, 0);
+ g_return_val_if_fail (key != NULL, 0);
+ val = mix_config_get (config, key);
+ if (!val) return 0;
+ return atoi (val);
+}
+
+/* update (or create if it does not exist) a new config item */
+void
+mix_config_update (mix_config_t *config, const gchar *key, const gchar *value)
+{
+ gpointer okey = NULL;
+ gpointer oval = NULL;
+
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ if (g_hash_table_lookup_extended (config->items, key, &okey, &oval))
+ {
+ if (oval != value)
+ {
+ g_free (oval);
+ oval = (gpointer)g_strdup (value);
+ }
+ }
+ else
+ {
+ okey = (gpointer)g_strdup (key);
+ oval = (gpointer)g_strdup (value);
+ }
+
+ g_hash_table_insert (config->items, okey, oval);
+}
+
+void
+mix_config_update_integer (mix_config_t *config, const gchar *key, gint value)
+{
+ gchar *val;
+
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (key != NULL);
+
+ val = g_strdup_printf ("%d", value);
+ mix_config_update (config, key, val);
+ g_free (val);
+}
+
+void
+mix_config_remove (mix_config_t *config, const gchar *key)
+{
+ gchar *val;
+
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (key != NULL);
+
+ val = g_hash_table_lookup (config->items, key);
+ if (val != NULL)
+ {
+ g_hash_table_remove (config->items, key);
+ g_free (val);
+ }
+}
+
+/* save the current configuration */
+static void
+save_ (gpointer key, gpointer value, gpointer file)
+{
+ fprintf ((FILE *)file, "%s=%s\n", (char *)key, (char *)value);
+}
+
+void
+mix_config_save (const mix_config_t *config)
+{
+ FILE *f;
+
+ g_return_if_fail (config != NULL);
+
+ f = fopen (config->filename, "w");
+ if (!f)
+ {
+ g_warning (_("Unable to open config file %s (%s)"),
+ config->filename, g_strerror (errno));
+ return;
+ }
+ g_hash_table_foreach (config->items, save_, (gpointer)f);
+ fclose (f);
+}
+
+/* set autosave on delete flag */
+void
+mix_config_set_autosave (mix_config_t *config, gboolean autosave)
+{
+ mix_config_update (config, AUTOSAVE_KEY_,
+ autosave? AUTOSAVE_YES_ : AUTOSAVE_NO_);
+ config->autosave = autosave;
+}
+
+
+gboolean
+mix_config_is_autosave (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, FALSE);
+ return config->autosave;
+}
+
+/* devices dir*/
+void
+mix_config_set_devices_dir (mix_config_t *config, const gchar *dirname)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (dirname != NULL);
+ if (mix_stat_dir (dirname, "devices"))
+ mix_config_update (config, DEVICES_KEY_, dirname);
+}
+
+extern const gchar *
+mix_config_get_devices_dir (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ return mix_config_get (config, DEVICES_KEY_);
+}
+
+/* history file. if relative path, config dir taken as root */
+void
+mix_config_set_history_file (mix_config_t *config, const gchar *path)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (path != NULL);
+ if (g_path_is_absolute (path))
+ {
+ mix_config_update (config, HISTORY_KEY_, path);
+ }
+ else
+ {
+ gchar *base = g_path_get_dirname (config->filename);
+ gchar *hf = g_strconcat (base, G_DIR_SEPARATOR_S, path, NULL);
+ mix_config_update (config, HISTORY_KEY_, hf);
+ g_free (hf);
+ g_free (base);
+ }
+}
+
+const gchar *
+mix_config_get_history_file (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ return mix_config_get (config, HISTORY_KEY_);
+}
+
+void
+mix_config_set_history_size (mix_config_t *config, gint s)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (s >= 0);
+ mix_config_update_integer (config, HISTORY_SIZE_KEY_, s);
+}
+
+gint
+mix_config_get_history_size (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, 0);
+ return mix_config_get_integer (config, HISTORY_SIZE_KEY_);
+}
diff --git a/mixlib/mix_config.h b/mixlib/mix_config.h
new file mode 100644
index 0000000..9d2af32
--- /dev/null
+++ b/mixlib/mix_config.h
@@ -0,0 +1,100 @@
+/* -*-c-*- ---------------- mix_config.h :
+ * Basic config storage utility.
+ * ------------------------------------------------------------------
+ * $Id: mix_config.h,v 1.6 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_CONFIG_H
+#define MIX_CONFIG_H
+
+#include "mix.h"
+
+/* default config dir */
+extern const gchar *MIX_CONFIG_DIR;
+
+/* the config type */
+typedef struct mix_config_t mix_config_t;
+
+/* create a new config handler, giving the dir and name of the config file */
+extern mix_config_t *
+mix_config_new (const gchar *dirname, const gchar *filename);
+
+/* delete a config handler, saving the configuration if needed */
+extern void
+mix_config_delete (mix_config_t *config);
+
+/* get the config filename (fully qualified) */
+extern const gchar *
+mix_config_get_filename (const mix_config_t *config);
+
+/* get a config item's value from its key */
+extern const gchar *
+mix_config_get (const mix_config_t *config, const gchar *key);
+
+extern gint
+mix_config_get_integer (const mix_config_t *config, const gchar *key);
+
+/* update (or create if it does not exist) a new config item */
+extern void
+mix_config_update (mix_config_t *config, const gchar *key, const gchar *value);
+
+extern void
+mix_config_update_integer (mix_config_t *config, const gchar *key, gint value);
+
+extern void
+mix_config_remove (mix_config_t *config, const gchar *key);
+
+/* save the current configuration */
+extern void
+mix_config_save (const mix_config_t *config);
+
+/** shared config params **/
+
+/* set autosave on delete flag */
+extern void
+mix_config_set_autosave (mix_config_t *config, gboolean autosave);
+
+extern gboolean
+mix_config_is_autosave (const mix_config_t *config);
+
+/* devices dir*/
+extern void
+mix_config_set_devices_dir (mix_config_t *config, const gchar *dirname);
+
+extern const gchar *
+mix_config_get_devices_dir (const mix_config_t *config);
+
+/* history file. if relative path, config dir taken as root */
+extern void
+mix_config_set_history_file (mix_config_t *config, const gchar *path);
+
+extern const gchar *
+mix_config_get_history_file (const mix_config_t *config);
+
+extern void
+mix_config_set_history_size (mix_config_t *config, gint s);
+
+extern gint
+mix_config_get_history_size (const mix_config_t *config);
+
+
+#endif /* MIX_CONFIG_H */
+
diff --git a/mixlib/mix_device.c b/mixlib/mix_device.c
new file mode 100644
index 0000000..6a99e8a
--- /dev/null
+++ b/mixlib/mix_device.c
@@ -0,0 +1,164 @@
+/* -*-c-*- -------------- mix_device.c :
+ * Implementation of the functions declared in mix_device.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mix_file.h"
+#include "xmix_device.h"
+
+/*
+ Set the directory for mix device files (by default, it's ".")
+ If the dir does not exist, it is created.
+*/
+gboolean
+mix_device_set_dir (const gchar *dirname)
+{
+ if (mix_stat_dir (dirname, "devices"))
+ {
+ if (DEV_DIR_) g_free (DEV_DIR_);
+ DEV_DIR_ = g_strdup (dirname);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+const gchar *
+mix_device_get_dir (void)
+{
+ return DEV_DIR_;
+}
+
+mix_device_t *
+mix_device_new (mix_device_type_t type)
+{
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
+ construct_device_ (result, type);
+ return result;
+}
+
+
+
+mix_device_t *
+mix_device_new_with_name (mix_device_type_t type, const gchar *name)
+{
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
+ construct_device_with_name_ (result, type, name);
+ return result;
+}
+
+/*
+ Create a new device with a given type and stream
+*/
+mix_device_t *
+mix_device_new_with_file (mix_device_type_t type, FILE *file)
+{
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
+ construct_device_with_file_ (result, type, file);
+ return result;
+}
+
+void
+mix_device_delete (mix_device_t *dev)
+{
+ if (dev != NULL)
+ {
+ (dev->vtable->destroy) (dev);
+ g_free (dev);
+ }
+}
+
+mix_device_type_t
+mix_device_type (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, mix_dev_INVALID);
+ return dev->type;
+}
+
+const char *
+mix_device_get_name (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, NULL);
+ return mix_file_base_name(GET_FILE_(dev));
+}
+
+/*
+ Get the device block size
+*/
+size_t
+mix_device_block_size (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, 0);
+ return SIZES_[dev->type];
+}
+
+/*
+ Get the device io mode
+*/
+mix_device_mode_t
+mix_device_mode (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, 0);
+ return MODES_[dev->type];
+}
+
+/*
+ Write a block to the device.
+*/
+gboolean
+mix_device_write (mix_device_t *dev, const mix_word_t *block)
+{
+ g_return_val_if_fail (dev != NULL, FALSE);
+ g_return_val_if_fail (block != NULL, FALSE);
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->write) (dev, block);
+}
+
+gboolean
+mix_device_read (mix_device_t *dev, mix_word_t *block)
+{
+ g_return_val_if_fail (dev != NULL, FALSE);
+ g_return_val_if_fail (block != NULL, FALSE);
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->read) (dev, block);
+}
+
+gboolean
+mix_device_ioc (mix_device_t *dev, mix_short_t arg)
+{
+ g_return_val_if_fail (dev != NULL, FALSE);
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->ioc) (dev, arg);
+}
+
+gboolean
+mix_device_busy (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, FALSE);
+ return (dev->vtable->busy) (dev);
+
+}
diff --git a/mixlib/mix_device.h b/mixlib/mix_device.h
new file mode 100644
index 0000000..7830dfe
--- /dev/null
+++ b/mixlib/mix_device.h
@@ -0,0 +1,160 @@
+/* -*-c-*- ---------------- mix_device.h :
+ * Declaration of mix_device_t and associated methods.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_DEVICE_H
+#define MIX_DEVICE_H
+
+#include <stddef.h>
+#include <stdio.h>
+#include "mix.h"
+#include "mix_types.h"
+
+/*
+ A mix device, which derives from mix_io_channel_t
+*/
+typedef struct mix_device_t mix_device_t;
+
+/*
+ The device type
+*/
+typedef enum {
+ mix_dev_TAPE_0,
+ mix_dev_TAPE_1,
+ mix_dev_TAPE_2,
+ mix_dev_TAPE_3,
+ mix_dev_TAPE_4,
+ mix_dev_TAPE_5,
+ mix_dev_TAPE_6,
+ mix_dev_TAPE_7,
+ mix_dev_DISK_0,
+ mix_dev_DISK_1,
+ mix_dev_DISK_2,
+ mix_dev_DISK_3,
+ mix_dev_DISK_4,
+ mix_dev_DISK_5,
+ mix_dev_DISK_6,
+ mix_dev_DISK_7,
+ mix_dev_CARD_RD,
+ mix_dev_CARD_WR,
+ mix_dev_PRINTER,
+ mix_dev_CONSOLE,
+ mix_dev_PAPER_TAPE,
+ mix_dev_INVALID
+} mix_device_type_t;
+
+/*
+ The device io mode
+*/
+typedef enum {
+ mix_dev_BIN,
+ mix_dev_CHAR
+} mix_device_mode_t;
+
+/*
+ Set the directory for mix device files (by default, it's ".")
+ If the dir does not exist, it is created.
+*/
+extern gboolean
+mix_device_set_dir (const gchar *dirname);
+
+extern const gchar *
+mix_device_get_dir (void);
+
+/*
+ Create a new device with default name and given type.
+*/
+extern mix_device_t *
+mix_device_new (mix_device_type_t type);
+
+/*
+ Create a new device with a given type and name.
+*/
+extern mix_device_t *
+mix_device_new_with_name (mix_device_type_t type, const gchar *name);
+
+/*
+ Create a new device with a given type and stream
+*/
+extern mix_device_t *
+mix_device_new_with_file (mix_device_type_t type, FILE *file);
+
+/*
+ Delete a device.
+*/
+extern void
+mix_device_delete (mix_device_t *dev);
+
+/*
+ Get a device type
+*/
+extern mix_device_type_t
+mix_device_type (const mix_device_t *dev);
+
+
+/*
+ Get a device name
+*/
+extern const char *
+mix_device_get_name (const mix_device_t *dev);
+
+/*
+ Get the device block size
+*/
+extern size_t
+mix_device_block_size (const mix_device_t *dev);
+
+/*
+ Get the device io mode
+*/
+extern mix_device_mode_t
+mix_device_mode (const mix_device_t *dev);
+
+/*
+ Write a block to the device.
+*/
+extern gboolean
+mix_device_write (mix_device_t *dev, const mix_word_t *block);
+
+/*
+ Read a block from the device.
+*/
+extern gboolean
+mix_device_read (mix_device_t *dev, mix_word_t *block);
+
+/*
+ Perform an io control operation on the device.
+ The parameter _arg_ is the operation's argument:
+ 0- rewind to beginning
+ <0 - rewind the given number of blocks
+ >0 - skip forward the given number of blocks
+*/
+extern gboolean
+mix_device_ioc (mix_device_t *dev, mix_short_t arg);
+
+/*
+ Check if a device is busy
+*/
+extern gboolean
+mix_device_busy (const mix_device_t *dev);
+
+#endif /* MIX_DEVICE_H */
+
diff --git a/mixlib/mix_eval.c b/mixlib/mix_eval.c
new file mode 100644
index 0000000..f6f816a
--- /dev/null
+++ b/mixlib/mix_eval.c
@@ -0,0 +1,191 @@
+/* -*-c-*- -------------- mix_eval.c :
+ * Implementation of the functions declared in mix_eval.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/02/20 00:23:58 jose"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "xmix_eval.h"
+
+
+static const gchar *errors_[] = {
+ N_("Successful evaluation"),
+ N_("Syntax error in expression"),
+ N_("Out of range F-specification"),
+ N_("Mismatched parenthesis"),
+ N_("Undefined symbol"),
+ N_("Internal error")
+};
+
+
+/* create a new evaluator */
+mix_eval_t *
+mix_eval_new (void)
+{
+ mix_eval_t *result = g_new (mix_eval_t, 1);
+ result->table = mix_symbol_table_new ();
+ if (result->table == NULL) {
+ g_free (result);
+ return NULL;
+ }
+ result->towner = TRUE;
+ result->value = MIX_WORD_ZERO;
+ result->errpos = 0;
+ return result;
+}
+
+/* create a new evaluator with an external symbol table */
+mix_eval_t *
+mix_eval_new_with_table (mix_symbol_table_t *table)
+{
+ mix_eval_t *result = g_new (mix_eval_t, 1);
+ result->table = table;
+ result->towner = FALSE;
+ result->value = MIX_WORD_ZERO;
+ result->errpos = 0;
+ return result;
+}
+
+/* delete */
+void
+mix_eval_delete (mix_eval_t *eval)
+{
+ g_return_if_fail (eval);
+ if (eval->table && eval->towner) {
+ mix_symbol_table_delete (eval->table);
+ }
+ g_free (eval);
+}
+
+/* eval an expression */
+mix_eval_result_t
+mix_eval_expression_with_loc (mix_eval_t *eval, const gchar *expr,
+ mix_short_t loc)
+{
+ mix_eval_data_ data;
+
+ if (expr == NULL || eval == NULL)
+ return MIX_EVAL_INTERN;
+ data.expr = g_strdup_printf ("%s\n", expr);
+ data.table = eval->table;
+ data.errpos = eval->errpos;
+ data.value = eval->value;
+ data.loc = loc;
+ eval->result = mix_eval_expr (&data);
+ if (eval->result == MIX_EVAL_OK) {
+ eval->value = data.value;
+ eval->errpos = -1;
+ } else {
+ eval->errpos = data.errpos;
+ }
+ g_free (data.expr);
+
+ return eval->result;
+}
+
+/* get the result of the last evaluation */
+mix_word_t
+mix_eval_value (const mix_eval_t *eval)
+{
+ g_return_val_if_fail (eval != NULL, MIX_WORD_ZERO);
+ return eval->value;
+}
+
+/* get the last eval result code */
+mix_eval_result_t
+mix_eval_last_error (const mix_eval_t *eval)
+{
+ g_return_val_if_fail (eval != NULL, MIX_EVAL_INTERN);
+ return eval->result;
+}
+
+/* get the last error string */
+const gchar*
+mix_eval_last_error_string (const mix_eval_t *eval)
+{
+ g_return_val_if_fail (eval != NULL, errors_[MIX_EVAL_INTERN]);
+ return errors_[eval->result];
+}
+
+/* get the position of last error */
+guint
+mix_eval_last_error_pos (const mix_eval_t *eval)
+{
+ g_return_val_if_fail (eval != NULL, 0);
+ return eval->errpos;
+}
+
+/* add, or redefine, a symbol. see mix_symbol_table.h for
+ possible outcomes. */
+gint
+mix_eval_set_symbol (mix_eval_t *eval, const gchar *symbol,
+ mix_word_t value)
+{
+ g_return_val_if_fail (eval != NULL && eval->table != NULL,
+ MIX_SYM_FAIL);
+ return mix_symbol_table_insert (eval->table, symbol, value);
+}
+
+void
+mix_eval_remove_symbol (mix_eval_t *eval, const gchar *symbol)
+{
+ g_return_if_fail (eval != NULL && eval->table != NULL);
+ mix_symbol_table_remove (eval->table, symbol);
+}
+
+void
+mix_eval_use_symbol_table (mix_eval_t *eval,
+ mix_symbol_table_t *table)
+{
+ g_return_if_fail (eval != NULL);
+ if (eval->table != NULL && eval->towner)
+ mix_symbol_table_delete (eval->table);
+ eval->table = table;
+ eval->towner = FALSE;
+}
+
+const mix_symbol_table_t *
+mix_eval_symbol_table (const mix_eval_t *eval)
+{
+ g_return_val_if_fail (eval != NULL, NULL);
+ return eval->table;
+}
+
+gboolean
+mix_eval_set_symbols_from_table (mix_eval_t *eval,
+ const mix_symbol_table_t *table)
+{
+ g_return_val_if_fail (eval != NULL, FALSE);
+ if (eval->table != NULL)
+ return mix_symbol_table_merge_table (eval->table, table);
+ else
+ return FALSE;
+}
+
+gboolean
+mix_eval_remove_symbols_from_table (mix_eval_t *eval,
+ const mix_symbol_table_t *table)
+{
+ g_return_val_if_fail (eval != NULL, FALSE);
+ if (eval->table != NULL)
+ return mix_symbol_table_substract_table (eval->table, table);
+ else
+ return FALSE;
+}
diff --git a/mixlib/mix_eval.h b/mixlib/mix_eval.h
new file mode 100644
index 0000000..c1c1243
--- /dev/null
+++ b/mixlib/mix_eval.h
@@ -0,0 +1,110 @@
+/* -*-c-*- ---------------- mix_eval.h :
+ * mix_eval_t is an evaluator of MIX W-expressions
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/02/20 00:23:58 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_EVAL_H
+#define MIX_EVAL_H
+
+#include "mix.h"
+#include "mix_types.h"
+#include "mix_symbol_table.h"
+
+/* the evaluator type */
+typedef struct mix_eval_t mix_eval_t;
+
+/* possible evaluation outcomes*/
+typedef enum {
+ MIX_EVAL_OK, /* sucess*/
+ MIX_EVAL_SYNTAX, /* syntax error */
+ MIX_EVAL_INV_FSPEC, /* out of range fspec */
+ MIX_EVAL_MIS_PAREN, /* mismatched parenthesis */
+ MIX_EVAL_UNDEF_SYM, /* undefined symbol */
+ MIX_EVAL_INTERN /* internal error */
+} mix_eval_result_t;
+
+/* create a new evaluator */
+extern mix_eval_t *
+mix_eval_new (void);
+
+/* create a new evaluator with an external symbol table */
+extern mix_eval_t *
+mix_eval_new_with_table (mix_symbol_table_t *table);
+
+/* delete */
+extern void
+mix_eval_delete (mix_eval_t *eval);
+
+/* provide a new symbol table to be used */
+extern void
+mix_eval_use_symbol_table (mix_eval_t *eval,
+ mix_symbol_table_t *table);
+
+extern const mix_symbol_table_t *
+mix_eval_symbol_table (const mix_eval_t *eval);
+
+/* eval an expression providing a value for loc counter */
+extern mix_eval_result_t
+mix_eval_expression_with_loc (mix_eval_t *eval, const gchar *expr,
+ mix_short_t loc);
+/* eval an expression with null loc*/
+#define mix_eval_expression (eval,expr) \
+ mix_eval_expression_with_loc (eval, expr, MIX_SHORT_ZERO)
+
+
+/* get the result of the last evaluation */
+extern mix_word_t
+mix_eval_value (const mix_eval_t *eval);
+
+/* get the last eval result code */
+extern mix_eval_result_t
+mix_eval_last_error (const mix_eval_t *eval);
+
+/* get the last error string */
+extern const gchar*
+mix_eval_last_error_string (const mix_eval_t *eval);
+
+/* get the position of last error */
+extern guint
+mix_eval_last_error_pos (const mix_eval_t *eval);
+
+/* add, or redefine, a symbol. see mix_symbol_table.h for
+ possible outcomes. */
+extern gint
+mix_eval_set_symbol (mix_eval_t *eval, const gchar *symbol,
+ mix_word_t value);
+
+extern gboolean
+mix_eval_set_symbols_from_table (mix_eval_t *eval,
+ const mix_symbol_table_t *table);
+
+extern void
+mix_eval_remove_symbol (mix_eval_t *eval, const gchar *symbol);
+
+extern gboolean
+mix_eval_remove_symbols_from_table (mix_eval_t *eval,
+ const mix_symbol_table_t *table);
+
+
+
+#endif /* MIX_EVAL_H */
+
diff --git a/mixlib/mix_eval_scanner.l b/mixlib/mix_eval_scanner.l
new file mode 100644
index 0000000..8d0d3bd
--- /dev/null
+++ b/mixlib/mix_eval_scanner.l
@@ -0,0 +1,276 @@
+/* -*-c-*- ------------------ mix_eval_scanner.l :
+ * scanner used by mix_eval_t
+ * ------------------------------------------------------------------
+ * $Id: mix_eval_scanner.l,v 1.4 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+%{
+#include <string.h>
+#include "mix.h"
+#include "xmix_eval.h"
+
+#define YY_DECL \
+ mix_eval_result_t mix_eval_expr (mix_eval_data_ *data)
+
+/* keep track of current position in buffer */
+#define YY_USER_ACTION yypos += yyleng;
+
+#define RETURN_STATE(err) \
+ do { \
+ done = TRUE; \
+ state = err; \
+ BEGIN (INITIAL); \
+ } while (FALSE)
+
+#define CLEAN_UP() \
+ do { \
+ yy_delete_buffer (buffer); \
+ g_free (expr_cp); \
+ } while (FALSE)
+
+static mix_word_t eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y);
+
+static int unput_word_ (mix_word_t word);
+
+/* { */
+/* gchar *value; */
+/* gint k, result; */
+/* value = g_strdup_printf ("%s%ld", */
+/* mix_word_is_negative (word)? "-":"+", */
+/* mix_word_magnitude (word)); */
+/* result = strlen (value); */
+/* for (k = result - 1; k >= 0; --k) */
+/* unput (value[k]); */
+/* g_free (value); */
+/* return result; */
+/* } */
+
+%}
+
+%option nomain
+%option caseless
+%option array
+%option stack
+%option noyywrap
+%option noyy_top_state
+%option noreject
+%option outfile="lex.yy.c"
+
+%s EVAL
+%s WEVAL
+
+ws [ \t]+
+digit [0-9]
+letter [A-Z]
+number [+-]?{digit}+
+mixchar [0-9A-Z .,'')(+*/=$<>@;:\-]
+locsymbol {digit}H
+flocsymbol {digit}F
+blocsymbol {digit}B
+symbol {digit}*{letter}+[A-Z0-9]*
+binops "+"|"-"|"/"|"//"|":"
+binop {binops}|"*"
+atexpr {digit}+|{symbol}|\*
+expr [+-]?{atexpr}({binop}{1}{atexpr})*
+fpart \({expr}\)
+wexpr {expr}({fpart})?(,{expr}({fpart})?)*
+
+
+%%
+
+%{
+ YY_BUFFER_STATE buffer;
+ mix_word_t expr_val = MIX_WORD_ZERO, wexpr_val = MIX_WORD_ZERO;
+ mix_word_t wexpr_val_tmp = MIX_WORD_ZERO;
+ mix_eval_result_t state = MIX_EVAL_OK;
+ gchar *expr_cp;
+ gint yypos = -22; /* to account for padding */
+ gboolean is_fp = FALSE, done = FALSE;
+ g_assert (data != NULL && data->expr != NULL);
+ /* make room enough to unput computed values */
+ expr_cp = g_strdup_printf ("%-20s%s"," ", data->expr);
+ buffer = yy_scan_string (expr_cp);
+ data->errpos = -1;
+%}
+
+
+<*><<EOF>> {
+ CLEAN_UP ();
+ return MIX_EVAL_INTERN;
+}
+
+<INITIAL>{
+ {ws} /* eat whitespace */
+ . {
+ if (!done && state == MIX_EVAL_OK) {
+ yypos -= yyleng; yyless (0);
+ yy_push_state (WEVAL);
+ } else {
+ CLEAN_UP ();
+ if (state == MIX_EVAL_OK) return (MIX_EVAL_SYNTAX);
+ data->errpos = yypos;
+ return state;
+ }
+ }
+ "\n" {
+ CLEAN_UP();
+ if (state == MIX_EVAL_OK)
+ data->value = wexpr_val;
+ else
+ data->errpos = yypos;
+ return state;
+ }
+}
+
+<WEVAL>{
+ {number}"(" {
+ is_fp = TRUE;
+ wexpr_val_tmp = mix_word_new (atol (yytext));
+ }
+ {number}")" {
+ glong val = atol (yytext);
+ if ( !is_fp ) {
+ RETURN_STATE (MIX_EVAL_MIS_PAREN);
+ } else if ( val < 0 || val > MIX_BYTE_MAX
+ || !mix_fspec_is_valid (mix_byte_new (val)) ) {
+ RETURN_STATE (MIX_EVAL_INV_FSPEC);
+ } else {
+ is_fp = FALSE;
+ wexpr_val = mix_word_store_field (mix_byte_new (val),
+ wexpr_val_tmp,
+ wexpr_val);
+ }
+ }
+ {number}/({ws}*\n)|[,()] {
+ wexpr_val = mix_word_new (atol (yytext));
+ }
+ {expr}/({ws}*\n)|[,()] {
+ if (yytext[0] != '*')
+ {
+ yypos -= yyleng;
+ yyless (0);
+ }
+ else
+ {
+ yypos -= yyleng - 1;
+ expr_val = mix_short_to_word_fast (data->loc);
+ yyless (1);
+ }
+ yy_push_state (EVAL);
+ }
+ ,/{expr} /* eat comma if followed by expression */
+ [\t\n ] { /* ok if not inside an f-part */
+ if ( is_fp ) {
+ RETURN_STATE (MIX_EVAL_MIS_PAREN);
+ }
+ unput (yytext[yyleng-1]); --yypos;
+ done = TRUE;
+ yy_pop_state ();
+ }
+ . RETURN_STATE (MIX_EVAL_SYNTAX);
+}
+
+<EVAL>{
+ {binop}{digit}+ {
+ const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;
+ mix_word_t value = mix_word_new (atol (s));
+ expr_val = eval_binop_ (yytext, expr_val, value);
+ }
+ {binop}{symbol} {
+ const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;
+ if ( !mix_symbol_table_is_defined (data->table, s) ) {
+ RETURN_STATE (MIX_EVAL_UNDEF_SYM);
+ }
+ expr_val = eval_binop_ (yytext, expr_val,
+ mix_symbol_table_value (data->table, s));
+ }
+ {binop}"*" {
+ expr_val = eval_binop_ (yytext, expr_val,
+ mix_short_to_word_fast (data->loc));
+ }
+ "*" yypos -= unput_word_ (mix_short_to_word_fast (data->loc));
+ {number} expr_val = mix_word_new (atol (yytext));
+ {symbol} {
+ if ( !mix_symbol_table_is_defined (data->table, yytext) ) {
+ RETURN_STATE (MIX_EVAL_UNDEF_SYM);
+ }
+ expr_val = mix_symbol_table_value (data->table, yytext);
+ }
+ [,)(\n\t ] {
+ unput (yytext[0]); --yypos;
+ yypos -= unput_word_ (expr_val);
+ yy_pop_state ();
+ }
+
+ . RETURN_STATE (MIX_EVAL_SYNTAX);
+}
+
+
+%%
+
+static mix_word_t
+eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y)
+{
+ mix_word_t result = MIX_WORD_ZERO;
+ switch (op[0])
+ {
+ case '+':
+ result = mix_word_add (x,y);
+ break;
+ case '-':
+ result = mix_word_sub (x,y);
+ break;
+ case '*':
+ mix_word_mul (x, y, NULL, &result);
+ break;
+ case ':':
+ {
+ mix_word_t a;
+ mix_word_mul (x, 8, NULL, &a);
+ result = mix_word_add (a, y);
+ break;
+ }
+ case '/':
+ if ( strlen (op) > 1 && op[1] == '/' ) {
+ mix_word_div (x,MIX_WORD_ZERO,y, &result, NULL);
+ } else {
+ mix_word_div (MIX_WORD_ZERO, x, y, &result, NULL);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return result;
+}
+
+static int
+unput_word_ (mix_word_t word)
+{
+ gchar *value;
+ gint k, result;
+ value = g_strdup_printf ("%s%ld",
+ mix_word_is_negative (word)? "-":"+",
+ mix_word_magnitude (word));
+ result = strlen (value);
+ for (k = result - 1; k >= 0; --k)
+ unput (value[k]);
+ g_free (value);
+ return result;
+}
diff --git a/mixlib/mix_file.c b/mixlib/mix_file.c
new file mode 100644
index 0000000..383d3b4
--- /dev/null
+++ b/mixlib/mix_file.c
@@ -0,0 +1,159 @@
+/* -*-c-*- -------------- mix_file.c :
+ * Implementation of the functions declared in mix_file.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+
+#include "xmix_io.h"
+#include "mix_file.h"
+
+const gchar *MIX_SRC_DEFEXT = ".mixal",
+ *MIX_LIST_DEFEXT = ".mls", *MIX_CODE_DEFEXT = ".mix";
+
+/* file names completions */
+#define needs_completion_(name,defext) \
+ ( strcmp(name + strlen(name) - strlen(defext), defext) != 0 )
+
+#define add_completion_(name, defext) \
+ g_strconcat(name, defext, NULL)
+
+/* The actual definition of mix_file_t */
+struct mix_file_t
+{
+ mix_iochannel_t parent;
+ gchar *base_name;
+ gchar *ext;
+};
+
+/* Creation/destruction of files */
+static mix_file_t *
+open_file_(const gchar *name, mix_fmode_t mode)
+{
+ mix_file_t *result;
+ FILE *file;
+ const gchar *fmode = fmode_to_type_ (mode);
+
+ /* if the read/write file already exists, open in r+ mode */
+ if (mode == mix_io_RDWRT && (file = fopen (name, "r")))
+ {
+ fmode = "r+";
+ fclose (file);
+ }
+
+ result = g_new(mix_file_t, 1);
+ file = fopen(name, fmode);
+ if ( file == NULL ) {
+ g_free (result);
+ return NULL;
+ }
+ io_init_from_file_(MIX_IOCHANNEL(result), file);
+ return result;
+}
+
+mix_file_t *
+mix_file_new(const gchar *name, mix_fmode_t mode)
+{
+ mix_file_t *result;
+ gchar *bname;
+
+ if ( name == NULL ) return NULL;
+ bname = g_strdup(name);
+ if ( bname == NULL ) return NULL;
+ result = open_file_(name, mode);
+ if ( result == NULL )
+ {
+ g_free(bname);
+ return NULL;
+ }
+ result->base_name = bname;
+ result->ext = NULL;
+ return result;
+}
+
+/* creates a file adding to its name the defext if missing */
+mix_file_t *
+mix_file_new_with_def_ext(const gchar *name, mix_fmode_t mode,
+ const gchar *defext)
+{
+ const gchar *real_name;
+ mix_file_t *result;
+
+ if ( name == NULL ) return NULL;
+ if ( defext == NULL ) return mix_file_new(name, mode);
+ real_name = needs_completion_(name, defext) ?
+ add_completion_(name, defext) : name;
+ result = open_file_(real_name, mode);
+ if ( real_name != name ) g_free((void *)real_name);
+ if ( result == NULL ) return NULL;
+ result->ext = g_strdup(defext);
+ if ( needs_completion_(name, defext) )
+ result->base_name = g_strdup(name);
+ else
+ result->base_name = g_strndup(name, strlen(name) - strlen(defext));
+ if ( result->ext == NULL || result->base_name == NULL )
+ {
+ mix_file_delete(result);
+ return NULL;
+ }
+ return result;
+}
+
+void
+mix_file_delete(mix_file_t *file)
+{
+ g_return_if_fail(file != NULL);
+ io_close_(MIX_IOCHANNEL(file));
+ if (file->base_name) g_free(file->base_name);
+ if (file->ext) g_free(file->ext);
+ g_free(file);
+}
+
+/* convert to a standard FILE */
+extern FILE *
+mix_file_to_FILE(const mix_file_t *file)
+{
+ if ( file == NULL ) return NULL;
+ return io_get_FILE_(file);
+}
+
+/* complete a name with an extension, if needed */
+gchar *
+mix_file_complete_name (const gchar *name, const gchar *extension)
+{
+ if (!name) return NULL;
+ if (!extension || !needs_completion_ (name, extension))
+ return g_strdup (name);
+ return add_completion_ (name, extension);
+}
+
+/* Get the base name and extension of file */
+const gchar *
+mix_file_base_name(const mix_file_t *file)
+{
+ g_return_val_if_fail(file != NULL, NULL);
+ return file->base_name;
+}
+
+const gchar *
+mix_file_extension(const mix_file_t *file)
+{
+ g_return_val_if_fail(file != NULL, NULL);
+ return file->ext;
+}
diff --git a/mixlib/mix_file.h b/mixlib/mix_file.h
new file mode 100644
index 0000000..059eebb
--- /dev/null
+++ b/mixlib/mix_file.h
@@ -0,0 +1,65 @@
+/* -*-c-*- ---------------- mix_file.h :
+ * Declarations for the mix_file_t type.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_FILE_H
+#define MIX_FILE_H
+
+#include "mix_io.h"
+
+/* The mix_file_t type, deriving from mix_iochannel_t and
+ representing a disk file
+*/
+typedef struct mix_file_t mix_file_t;
+
+/* Creation/destruction of files */
+extern mix_file_t *
+mix_file_new(const gchar *name, mix_fmode_t mode);
+
+/* creates a file adding to its name the defext if missing */
+extern mix_file_t *
+mix_file_new_with_def_ext(const gchar *name, mix_fmode_t mode,
+ const gchar *defext);
+
+extern void
+mix_file_delete(mix_file_t *file);
+
+/* convert to a standard FILE */
+extern FILE *
+mix_file_to_FILE(const mix_file_t *file);
+
+/* standard default extensions */
+extern const gchar *MIX_SRC_DEFEXT, *MIX_LIST_DEFEXT, *MIX_CODE_DEFEXT;
+
+/* complete a name with an extension, if needed */
+extern gchar *
+mix_file_complete_name (const gchar *name, const gchar *extension);
+
+/* Get the base name and extension of file */
+extern const gchar *
+mix_file_base_name(const mix_file_t *file);
+
+extern const gchar *
+mix_file_extension(const mix_file_t *file);
+
+
+#endif /* MIX_FILE_H */
+
diff --git a/mixlib/mix_ins.c b/mixlib/mix_ins.c
new file mode 100644
index 0000000..1aa3f70
--- /dev/null
+++ b/mixlib/mix_ins.c
@@ -0,0 +1,269 @@
+/* -*-c-*- ------------------ mix_ins.c :
+ * Implementation of the functions declared in mix_ins.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mix_ins.h"
+
+
+struct mix_ins_desc_
+{
+ mix_opcode_t opcode;
+ mix_fspec_t def_fspec;
+ const gchar *string_rep;
+ gboolean is_ext;
+};
+
+#define IDES_(c,f,s) {c,f,#s,FALSE}
+#define IDESX_(c,f,s) {c,f,#s,TRUE}
+
+static const struct mix_ins_desc_ id_to_desc_[] = {
+ IDES_(0,0,NOP), IDES_(1,5,ADD), IDES_(2,5,SUB), IDES_(3,5,MUL),
+ IDES_(4,5,DIV),
+ IDESX_(5,0,NUM), IDESX_(5,1,CHAR), IDESX_(5,2,HLT),
+ IDESX_(6,0,SLA), IDESX_(6,1,SRA), IDESX_(6,2,SLAX), IDESX_(6,3,SRAX),
+ IDESX_(6,4,SLC), IDESX_(6,5,SRC),
+ IDES_(7,1,MOVE), IDES_(8,5,LDA), IDES_(9,5,LD1), IDES_(10,5,LD2),
+ IDES_(11,5,LD3), IDES_(12,5,LD4), IDES_(13,5,LD5),
+ IDES_(14,5,LD6), IDES_(15,5,LDX), IDES_(16,5,LDAN), IDES_(17,5,LD1N),
+ IDES_(18,5,LD2N), IDES_(19,5,LD3N), IDES_(20,5,LD4N),
+ IDES_(21,5,LD5N), IDES_(22,5,LD6N), IDES_(23,5,LDXN),
+ IDES_(24,5,STA), IDES_(25,5,ST1), IDES_(26,5,ST2), IDES_(27,5,ST3),
+ IDES_(28,5,ST4), IDES_(29,5,ST5), IDES_(30,5,ST6), IDES_(31,5,STX),
+ IDES_(32,2,STJ), IDES_(33,5,STZ), IDES_(34,0,JBUS), IDES_(35,0,IOC),
+ IDES_(36,0,IN), IDES_(37,0,OUT), IDES_(38,0,JRED),
+ IDESX_(39,0,JMP), IDESX_(39,1,JSJ), IDESX_(39,2,JOV), IDESX_(39,3,JNOV),
+ IDESX_(39,4,JL), IDESX_(39,5,JE), IDESX_(39,6,JG), IDESX_(39,7,JGE),
+ IDESX_(39,8,JNE), IDESX_(39,9,JLE),
+ IDESX_(40,0,JAN), IDESX_(40,1,JAZ), IDESX_(40,2,JAP), IDESX_(40,3,JANN),
+ IDESX_(40,4,JANZ), IDESX_(40,5,JANP),
+ IDESX_(41,0,J1N), IDESX_(41,1,J1Z), IDESX_(41,2,J1P), IDESX_(41,3,J1NN),
+ IDESX_(41,4,J1NZ), IDESX_(41,5,J1NP),
+ IDESX_(42,0,J2N), IDESX_(42,1,J2Z), IDESX_(42,2,J2P), IDESX_(42,3,J2NN),
+ IDESX_(42,4,J2NZ), IDESX_(42,5,J2NP),
+ IDESX_(43,0,J3N), IDESX_(43,1,J3Z), IDESX_(43,2,J3P), IDESX_(43,3,J3NN),
+ IDESX_(43,4,J3NZ), IDESX_(43,5,J3NP),
+ IDESX_(44,0,J4N), IDESX_(44,1,J4Z), IDESX_(44,2,J4P), IDESX_(44,3,J4NN),
+ IDESX_(44,4,J4NZ), IDESX_(44,5,J4NP),
+ IDESX_(45,0,J5N), IDESX_(45,1,J5Z), IDESX_(45,2,J5P), IDESX_(45,3,J5NN),
+ IDESX_(45,4,J5NZ), IDESX_(45,5,J5NP),
+ IDESX_(46,0,J6N), IDESX_(46,1,J6Z), IDESX_(46,2,J6P), IDESX_(46,3,J6NN),
+ IDESX_(46,4,J6NZ), IDESX_(46,5,J6NP),
+ IDESX_(47,0,JXN), IDESX_(47,1,JXZ), IDESX_(47,2,JXP), IDESX_(47,3,JXNN),
+ IDESX_(47,4,JXNZ), IDESX_(47,5,JXNP),
+ IDESX_(48,0,INCA), IDESX_(48,1,DECA), IDESX_(48,2,ENTA), IDESX_(48,3,ENNA),
+ IDESX_(49,0,INC1), IDESX_(49,1,DEC1), IDESX_(49,2,ENT1), IDESX_(49,3,ENN1),
+ IDESX_(50,0,INC2), IDESX_(50,1,DEC2), IDESX_(50,2,ENT2), IDESX_(50,3,ENN2),
+ IDESX_(51,0,INC3), IDESX_(51,1,DEC3), IDESX_(51,2,ENT3), IDESX_(51,3,ENN3),
+ IDESX_(52,0,INC4), IDESX_(52,1,DEC4), IDESX_(52,2,ENT4), IDESX_(52,3,ENN4),
+ IDESX_(53,0,INC5), IDESX_(53,1,DEC5), IDESX_(53,2,ENT5), IDESX_(53,3,ENN5),
+ IDESX_(54,0,INC6), IDESX_(54,1,DEC6), IDESX_(54,2,ENT6), IDESX_(54,3,ENN6),
+ IDESX_(55,0,INCX), IDESX_(55,1,DECX), IDESX_(55,2,ENTX), IDESX_(55,3,ENNX),
+ IDES_(56,5,CMPA), IDES_(57,5,CMP1), IDES_(58,5,CMP2), IDES_(59,5,CMP3),
+ IDES_(60,5,CMP4), IDES_(61,5,CMP5), IDES_(62,5,CMP6), IDES_(63,5,CMPX)
+};
+
+static const gsize ID_TO_DESC_SIZE_=
+sizeof(id_to_desc_)/sizeof(id_to_desc_[0]);
+
+/* To look for the mix_ins_id corresponding to a pair (fspec,opcode)
+ we use an array indexed by opcode with values
+ (initial_ins, final_ins - initial_ins)
+*/
+struct mix_opcode_desc_
+{
+ mix_ins_id_t init_id;
+ guchar inc; /* when inc == 0, the id does not depend on fspec */
+};
+
+static struct mix_opcode_desc_ opcode_to_id_[MIX_BYTE_MAX + 1];
+
+/* a hash table mapping strings to mix_ins_id's */
+static GHashTable *string_to_id_ = NULL;
+
+void
+mix_init_ins (void)
+{
+ guint k;
+ g_assert (ID_TO_DESC_SIZE_ == mix_INVALID_INS);
+
+ for ( k = 0; k < MIX_BYTE_MAX + 1; ++k )
+ {
+ opcode_to_id_[k].init_id = mix_INVALID_INS;
+ opcode_to_id_[k].inc = 0;
+ }
+
+ for ( k = 0; k < ID_TO_DESC_SIZE_; ++k )
+ {
+ if ( opcode_to_id_[id_to_desc_[k].opcode].init_id == mix_INVALID_INS )
+ opcode_to_id_[id_to_desc_[k].opcode].init_id = k;
+ else
+ ++opcode_to_id_[id_to_desc_[k].opcode].inc;
+ }
+
+ if ( string_to_id_ == NULL )
+ {
+ string_to_id_ = g_hash_table_new (g_str_hash, g_str_equal);
+ for ( k = 0; k < ID_TO_DESC_SIZE_; ++k)
+ g_hash_table_insert (string_to_id_, (gpointer)id_to_desc_[k].string_rep,
+ GUINT_TO_POINTER (k));
+ }
+
+}
+
+void
+mix_release_ins (void)
+{
+ g_hash_table_destroy (string_to_id_);
+}
+
+/* Conversions between words and ins */
+mix_word_t
+mix_ins_to_word (const mix_ins_t *ins)
+{
+ g_return_val_if_fail (ins != NULL, MIX_WORD_ZERO);
+ return (mix_word_t)((ins->address<<18)|
+ ((ins->index&7)<<12)|(ins->fspec<<6)|(ins->opcode));
+}
+
+mix_ins_id_t
+mix_word_to_ins (mix_word_t word, mix_ins_t *ins)
+{
+ mix_ins_id_t result = mix_get_ins_id (mix_get_ins_opcode (word),
+ mix_get_ins_fspec (word));
+
+ g_return_val_if_fail (ins != NULL, result);
+ mix_word_to_ins_uncheck (word,*ins);
+ return result;
+}
+
+/* Getting ins parameters */
+mix_opcode_t
+mix_get_opcode_from_id (mix_ins_id_t id)
+{
+ g_return_val_if_fail (id < ID_TO_DESC_SIZE_, MIX_BYTE_ZERO);
+ return id_to_desc_[id].opcode;
+}
+
+gboolean
+mix_ins_id_is_extended (mix_ins_id_t id)
+{
+ g_return_val_if_fail (id < ID_TO_DESC_SIZE_, FALSE);
+ return id_to_desc_[id].is_ext;
+}
+
+
+mix_fspec_t
+mix_get_fspec_from_id (mix_ins_id_t id)
+{
+ g_return_val_if_fail (id < ID_TO_DESC_SIZE_, MIX_BYTE_ZERO);
+ return id_to_desc_[id].def_fspec;
+}
+
+
+const gchar *
+mix_get_string_from_id (mix_ins_id_t id)
+{
+ g_return_val_if_fail (id < ID_TO_DESC_SIZE_, NULL);
+ return id_to_desc_[id].string_rep;
+}
+
+mix_ins_id_t
+mix_get_id_from_string (const gchar *name)
+{
+ gpointer key, value;
+ if ( !g_hash_table_lookup_extended (string_to_id_, (gpointer)name,
+ &key, &value) )
+ return mix_INVALID_INS;
+ return (mix_ins_id_t)GPOINTER_TO_UINT (value);
+}
+
+
+mix_ins_id_t
+mix_get_ins_id (mix_opcode_t code, mix_fspec_t fspec)
+{
+ if ( opcode_to_id_[code].inc == 0 )
+ return opcode_to_id_[code].init_id;
+ else if ( opcode_to_id_[code].inc < fspec )
+ return mix_INVALID_INS;
+ else
+ return (opcode_to_id_[code].init_id + fspec);
+}
+
+/* Printable representation */
+extern gchar * /* this pointer must be freed by caller */
+mix_ins_to_string (const mix_ins_t *ins)
+{
+ gboolean needs_f;
+ gchar *result;
+ mix_ins_id_t id;
+
+ g_return_val_if_fail (ins != NULL, NULL);
+ id = mix_ins_id_from_ins (*ins);
+ needs_f = ins->fspec != id_to_desc_[id].def_fspec;
+ if ( needs_f )
+ result = g_strdup_printf ("%s\t%s%d,%d(%d:%d)",
+ mix_get_string_from_id (id),
+ mix_short_is_negative (ins->address) ? "-" : "",
+ mix_short_magnitude (ins->address), ins->index,
+ mix_fspec_left (ins->fspec),
+ mix_fspec_right (ins->fspec));
+ else
+ result = g_strdup_printf ("%s\t%s%d,%d", mix_get_string_from_id (id),
+ mix_short_is_negative (ins->address) ? "-" : "",
+ mix_short_magnitude (ins->address), ins->index);
+ return result;
+}
+
+extern void
+mix_ins_to_string_in_buffer (const mix_ins_t *ins, gchar *buf, guint len)
+{
+ gboolean needs_f;
+ mix_ins_id_t id;
+
+ g_return_if_fail (ins != NULL);
+ g_return_if_fail (buf != NULL);
+ id = mix_ins_id_from_ins (*ins);
+ needs_f = ins->fspec != id_to_desc_[id].def_fspec;
+ if ( needs_f )
+ g_snprintf (buf, len, "%s\t%s%d,%d(%d:%d)",
+ mix_get_string_from_id (id),
+ mix_short_is_negative (ins->address) ? "-" : "",
+ mix_short_magnitude (ins->address), ins->index,
+ mix_fspec_left (ins->fspec),
+ mix_fspec_right (ins->fspec));
+ else
+ g_snprintf (buf, len, "%s\t%s%d,%d",
+ mix_get_string_from_id (id),
+ mix_short_is_negative (ins->address) ? "-" : "",
+ mix_short_magnitude (ins->address), ins->index);
+}
+
+
+
+void
+mix_ins_print (const mix_ins_t *ins)
+{
+ g_return_if_fail (ins != NULL);
+ g_print (mix_get_string_from_id (mix_ins_id_from_ins (*ins)));
+ g_print (" %s%d,%d(%d:%d)", mix_short_is_negative (ins->address) ? "-" : "+",
+ mix_short_magnitude (ins->address), ins->index,
+ mix_fspec_left (ins->fspec), mix_fspec_right (ins->fspec));
+}
+
diff --git a/mixlib/mix_ins.h b/mixlib/mix_ins.h
new file mode 100644
index 0000000..07d8e38
--- /dev/null
+++ b/mixlib/mix_ins.h
@@ -0,0 +1,195 @@
+/* -*-c-*- -------------------- mix_ins.h:
+ * This file declares types and functions for manipulating MIX
+ * instructions
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_INS_H
+#define MIX_INS_H
+
+#include "mix_types.h"
+
+
+/* Initialise and free mix_ins data */
+extern void
+mix_init_ins(void);
+
+extern void
+mix_release_ins(void);
+
+/* A MIX instruction is made up of address, index, fspec and op_code */
+
+/*-- Address field: contains two bytes */
+typedef mix_short_t mix_address_t;
+
+/*-- Index field: a value between 0 and 6 */
+typedef enum {
+ mix_I0, mix_I1, mix_I2, mix_I3, mix_I4, mix_I5, mix_I6 } mix_index_t;
+
+/*-- Instruction id: enumeration of MIX instruction set */
+typedef enum {
+ mix_NOP, mix_ADD, mix_SUB, mix_MUL, mix_DIV,
+ mix_NUM, mix_CHAR, mix_HLT,
+ mix_SLA, mix_SRA, mix_SLAX, mix_SRAX, mix_SLC, mix_SRC,
+ mix_MOVE, mix_LDA, mix_LD1, mix_LD2, mix_LD3, mix_LD4, mix_LD5,
+ mix_LD6, mix_LDX, mix_LDAN, mix_LD1N, mix_LD2N, mix_LD3N, mix_LD4N,
+ mix_LD5N, mix_LD6N, mix_LDXN, mix_STA, mix_ST1, mix_ST2, mix_ST3, mix_ST4,
+ mix_ST5, mix_ST6, mix_STX, mix_STJ, mix_STZ, mix_JBUS, mix_IOC, mix_IN,
+ mix_OUT, mix_JRED,
+ mix_JMP, mix_JSJ, mix_JOV, mix_JNOV, mix_JL, mix_JE, mix_JG, mix_JGE,
+ mix_JNE, mix_JLE,
+ mix_JAN, mix_JAZ, mix_JAP, mix_JANN, mix_JANZ, mix_JANP,
+ mix_J1N, mix_J1Z, mix_J1P, mix_J1NN, mix_J1NZ, mix_J1NP,
+ mix_J2N, mix_J2Z, mix_J2P, mix_J2NN, mix_J2NZ, mix_J2NP,
+ mix_J3N, mix_J3Z, mix_J3P, mix_J3NN, mix_J3NZ, mix_J3NP,
+ mix_J4N, mix_J4Z, mix_J4P, mix_J4NN, mix_J4NZ, mix_J4NP,
+ mix_J5N, mix_J5Z, mix_J5P, mix_J5NN, mix_J5NZ, mix_J5NP,
+ mix_J6N, mix_J6Z, mix_J6P, mix_J6NN, mix_J6NZ, mix_J6NP,
+ mix_JXN, mix_JXZ, mix_JXP, mix_JXNN, mix_JXNZ, mix_JXNP,
+ mix_INCA, mix_DECA, mix_ENTA, mix_ENNA,
+ mix_INC1, mix_DEC1, mix_ENT1, mix_ENN1,
+ mix_INC2, mix_DEC2, mix_ENT2, mix_ENN2,
+ mix_INC3, mix_DEC3, mix_ENT3, mix_ENN3,
+ mix_INC4, mix_DEC4, mix_ENT4, mix_ENN4,
+ mix_INC5, mix_DEC5, mix_ENT5, mix_ENN5,
+ mix_INC6, mix_DEC6, mix_ENT6, mix_ENN6,
+ mix_INCX, mix_DECX, mix_ENTX, mix_ENNX,
+ mix_CMPA, mix_CMP1, mix_CMP2, mix_CMP3, mix_CMP4,
+ mix_CMP5, mix_CMP6, mix_CMPX, mix_INVALID_INS
+} mix_ins_id_t;
+
+/* each one of the above id's has associated an opcode, a default
+ fspec and a string representation */
+/* the opcode fits in a byte */
+typedef mix_byte_t mix_opcode_t;
+
+/* labels for each opcode */
+enum {
+ mix_opNOP = 0, mix_opADD, mix_opSUB, mix_opMUL, mix_opDIV,
+ mix_opSPC, mix_opSLx, mix_opMOVE,
+ mix_opLDA, mix_opLD1, mix_opLD2, mix_opLD3, mix_opLD4, mix_opLD5,
+ mix_opLD6, mix_opLDX, mix_opLDAN, mix_opLD1N, mix_opLD2N, mix_opLD3N,
+ mix_opLD4N, mix_opLD5N, mix_opLD6N, mix_opLDXN,
+ mix_opSTA, mix_opST1, mix_opST2, mix_opST3, mix_opST4,
+ mix_opST5, mix_opST6, mix_opSTX, mix_opSTJ, mix_opSTZ,
+ mix_opJBUS, mix_opIOC, mix_opIN, mix_opOUT, mix_opJRED,
+ mix_opJMP, mix_opJAx, mix_opJ1x, mix_opJ2x, mix_opJ3x,
+ mix_opJ4x, mix_opJ5x, mix_opJ6x, mix_opJXx,
+ mix_opINCA, mix_opINC1, mix_opINC2, mix_opINC3,
+ mix_opINC4, mix_opINC5, mix_opINC6, mix_opINCX,
+ mix_opCMPA, mix_opCMP1, mix_opCMP2, mix_opCMP3, mix_opCMP4,
+ mix_opCMP5, mix_opCMP6, mix_opCMPX
+};
+
+extern mix_opcode_t
+mix_get_opcode_from_id(mix_ins_id_t id);
+
+extern mix_fspec_t
+mix_get_fspec_from_id(mix_ins_id_t id);
+
+/* For extended instructions, both the opcode and fspec determine
+ the id (i.e., an explicit fspec cannot be used)
+*/
+extern gboolean
+mix_ins_id_is_extended(mix_ins_id_t id);
+
+extern const gchar *
+mix_get_string_from_id(mix_ins_id_t id);
+
+extern mix_ins_id_t
+mix_get_id_from_string(const gchar *name);
+
+extern mix_ins_id_t
+mix_get_ins_id(mix_opcode_t code, mix_fspec_t fspec);
+
+
+/*-- MIX instruction type */
+typedef struct mix_ins_t mix_ins_t;
+struct mix_ins_t
+{
+ mix_address_t address;
+ mix_index_t index;
+ mix_fspec_t fspec;
+ mix_opcode_t opcode;
+};
+
+#define mix_ins_fill_from_id(ins,id) \
+ do { \
+ (ins).opcode = mix_get_opcode_from_id(id); \
+ (ins).fspec = mix_get_fspec_from_id(id); \
+ } while(FALSE)
+
+
+/* A mix ins can be codified into a word */
+extern mix_word_t
+mix_ins_to_word(const mix_ins_t *ins);
+
+extern mix_ins_id_t
+mix_word_to_ins(mix_word_t w, mix_ins_t *ins);
+
+#define mix_word_add_address(word,addr) (word) |= ((addr)<<18)
+
+/* decompose an instruction codified in a word into its parts */
+#define mix_get_ins_address(word) ((mix_address_t)((word)>>18))
+#define mix_get_ins_index(word) ((mix_index_t)(((word)>>12)&7))
+#define mix_get_ins_fspec(word) ((mix_fspec_t)(mix_byte_new((word)>>6)))
+#define mix_get_ins_opcode(word) ((mix_opcode_t)(mix_byte_new(word)))
+
+/* unchecked versions for speed */
+#define mix_ins_to_word_uncheck(ins) \
+ (mix_word_t)(((ins).address<<18)| \
+ (((ins).index&7)<<12)|((ins).fspec<<6)|((ins).opcode))
+
+#define mix_word_to_ins_uncheck(word,ins) \
+ do { \
+ (ins).address = mix_get_ins_address(word); \
+ (ins).index = mix_get_ins_index(word); \
+ (ins).fspec = mix_get_ins_fspec(word); \
+ (ins).opcode = mix_get_ins_opcode(word); \
+ } while(FALSE)
+
+#define mix_ins_id_from_ins(ins) mix_get_ins_id((ins).opcode,(ins).fspec)
+
+
+/* Printable representation */
+extern gchar * /* this pointer must be freed by caller */
+mix_ins_to_string(const mix_ins_t *ins);
+
+extern void
+mix_ins_to_string_in_buffer (const mix_ins_t *ins, gchar *buf, guint len);
+
+extern void
+mix_ins_print(const mix_ins_t *ins);
+
+
+
+/* A MIX ins has an associated execution time */
+/* Initialise mix_ins data providing an interlock time for I/O devices */
+/* --------------------------------------> MOVE to VM
+typedef guint mix_time_t;
+
+extern void
+mix_init_ins_with_interlock_time(mix_time_t t);
+
+extern mix_time_t
+mix_ins_exec_time(const mix_ins_t *ins);
+*/
+
+#endif /* MIX_INS_H */
diff --git a/mixlib/mix_io.c b/mixlib/mix_io.c
new file mode 100644
index 0000000..31e43df
--- /dev/null
+++ b/mixlib/mix_io.c
@@ -0,0 +1,208 @@
+/* -*-c-*- --------------- mix_io.c :
+ * Implementation of the functions declared in mix_io.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "xmix_io.h"
+
+mix_iochannel_t *
+mix_io_new (FILE *file)
+{
+ mix_iochannel_t *result;
+ g_return_val_if_fail (file != NULL, NULL);
+ result = g_new (mix_iochannel_t, 1);
+ result->file = file;
+ return result;
+}
+
+void
+mix_io_delete (mix_iochannel_t *ch)
+{
+ if (ch != NULL)
+ {
+ fclose (ch->file);
+ g_free (ch);
+ }
+}
+
+FILE *
+mix_io_to_FILE (mix_iochannel_t *ioc)
+{
+ if (ioc == NULL) return NULL;
+ return ioc->file;
+}
+
+gboolean
+mix_io_eof (mix_iochannel_t *ioc)
+{
+ if (ioc == NULL) return TRUE;
+ return is_eof_ (ioc);
+}
+
+gboolean
+mix_io_is_ready (mix_iochannel_t *ioc)
+{
+ if (ioc == NULL) return FALSE;
+ return is_ready_ (ioc);
+}
+
+gboolean
+mix_io_write_byte (mix_iochannel_t *ioc, mix_byte_t b)
+{
+ if (ioc == NULL) return FALSE;
+ return write_data_ (ioc, &b, 1);
+}
+
+gboolean
+mix_io_write_byte_array (mix_iochannel_t *ioc, const mix_byte_t *b,
+ size_t s)
+{
+ if (ioc == NULL || b == NULL) return FALSE;
+ return write_data_ (ioc, b, s);
+}
+
+mix_byte_t
+mix_io_read_byte (mix_iochannel_t *ioc)
+{
+ mix_byte_t result = MIX_BYTE_ZERO;
+ if (ioc != NULL) read_data_ (ioc, &result, 1);
+ return result;
+}
+
+gboolean
+mix_io_read_byte_array (mix_iochannel_t *ioc, mix_byte_t *b, size_t s)
+{
+ return (ioc != NULL) && (b != NULL) && read_data_ (ioc, b, s);
+}
+
+gboolean
+mix_io_write_word (mix_iochannel_t *ioc, mix_word_t w)
+{
+ return (ioc != NULL) && write_data_ (ioc, &w, 1);
+}
+
+gboolean
+mix_io_write_word_array (mix_iochannel_t *ioc, const mix_word_t *w,
+ size_t s)
+{
+ return (ioc != NULL) && (w != NULL) && write_data_ (ioc, w, s);
+}
+
+mix_word_t
+mix_io_read_word (mix_iochannel_t *ioc)
+{
+ mix_word_t result = MIX_WORD_ZERO;
+ if (ioc != NULL) read_data_ (ioc, &result, 1);
+ return result;
+}
+
+gboolean
+mix_io_read_word_array (mix_iochannel_t *ioc, mix_word_t *w, size_t s)
+{
+ return (ioc != NULL) && (w != NULL) && read_data_ (ioc, w, s);
+}
+
+gboolean
+mix_io_write_short (mix_iochannel_t *ioc, mix_short_t w)
+{
+ return (ioc != NULL) && write_data_ (ioc, &w, 1);
+}
+
+gboolean
+mix_io_write_short_array (mix_iochannel_t *ioc, const mix_short_t *w,
+ size_t s)
+{
+ return (ioc != NULL) && (w != NULL) && write_data_ (ioc, w, s);
+}
+
+mix_short_t
+mix_io_read_short (mix_iochannel_t *ioc)
+{
+ mix_short_t result = MIX_SHORT_ZERO;
+ if (ioc != NULL) read_data_ (ioc, &result, 1);
+ return result;
+}
+
+gboolean
+mix_io_read_short_array (mix_iochannel_t *ioc, mix_short_t *w, size_t s)
+{
+ return (ioc != NULL) && (w != NULL) && read_data_ (ioc, w, s);
+}
+
+gboolean
+mix_io_write_char (mix_iochannel_t *ioc, mix_char_t c)
+{
+ guchar value = mix_char_to_ascii (c);
+ return (ioc != NULL) && write_data_ (ioc, &value, 1);
+}
+
+mix_char_t
+mix_io_read_char (mix_iochannel_t *ioc)
+{
+ guchar value = MIX_CHAR_MAX;
+ if (ioc != NULL) read_data_ (ioc, &value, 1);
+ return mix_ascii_to_char (value);
+}
+
+gboolean
+mix_io_write_word_array_as_char (mix_iochannel_t *ioc,
+ const mix_word_t *w, size_t s)
+{
+ guint k, j;
+ guchar value;
+
+ if ((ioc == NULL) || (w == NULL)) return FALSE;
+
+ for (k = 0; k < s; k++)
+ for (j = 1; j < 6; j++)
+ {
+ mix_char_t ch = mix_byte_to_char (mix_word_get_byte (w[k], j));
+ value = mix_char_to_ascii (ch);
+ if (!write_data_ (ioc, &value, 1)) return FALSE;
+ }
+ value = '\n';
+ return write_data_ (ioc, &value, 1);
+}
+
+gboolean
+mix_io_read_word_array_as_char (mix_iochannel_t *ioc,
+ mix_word_t *w, size_t s)
+{
+ guint k, j;
+ guchar value;
+ gboolean eol = FALSE;
+ mix_char_t spc = mix_ascii_to_char (' ');
+
+ if ((ioc == NULL) || (w == NULL)) return FALSE;
+
+ for (k = 0; k < s && !eol; k++)
+ for (j = 1; j < 6; j++)
+ {
+ if (!eol && !read_data_ (ioc, &value, 1)) return FALSE;
+ eol = eol || (value == '\n') || is_eof_ (ioc);
+ mix_word_set_byte (&w[k], j, eol? spc : mix_ascii_to_char (value));
+ }
+ for (; k < s; ++k) w[k] = MIX_WORD_ZERO;
+
+ while (!eol && !is_eof_ (ioc) && value != '\n')
+ if (!read_data_ (ioc, &value, 1)) return FALSE;
+
+ return TRUE;
+}
diff --git a/mixlib/mix_io.h b/mixlib/mix_io.h
new file mode 100644
index 0000000..0e79d67
--- /dev/null
+++ b/mixlib/mix_io.h
@@ -0,0 +1,119 @@
+/* -*-c-*- ------------------ mix_io.h :
+ * Declarations for mix_iochannel_t and mix_file_t
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_IOCHANNEL_H
+#define MIX_IOCHANNEL_H
+
+#include <stdio.h>
+#include "mix_types.h"
+
+/* mix_iochannel_t: an object for input/output of mix types */
+typedef struct mix_iochannel_t mix_iochannel_t;
+
+/* Cast to mix_iochannel_t */
+#define MIX_IOCHANNEL(file) (mix_iochannel_t *)(file)
+
+/* I/O channels can be created in different modes: */
+typedef enum {
+ mix_io_READ, /* read existing file */
+ mix_io_WRITE, /* write new file */
+ mix_io_RDWRT, /* read/write existing from beginning */
+ mix_io_APPEND, /* append to existing or new file */
+ mix_io_RAPPEND /* read from beginning, append to end */
+} mix_fmode_t;
+
+/* Create from a file handle */
+extern mix_iochannel_t *
+mix_io_new (FILE *file);
+
+/* Delete */
+extern void
+mix_io_delete (mix_iochannel_t *ch);
+
+/* Convert to a FILE * */
+extern FILE *
+mix_io_to_FILE (mix_iochannel_t *ioc);
+
+/* Read/write from/to an iochannel */
+extern gboolean
+mix_io_eof (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_is_ready (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_write_byte (mix_iochannel_t *ioc, mix_byte_t b);
+
+extern gboolean
+mix_io_write_byte_array (mix_iochannel_t *ioc, const mix_byte_t *b, size_t s);
+
+
+extern mix_byte_t
+mix_io_read_byte (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_read_byte_array (mix_iochannel_t *ioc, mix_byte_t *b, size_t s);
+
+
+extern gboolean
+mix_io_write_word (mix_iochannel_t *ioc, mix_word_t w);
+
+
+extern gboolean
+mix_io_write_word_array (mix_iochannel_t *ioc, const mix_word_t *w, size_t s);
+
+extern mix_word_t
+mix_io_read_word (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_read_word_array (mix_iochannel_t *ioc, mix_word_t *w, size_t s);
+
+extern gboolean
+mix_io_write_short (mix_iochannel_t *ioc, mix_short_t w);
+
+
+extern gboolean
+mix_io_write_short_array (mix_iochannel_t *ioc, const mix_short_t *w, size_t s);
+
+extern mix_short_t
+mix_io_read_short (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_read_short_array (mix_iochannel_t *ioc, mix_short_t *w, size_t s);
+
+extern gboolean
+mix_io_write_char (mix_iochannel_t *ioc, mix_char_t c);
+
+extern mix_char_t
+mix_io_read_char (mix_iochannel_t *ioc);
+
+extern gboolean
+mix_io_write_word_array_as_char (mix_iochannel_t *ioc,
+ const mix_word_t *w, size_t s);
+
+extern gboolean
+mix_io_read_word_array_as_char (mix_iochannel_t *ioc,
+ mix_word_t *w, size_t s);
+
+
+#endif /* MIX_IOCHANNEL_H */
+
diff --git a/mixlib/mix_parser.c b/mixlib/mix_parser.c
new file mode 100644
index 0000000..0dfcf81
--- /dev/null
+++ b/mixlib/mix_parser.c
@@ -0,0 +1,605 @@
+/* -*-c-*- -------------- mix_parser.c :
+ * Implementation of the functions declared in mix_parser.h and
+ * xmix_parser.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+
+#include "mix.h"
+#include "mix_code_file.h"
+#include "xmix_parser.h"
+
+/* The flex-generated scanner, according to file mix_scanner.l */
+extern mix_parser_err_t
+mix_flex_scan (mix_parser_t *parser);
+
+/*------------ mixparser.h functions -------------------------------------*/
+
+/* error messages */
+static const gchar * const ERR_MESSAGE_[] = {
+ N_("successful compilation"),
+ N_("file not yet compiled"),
+ N_("internal error"),
+ N_("unable to open MIX source file"),
+ N_("unable to open MIX output file"),
+ N_("unexpected end of file"),
+ N_("invalid location field"),
+ N_("duplicated symbol"),
+ N_("symbol too long"),
+ N_("missing operator field"),
+ N_("unexpected location symbol"),
+ N_("invalid address field"),
+ N_("invalid index field"),
+ N_("invalid f-specification"),
+ N_("invalid operation field"),
+ N_("invalid expression"),
+ N_("undefined symbol"),
+ N_("mismatched parenthesis"),
+ N_("unexpected f-specfication"),
+ N_("missing symbol name"),
+ N_("symbol is an instruction name"),
+ N_("failed write access to code file"),
+ N_("operand of ALF pseudo instruction has less than 5 chars"),
+ N_("operand of ALF pseudo instruction has more than 5 chars"),
+ N_("operand of ALF pseudo instruction must be quoted")
+};
+
+static const guint NO_OF_MESSAGES_ = sizeof(ERR_MESSAGE_)/sizeof (gchar*);
+
+const gchar *
+mix_parser_err_string (mix_parser_err_t error)
+{
+ return (error < NO_OF_MESSAGES_) ? _(ERR_MESSAGE_[error]) : NULL;
+}
+
+guint
+mix_parser_err_count (const mix_parser_t *parser)
+{
+ return (parser) ? parser->err_count : 0;
+}
+
+guint
+mix_parser_warning_count (const mix_parser_t *parser)
+{
+ return (parser) ? parser->warn_count : 0;
+}
+
+const gchar *
+mix_parser_src_file_base_name (const mix_parser_t *parser)
+{
+ return (parser) ? mix_file_base_name (parser->in_file) : NULL;
+}
+
+const gchar *
+mix_parser_src_file_extension (const mix_parser_t *parser)
+{
+ return (parser) ? mix_file_extension (parser->in_file) : NULL;
+}
+
+
+/* Create/destroy a mix_parser */
+/* compare function for the table of ins */
+static gint
+compare_shorts_ (gconstpointer s1, gconstpointer s2)
+{
+ mix_short_t a = (mix_short_t)GPOINTER_TO_UINT (s1);
+ mix_short_t b = (mix_short_t)GPOINTER_TO_UINT (s2);
+ if ( mix_short_sign (a) == mix_short_sign (b) )
+ return mix_short_magnitude (a) - mix_short_magnitude (b);
+ else if ( mix_short_magnitude (a) == 0 && mix_short_magnitude (b) == 0 )
+ return 0;
+ else if ( mix_short_is_positive (a) )
+ return 1;
+ return -1;
+}
+
+mix_parser_t *
+mix_parser_new (const gchar *in_file)
+{
+ mix_parser_t *result;
+ mix_file_t *f = mix_file_new_with_def_ext (in_file, mix_io_READ,
+ MIX_SRC_DEFEXT);
+
+ if ( f == NULL ) return NULL;
+ result = g_new (mix_parser_t, 1);
+ result->symbol_table = mix_symbol_table_new ();
+ result->ls_table = mix_symbol_table_new ();
+ result->cur_ls = 0;
+ result->future_refs = g_hash_table_new (g_str_hash, g_str_equal);
+ result->ins_table = g_tree_new (compare_shorts_);
+ if ( result->symbol_table == NULL || result->future_refs == NULL
+ || result->ins_table == NULL || result->ls_table == NULL )
+ {
+ mix_symbol_table_delete (result->symbol_table);
+ mix_symbol_table_delete (result->ls_table);
+ g_hash_table_destroy (result->future_refs);
+ g_tree_destroy (result->ins_table);
+ mix_file_delete (f);
+ g_free (result);
+ g_warning (_("No system resources"));
+ return NULL;
+ }
+ result->con_list = NULL;
+ result->alf_list = NULL;
+ result->in_file = f;
+ result->loc_count = MIX_SHORT_ZERO;
+ result->start = MIX_SHORT_ZERO;
+ result->end = MIX_SHORT_ZERO;
+ result->status = MIX_PERR_NOCOMP;
+ result->err_line = 0;
+ result->err_count = 0;
+ result->warn_count = 0;
+ return result;
+}
+
+static void
+delete_list_vals_ (gpointer key, gpointer value, gpointer data)
+{
+ g_free (key);
+ g_slist_free ((GSList*)value);
+}
+
+static int
+delete_tree_vals_ (gpointer key, gpointer value, gpointer data)
+{
+ g_free (value);
+ return FALSE;
+}
+
+void
+mix_parser_delete (mix_parser_t *parser)
+{
+ g_return_if_fail (parser != NULL);
+ /* clear the GSList values of future_refs and its keys */
+ g_hash_table_foreach (parser->future_refs, delete_list_vals_, NULL);
+ /* clear the ins_node_'s of the ins tree */
+ g_tree_foreach (parser->ins_table, delete_tree_vals_, NULL);
+ /* destroy the tree and hash tables */
+ g_tree_destroy (parser->ins_table);
+ mix_symbol_table_delete (parser->symbol_table);
+ mix_symbol_table_delete (parser->ls_table);
+ g_hash_table_destroy (parser->future_refs);
+ g_slist_free (parser->con_list);
+ g_slist_free (parser->alf_list);
+ mix_file_delete (parser->in_file);
+ g_free (parser);
+}
+
+/* Compile a mix source file */
+static void
+update_future_refs_value_ (mix_parser_t *parser, const gchar *name,
+ mix_short_t value, gboolean remove)
+{
+ GSList *list = NULL;
+ gpointer *plist = (gpointer *)(&list);
+ gpointer key;
+
+ g_assert (parser != NULL && name != NULL);
+ if ( g_hash_table_lookup_extended (parser->future_refs, name, &key, plist) )
+ {
+ GSList *tmp = list;
+ ins_node_ *node;
+ while ( tmp != NULL )
+ {
+ node =
+ (ins_node_ *)g_tree_lookup (parser->ins_table, tmp->data);
+ g_assert (node);
+ if (mix_get_ins_address (node->ins) == 1) {
+ value = mix_short_negative (value);
+ node->ins = mix_word_set_field (node->ins,
+ MIX_WORD_ZERO,
+ mix_fspec_new (1,2));
+ }
+ mix_word_add_address (node->ins, value);
+ g_tree_insert (parser->ins_table, tmp->data, (gpointer)node);
+ tmp = g_slist_next (tmp);
+ }
+ if (remove) {
+ g_hash_table_remove (parser->future_refs, name);
+ g_free (key);
+ }
+ g_slist_free (list);
+ }
+}
+
+#define update_future_refs_(parser,name,rem) \
+ update_future_refs_value_(parser, name, (parser)->loc_count, rem)
+
+static void
+update_ls_ (gpointer symbol, gpointer value, gpointer parser)
+{ /* add an instruction on current location and update refs to it */
+ mix_ins_t ins;
+ mix_word_t w = (mix_word_t) GPOINTER_TO_UINT (value);
+ mix_parser_t *par = (mix_parser_t *) parser;
+
+ mix_word_to_ins_uncheck (w, ins);
+ update_future_refs_ (par, (const gchar *)symbol, TRUE);
+ mix_parser_add_ins (par, &ins, 0);
+ par->loc_count++;
+}
+
+static gboolean
+undef_warning_ (gpointer symbol, gpointer value, gpointer data)
+{
+ mix_parser_t *parser = (mix_parser_t *)data;
+ const gchar *name = (const gchar *)symbol;
+ mix_ins_t ins;
+
+ mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, 0, name, TRUE);
+
+ mix_word_to_ins_uncheck (MIX_WORD_ZERO, ins);
+ update_future_refs_ (parser, name, FALSE);
+ mix_parser_add_ins (parser, &ins, 0);
+ mix_symbol_table_insert (parser->symbol_table, name,
+ mix_short_to_word_fast (parser->loc_count));
+
+ parser->loc_count++;
+ return TRUE;
+}
+
+mix_parser_err_t
+mix_parser_compile (mix_parser_t *parser)
+{
+ g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
+ g_return_val_if_fail (parser->in_file != NULL, MIX_PERR_NOIN);
+ g_return_val_if_fail (parser->symbol_table != NULL, MIX_PERR_INTERNAL);
+ g_return_val_if_fail (parser->future_refs != NULL, MIX_PERR_INTERNAL);
+ g_return_val_if_fail (parser->ins_table != NULL, MIX_PERR_INTERNAL);
+
+ parser->status = mix_flex_scan (parser);
+
+ if ( parser->status == MIX_PERR_OK )
+ {
+ parser->loc_count = parser->end;
+ mix_symbol_table_foreach (parser->ls_table, update_ls_, (gpointer)parser);
+ if ( g_hash_table_size (parser->future_refs) > 0)
+ {
+ g_hash_table_foreach_remove (parser->future_refs,
+ undef_warning_, (gpointer)parser);
+ }
+ }
+
+ return parser->status;
+}
+
+/* Write a compiled source to a code file */
+struct write_code_context_
+{
+ mix_code_file_t *file;
+ mix_parser_t *parser;
+};
+
+static gint
+write_code_ (gpointer address, gpointer ins_node, gpointer context)
+{
+ mix_ins_desc_t desc;
+ struct write_code_context_ *cntx = (struct write_code_context_ *)context;
+ desc.ins = ((ins_node_ *)ins_node)->ins;
+ desc.lineno = ((ins_node_ *)ins_node)->lineno;
+ desc.address = (mix_address_t)GPOINTER_TO_UINT (address);
+ if ( mix_code_file_write_ins (cntx->file, &desc) )
+ return FALSE;
+ else
+ {
+ cntx->parser->status = MIX_PERR_NOWRITE;
+ return TRUE;
+ }
+}
+
+mix_parser_err_t
+mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
+ gboolean debug)
+{
+ struct write_code_context_ context;
+ const gchar *cfname = (code_file) ?
+ code_file : mix_file_base_name (parser->in_file);
+ gchar *source_path;
+
+ g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
+ if (parser->status != MIX_PERR_OK ) return parser->status;
+ context.parser = parser;
+ if (!g_path_is_absolute (mix_file_base_name (parser->in_file)))
+ {
+ gchar *dir = g_get_current_dir ();
+ source_path = g_strconcat (dir, G_DIR_SEPARATOR_S,
+ mix_file_base_name (parser->in_file), NULL);
+ g_free (dir);
+ }
+ else
+ source_path = g_strdup (mix_file_base_name (parser->in_file));
+
+ context.file = mix_code_file_new_write (cfname, parser->start, source_path,
+ debug, parser->symbol_table);
+ g_free (source_path);
+
+ if (context.file == NULL) return MIX_PERR_NOOUT;
+ g_tree_foreach (parser->ins_table, write_code_, (gpointer)&context);
+ mix_code_file_delete (context.file);
+ return parser->status;
+}
+
+/* Produce a listing file summarising the compilation */
+typedef struct
+{
+ FILE *file;
+ mix_parser_t *parser;
+} listing_context_t;
+
+static gint
+write_listing_ (gpointer address, gpointer ins, gpointer context)
+{
+ guint k;
+ FILE *file = ((listing_context_t *)context)->file;
+ mix_parser_t *parser = ((listing_context_t *)context)->parser;
+ guint end = parser->end;
+ ins_node_ *ins_node = (ins_node_ *)ins;
+ mix_ins_t instruct;
+
+ fprintf (file, "%03d %05d %s ",
+ ins_node->lineno,
+ GPOINTER_TO_INT (address),
+ mix_word_is_negative (ins_node->ins)? "-":"+");
+ for ( k = 1; k < 6; ++k )
+ fprintf (file, "%02d ", mix_word_get_byte (ins_node->ins, k));
+
+ if (g_slist_find (parser->con_list, GUINT_TO_POINTER (ins_node->lineno))
+ || GPOINTER_TO_UINT (address) >= end)
+ fprintf (file, "\tCON\t%04d\n", (int)(ins_node->ins));
+ else if (g_slist_find (parser->alf_list, GUINT_TO_POINTER (ins_node->lineno)))
+ {
+ size_t i;
+ fprintf (file, "\tALF\t\"");
+ for (i = 1; i < 6; ++i)
+ fprintf (file, "%c",
+ mix_char_to_ascii (mix_byte_to_char
+ (mix_word_get_byte (ins_node->ins, i))));
+ fprintf (file, "\"\n");
+ }
+ else if (GPOINTER_TO_UINT (address) < end)
+ {
+ gchar *instext = NULL;
+ mix_ins_id_t id = mix_word_to_ins (ins_node->ins, &instruct);
+ if (id != mix_INVALID_INS)
+ instext = mix_ins_to_string (&instruct);
+ fprintf (file, _("\t%s\n"), instext? instext : _("UNKNOWN"));
+ if (instext) g_free (instext);
+ }
+ else
+ g_assert_not_reached ();
+
+ return FALSE;
+}
+
+mix_parser_err_t
+mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file)
+{
+ mix_file_t *mfile;
+ const gchar *name;
+ listing_context_t context;
+ static const char *sep =
+ "-----------------------------------------------------------------\n";
+
+ g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
+ if (parser->status != MIX_PERR_OK ) return parser->status;
+ name = (list_file) ? list_file : mix_file_base_name (parser->in_file);
+ mfile = mix_file_new_with_def_ext (name, mix_io_WRITE, MIX_LIST_DEFEXT);
+ if ( mfile == NULL ) return MIX_PERR_NOOUT;
+ context.file = mix_file_to_FILE (mfile);
+ context.parser = parser;
+ fprintf (context.file, _("*** %s%s: compilation summary ***\n\n"),
+ mix_file_base_name (parser->in_file),
+ mix_file_extension (parser->in_file));
+ fputs (sep, context.file);
+ fputs ( _("Src Address Compiled word Symbolic rep\n"),
+ context.file);
+ fputs (sep, context.file);
+ g_tree_foreach (parser->ins_table, write_listing_, (gpointer)(&context));
+ fputs (sep, context.file);
+ fprintf (context.file, _("\n*** Start address:\t%d\n*** End address:\t%d\n"),
+ mix_short_magnitude (parser->start),
+ mix_short_magnitude (parser->end));
+ fprintf (context.file, _("\n*** Symbol table\n"));
+ mix_symbol_table_print (parser->symbol_table, MIX_SYM_ROWS,
+ context.file, TRUE);
+ fprintf (context.file, _("\n*** End of summary ***\n"));
+ mix_file_delete (mfile);
+ return parser->status;
+}
+
+/* load a virtual machine's memory with the contents of a compiled file */
+static gint
+load_vm_ (gpointer address, gpointer ins, gpointer vm)
+{
+ mix_vm_set_addr_contents ((mix_vm_t*)vm,
+ (mix_address_t)GPOINTER_TO_UINT (address),
+ ((ins_node_ *)ins)->ins);
+ return FALSE;
+}
+
+mix_parser_err_t
+mix_parser_load_vm (const mix_parser_t *parser, mix_vm_t *vm)
+{
+ g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
+ g_return_val_if_fail (vm != NULL, MIX_PERR_INTERNAL);
+ g_return_val_if_fail (parser->status == MIX_PERR_OK, parser->status);
+ mix_vm_reset (vm);
+ g_tree_foreach (parser->ins_table, load_vm_, (gpointer)vm);
+ mix_vm_set_start_addr (vm, parser->start);
+ return parser->status;
+}
+
+
+
+/*------------ xmiparser.h functions -------------------------------------*/
+/* functions to manipulate mix_parser_t during compilation */
+
+
+/* symbol table */
+/* Define a new symbol with value equal to the current loc_count
+ * and update future refs to this symbol
+ */
+mix_parser_err_t
+mix_parser_define_symbol_here (mix_parser_t *parser, const gchar *name)
+{
+ mix_word_t value = mix_short_to_word_fast (parser->loc_count);
+ return mix_parser_define_symbol_value (parser, name, value);
+}
+
+mix_parser_err_t
+mix_parser_define_symbol_value (mix_parser_t *parser, const gchar *name,
+ mix_word_t value)
+{
+ g_assert (parser != NULL && name != NULL);
+
+ switch (mix_symbol_table_add (parser->symbol_table, name, value))
+ {
+ case MIX_SYM_OK:
+ if ( parser->status == MIX_PERR_NOCOMP )
+ update_future_refs_value_ (parser, name, value, TRUE);
+ return MIX_PERR_OK;
+ case MIX_SYM_LONG: return MIX_PERR_LONG_SYMBOL;
+ case MIX_SYM_DUP: return MIX_PERR_DUP_SYMBOL;
+ default: return MIX_PERR_INTERNAL;
+ }
+}
+
+/* Obtain the value of a symbol */
+void
+mix_parser_set_future_ref (mix_parser_t *parser, const gchar *name)
+{
+ const gchar *nname = name;
+ GSList *list;
+
+ g_assert (parser != NULL && name != NULL);
+
+ if ( parser->status == MIX_PERR_NOCOMP )
+ {
+ list = g_hash_table_lookup (parser->future_refs, name);
+ if ( list == NULL ) nname = g_strdup (name);
+ list = g_slist_prepend (list, (gpointer)((guint)parser->loc_count));
+ g_hash_table_insert (parser->future_refs, (gpointer)nname, list);
+ }
+}
+
+/* Redefine the value of a local symbol as the current loc_count */
+void
+mix_parser_manage_local_symbol (mix_parser_t *parser, const gchar *name,
+ mix_short_t value)
+{
+ gchar ref[3];
+ ref[2] = 0;
+
+ g_assert (parser != NULL && name != NULL);
+ g_assert (strlen(name) == 2);
+
+ switch (name[1])
+ {
+ case 'f': case 'F':
+ mix_parser_set_future_ref (parser, name);
+ break;
+ case 'h': case 'H':
+ ref[0] = name[0];
+ ref[1] = 'F';
+ if ( parser->status == MIX_PERR_NOCOMP )
+ update_future_refs_value_ (parser, ref, value, TRUE);
+ ref[1] = 'B';
+ mix_symbol_table_insert (parser->symbol_table, ref,
+ mix_short_to_word_fast (value));
+ break;
+ default:
+ return;
+ }
+}
+
+/* Literal strings symbols */
+void
+mix_parser_define_ls (mix_parser_t *parser, mix_word_t value)
+{
+ gchar *name = g_strdup_printf ("%05d", parser->cur_ls++);
+ mix_symbol_table_add (parser->ls_table, name, value);
+ mix_parser_set_future_ref (parser, name);
+ g_free (name);
+}
+
+/* Compilation */
+static void
+add_raw_ (mix_parser_t *parser, mix_word_t word, guint lineno)
+{
+ if ( parser->status == MIX_PERR_NOCOMP || parser->status == MIX_PERR_OK )
+ {
+ ins_node_ *node = g_new (ins_node_, 1);
+ node->ins = word;
+ node->lineno = lineno;
+ g_tree_insert (parser->ins_table, (gpointer)((guint)parser->loc_count),
+ (gpointer)node);
+ }
+}
+
+void
+mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
+ guint lineno)
+{
+ g_assert (parser != NULL && new_ins != NULL);
+ add_raw_ (parser, mix_ins_to_word_uncheck (*new_ins), lineno);
+}
+
+void
+mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno,
+ gboolean is_con)
+{
+ g_assert (parser != NULL);
+ add_raw_ (parser, word, lineno);
+ if ( parser->status == MIX_PERR_NOCOMP || parser->status == MIX_PERR_OK )
+ {
+ if (is_con)
+ parser->con_list = g_slist_append (parser->con_list,
+ GUINT_TO_POINTER (lineno));
+ else
+ parser->alf_list = g_slist_append (parser->alf_list,
+ GUINT_TO_POINTER (lineno));
+ }
+}
+
+/* Error handling */
+void
+mix_parser_log_error (mix_parser_t *parser, mix_parser_err_t error,
+ gint lineno, const gchar *comment, gboolean warn)
+{
+ g_assert (parser != NULL);
+ if ( warn )
+ parser->warn_count += 1;
+ else
+ {
+ parser->err_count += 1;
+ parser->err_line = lineno;
+ parser->status = error;
+ }
+
+ fprintf (stderr, "%s%s:%d: %s: %s",
+ mix_file_base_name (parser->in_file),
+ mix_file_extension (parser->in_file),
+ lineno, warn ? _("warning"):_("error"), _(ERR_MESSAGE_[error]));
+
+ if (comment != NULL)
+ fprintf (stderr, ": %s\n", comment);
+ else
+ fputs ("\n", stderr);
+}
+
diff --git a/mixlib/mix_parser.h b/mixlib/mix_parser.h
new file mode 100644
index 0000000..2335fb1
--- /dev/null
+++ b/mixlib/mix_parser.h
@@ -0,0 +1,111 @@
+/* -*-c-*- ---------------- mix_parser.h :
+ * Declarations for mix_parser_t, which compiles a source file into
+ * a mix code file.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_PARSER_H
+#define MIX_PARSER_H
+
+#include <glib.h>
+#include "mix_vm.h"
+
+/* The parser type */
+typedef struct mix_parser_t mix_parser_t;
+
+/* Create/destroy a mix_parser */
+extern mix_parser_t *
+mix_parser_new (const gchar *in_file);
+
+extern void
+mix_parser_delete (mix_parser_t *parser);
+
+/* Access source file name */
+extern const gchar *
+mix_parser_src_file_base_name (const mix_parser_t *parser);
+
+extern const gchar *
+mix_parser_src_file_extension (const mix_parser_t *parser);
+
+/* Compile a mix source file */
+/* compilation errors */
+typedef enum {
+ MIX_PERR_OK, /* no error */
+ MIX_PERR_NOCOMP, /* file not yet compiled */
+ MIX_PERR_INTERNAL, /* internal error */
+ MIX_PERR_NOIN, /* unable to open input file */
+ MIX_PERR_NOOUT, /* unable to open output file */
+ MIX_PERR_UNEX_EOF, /* unexpected end of file */
+ MIX_PERR_INV_LOC, /* invalid loc field */
+ MIX_PERR_DUP_SYMBOL, /* duplicated symbol */
+ MIX_PERR_LONG_SYMBOL, /* symbol name too long */
+ MIX_PERR_NOOP, /* missing op field */
+ MIX_PERR_UNEX_LOC, /* unexpected location symbol */
+ MIX_PERR_INV_ADDRESS, /* invalid address field */
+ MIX_PERR_INV_IDX, /* invalid index field */
+ MIX_PERR_INV_FSPEC, /* invalid fspec */
+ MIX_PERR_INV_OP, /* invalid operation */
+ MIX_PERR_INV_EXPR, /* invalid expression */
+ MIX_PERR_UNDEF_SYM, /* undefined symbol */
+ MIX_PERR_MIS_PAREN, /* mismatched parenthesis */
+ MIX_PERR_UNEX_FSPEC, /* unexpected f-spec */
+ MIX_PERR_MIS_SYM, /* missing symbol name */
+ MIX_PERR_SYM_INS, /* symbol has the same name as instruction */
+ MIX_PERR_NOWRITE, /* failed code write */
+ MIX_PERR_SHORT_ALF, /* short ALF operand */
+ MIX_PERR_LONG_ALF, /* too long ALF operand */
+ MIX_PERR_UNQUOTED_ALF /* unquoted ALF operand */
+} mix_parser_err_t;
+
+extern const gchar *
+mix_parser_err_string (mix_parser_err_t error);
+
+extern mix_parser_err_t
+mix_parser_compile (mix_parser_t *parser);
+
+extern guint
+mix_parser_warning_count (const mix_parser_t *parser);
+
+extern guint
+mix_parser_err_count (const mix_parser_t *parser);
+
+/* Write the compilation result to a code file with the given name.
+ code_file is completed, if required, with the requisite extension;
+ if code_file == NULL [source_file_name].[extension] is used.
+ If debug == TRUE, debug information is written.
+*/
+extern mix_parser_err_t
+mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
+ gboolean debug);
+
+/* Write a "canonical" listing of a compiled source, i.e. a source
+ file with all symbols substituted by their actual values after
+ compilation.
+*/
+extern mix_parser_err_t
+mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file);
+
+/* load a virtual machine's memory with the contents of a compiled file */
+extern mix_parser_err_t
+mix_parser_load_vm (const mix_parser_t *parser, mix_vm_t *vm);
+
+
+#endif /* MIX_PARSER_H */
+
diff --git a/mixlib/mix_predicate.c b/mixlib/mix_predicate.c
new file mode 100644
index 0000000..2143757
--- /dev/null
+++ b/mixlib/mix_predicate.c
@@ -0,0 +1,215 @@
+/* -*-c-*- -------------- mix_predicate.c :
+ * Implementation of the functions declared in mix_predicate.h
+ * ------------------------------------------------------------------
+ * $Id: mix_predicate.c,v 1.6 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mix_vm.h"
+#include "mix_predicate.h"
+
+/* predicate data */
+typedef union pred_data_t
+{
+ mix_word_t regA;
+ mix_word_t regX;
+ mix_short_t regI;
+ mix_cmpflag_t cmp;
+ gboolean over;
+ mix_word_t mem;
+} pred_data_t;
+
+/* the predicate function type */
+typedef gboolean (*mix_predicate_fun_t) (mix_predicate_t *pred,
+ const mix_vm_t *vm);
+
+/* the predicate type */
+struct mix_predicate_t
+{
+ mix_predicate_type_t type;
+ pred_data_t data;
+ guint control;
+};
+
+/* predicate funcs */
+static gboolean
+pred_func_rA (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val = mix_vm_get_rA (vm);
+ if (pred->data.regA == val) return FALSE;
+ pred->data.regA = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_rX (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val = mix_vm_get_rX (vm);
+ if (pred->data.regX == val) return FALSE;
+ pred->data.regX = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_rI (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_short_t val = (pred->control == 0) ? mix_vm_get_rJ (vm)
+ : mix_vm_get_rI (vm, pred->control);
+ if (pred->data.regI == val) return FALSE;
+ pred->data.regI = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_mem (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val =
+ mix_vm_get_addr_contents (vm, (mix_address_t)pred->control);
+ if (pred->data.mem == val) return FALSE;
+ pred->data.mem = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_cmp (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_cmpflag_t val = mix_vm_get_cmpflag (vm);
+ if (pred->data.cmp == val) return FALSE;
+ pred->data.cmp = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_over (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ gboolean val = mix_vm_get_overflow (vm);
+ if (pred->data.over == val) return FALSE;
+ pred->data.over = val;
+ return TRUE;
+}
+
+static mix_predicate_fun_t PRED_FUNCS_[] = {
+ pred_func_rA, pred_func_rX, pred_func_rI, pred_func_rI, pred_func_rI,
+ pred_func_rI, pred_func_rI, pred_func_rI, pred_func_rI,
+ pred_func_over, pred_func_cmp, pred_func_mem
+};
+
+/* create predicates based on vm status */
+mix_predicate_t *
+mix_predicate_new (mix_predicate_type_t type)
+{
+ mix_predicate_t *result;
+ g_return_val_if_fail (type <= MIX_PRED_MEM, NULL);
+ result = g_new (mix_predicate_t, 1);
+ result->type = type;
+ result->data.regA = MIX_WORD_ZERO;
+ if (type >= MIX_PRED_REG_I1 && type <= MIX_PRED_REG_I6)
+ result->control = 1 + type - MIX_PRED_REG_I1;
+ else
+ result->control = 0;
+ return result;
+}
+
+/* delete a predicate */
+void
+mix_predicate_delete (mix_predicate_t *predicate)
+{
+ g_return_if_fail (predicate != NULL);
+ g_free (predicate);
+}
+
+/* return the predicate's type */
+mix_predicate_type_t
+mix_predicate_get_type (const mix_predicate_t *pred)
+{
+ g_return_val_if_fail (pred != NULL, MIX_PRED_INVALID);
+ return pred->type;
+}
+
+/* test a predicate */
+gboolean
+mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ g_return_val_if_fail (pred != NULL, FALSE);
+ g_return_val_if_fail (vm != NULL, FALSE);
+ return PRED_FUNCS_[pred->type] (pred, vm);
+}
+
+/* change mem address of a MIX_PRED_MEM predicate */
+void
+mix_predicate_set_mem_address (mix_predicate_t *predicate,
+ mix_address_t address)
+{
+ g_return_if_fail (predicate != NULL);
+ predicate->control = address;
+}
+
+/* get message about predicate evaluation */
+const gchar *
+mix_predicate_get_message (const mix_predicate_t *predicate)
+{
+ enum {SIZE = 256};
+ static gchar BUFFER[SIZE];
+ static const gchar *CMP_STRINGS[] = { "L", "E", "G"};
+
+ g_return_val_if_fail (predicate != NULL, NULL);
+
+ switch (predicate->type)
+ {
+ case MIX_PRED_REG_A:
+ g_snprintf (BUFFER, SIZE, _("Register A changed to %s%ld"),
+ mix_word_is_negative (predicate->data.regA)? "-" : "+",
+ mix_word_magnitude (predicate->data.regA));
+ break;
+ case MIX_PRED_REG_X:
+ g_snprintf (BUFFER, SIZE, _("Register X changed to %s%ld"),
+ mix_word_is_negative (predicate->data.regX)? "-" : "+",
+ mix_word_magnitude (predicate->data.regX));
+ break;
+ case MIX_PRED_REG_J:
+ g_snprintf (BUFFER, SIZE, _("Register J changed to %d"),
+ mix_short_magnitude (predicate->data.regI));
+ break;
+ case MIX_PRED_REG_I1: case MIX_PRED_REG_I2: case MIX_PRED_REG_I3:
+ case MIX_PRED_REG_I4: case MIX_PRED_REG_I5: case MIX_PRED_REG_I6:
+ g_snprintf (BUFFER, SIZE, _("Register I%d changed to %s%d"),
+ predicate->control,
+ mix_short_is_negative (predicate->data.regI)? "-" : "+",
+ mix_short_magnitude (predicate->data.regI));
+ break;
+ case MIX_PRED_CMP:
+ g_snprintf (BUFFER, SIZE, _("Comparison flag changed to %s"),
+ CMP_STRINGS[predicate->data.cmp]);
+ break;
+ case MIX_PRED_OVER:
+ g_snprintf (BUFFER, SIZE, _("Overflow toggled %s"),
+ predicate->data.over ? "ON" : "OFF");
+ break;
+ case MIX_PRED_MEM:
+ g_snprintf (BUFFER, SIZE, _("Memory address %d changed to %s%ld"),
+ predicate->control,
+ mix_word_is_negative (predicate->data.mem)? "-" : "+",
+ mix_word_magnitude (predicate->data.mem));
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return BUFFER;
+}
+
diff --git a/mixlib/mix_predicate.h b/mixlib/mix_predicate.h
new file mode 100644
index 0000000..903de57
--- /dev/null
+++ b/mixlib/mix_predicate.h
@@ -0,0 +1,80 @@
+/* -*-c-*- ---------------- mix_predicate.h :
+ * Predicates and lists of predicates testing vm status.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <2001-07-13 22:32:42 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_PREDICATE_H
+#define MIX_PREDICATE_H
+
+#include "mix.h"
+#include "mix_types.h"
+#include "mix_ins.h"
+
+/* the predicate type */
+typedef struct mix_predicate_t mix_predicate_t;
+
+/* predicate types */
+typedef enum {
+ MIX_PRED_REG_A,
+ MIX_PRED_REG_X,
+ MIX_PRED_REG_J,
+ MIX_PRED_REG_I1,
+ MIX_PRED_REG_I2,
+ MIX_PRED_REG_I3,
+ MIX_PRED_REG_I4,
+ MIX_PRED_REG_I5,
+ MIX_PRED_REG_I6,
+ MIX_PRED_OVER,
+ MIX_PRED_CMP,
+ MIX_PRED_MEM,
+ MIX_PRED_INVALID
+} mix_predicate_type_t;
+
+/* create predicates based on vm status */
+extern mix_predicate_t *
+mix_predicate_new (mix_predicate_type_t type);
+
+/* delete a predicate */
+extern void
+mix_predicate_delete (mix_predicate_t *predicate);
+
+/* return the predicate's type */
+extern mix_predicate_type_t
+mix_predicate_get_type (const mix_predicate_t *pred);
+
+/* change mem address of a MIX_PRED_MEM predicate */
+extern void
+mix_predicate_set_mem_address (mix_predicate_t *predicate,
+ mix_address_t address);
+
+/* get message about predicate evaluation */
+extern const gchar *
+mix_predicate_get_message (const mix_predicate_t *predicate);
+
+/* test a predicate */
+#include "mix_vm.h"
+
+extern gboolean
+mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm);
+
+#endif /* MIX_PREDICATE_H */
+
diff --git a/mixlib/mix_predicate_list.c b/mixlib/mix_predicate_list.c
new file mode 100644
index 0000000..1b68d35
--- /dev/null
+++ b/mixlib/mix_predicate_list.c
@@ -0,0 +1,117 @@
+/* -*-c-*- -------------- mix_predicate_list.c :
+ * Implementation of the functions declared in mix_predicate_list.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/07/18 23:02:26 jao"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "mix_predicate_list.h"
+
+/* the predicate list type */
+struct mix_predicate_list_t
+{
+ GSList *predicates;
+ const mix_vm_t *vm;
+ const mix_predicate_t *last;
+};
+
+/* a list of predicates */
+mix_predicate_list_t *
+mix_predicate_list_new (const mix_vm_t *vm)
+{
+ mix_predicate_list_t *result;
+ g_return_val_if_fail (vm != NULL, NULL);
+ result = g_new (mix_predicate_list_t, 1);
+ result->predicates = NULL;
+ result->vm = vm;
+ result->last = NULL;
+ return result;
+}
+
+void
+mix_predicate_list_delete (mix_predicate_list_t *list)
+{
+ g_return_if_fail (list != NULL);
+ g_slist_free (list->predicates);
+ g_free (list);
+}
+
+/* evaluate the predicate list */
+gboolean
+mix_predicate_list_eval (mix_predicate_list_t *list)
+{
+ GSList *node;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+ node = list->predicates;
+ while (node) {
+ mix_predicate_t *pred = (mix_predicate_t *)(node->data);
+ if (mix_predicate_eval (pred, list->vm))
+ {
+ list->last = pred;
+ return TRUE;
+ }
+ node = node->next;
+ }
+ list->last = NULL;
+ return FALSE;
+}
+
+/* add/remove predicates to the list */
+void
+mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate)
+{
+ g_return_if_fail (list != NULL);
+ g_return_if_fail (predicate != NULL);
+ if (!g_slist_find (list->predicates, predicate))
+ list->predicates = g_slist_append (list->predicates, (gpointer)predicate);
+ (void)mix_predicate_eval (predicate, list->vm);
+}
+
+gboolean
+mix_predicate_list_remove (mix_predicate_list_t *list,
+ mix_predicate_t *predicate)
+{
+ g_return_val_if_fail (list != NULL, FALSE);
+ g_return_val_if_fail (predicate != NULL, FALSE);
+ if (g_slist_find (list->predicates, predicate))
+ {
+ list->predicates = g_slist_remove (list->predicates, predicate);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void
+mix_predicate_list_clear (mix_predicate_list_t *list)
+{
+ g_return_if_fail (list != NULL);
+ g_slist_free (list->predicates);
+ list->predicates = NULL;
+ list->last = NULL;
+}
+
+const mix_predicate_t *
+mix_predicate_list_last_true_eval (const mix_predicate_list_t *list)
+{
+ g_return_val_if_fail (list != NULL, NULL);
+ return list->last;
+}
diff --git a/mixlib/mix_predicate_list.h b/mixlib/mix_predicate_list.h
new file mode 100644
index 0000000..d651df7
--- /dev/null
+++ b/mixlib/mix_predicate_list.h
@@ -0,0 +1,64 @@
+/* -*-c-*- ---------------- mix_predicate_list.h :
+ * A list of predicates.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/07/18 23:02:40 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_PREDICATE_LIST_H
+#define MIX_PREDICATE_LIST_H
+
+#include "mix.h"
+#include "mix_vm.h"
+#include "mix_predicate.h"
+
+/* the predicate list type */
+typedef struct mix_predicate_list_t mix_predicate_list_t;
+
+/* create/destroy a list of predicates */
+extern mix_predicate_list_t *
+mix_predicate_list_new (const mix_vm_t *vm);
+
+extern void
+mix_predicate_list_delete (mix_predicate_list_t *list);
+
+/* evaluate the predicate list */
+extern gboolean
+mix_predicate_list_eval (mix_predicate_list_t *list);
+
+extern const mix_predicate_t *
+mix_predicate_list_last_true_eval (const mix_predicate_list_t *list);
+
+#define mix_predicate_list_last_true_eval_type(list) \
+ mix_predicate_get_type (mix_predicate_list_last_true_eval (list))
+
+/* add/remove predicates to the list */
+extern void
+mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate);
+
+extern gboolean
+mix_predicate_list_remove (mix_predicate_list_t *list,
+ mix_predicate_t *predicate);
+
+extern void
+mix_predicate_list_clear (mix_predicate_list_t *list);
+
+#endif /* MIX_PREDICATE_LIST_H */
+
diff --git a/mixlib/mix_scanner.l b/mixlib/mix_scanner.l
new file mode 100644
index 0000000..6150007
--- /dev/null
+++ b/mixlib/mix_scanner.l
@@ -0,0 +1,581 @@
+/* -*-c-*- -------------- mix_scanner.l :
+ * Lexical scanner used by mix_parser_t
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+%{
+#include <ctype.h>
+#include <string.h>
+
+#include "mix.h"
+#include "xmix_parser.h"
+
+#define YY_DECL mix_parser_err_t mix_flex_scan (mix_parser_t *parser)
+
+#define RESET() \
+ do { \
+ mix_ins_fill_from_id (ins, mix_NOP); \
+ ins.address = 0; \
+ ins.index = 0; \
+ nof = FALSE; \
+ lsf = FALSE; \
+ if (symbol != NULL ) \
+ { \
+ g_free (symbol); \
+ symbol = NULL; \
+ } \
+ if (lsymbol != NULL) \
+ { \
+ g_free (lsymbol); \
+ lsymbol = NULL; \
+ } \
+ } while (FALSE)
+
+#define NEXT() \
+ do { \
+ if (lsymbol != NULL) \
+ mix_parser_manage_local_symbol (parser,lsymbol, \
+ loc); \
+ parser->loc_count++; \
+ RESET (); \
+ ++lineno; \
+ BEGIN (INITIAL); \
+ } while (FALSE)
+
+#define ADD_INS() \
+ do { \
+ mix_parser_add_ins (parser, &ins, lineno); \
+ NEXT (); \
+ } while (FALSE)
+
+#define ADD_RAW(value,is_con) \
+ do { \
+ mix_parser_add_raw (parser, value, lineno, is_con); \
+ NEXT (); \
+ } while (FALSE)
+
+
+#define ENTER_EVAL() \
+ do { \
+ if (yytext[0] != '*') \
+ { \
+ expr_val = MIX_WORD_ZERO; \
+ yyless (0); \
+ } \
+ else \
+ { \
+ expr_val = mix_short_to_word_fast (parser->loc_count); \
+ yyless (1); \
+ } \
+ yy_push_state (EVAL); \
+ } while (FALSE)
+
+#define ENTER_WEVAL(s) \
+ do { \
+ wexpr_val = MIX_WORD_ZERO; \
+ wexpr_val_tmp = MIX_WORD_ZERO; \
+ is_fp = FALSE; \
+ yyless (s); \
+ yy_push_state (WEVAL); \
+ } while (FALSE)
+
+#define RETURN_ERROR(error, comment) \
+ do { \
+ char c; \
+ mix_parser_log_error (parser,error,lineno,comment,FALSE); \
+ while ( (c = input ()) != '\n' && c != EOF ) ; \
+ if ( c == EOF ) return error; else ++lineno; \
+ RESET (); \
+ BEGIN (INITIAL); \
+ } while (FALSE)
+
+
+static mix_word_t eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y);
+
+static void unput_word_ (mix_word_t word);
+
+%}
+
+%option nomain
+%option caseless
+%option array
+%option stack
+%option noyywrap
+%option noyy_top_state
+%option noreject
+%option outfile="lex.yy.c"
+
+%s LOC
+%s OP
+%s ADDRESS
+%s INDEX
+%s FSPEC
+%s EVAL
+%s WEVAL
+%s ORIG
+%s CON
+%s EQU
+%s END
+
+ws [ \t]
+digit [0-9]
+letter [A-Z]
+number [+-]?{digit}+
+mixchar [0-9A-Z .,'')(+*/=$<>@;:\-]
+locsymbol {digit}H
+flocsymbol {digit}F
+blocsymbol {digit}B
+symbol {digit}*{letter}+[A-Z0-9]*
+binop "+"|"-"|"*"|"/"|"//"|":"
+atexpr {digit}+|{symbol}|\*
+expr [+-]?{atexpr}({binop}{1}{atexpr})*
+fpart \({expr}\)
+wexpr {expr}({fpart})?(,{expr}({fpart})?)*
+
+
+%%
+
+%{
+
+ mix_ins_t ins;
+ gboolean nof = FALSE, is_fp = FALSE, end = FALSE, lsf = FALSE;
+ mix_word_t expr_val = MIX_WORD_ZERO, wexpr_val = MIX_WORD_ZERO,
+ wexpr_val_tmp = MIX_WORD_ZERO;
+ gchar *symbol = NULL, *lsymbol = NULL;
+ mix_address_t loc = MIX_SHORT_ZERO;
+ guint lineno = 1;
+ mix_ins_fill_from_id (ins, mix_NOP);
+ ins.address = 0;
+ ins.index = 0;
+ parser->err_line = 0;
+#ifdef FLEX_DEBUG
+ yy_flex_debug = getenv("FLEX_DEBUG");
+#endif
+ yyin = mix_file_to_FILE (parser->in_file);
+
+%}
+
+
+<*><<EOF>> {
+ mix_parser_log_error (parser, MIX_PERR_UNEX_EOF, lineno, NULL, FALSE);
+ return MIX_PERR_UNEX_EOF;
+}
+
+<INITIAL>{
+ ^\*.* /* eat comments */
+ . {
+ if ( end ) return parser->status;
+ yyless (0);
+ BEGIN (LOC);
+ }
+ \n {
+ ++lineno;
+ if ( end ) return parser->status;
+ }
+}
+
+<LOC>{
+ {ws}+ BEGIN (OP); /* LOC field is empty */
+ {locsymbol} { /* manage local symbol */
+ loc = get_ploc_ (parser);
+ lsymbol = g_strdup (yytext);
+ if ( lsymbol == NULL ) {
+ mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);
+ return MIX_PERR_INTERNAL;
+ }
+ BEGIN (OP);
+ }
+ {locsymbol}/({ws}+EQU) {/* local symbol with value */
+ loc = get_ploc_ (parser);
+ symbol = g_strdup (yytext);
+ lsymbol = g_strdup (yytext);
+ if ( symbol == NULL || lsymbol == NULL) {
+ mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);
+ return MIX_PERR_INTERNAL;
+ }
+ symbol[1] = 'B'; /* this will be referred as nB afterwards */
+ BEGIN (OP);
+ }
+ {flocsymbol}|{blocsymbol} RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext);
+ {symbol}/({ws}+EQU) { /* store symbol name for future definition */
+ symbol = g_strdup (yytext);
+ if ( symbol == NULL ) {
+ mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);
+ return MIX_PERR_INTERNAL;
+ }
+ BEGIN (OP);
+ }
+ {symbol} { /* define a new symbol */
+ mix_parser_err_t err;
+ if ( mix_get_id_from_string (yytext) != mix_INVALID_INS )
+ mix_parser_log_error (parser, MIX_PERR_SYM_INS, lineno, yytext, TRUE);
+ if ( (err = mix_parser_define_symbol_here (parser,yytext)) != MIX_PERR_OK )
+ mix_parser_log_error (parser, err, lineno, yytext, FALSE);
+ BEGIN (OP);
+ }
+ . RETURN_ERROR (MIX_PERR_INV_LOC, yytext);
+ \n ++lineno; /* empty line */
+}
+
+<OP>{
+ {ws}+ /* eat leading whitespace */
+ \n RETURN_ERROR (MIX_PERR_NOOP, NULL);
+ ORIG{ws}+ BEGIN (ORIG);
+ CON{ws}+ BEGIN (CON);
+ EQU{ws}+ BEGIN (EQU);
+ END{ws}+ BEGIN (END);
+ ALF{ws}+\"{mixchar}{0,5}\"{ws}+.*\n |
+ ALF{ws}+\"{mixchar}{0,5}\"{ws}*\n {
+ mix_byte_t bytes[5];
+ mix_word_t value;
+ guint k, j = 4;
+
+ while ( yytext[j++] != '\"' ) ;
+ for ( k = j; k < 5+j && yytext[k] != '\"'; ++k )
+ bytes[k-j] = mix_ascii_to_char (yytext[k]);
+ if ( k-j < 5 )
+ {
+ mix_parser_log_error (parser, MIX_PERR_SHORT_ALF, lineno, NULL, TRUE);
+ /* Fill with spaces */
+ for (; k < 5+j; k++)
+ bytes[k-j] = mix_ascii_to_char (' ');
+ }
+ else if ( yytext[k] != '\"' )
+ mix_parser_log_error (parser, MIX_PERR_LONG_ALF, lineno, NULL, TRUE);
+
+ value = mix_bytes_to_word (bytes, 5);
+ ADD_RAW (value, FALSE);
+ }
+ ALF{ws}*\n {
+ mix_byte_t bytes[5];
+ memset (bytes, mix_ascii_to_char (' '), 5);
+ mix_word_t value = mix_bytes_to_word (bytes, 5);
+ ADD_RAW (value, FALSE);
+ }
+ ALF{ws}+({mixchar}{1,5}) {
+ mix_byte_t bytes[5];
+ mix_word_t value;
+ int i, n;
+ for (n = 3; n < yyleng; n++)
+ if (!isspace (yytext[n]))
+ break;
+
+ for (i = 0; i < 5 && n < yyleng; i++, n++)
+ bytes[i] = mix_ascii_to_char (yytext[n]);
+
+ for (; i < 5; i++)
+ bytes[i] = mix_ascii_to_char (' ');
+
+ value = mix_bytes_to_word (bytes, 5);
+ ADD_RAW (value, FALSE);
+ }
+ /* ALF " " */
+ [A-Z0-9]+{ws}*/\n |
+ [A-Z0-9]+{ws}+ {
+ mix_ins_id_t id = mix_get_id_from_string (g_strchomp (yytext));
+ if ( id == mix_INVALID_INS )
+ mix_parser_log_error (parser, MIX_PERR_INV_OP, lineno, yytext, FALSE);
+ else {
+ mix_ins_fill_from_id (ins, id);
+ nof = mix_ins_id_is_extended (id);
+ }
+ BEGIN (ADDRESS);
+ }
+ {expr} RETURN_ERROR (MIX_PERR_INV_OP, yytext);
+ . RETURN_ERROR (MIX_PERR_INV_OP, yytext);
+}
+
+
+<ORIG>{
+ {number}{ws}*\n |
+ {number}{ws}+.*\n {
+ mix_word_t value = mix_word_new (atol (yytext));
+ parser->loc_count = mix_word_to_short_fast (value);
+ ++lineno;
+ BEGIN (INITIAL);
+ }
+}
+
+<CON>{
+ {number}{ws}*\n |
+ {number}{ws}+.*\n {
+ mix_word_t value = mix_word_new (atol (yytext));
+ ADD_RAW (value, TRUE);
+ }
+}
+
+<EQU>{
+ {number}{ws}*\n |
+ {number}{ws}+.*\n {
+ mix_word_t value;
+ gint def;
+ if ( symbol == NULL ) RETURN_ERROR (MIX_PERR_MIS_SYM, NULL);
+ value = mix_word_new (atol (yytext));
+ def = mix_parser_define_symbol_value (parser, symbol, value);
+ if ( def == MIX_SYM_DUP ) RETURN_ERROR (MIX_PERR_DUP_SYMBOL, symbol);
+ if ( def == MIX_SYM_LONG ) RETURN_ERROR (MIX_PERR_LONG_SYMBOL, symbol);
+ ++lineno;
+ BEGIN (INITIAL);
+ }
+}
+
+<END>{
+ {number}{ws}*\n |
+ {number}{ws}+.*\n {
+ parser->start = mix_short_new (atol (yytext));
+ parser->end = parser->loc_count;
+ end = TRUE;
+ if ( parser->status == MIX_PERR_NOCOMP ) parser->status = MIX_PERR_OK;
+ return parser->status;
+ }
+}
+
+<ORIG,CON,EQU,END>{
+ {wexpr} ENTER_WEVAL (0);
+ . RETURN_ERROR (MIX_PERR_INV_OP, yytext);
+}
+
+
+<ADDRESS,INDEX,FSPEC>{locsymbol} RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext);
+
+<ADDRESS>{
+ =/[+-]?{number}= lsf = TRUE;
+ =/{expr}= lsf = TRUE;
+ ={wexpr}= { lsf = TRUE; ENTER_WEVAL (1); }
+ [+-]?{number}={ws}*\n |
+ [+-]?{number}={ws}+.*\n {
+ if (!lsf) RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);
+ mix_parser_define_ls (parser, mix_word_new (atol (yytext)));
+ lsf = FALSE;
+ ADD_INS ();
+ }
+ [+-]?{number}=[(,] {
+ int pos = yyleng - 3;
+ if (!lsf) RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);
+ unput (yytext[yyleng - 1]);
+ while (pos >= 0) {
+ unput (yytext[pos]);
+ --pos;
+ }
+ }
+ [+-]?{number}{ws}+.*\n |
+ [+-]?{number}[(,\n] {
+ ins.address = mix_short_new (atol (yytext));
+ switch ( yytext[yyleng-1] ) {
+ case '(' : BEGIN (FSPEC); break;
+ case ',' : BEGIN (INDEX); break;
+ case '\n' : ADD_INS (); break;
+ default: g_assert_not_reached ();
+ }
+ }
+ ([+-]?{symbol})/[(,\n\t ] {
+ gboolean neg = (yytext[0] == '-');
+ const gchar *s = (neg || yytext[0] == '+')? yytext+1 : yytext;
+ if ( !mix_symbol_table_is_defined (parser->symbol_table, s) )
+ {
+ mix_parser_set_future_ref (parser, s);
+ if (neg)
+ mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, TRUE);
+ unput (neg? '1':'0');
+ }
+ else
+ {
+ mix_word_t v = mix_symbol_table_value (parser->symbol_table, s);
+ if ( neg ) mix_word_reverse_sign (v);
+ unput_word_ (v);
+ }
+ }
+ {expr}/[(,=\n\t ] ENTER_EVAL ();
+ \n ADD_INS ();
+ . RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);
+}
+
+
+<INDEX>{
+ {number}[\n(\t ] {
+ int end = yytext[yyleng-1];
+ ins.index = mix_byte_new (atol (yytext));
+ if ( end == '\n' )
+ ADD_INS ();
+ else if ( end == '(' )
+ BEGIN (FSPEC);
+ else
+ { /* eat rest of line (comment) */
+ while ( (end = input()) != '\n' && end != EOF ) ;
+ if ( end == '\n' ) ADD_INS ();
+ else RETURN_ERROR (MIX_PERR_UNEX_EOF, NULL);
+ }
+ }
+ {expr}/[\n(\t ] ENTER_EVAL ();
+ \n {
+ mix_parser_log_error (parser, MIX_PERR_INV_IDX, lineno++, NULL, FALSE);
+ RESET ();
+ BEGIN (INITIAL);
+ }
+ . RETURN_ERROR (MIX_PERR_INV_IDX, yytext);
+}
+
+<FSPEC>{
+ {number}")"(({ws}+.*\n)|\n) {
+ glong val = atol (yytext);
+ if ( val < 0 || val > MIX_BYTE_MAX )
+ RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);
+ if ( ins.opcode != mix_opMOVE
+ && ( ins.opcode < mix_opJBUS || ins.opcode > mix_opJXx )
+ && !mix_fspec_is_valid (mix_byte_new (val)) )
+ RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);
+ if ( nof )
+ mix_parser_log_error (parser, MIX_PERR_INV_FSPEC,
+ lineno, _("ignored"), TRUE);
+ else
+ {
+ ins.fspec = mix_byte_new (val);
+ if (lsf)
+ {
+ mix_parser_define_ls (parser,
+ mix_short_to_word_fast (ins.address));
+ ins.address = MIX_WORD_ZERO;
+ lsf = FALSE;
+ }
+ ADD_INS ();
+ }
+ }
+ {expr}/")" {
+ ENTER_EVAL ();
+ }
+ . RETURN_ERROR (MIX_PERR_INV_FSPEC, yytext);
+}
+
+
+<EVAL>{
+ {binop}{digit}+ {
+ const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;
+ mix_word_t value = mix_word_new (atol (s));
+ expr_val = eval_binop_ (yytext, expr_val, value);
+ }
+ {binop}{symbol} {
+ const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;
+ if ( !mix_symbol_table_is_defined (parser->symbol_table, s) ) {
+ mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, FALSE);
+ yy_pop_state ();
+ }
+ expr_val = eval_binop_ (yytext, expr_val,
+ mix_symbol_table_value (parser->symbol_table, s));
+ }
+ {binop}"*" {
+ expr_val = eval_binop_ (yytext, expr_val,
+ mix_short_to_word_fast (parser->loc_count));
+ }
+ "*" unput_word_ (mix_short_to_word_fast (parser->loc_count));
+ {number} expr_val = mix_word_new (atol (yytext));
+ {symbol} {
+ if ( !mix_symbol_table_is_defined (parser->symbol_table, yytext) ) {
+ mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, yytext, FALSE);
+ yy_pop_state ();
+ }
+ expr_val = mix_symbol_table_value (parser->symbol_table, yytext);
+ }
+ [,)(=\n\t ] unput (yytext[0]); unput_word_ (expr_val); yy_pop_state ();
+ . RETURN_ERROR (MIX_PERR_INV_EXPR, yytext);
+}
+
+<WEVAL>{
+ {number}"(" {
+ is_fp = TRUE;
+ wexpr_val_tmp = mix_word_new (atol (yytext));
+ }
+ {number}")" {
+ glong val = atol (yytext);
+ if ( !is_fp ) {
+ mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE);
+ yy_pop_state ();
+ }
+ if ( val < 0 || val > MIX_BYTE_MAX
+ || !mix_fspec_is_valid (mix_byte_new (val)) ) {
+ mix_parser_log_error (parser, MIX_PERR_INV_FSPEC, lineno, NULL, FALSE);
+ yy_pop_state ();
+ }
+ is_fp = FALSE;
+ wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp,
+ wexpr_val);
+ }
+ {number}/[,()\n\t ] wexpr_val = mix_word_new (atol (yytext));
+ {expr}/[,()\n\t ] ENTER_EVAL ();
+ ,/{expr} /* eat comma if followed by expression */
+ [=\n\t ] { /* ok if not inside an f-part */
+ if ( is_fp ) {
+ mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE);
+ yy_pop_state ();
+ }
+ unput (yytext[yyleng-1]);
+ unput_word_ (wexpr_val);
+ yy_pop_state ();
+ }
+ . RETURN_ERROR (MIX_PERR_INV_EXPR, NULL);
+}
+
+%%
+
+static mix_word_t
+eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y)
+{
+ mix_word_t result = MIX_WORD_ZERO;
+ switch (op[0])
+ {
+ case '+':
+ result = mix_word_add (x,y);
+ break;
+ case '-':
+ result = mix_word_sub (x,y);
+ break;
+ case '*':
+ mix_word_mul (x, y, NULL, &result);
+ break;
+ case ':':
+ {
+ mix_word_t a;
+ mix_word_mul (x, 8, NULL, &a);
+ result = mix_word_add (a, y);
+ break;
+ }
+ case '/':
+ if ( strlen (op) > 1 && op[1] == '/' ) {
+ mix_word_div (x,MIX_WORD_ZERO,y, &result, NULL);
+ } else {
+ mix_word_div (MIX_WORD_ZERO, x, y, &result, NULL);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return result;
+}
+
+static void
+unput_word_ (mix_word_t word)
+{
+ gchar *value;
+ gint k;
+ value = g_strdup_printf ("%s%ld",
+ mix_word_is_negative (word)? "-":"+",
+ mix_word_magnitude (word));
+ for (k = strlen (value) - 1; k >= 0; --k)
+ unput (value[k]);
+ g_free (value);
+}
diff --git a/mixlib/mix_src_file.c b/mixlib/mix_src_file.c
new file mode 100644
index 0000000..b376643
--- /dev/null
+++ b/mixlib/mix_src_file.c
@@ -0,0 +1,157 @@
+/* -*-c-*- -------------- mix_src_file.c :
+ * Implementation of the functions declared in mix_src_file.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/03/10 15:23:46 jose"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "mix_src_file.h"
+
+/* the MIXAL source file type */
+struct mix_src_file_t
+{
+ gchar *path; /* the path to the disk file */
+ GPtrArray *lines; /* an array of the file lines */
+ guint lineno; /* the number of lines */
+};
+
+/* format a source line */
+static gchar *
+format_line_ (gchar *line)
+{
+ const gchar *label, *op, *rest;
+ gint k = 0;
+
+ if (!line) return line;
+ if (line[0] == '*' || strlen(line) == 0)
+ return g_strdup (line);
+
+ if (isspace (line[0]))
+ {
+ label = " ";
+ while (line[k] && isspace (line[k])) ++k;
+ }
+ else
+ {
+ label = line;
+ while (line[k] && !isspace (line[k])) ++k;
+ while (line[k] && isspace (line[k])) ++k;
+ }
+
+ if (line[k])
+ {
+ line[k - 1] = 0;
+ op = line + k;
+ while (line[k] && !isspace (line[k])) ++k;
+ while (line[k] && isspace (line[k])) ++k;
+ line[k - 1] = 0;
+ rest = (line[k]) ? line + k: "";
+ }
+ else
+ {
+ op = rest = "";
+ }
+
+
+ return g_strdup_printf ("%-11s %-5s %s", label, op, rest);
+}
+
+/* load the source file lines into memory */
+static gboolean
+load_file_ (mix_src_file_t *file)
+{
+ mix_file_t *mf = mix_file_new_with_def_ext (file->path,
+ mix_io_READ,
+ MIX_SRC_DEFEXT);
+ if (mf != NULL)
+ {
+ enum {BUFFER_SIZE = 256};
+ static gchar BUFFER[BUFFER_SIZE];
+
+ FILE *f = mix_file_to_FILE (mf);
+ file->lines = g_ptr_array_new ();
+ file->lineno = 0;
+
+ while (fgets (BUFFER, BUFFER_SIZE, f) == BUFFER)
+ {
+ g_ptr_array_add (file->lines, (gpointer) format_line_ (BUFFER));
+ file->lineno++;
+ }
+
+ mix_file_delete (mf);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* create a new src file from an existing disk file */
+mix_src_file_t *
+mix_src_file_new_for_read (const gchar *path)
+{
+ mix_src_file_t *result = g_new (mix_src_file_t, 1);
+ result->lines = NULL;
+ result->path = g_strdup (path);
+ result->lineno = 0;
+ return result;
+}
+
+/* destroy a src file object */
+void
+mix_src_file_delete (mix_src_file_t *src)
+{
+ g_return_if_fail (src != NULL);
+ if (src->lines) g_ptr_array_free (src->lines, TRUE);
+ g_free (src->path);
+ g_free (src);
+}
+
+/* get the source file path */
+const gchar *
+mix_src_file_get_path (const mix_src_file_t *src)
+{
+ g_return_val_if_fail (src != NULL, NULL);
+ return src->path;
+}
+
+/* get a given line of the source file */
+const gchar *
+mix_src_file_get_line (const mix_src_file_t *src, guint lineno)
+{
+ g_return_val_if_fail (src != NULL, NULL);
+ if (src->lines == NULL && !load_file_ ((mix_src_file_t*)src))
+ return NULL;
+ if (lineno > src->lineno || lineno == 0)
+ return NULL;
+ return (gchar *)g_ptr_array_index (src->lines, lineno - 1);
+}
+
+/* get the total no. of lines in the file */
+guint
+mix_src_file_get_line_no (const mix_src_file_t *src)
+{
+ g_return_val_if_fail (src != NULL, 0);
+ if (src->lines == NULL && !load_file_ ((mix_src_file_t*)src))
+ return 0;
+ return src->lineno;
+}
+
diff --git a/mixlib/mix_src_file.h b/mixlib/mix_src_file.h
new file mode 100644
index 0000000..d3a7461
--- /dev/null
+++ b/mixlib/mix_src_file.h
@@ -0,0 +1,57 @@
+/* -*-c-*- ---------------- mix_src_file.h :
+ * Declaration of mix_src_file_t, a type representing a MIXAL source
+ * file.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/02/20 00:23:58 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_SRC_FILE_H
+#define MIX_SRC_FILE_H
+
+#include "mix_file.h"
+
+/* the MIXAL source file type */
+typedef struct mix_src_file_t mix_src_file_t;
+
+/* create a new src file from an existing disk file */
+extern mix_src_file_t *
+mix_src_file_new_for_read (const gchar *path);
+
+/* destroy a src file object */
+extern void
+mix_src_file_delete (mix_src_file_t *src);
+
+/* get the source file path */
+extern const gchar *
+mix_src_file_get_path (const mix_src_file_t *src);
+
+/* get a given line of the source file */
+extern const gchar *
+mix_src_file_get_line (const mix_src_file_t *src, guint lineno);
+
+/* get the total no. of lines in the file */
+extern guint
+mix_src_file_get_line_no (const mix_src_file_t *src);
+
+
+
+#endif /* MIX_SRC_FILE_H */
+
diff --git a/mixlib/mix_symbol_table.c b/mixlib/mix_symbol_table.c
new file mode 100644
index 0000000..dc56b7a
--- /dev/null
+++ b/mixlib/mix_symbol_table.c
@@ -0,0 +1,198 @@
+/* -*-c-*- -------------- mix_symbol_table.c :
+ * Implementation of the functions declared in mix_symbol_table.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <ctype.h> /* isdigit */
+#include <string.h>
+
+#include "mix_symbol_table.h"
+
+/* Create an empty table */
+mix_symbol_table_t *
+mix_symbol_table_new (void)
+{
+ return g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+/* Create a table and populate it with the contents of a table stored
+ in -file- using mix_symbol_table_print (table, MIX_SYM_LINE, file)
+*/
+mix_symbol_table_t *
+mix_symbol_table_new_from_file (FILE *file)
+{
+ mix_symbol_table_t *result = mix_symbol_table_new ();
+ if ( result != NULL )
+ {
+ gchar sym[MIX_SYM_MAX_LEN + 1];
+ glong val;
+
+ while ( getc (file) == ',' )
+ {
+ if ( fscanf (file, "%s =%ld", sym, &val) != EOF )
+ mix_symbol_table_add (result, sym, mix_word_new (val));
+ }
+ }
+ return result;
+}
+
+/* Delete a table */
+static void
+delete_hash_keys_ (gpointer key, gpointer value, gpointer data)
+{
+ g_free (key);
+}
+
+void
+mix_symbol_table_delete (mix_symbol_table_t *table)
+{
+ g_hash_table_foreach (table, delete_hash_keys_, NULL);
+ g_hash_table_destroy (table);
+}
+
+/* add/remove symbols from other table */
+static void
+add_symbol_ (gpointer symbol, gpointer value, gpointer target)
+{
+ mix_symbol_table_t *t = (mix_symbol_table_t *)target;
+ gchar *s = (gchar *)symbol;
+ mix_word_t v = (mix_word_t)GPOINTER_TO_UINT (value);
+ mix_symbol_table_insert (t, s, v);
+}
+
+static void
+remove_symbol_ (gpointer symbol, gpointer value, gpointer target)
+{
+ mix_symbol_table_t *t = (mix_symbol_table_t *)target;
+ gchar *s = (gchar *)symbol;
+ mix_symbol_table_remove (t, s);
+}
+
+gboolean
+mix_symbol_table_merge_table (mix_symbol_table_t *table,
+ const mix_symbol_table_t *from)
+{
+ g_return_val_if_fail (table != NULL, FALSE);
+ if (from != NULL)
+ {
+ mix_symbol_table_foreach ((gpointer)from, add_symbol_, table);
+ }
+ return TRUE;
+}
+
+gboolean
+mix_symbol_table_substract_table (mix_symbol_table_t *table,
+ const mix_symbol_table_t *other)
+{
+ g_return_val_if_fail (table != NULL, FALSE);
+ if (other != NULL)
+ {
+ mix_symbol_table_foreach ((gpointer)other, remove_symbol_, table);
+ }
+ return TRUE;
+}
+
+
+/* Add/remove symbols one by one */
+gint
+mix_symbol_table_add (mix_symbol_table_t *table,
+ const gchar *sym, mix_word_t value)
+{
+ gpointer key, val;
+
+ if ( table == NULL || sym == NULL ) return MIX_SYM_FAIL;
+ if ( strlen (sym) > MIX_SYM_MAX_LEN ) return MIX_SYM_LONG;
+
+ if ( !g_hash_table_lookup_extended (table, sym, &key, &val) )
+ {
+ key = g_strdup (sym);
+ g_hash_table_insert (table, key, (gpointer)value);
+ return MIX_SYM_OK;
+ }
+ else
+ return MIX_SYM_DUP;
+}
+
+/* Add or modify symbol if it exists */
+gint
+mix_symbol_table_insert (mix_symbol_table_t *table,
+ const gchar *sym, mix_word_t new_value)
+{
+ gpointer key, val;
+
+ if ( table == NULL || sym == NULL ) return MIX_SYM_FAIL;
+ if ( strlen (sym) > MIX_SYM_MAX_LEN ) return MIX_SYM_LONG;
+
+ if ( !g_hash_table_lookup_extended (table, sym, &key, &val) )
+ key = g_strdup (sym);
+ g_hash_table_insert (table, key, (gpointer)new_value);
+ return MIX_SYM_OK;
+}
+
+
+/* Symbols lookup */
+gboolean
+mix_symbol_table_is_defined (const mix_symbol_table_t *table, const gchar *sym)
+{
+ gpointer key, val;
+ return g_hash_table_lookup_extended((GHashTable *)table, sym, &key, &val);
+}
+
+/* Print table */
+#define is_local_sym_(sym) \
+ ((sym) && (strlen (sym)==2) && (sym[1] == 'B') && isdigit (sym[0]))
+
+static gboolean skip_ = FALSE;
+
+static void
+print_sym_rows_ (gpointer symbol, gpointer value, gpointer file)
+{
+ char *s = (char *)symbol;
+ if (skip_ && !is_local_sym_ (s)) {
+ mix_word_t word = (mix_word_t)GPOINTER_TO_UINT (value);
+ fprintf((FILE *)file, "%-20s: %s%ld\n", s,
+ mix_word_is_negative (word)? "-":"",
+ mix_word_magnitude (word));
+ }
+}
+
+static void
+print_sym_line_ (gpointer symbol, gpointer value, gpointer file)
+{
+ char *s = (char *)symbol;
+ if (skip_ && !is_local_sym_ (s)) {
+ mix_word_t word = (mix_word_t)GPOINTER_TO_UINT (value);
+ fprintf((FILE *)file, ",%s =%s%ld", s,
+ mix_word_is_negative (word)? "-":"",
+ mix_word_magnitude (word));
+ }
+}
+
+void
+mix_symbol_table_print (const mix_symbol_table_t *table, gint mode,
+ FILE *file, gboolean skiplocal)
+{
+ GHFunc func = (mode == MIX_SYM_LINE)? print_sym_line_ : print_sym_rows_;
+ skip_ = skiplocal;
+ if ( table != NULL )
+ g_hash_table_foreach ((GHashTable *)table, func, (gpointer)file);
+ if ( mode == MIX_SYM_LINE ) putc (';', file); /* to mark end-of-table */
+}
+
+
diff --git a/mixlib/mix_symbol_table.h b/mixlib/mix_symbol_table.h
new file mode 100644
index 0000000..c54c3f8
--- /dev/null
+++ b/mixlib/mix_symbol_table.h
@@ -0,0 +1,109 @@
+/* -*-c-*- ---------------- mix_symbol_table.h :
+ * Type mix_symbol_table_t and functions to manipulate it.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_SYMBOL_TABLE_H
+#define MIX_SYMBOL_TABLE_H
+
+#include <stdio.h>
+#include "mix_types.h"
+
+/* A symbol table shall be implemented as a hash table */
+typedef GHashTable mix_symbol_table_t ;
+
+/* Maximum length of stored symbols */
+#define MIX_SYM_MAX_LEN 10
+
+/* Create an empty table */
+extern mix_symbol_table_t *
+mix_symbol_table_new (void);
+
+/* Create a table and populate it with the contents of a table stored
+ in -file- using mix_symbol_table_print (table, MIX_SYM_LINE, file)
+*/
+extern mix_symbol_table_t *
+mix_symbol_table_new_from_file (FILE *file);
+
+
+/* Delete a table */
+extern void
+mix_symbol_table_delete (mix_symbol_table_t *table);
+
+/* add/remove symbols from other table */
+extern gboolean
+mix_symbol_table_merge_table (mix_symbol_table_t *table,
+ const mix_symbol_table_t *from);
+
+extern gboolean
+mix_symbol_table_substract_table (mix_symbol_table_t *table,
+ const mix_symbol_table_t *other);
+
+/* Add/remove symbols one by one */
+/* possible outcomes: */
+enum {
+ MIX_SYM_FAIL, /* attempt failed */
+ MIX_SYM_OK,
+ MIX_SYM_DUP, /* duplicated symbol */
+ MIX_SYM_LONG /* symbol too long: only MIX_SYM_MAX_LEN chars used */
+};
+
+extern gint
+mix_symbol_table_add (mix_symbol_table_t *table,
+ const gchar *sym, mix_word_t value);
+
+#define mix_symbol_table_remove(table, sym) \
+ g_hash_table_remove (table, sym)
+
+
+/* Add or modify symbol if it exists */
+extern gint
+mix_symbol_table_insert (mix_symbol_table_t *table,
+ const gchar *sym, mix_word_t new_value);
+
+/* Add or modify symbol if it exists, without copying sym */
+#define mix_symbol_table_insert_static(table,sym,value)\
+ g_hash_table_insert (table,(gpointer)sym,GUINT_TO_POINTER (value))
+
+/* Symbols lookup */
+extern gboolean
+mix_symbol_table_is_defined (const mix_symbol_table_t *table, const gchar *sym);
+
+#define mix_symbol_table_value(table,sym) \
+ (mix_word_t)GPOINTER_TO_UINT (g_hash_table_lookup ((GHashTable *)table, \
+ (gpointer)sym))
+
+/* Traverse the table */
+#define mix_symbol_table_foreach(table,func,data) \
+ g_hash_table_foreach (table,func,data)
+
+/* Print the table */
+enum {
+ MIX_SYM_ROWS, /* each symbol/value in a row */
+ MIX_SYM_LINE /* {,symbol =value}*; in a single row */
+};
+
+extern void
+mix_symbol_table_print (const mix_symbol_table_t *table, gint mode,
+ FILE *file, gboolean skiplocal);
+
+
+#endif /* MIX_SYMBOL_TABLE_H */
+
diff --git a/mixlib/mix_types.c b/mixlib/mix_types.c
new file mode 100644
index 0000000..f87247a
--- /dev/null
+++ b/mixlib/mix_types.c
@@ -0,0 +1,569 @@
+/* -*-c-*- ------------------ mix_types.c :
+ * Implementation file for mix_types.h declarations.
+ * ------------------------------------------------------------------
+ * $Id: mix_types.c,v 1.5 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mix.h"
+#include <limits.h>
+#include <ctype.h>
+#include "mix_types.h"
+
+
+/*------------------------ initialisation stuff ------------------------*/
+/* flag telling whether a field spec is valid */
+static gboolean is_bad_field_[MIX_BYTE_MAX + 1];
+/* shift associated with a fspec */
+static guint shift_[MIX_BYTE_MAX + 1];
+/* mask associated with a fspec */
+static glong mask_[MIX_BYTE_MAX + 1];
+
+/* maps from gchar's to mix_char_t */
+#define NONP_ (guchar)('?')
+static mix_char_t ascii_to_mix_char_[UCHAR_MAX + 1];
+static guchar mix_char_to_ascii_[MIX_CHAR_MAX + 1] = {
+ ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', '~', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', '[', '#', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '.', ',', '(', ')', '+', '-', '*', '/', '=', '$',
+ '<', '>', '@', ';', ':', '\''
+};
+
+
+/* initialise the above arrays */
+void
+mix_init_types (void)
+{
+ guint lt, rt;
+ for (lt = 0; lt < 8; ++lt)
+ for (rt = 0; rt < 8; ++rt)
+ {
+ guint F = 8 * lt + rt;
+ is_bad_field_[F] = rt < lt || 5 < rt;
+ if ( is_bad_field_[F] )
+ shift_[F] = 0, mask_[F] = 0;
+ else
+ {
+ guint width = rt - (lt == 0 ? 1 : lt) + 1;
+ shift_[F] = 6 * (5 - rt);
+ mask_[F] = ((1L << (6 * width)) - 1) << shift_[F];
+ }
+ }
+
+ for ( lt = 0; lt < UCHAR_MAX + 1; ++lt )
+ ascii_to_mix_char_[lt] = NONP_;
+ for ( lt = 0; lt < MIX_CHAR_MAX + 1; ++lt )
+ ascii_to_mix_char_[mix_char_to_ascii_[lt]] = (guchar)lt;
+}
+
+mix_char_t
+mix_ascii_to_char (guchar c)
+{
+ return ascii_to_mix_char_[toupper (c)];
+}
+
+
+guchar
+mix_char_to_ascii (mix_char_t c)
+{
+ return c > MIX_CHAR_MAX ? NONP_ : mix_char_to_ascii_[c];
+}
+
+
+/*---------------------------- m_word_t --------------------------------- */
+
+/* Create mix_word_t from an array of mix_byte_t */
+mix_word_t
+mix_bytes_to_word (mix_byte_t *bytes, guint byteno)
+{
+ mix_word_t result = 0;
+ guint k;
+
+ g_return_val_if_fail (bytes != NULL, MIX_WORD_ZERO);
+ g_return_val_if_fail (byteno != 0, MIX_WORD_ZERO);
+
+ if ( byteno > 5 ) byteno = 5;
+ for ( k = 0; k < byteno; k++ )
+ result |= ((gulong)bytes[k]) << (6*(byteno-k-1));
+
+ return result;
+}
+
+
+/* Field operations */
+mix_word_t /* the specified field or 0 if f is not valid */
+mix_word_get_field (mix_fspec_t f, mix_word_t word)
+{
+ mix_word_t result;
+
+ g_return_val_if_fail (!is_bad_field_[f],MIX_WORD_ZERO);
+
+ result = ( (word & mask_[f]) >> shift_[f] );
+ if (f < 8) /* if f is of the form (0:R), retain the sign of word */
+ result |= mix_word_sign (word);
+
+ return result;
+}
+
+
+mix_word_t
+mix_word_set_field (mix_fspec_t f, mix_word_t from, mix_word_t to)
+{
+ mix_word_t result;
+ glong m = mask_[f];
+
+ g_return_val_if_fail (!is_bad_field_[f],to);
+
+ if (f < 8) /* if F is of the form (0:R), use the sign of -from- */
+ result = (to & ~m & ~MIX_WORD_SIGN_BIT)
+ | ((from /*<< shift_[f]*/) & m) | mix_word_sign (from);
+ else
+ result = (to & ~m) | ((from /*<< shift_[f]*/) & m);
+
+ return result;
+}
+
+mix_word_t
+mix_word_store_field (mix_fspec_t f, mix_word_t from, mix_word_t to)
+{
+ mix_word_t result;
+ glong m = mask_[f];
+
+ g_return_val_if_fail (!is_bad_field_[f],to);
+
+ if (f < 8) /* if F is of the form (0:R), use the sign of -from- */
+ result = (to & ~m & ~MIX_WORD_SIGN_BIT)
+ | ((from << shift_[f]) & m) | mix_word_sign (from);
+ else
+ result = (to & ~m) | ((from << shift_[f]) & m);
+
+ return result;
+}
+
+
+
+gboolean
+mix_fspec_is_valid (mix_fspec_t f)
+{
+ return !(is_bad_field_[f]);
+}
+
+mix_byte_t
+mix_word_get_byte (mix_word_t word, /* word parsed */
+ guint idx /* byte: 1 to 5 */ )
+{
+ mix_byte_t fspec = mix_fspec_new (idx,idx);
+
+ g_return_val_if_fail ((idx > 0 && idx < 6), MIX_BYTE_ZERO);
+
+ return mix_byte_new (mix_word_get_field (fspec,word));
+}
+
+
+extern void
+mix_word_set_byte (mix_word_t *into, guint idx, mix_byte_t value)
+{
+ mix_word_t from = value;
+ mix_byte_t fspec = mix_fspec_new (idx,idx);
+
+ g_return_if_fail (into != NULL);
+ g_return_if_fail (idx > 0 && idx < 6);
+
+ from <<= shift_[fspec];
+ *into = mix_word_set_field (fspec,from,*into);
+}
+
+/* Arithmetic operations */
+mix_word_t
+mix_word_add (mix_word_t x, mix_word_t y)
+{
+ static const gulong MIX_WORD_MAX_SIM = 2*MIX_WORD_MAX + 1;
+
+ gint32 result;
+ if ( mix_word_sign (x) == mix_word_sign (y) )
+ {
+ result = (mix_word_magnitude (x) + mix_word_magnitude (y));
+ if ( result > MIX_WORD_MAX ) {
+ /* for instance MIX_WORD_MAX + 1 = - MIX_WORD_MAX */
+ result = MIX_WORD_MAX_SIM - result;
+ result |= mix_word_sign (mix_word_negative (x));
+ } else if ( result != 0 )
+ result |= mix_word_sign (x);
+ /* keep positive sign for 0 so that w - w == -w + w */
+ }
+ else
+ {
+ result = mix_word_magnitude (x) - mix_word_magnitude (y);
+ if (result < 0)
+ result = -result|mix_word_sign (y);
+ else if (result > 0)
+ result = result|mix_word_sign (x);
+ /* keep positive sign for 0 so that w - w == -w + w */
+ }
+
+ g_assert ( result >= 0 );
+
+ return (mix_word_t)result;
+}
+
+gboolean /* TRUE if overflow */
+mix_word_add_and_carry (mix_word_t x, mix_word_t y,
+ mix_word_t *h, mix_word_t *l)
+{
+ gboolean result;
+
+ if ( mix_word_sign (x) == mix_word_sign (y) )
+ {
+ guint32 sum = (mix_word_magnitude (x) + mix_word_magnitude (y));
+ if ( sum > MIX_WORD_MAX )
+ {
+ result = TRUE;
+ if ( l != NULL )
+ {
+ *l = sum - MIX_WORD_MAX -1;
+ *l |= mix_word_sign (x);
+ }
+ if ( h != NULL )
+ {
+ *h = sum >> 30;
+ *h |= mix_word_sign (x);
+ }
+ }
+ else /* sum <= MIX_WORD_MAX */
+ {
+ result = FALSE;
+ if ( h != NULL ) *h = 0;
+ if ( l != NULL )
+ {
+ *l = sum;
+ if ( sum != 0 )
+ *l |= mix_word_sign (x);
+ /* keep positive sign for 0 so that w - w == -w + w */
+ }
+ }
+ }
+ else /* mix_word_sign (x) != mix_word_sign (y) */
+ {
+ result = FALSE;
+ if ( h != NULL ) *h = 0;
+ if ( l != NULL )
+ {
+ gint32 dif = mix_word_magnitude (x) - mix_word_magnitude (y);
+ if ( dif < 0)
+ *l = (-dif)|mix_word_sign (y);
+ else if ( dif > 0)
+ *l = dif|mix_word_sign (x);
+ else /* keep positive sign for 0 so that w - w == -w + w */
+ *l = MIX_WORD_ZERO;
+ }
+ }
+
+ return result;
+}
+
+
+void
+mix_word_mul (mix_word_t x, mix_word_t y,
+ mix_word_t *high_word, mix_word_t *low_word)
+{
+ guint32 sign = mix_word_sign (x) ^ mix_word_sign (y);
+
+ /*
+ x = x0 + x1 * 2 ^ 10 + x2 * 2 ^ 20
+ y = y0 + y1 * 2 ^ 10 + y2 * 2 ^ 20
+ x0, x1, x2, y0, y1, y2 are < 2 ^ 10
+ */
+ guint32 x0 = (x & 0x000003FF);
+ guint32 x1 = (x & 0x000FFC00) >> 10;
+ guint32 x2 = (x & 0x3FF00000) >> 20;
+ guint32 y0 = (y & 0x000003FF);
+ guint32 y1 = (y & 0x000FFC00) >> 10;
+ guint32 y2 = (y & 0x3FF00000) >> 20;
+
+ /*
+ x * y = partial0 +
+ partial1 * 2 ^ 10 +
+ partial2 * 2 ^ 20 +
+ partial3 * 2 ^ 30 +
+ partial4 * 2 ^ 40
+ partial0 and partial4 are < 2 ^ 20
+ partial1 and partial3 are < 2 ^ 21
+ partial2 is < 3 * 2 ^ 20
+ */
+ guint32 partial0 = x0 * y0;
+ guint32 partial1 = x0 * y1 + x1 * y0;
+ guint32 partial2 = x0 * y2 + x1 * y1 + x2 * y0;
+ guint32 partial3 = x1 * y2 + x2 * y1;
+ guint32 partial4 = x2 * y2;
+
+ /* sum1 has a place value of 1 and is < 2 ^ 32 */
+ guint32 sum1 = partial0 + (partial1 << 10);
+ guint32 carry1 = (sum1 & 0xFFF00000) >> 20;
+
+ /* sum2 has a place value of 2 ^ 20 and is < 2 ^ 32 */
+ guint32 sum2 = partial2 + (partial3 << 10) + carry1;
+ guint32 carry2 = (sum2 & 0xFFF00000) >> 20;
+
+ /* sum3 has a place value of 2 ^ 40 and is < 2 ^ 20 */
+ guint32 sum3 = partial4 + carry2;
+
+ sum1 &= ~0xFFF00000;
+ sum2 &= ~0xFFF00000;
+
+ /*
+ Now paste the three values back into two.
+ */
+ if ( low_word != NULL ) {
+ *low_word = sum1 | ((sum2 & 0x000003FF) << 20);
+ *low_word |= sign;
+ }
+ if ( high_word != NULL ) {
+ *high_word = ((sum2 & 0x000FFC00) >> 10) | (sum3 << 10);
+ *high_word |= sign;
+ }
+}
+
+
+gboolean
+mix_word_div (mix_word_t n1, mix_word_t n0, mix_word_t d,
+ mix_word_t *quotient, mix_word_t *remainder)
+{
+ gboolean overflow = FALSE;
+ long magn1 = mix_word_magnitude (n1);
+ long magd = mix_word_magnitude (d);
+
+ if (magd == 0)
+ {
+ overflow = TRUE;
+ /* just so they have -some- valid value */
+ if ( quotient != NULL ) *quotient = 0;
+ if ( remainder != NULL ) *remainder = 0;
+ }
+ else if (magn1 == 0)
+ { /* special-cased for speed */
+ if ( quotient != NULL )
+ *quotient = (mix_word_sign (n1) ^ mix_word_sign (d))
+ | (mix_word_magnitude (n0) / magd);
+ if ( remainder != NULL )
+ *remainder = mix_word_sign (n1) | (mix_word_magnitude (n0) % magd);
+ }
+ else if (magd <= magn1)
+ {
+ overflow = TRUE;
+ if ( quotient != NULL ) *quotient = 0;
+ if ( remainder != NULL ) *remainder = 0;
+ }
+ else
+ {
+ long q = mix_word_magnitude (n0);
+ long r = magn1;
+ unsigned i;
+ for (i = 30; i != 0; --i) {
+ r <<= 1;
+ if ( (q & (1L << 29)) != 0 )
+ ++r;
+ q = (q << 1) & ((1L << 30) - 1);
+ if (magd <= r)
+ ++q, r -= magd;
+ }
+ if ( quotient != NULL )
+ *quotient = (mix_word_sign (n1) ^ mix_word_sign (d)) | q;
+ if ( remainder != NULL )
+ *remainder = mix_word_sign(n1) | r;
+ }
+ return overflow;
+}
+
+void
+mix_word_shift_right (mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX)
+{
+ if ( pX != NULL ) *pX = mix_word_sign (X);
+ if ( pA != NULL ) *pA = mix_word_sign (A);
+ if (count < 5) {
+ if ( pA != NULL )
+ *pA |= mix_word_magnitude (A) >> (6 * count);
+ if ( pX != NULL )
+ *pX |= MIX_WORD_MAX & ( (mix_word_magnitude (X) >> (6 * count))
+ | (A << (30 - 6 * count)) );
+ } else if (count < 10 && pX != NULL)
+ *pX |= mix_word_magnitude (A) >> (6 * count - 30);
+ else
+ ;
+}
+
+
+void
+mix_word_shift_left (mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX)
+{
+ if ( pX != NULL ) *pX = mix_word_sign (X);
+ if ( pA != NULL ) *pA = mix_word_sign (A);
+ if (count < 5) {
+ if ( pX != NULL ) *pX |= MIX_WORD_MAX & (X << (6 * count));
+ if ( pA != NULL )
+ *pA |= MIX_WORD_MAX & ( (A << (6 * count)) |
+ (mix_word_magnitude (X) >> (30 - 6 * count)) );
+ } else if (count < 10 && pA != NULL)
+ *pA |= MIX_WORD_MAX & (X << (6 * count - 30));
+ else
+ ;
+}
+
+void
+mix_word_shift_left_circular (mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX)
+{
+ mix_word_t A1, X1;
+ guint c;
+
+ count %= 10;
+ A1 = count < 5 ? A : X;
+ X1 = count < 5 ? X : A;
+ c = 6 * (count < 5 ? count : count - 5);
+ if ( pX != NULL )
+ *pX = mix_word_sign (X)
+ | ( MIX_WORD_MAX & (X1 << c) ) | ( mix_word_magnitude (A1) >> (30 - c) );
+ if ( pA != NULL )
+ *pA = mix_word_sign (A)
+ | ( MIX_WORD_MAX & (A1 << c) ) | ( mix_word_magnitude (X1) >> (30 - c) );
+}
+
+void
+mix_word_shift_right_circular (mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX)
+{
+ mix_word_t A1, X1;
+ guint c;
+
+ count %= 10;
+ A1 = count < 5 ? A : X;
+ X1 = count < 5 ? X : A;
+ c = 6 * (count < 5 ? count : count - 5);
+ if ( pX != NULL )
+ *pX = mix_word_sign (X)
+ | ( mix_word_magnitude (X1) >> c ) | ( MIX_WORD_MAX & (A1 << (30 - c)) );
+ if ( pA != NULL )
+ *pA = mix_word_sign (A)
+ | ( mix_word_magnitude (A1) >> c ) | ( MIX_WORD_MAX & (X1 << (30 - c)) );
+}
+
+
+/* Printable representation */
+void
+mix_word_print_to_file (mix_word_t word, const char *message, FILE *f)
+{
+ guint k;
+ if ( message ) fprintf (f, "%s ", message);
+ fprintf (f, "%s ", mix_word_sign (word) == 0 ? "+" : "-");
+ for ( k = 1; k < 6; ++k ) {
+ fprintf (f, "%02d ", mix_word_get_byte (word,k));
+ }
+ fprintf (f, "(%010ld)", mix_word_magnitude (word));
+}
+
+void
+mix_word_print_to_buffer (mix_word_t word, gchar *buf)
+{
+ g_return_if_fail (buf != NULL);
+ sprintf (buf, "%s %02d %02d %02d %02d %02d",
+ mix_word_sign (word) == 0 ? "+" : "-",
+ mix_word_get_byte (word, 1),
+ mix_word_get_byte (word, 2),
+ mix_word_get_byte (word, 3),
+ mix_word_get_byte (word, 4),
+ mix_word_get_byte (word, 5));
+}
+
+/* Conversions between words and shorts */
+mix_short_t
+mix_word_to_short (mix_word_t word)
+{
+ if ( mix_word_is_negative (word) )
+ return ( (word & MIX_SHORT_MAX) | MIX_SHORT_SIGN_BIT );
+ else
+ return (word & MIX_SHORT_MAX);
+}
+
+mix_word_t
+mix_short_to_word (mix_short_t s)
+{
+ if ( mix_short_is_negative (s) )
+ return ((mix_word_t) (mix_short_magnitude (s) | MIX_WORD_SIGN_BIT));
+ else
+ return ((mix_word_t)s);
+}
+
+mix_short_t
+mix_short_add (mix_short_t x, mix_short_t y)
+{
+ static const guint16 MIX_SHORT_MAX_SIM = 2*MIX_SHORT_MAX + 1;
+
+ gint16 result;
+ if ( mix_short_sign (x) == mix_short_sign (y) )
+ {
+ result = (mix_short_magnitude (x) + mix_short_magnitude (y));
+ if ( result > MIX_SHORT_MAX ) {
+ /* for instance MIX_SHORT_MAX + 1 = - MIX_SHORT_MAX */
+ result = MIX_SHORT_MAX_SIM - result;
+ result |= mix_short_sign (mix_short_negative (x));
+ } else if ( result != 0 )
+ result |= mix_short_sign (x);
+ /* keep positive sign for 0 so that w - w == -w + w */
+ }
+ else
+ {
+ result = mix_short_magnitude (x) - mix_short_magnitude (y);
+ if (result < 0)
+ result = -result|mix_short_sign (y);
+ else if (result > 0)
+ result = result|mix_short_sign (x);
+ /* keep positive sign for 0 so that w - w == -w + w */
+ }
+
+ g_assert ( result >= 0 );
+
+ return (mix_short_t)result;
+}
+
+
+/* Printable representation */
+void
+mix_short_print (mix_short_t s, const gchar *message)
+{
+ if ( message ) g_print ("%s ", message);
+ g_print ("%s ", mix_short_sign (s) == 0 ? "+" : "-");
+ g_print ("%02d %02d ", mix_byte_new (s>>6), mix_byte_new (s));
+ g_print ("(%04d)", mix_short_magnitude (s));
+}
+
+void
+mix_short_print_to_buffer (mix_short_t s, gchar *buf)
+{
+ g_return_if_fail (buf != NULL);
+ sprintf (buf, "%s %02d %02d",
+ mix_short_sign (s) == 0 ? "+" : "-",
+ mix_byte_new (s>>6), mix_byte_new (s));
+ /* g_print ("(%04d)", mix_short_magnitude (s));*/
+}
+
+
+
+
diff --git a/mixlib/mix_types.h b/mixlib/mix_types.h
new file mode 100644
index 0000000..c628e05
--- /dev/null
+++ b/mixlib/mix_types.h
@@ -0,0 +1,293 @@
+/* -*-c-*- --------------- mix_types.h:
+ * This file contains declarations for the basic types used in MIX:
+ * mix_byte_t, mix_char_t, mix_short_t and mix_word_t.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_TYPES_H
+#define MIX_TYPES_H
+
+#include <stdio.h>
+#include "mix.h"
+
+/* Initialisation function to be called before using the other
+ * functions in this file
+ */
+extern void
+mix_init_types(void);
+
+
+/*----------------- m_byte_t --------------------------------------------*/
+/* MIX byte type */
+typedef guint8 mix_byte_t;
+
+/* Maximum value stored in an mix_byte_t */
+#define MIX_BYTE_MAX ((1L << 6) - 1)
+
+/* Zero mix byte */
+#define MIX_BYTE_ZERO ((mix_byte_t)0)
+
+/* Create a mix_byte_t from any native type */
+#define mix_byte_new(x) ((mix_byte_t)((x) & MIX_BYTE_MAX ))
+
+/* Operations */
+/* Addition */
+#define mix_byte_add(x,y) mix_byte_new((x) + (y))
+/* Substraction */
+#define mix_byte_sub(x,y) mix_byte_new((x) - (y))
+/* Product */
+#define mix_byte_mul(x,y) mix_byte_new((x) * (y))
+/* Quotient */
+#define mix_byte_div(x,y) mix_byte_new((x) / (y))
+
+
+/*----------------- mix_char_t --------------------------------------------*/
+/* MIX char type: chars are coded in MIX from 0 to MIX_CHAR_MAX */
+typedef guint8 mix_char_t;
+
+#define MIX_CHAR_MAX 55
+
+/* Conversions for mix_char_t's */
+#define mix_char_new(l) (((l) < MIX_CHAR_MAX )? (l) : MIX_CHAR_MAX)
+#define mix_char_to_byte(mchar) mix_byte_new (mchar)
+#define mix_byte_to_char(byte) mix_char_new (byte)
+
+extern mix_char_t
+mix_ascii_to_char(guchar c);
+
+extern guchar
+mix_char_to_ascii(mix_char_t c);
+
+
+/*----------------- mix_word_t --------------------------------------------*/
+/*
+ * Represented as a gint32 (glib ensures that this type has 32
+ * bits). Bit 30 is the sign, higher bits are 0,
+ * and bits 0-29 are the magnitude.
+ * Each MIX 'byte' is a 6-bit substring of the magnitude.
+ */
+typedef guint32 mix_word_t;
+
+/* Maximum value stored in an mix_word_t */
+#define MIX_WORD_MAX ((1L << 30) - 1)
+/* Sign bit in a word */
+#define MIX_WORD_SIGN_BIT (1L << 30)
+/* Zero mix word */
+#define MIX_WORD_ZERO ((mix_word_t)0)
+/* Negative zero mix word */
+#define MIX_WORD_MINUS_ZERO (MIX_WORD_ZERO | MIX_WORD_SIGN_BIT)
+
+
+/* Create a mix_word_t from any native type */
+#define mix_word_new(x) \
+( (x) < 0 \
+ ? ( MIX_WORD_SIGN_BIT | ((mix_word_t)(-(x)) & MIX_WORD_MAX) ) \
+ : ( (mix_word_t)(x) & MIX_WORD_MAX ) \
+)
+
+/* Create a mix_word_t from individual bytes */
+#define mix_word_new_b(b1,b2,b3,b4,b5) \
+((mix_word_t)(mix_byte_new(b5) + (mix_byte_new(b4)<<6) + \
+ (mix_byte_new(b3)<<12) + (mix_byte_new(b2)<<18) + \
+ (mix_byte_new(b1)<<24)))
+
+/* Create a negative mix_word_t from individual bytes */
+#define mix_word_new_bn(b1,b2,b3,b4,b5) \
+ mix_word_negative(mix_word_new_b(b1,b2,b3,b4,b5))
+
+/* Create mix_word_t from an array of mix_byte_t */
+extern mix_word_t
+mix_bytes_to_word(mix_byte_t *bytes, guint byteno);
+
+/* Access byte within a word */
+extern mix_byte_t /* byte -idx- or MIX_BYTE_ZERO if -idx- out of range */
+mix_word_get_byte(mix_word_t word, /* word parsed */
+ guint idx /* byte: 1 to 5 */);
+
+/* Set a byte within a mix_word_t */
+extern void
+mix_word_set_byte(mix_word_t *into, /* word to be modified */
+ guint idx, /* byte: 1 to 5 */
+ mix_byte_t value /* byte's value */);
+
+
+/* Operations */
+/* Sign-related definitions */
+#define mix_word_negative(word) ( (word) ^ MIX_WORD_SIGN_BIT )
+#define mix_word_reverse_sign(word) ( word ^= MIX_WORD_SIGN_BIT )
+#define mix_word_sign(word) ( (word) & MIX_WORD_SIGN_BIT )
+#define mix_word_magnitude(word) ( (word) & (MIX_WORD_SIGN_BIT - 1) )
+#define mix_word_is_positive(word) ( mix_word_sign(word) == 0 )
+#define mix_word_is_negative(word) ( mix_word_sign(word) != 0 )
+
+
+/* Arithmetic operations */
+extern mix_word_t
+mix_word_add(mix_word_t x, mix_word_t y);
+
+#define mix_word_sub(x,y) ( mix_word_add((x),mix_word_negative(y)) )
+
+/* Add two words filling a high word if needed.
+ -high_word- and/or -low_word- can be NULL.
+*/
+extern gboolean /* TRUE if overflow */
+mix_word_add_and_carry(mix_word_t x, mix_word_t y,
+ mix_word_t *high_word, mix_word_t *low_word);
+
+/* Product, stored in -high_word- and -low_word-, which
+ can be NULL.
+*/
+extern void
+mix_word_mul(mix_word_t x, mix_word_t y,
+ mix_word_t *high_word, mix_word_t *low_word);
+
+/* Division. -quotient- and/or -remainder- can be NULL. */
+extern gboolean /* TRUE if overflow */
+mix_word_div(mix_word_t n1, mix_word_t n0, mix_word_t d,
+ mix_word_t *quotient, mix_word_t *remainder);
+
+/* Shift operations */
+extern void
+mix_word_shift_left(mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX);
+extern void
+mix_word_shift_right(mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX);
+extern void
+mix_word_shift_left_circular(mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX);
+extern void
+mix_word_shift_right_circular(mix_word_t A, mix_word_t X, gulong count,
+ mix_word_t *pA, mix_word_t *pX);
+
+
+
+
+/*
+ * Fields within a word: a word containing the (L:R)
+ * bytes of the original one. L and R (with 0 <= L <= R < 6)
+ * are specified by a mix_fspec_t F = 8*L + R.
+ */
+typedef guint8 mix_fspec_t;
+
+#define mix_fspec_left(f) ( ((f)>>3) & 7 )
+#define mix_fspec_right(f) ( (f) & 7 )
+#define mix_fspec_new(L,R) ( mix_byte_new(8*(L) + (R)) )
+
+extern gboolean
+mix_fspec_is_valid(mix_fspec_t f);
+
+extern mix_word_t /* the specified field or 0 if f is not valid */
+mix_word_get_field(mix_fspec_t f, mix_word_t word);
+
+extern mix_word_t /* -to- with the field -f- from -from- or -to-
+ if -f- is not a valid fspec */
+mix_word_set_field(mix_fspec_t f, mix_word_t from, mix_word_t to);
+
+/* set field into a zero word */
+#define mix_word_extract_field(fspec,from_word) \
+ mix_word_set_field(fspec,from_word,MIX_WORD_ZERO)
+
+/* Store operation: the no. of bytes determined by -f- is taken
+ * from the right of -from- and stored into -to- in the location
+ * specified by -f-
+ */
+extern mix_word_t
+mix_word_store_field(mix_fspec_t f, mix_word_t from, mix_word_t to);
+
+
+/* Printable representation */
+#define mix_word_print(word,message) \
+ mix_word_print_to_file (word, message, stdout)
+
+extern void
+mix_word_print_to_file (mix_word_t word, const char *message, FILE *f);
+
+extern void
+mix_word_print_to_buffer (mix_word_t word, gchar *buf);
+
+
+/*----------------- mix_short_t ------------------------------------------*/
+typedef guint16 mix_short_t;
+
+#define MIX_SHORT_MAX ((1L << 12) - 1)
+#define MIX_SHORT_SIGN_BIT ((mix_short_t)(1L << 12))
+#define MIX_SHORT_ZERO ((mix_short_t)0)
+#define MIX_SHORT_MINUS_ZERO (MIX_SHORT_ZERO | MIX_SHORT_SIGN_BIT)
+
+/* Sign-related definitions */
+#define mix_short_negative(s) ( (s) ^ MIX_SHORT_SIGN_BIT )
+#define mix_short_sign(s) ( (s) & MIX_SHORT_SIGN_BIT )
+#define mix_short_magnitude(s) \
+ ( (s) & (MIX_SHORT_SIGN_BIT - 1) )
+#define mix_short_is_positive(s) ( mix_short_sign(s) == 0 )
+#define mix_short_is_negative(s) ( mix_short_sign(s) != 0 )
+#define mix_short_reverse_sign(s) ( (s) ^= MIX_SHORT_SIGN_BIT )
+
+/* create short from a long */
+#define mix_short_new(val) \
+ ((val)>= 0 ? (val)&MIX_SHORT_MAX : mix_short_negative(-(val)))
+
+/* Create shorts from individual bytes */
+#define mix_short_new_b(b1,b2) \
+((mix_short_t)((mix_byte_new(b1)<<6) + mix_byte_new(b2)))
+
+#define mix_short_new_bn(b1,b2) mix_short_negative(mix_short_new_b(b1,b2))
+
+/* Conversions between words and shorts. Arithmetic operations
+ on shorts are not provided but for addition: use words instead.
+*/
+/* Make a short taking word's sign and its two least significant
+ bytes (bytes no. 4 and 5)
+*/
+extern mix_short_t
+mix_word_to_short(mix_word_t word);
+
+extern mix_word_t
+mix_short_to_word(mix_short_t s);
+
+/* fast conversion (these macros' argument are evaluated twice */
+#define mix_word_to_short_fast(w) \
+( mix_word_is_negative(w) ? \
+ ((w) & MIX_SHORT_MAX)|MIX_SHORT_SIGN_BIT : (w)&MIX_SHORT_MAX )
+
+#define mix_short_to_word_fast(s) \
+( mix_short_is_negative(s) ? \
+(mix_word_t) (mix_short_magnitude(s)|MIX_WORD_SIGN_BIT): (mix_word_t)(s) )
+
+
+extern mix_short_t
+mix_short_add(mix_short_t x, mix_short_t y);
+
+
+/* printable representation */
+extern void
+mix_short_print(mix_short_t s, const gchar *message);
+
+extern void
+mix_short_print_to_buffer (mix_short_t s, gchar *buf);
+
+
+
+#endif /* MIX_TYPES_H */
+
+
+
+
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
new file mode 100644
index 0000000..71c8bae
--- /dev/null
+++ b/mixlib/mix_vm.c
@@ -0,0 +1,706 @@
+/* -*-c-*- ------------------ mix_vm.c :
+ * Implementation of the functions declared in mix_vm.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mix.h"
+#include "xmix_vm.h"
+
+#define vm_reset_(vm) vm_reset_reload_ (vm, FALSE);
+
+static void
+vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)
+{
+ guint k;
+ set_status_ (vm, MIX_VM_EMPTY);
+ set_rA_ (vm, MIX_WORD_ZERO);
+ set_rX_ (vm, MIX_WORD_ZERO);
+ set_rJ_ (vm, MIX_WORD_ZERO);
+ for ( k = 1; k < IREG_NO_+1; ++k ) set_rI_ (vm, k, MIX_WORD_ZERO);
+ set_over_ (vm, FALSE);
+ set_cmp_ (vm, mix_EQ);
+ set_loc_ (vm, MIX_WORD_ZERO);
+ set_last_error_ (vm, MIX_VM_ERROR_NONE);
+ for ( k = 0; k < MEM_CELLS_NO_; ++k) set_cell_ (vm, k, MIX_WORD_ZERO);
+
+ if (vm->symbol_table != NULL )
+ {
+ mix_symbol_table_delete (vm->symbol_table);
+ vm->symbol_table = NULL;
+ }
+
+ if (vm->line_table != NULL)
+ {
+ g_tree_destroy (vm->line_table);
+ vm->line_table = NULL;
+ }
+
+ if (vm->address_table != NULL)
+ {
+ g_tree_destroy (vm->address_table);
+ vm->address_table = NULL;
+ }
+
+ if (vm->src_file != NULL)
+ {
+ mix_src_file_delete (vm->src_file);
+ vm->src_file = NULL;
+ }
+
+ for (k = 0; k < BD_NO_; ++k)
+ if (vm->devices[k] != NULL)
+ {
+ mix_device_type_t type = mix_device_type (vm->devices[k]);
+ if (!is_reload || (type != mix_dev_CONSOLE
+ && type != mix_dev_PRINTER
+ && type != mix_dev_CARD_WR))
+ {
+ mix_device_delete (vm->devices[k]);
+ vm->devices[k] = NULL;
+ }
+ }
+
+ if (!is_reload)
+ mix_vm_clear_all_breakpoints (vm);
+
+ if (vm->address_list)
+ {
+ g_slist_free (vm->address_list);
+ vm->address_list = NULL;
+ }
+}
+
+
+/* Create/destroy a mix vm */
+mix_vm_t *
+mix_vm_new (void)
+{
+ int i;
+
+ mix_vm_t *vm = g_new (struct mix_vm_t,1);
+ vm->line_table = NULL;
+ vm->address_table = NULL;
+ vm->symbol_table = NULL;
+ vm->src_file = NULL;
+ vm->pred_list = mix_predicate_list_new (vm);
+ vm->address_list = NULL;
+ vm->last_error = MIX_VM_ERROR_NONE;
+
+ for (i = 0; i < BD_NO_; ++i)
+ vm->devices[i] = NULL;
+
+ vm->clock = mix_vm_clock_new ();
+ vm->factory = mix_device_new;
+
+ vm_reset_ (vm);
+
+ return vm;
+}
+
+
+void
+mix_vm_delete (mix_vm_t * vm)
+{
+ int i;
+
+ g_return_if_fail (vm != NULL);
+
+ if (vm->line_table != NULL) g_tree_destroy (vm->line_table);
+ if (vm->address_table != NULL) g_tree_destroy (vm->address_table);
+ if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table);
+ if (vm->src_file != NULL) mix_src_file_delete (vm->src_file);
+ if (vm->pred_list != NULL) mix_predicate_list_delete (vm->pred_list);
+ if (vm->address_list != NULL) g_slist_free (vm->address_list);
+ for (i = 0; i < BD_NO_; ++i)
+ mix_device_delete (vm->devices[i]);
+ mix_vm_clock_delete (vm->clock);
+ g_free (vm);
+}
+
+/* connect devices to a virtual machine */
+mix_device_t *
+mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device)
+{
+ mix_device_t *old;
+ mix_device_type_t type;
+
+ g_return_val_if_fail (vm != NULL, NULL);
+ g_return_val_if_fail (device != NULL, NULL);
+
+ type = mix_device_type (device);
+ old = vm->devices[type];
+ vm->devices[type] = device;
+
+ return old;
+}
+
+/* get device */
+mix_device_t *
+mix_vm_get_device (const mix_vm_t *vm, mix_device_type_t dev)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ g_return_val_if_fail (dev < mix_dev_INVALID, NULL);
+ return vm->devices[dev];
+}
+
+/* install a device factory for automatic connection */
+void
+mix_vm_set_device_factory (mix_vm_t *vm, mix_device_factory_t factory)
+{
+ g_return_if_fail (vm != NULL);
+ g_return_if_fail (factory != NULL);
+ vm->factory = factory;
+}
+
+/* Reset a vm (set state as of a newly created one) */
+void
+mix_vm_reset (mix_vm_t * vm)
+{
+ g_return_if_fail (vm != NULL);
+ vm_reset_ (vm);
+}
+
+/* Set start address for execution */
+void
+mix_vm_set_start_addr (mix_vm_t *vm, mix_address_t addr)
+{
+ g_return_if_fail (vm != NULL);
+ set_loc_ (vm, addr);
+}
+
+/* Access to the vm's registers */
+mix_word_t
+mix_vm_get_rA (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO);
+ return get_rA_ (vm);
+}
+
+mix_word_t
+mix_vm_get_rX (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO);
+ return get_rX_ (vm);
+}
+
+mix_short_t
+mix_vm_get_rJ (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_SHORT_ZERO);
+ return mix_word_to_short_fast (get_rJ_ (vm));
+}
+
+mix_short_t
+mix_vm_get_rI (const mix_vm_t *vm, guint idx)
+{
+ g_return_val_if_fail (vm != NULL, MIX_SHORT_ZERO);
+ g_return_val_if_fail (IOK_ (idx), MIX_SHORT_ZERO);
+ return mix_word_to_short_fast (get_rI_ (vm, idx));
+}
+
+void
+mix_vm_set_rA (mix_vm_t *vm, mix_word_t value)
+{
+ g_return_if_fail (vm != NULL);
+ set_rA_ (vm, value);
+}
+
+void
+mix_vm_set_rX (mix_vm_t *vm, mix_word_t value)
+{
+ g_return_if_fail (vm != NULL);
+ set_rX_ (vm, value);
+}
+
+void
+mix_vm_set_rJ (mix_vm_t *vm, mix_short_t value)
+{
+ g_return_if_fail (vm != NULL);
+ g_return_if_fail (mix_short_is_positive (value));
+ set_rJ_ (vm, mix_short_to_word_fast (value));
+}
+
+void
+mix_vm_set_rI (mix_vm_t *vm, guint idx, mix_short_t value)
+{
+ g_return_if_fail (vm != NULL);
+ g_return_if_fail (IOK_ (idx));
+ set_rI_ (vm, idx, mix_short_to_word_fast (value));
+}
+
+/* Access to the comparison flag and overflow toggle */
+mix_cmpflag_t
+mix_vm_get_cmpflag (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, mix_EQ);
+ return get_cmp_ (vm);
+}
+
+void
+mix_vm_set_cmpflag (mix_vm_t *vm, mix_cmpflag_t value)
+{
+ g_return_if_fail (vm != NULL);
+ set_cmp_ (vm, value);
+}
+
+gboolean
+mix_vm_get_overflow (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, TRUE);
+ return get_over_ (vm);
+}
+
+void
+mix_vm_set_overflow (mix_vm_t *vm, gboolean value)
+{
+ g_return_if_fail (vm != NULL);
+ set_over_ (vm, value);
+}
+
+void
+mix_vm_toggle_overflow (mix_vm_t *vm)
+{
+ g_return_if_fail (vm != NULL);
+ set_over_ (vm, !get_over_ (vm));
+}
+
+/* Access to memory cells */
+mix_word_t
+mix_vm_get_addr_contents (const mix_vm_t *vm, mix_address_t addr)
+{
+ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO);
+ return (MEMOK_ (addr))? get_cell_ (vm, addr) : MIX_WORD_ZERO;
+}
+
+void
+mix_vm_set_addr_contents (mix_vm_t *vm, mix_address_t addr, mix_word_t value)
+{
+ g_return_if_fail (vm != NULL);
+ if (MEMOK_ (addr)) set_cell_ (vm, addr, value);
+}
+
+gboolean
+mix_vm_is_halted (const mix_vm_t *vm)
+{
+ return is_halted_ (vm);
+}
+
+/* Execution of instructions */
+gboolean /* TRUE if success */
+mix_vm_exec_ins (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_return_val_if_fail (vm != NULL, FALSE);
+ g_return_val_if_fail (ins != NULL, FALSE);
+ return (*ins_handlers_[ins->opcode]) (vm,ins);
+}
+
+/* comparison function for the line and address tables tree */
+static gint
+cmp_uint_ (gconstpointer a, gconstpointer b)
+{
+ return GPOINTER_TO_UINT (a) - GPOINTER_TO_UINT (b);
+}
+
+gboolean
+mix_vm_load_file (mix_vm_t *vm, const gchar *name)
+{
+ mix_code_file_t *file;
+ mix_src_file_t *sfile = NULL;
+ mix_ins_desc_t ins;
+ const gchar *sp;
+ gboolean reload = FALSE;
+
+ g_return_val_if_fail (vm != NULL, FALSE);
+ file = mix_code_file_new_read (name);
+ if (file == NULL)
+ {
+ set_status_ (vm, MIX_VM_ERROR);
+ return FALSE;
+ }
+ sp = mix_code_file_get_source_path (file);
+
+ if (sp != NULL)
+ {
+ sfile = mix_src_file_new_for_read (sp);
+ reload = (vm->src_file
+ && !strcmp (mix_src_file_get_path (vm->src_file),
+ mix_src_file_get_path (sfile)));
+ }
+
+ vm_reset_reload_ (vm, reload);
+
+ if ( mix_code_file_is_debug (file) )
+ {
+ vm->symbol_table = mix_code_file_get_symbol_table (file);
+ vm->line_table = g_tree_new (cmp_uint_);
+ vm->address_table = g_tree_new (cmp_uint_);
+ }
+
+ vm->src_file = sfile;
+
+ while ( mix_code_file_get_ins (file, &ins) )
+ {
+ set_cell_ (vm, ins.address, ins.ins);
+ if ( vm->line_table != NULL )
+ {
+ g_tree_insert (vm->line_table,
+ GUINT_TO_POINTER (ins.lineno),
+ GUINT_TO_POINTER ((guint)ins.address));
+ g_tree_insert (vm->address_table,
+ GUINT_TO_POINTER ((guint)ins.address),
+ GUINT_TO_POINTER (ins.lineno));
+ }
+ }
+ set_loc_ (vm, mix_code_file_get_start_addr (file));
+ set_start_ (vm, get_loc_ (vm));
+ mix_code_file_delete (file);
+
+ set_status_ (vm, MIX_VM_LOADED);
+ return TRUE;
+}
+
+const mix_src_file_t *
+mix_vm_get_src_file (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ return vm->src_file;
+}
+
+const mix_symbol_table_t *
+mix_vm_get_symbol_table (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ return vm->symbol_table;
+}
+
+mix_address_t
+mix_vm_get_prog_count (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_SHORT_ZERO);
+ return get_loc_ (vm);
+}
+
+/* Get the source line number for a given address */
+guint
+mix_vm_get_address_lineno (const mix_vm_t *vm, mix_address_t addr)
+{
+ gpointer gp_addr = GUINT_TO_POINTER ((guint)addr);
+ guint lineno;
+
+ g_return_val_if_fail (vm != NULL, 0);
+ if (!(MEMOK_ (addr))) return 0;
+ lineno = GPOINTER_TO_UINT (g_tree_lookup (vm->address_table, gp_addr));
+ return lineno;
+}
+
+/* Get the address for a given source line number */
+typedef struct
+{
+ guint lineno;
+ mix_address_t result;
+} addr_traverse_t;
+
+static gint
+get_address_ (gpointer key, gpointer value, gpointer data)
+{
+ addr_traverse_t *tr = (addr_traverse_t *)data;
+ if (GPOINTER_TO_UINT (key) == tr->lineno)
+ {
+ tr->result = mix_short_new (GPOINTER_TO_UINT (value));
+ return TRUE;
+ }
+ return (GPOINTER_TO_UINT (key) < tr->lineno)? FALSE:TRUE;
+}
+
+mix_address_t
+mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno)
+{
+ addr_traverse_t tr;
+
+ g_return_val_if_fail (vm != NULL, MIX_VM_CELL_NO);
+ if (!vm->line_table) return MIX_VM_CELL_NO;
+ tr.lineno = lineno;
+ tr.result = MIX_VM_CELL_NO;
+ g_tree_foreach (vm->line_table, get_address_, (gpointer)&tr);
+ return tr.result;
+}
+
+
+/* continue execution of instructions in memory */
+mix_vm_status_t
+mix_vm_run (mix_vm_t *vm)
+{
+ mix_ins_t ins;
+ g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
+
+ while ( !is_halted_ (vm) )
+ {
+ mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins);
+ vm->address_list =
+ g_slist_prepend (vm->address_list,
+ GINT_TO_POINTER ((gint)get_loc_ (vm)));
+ if ( !(*ins_handlers_[ins.opcode]) (vm,&ins) )
+ return set_status_ (vm, MIX_VM_ERROR);
+ else
+ update_time_ (vm, &ins);
+ if (bp_is_set_ (vm, get_loc_ (vm)))
+ return set_status_ (vm, MIX_VM_BREAK);
+ if (mix_predicate_list_eval (get_pred_list_ (vm)))
+ return set_status_ (vm, MIX_VM_COND_BREAK);
+ if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
+ }
+ return set_status_ (vm, MIX_VM_HALT);
+}
+
+/* execute next memory instruction */
+mix_vm_status_t
+mix_vm_exec_next (mix_vm_t *vm)
+{
+ mix_ins_t ins;
+ g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
+ if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
+ if (is_halted_ (vm)) return set_status_ (vm, MIX_VM_HALT);
+ vm->address_list =
+ g_slist_prepend (vm->address_list,
+ GINT_TO_POINTER ((gint)get_loc_ (vm)));
+ mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins);
+ if (!(*ins_handlers_[ins.opcode]) (vm, &ins))
+ return set_status_ (vm, MIX_VM_ERROR);
+ else
+ update_time_ (vm, &ins);
+ if (is_halted_ (vm)) return set_status_ (vm, MIX_VM_HALT);
+ if (bp_is_set_ (vm, get_loc_ (vm))) return set_status_ (vm, MIX_VM_BREAK);
+ if (mix_predicate_list_eval (get_pred_list_ (vm)))
+ return set_status_ (vm, MIX_VM_COND_BREAK);
+ return set_status_ (vm, MIX_VM_RUNNING);
+}
+
+/* get the current execution status */
+mix_vm_status_t
+mix_vm_get_run_status (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
+ return get_status_ (vm);
+}
+
+mix_vm_error_t
+mix_vm_get_last_error (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_ERROR_UNEXPECTED);
+ return get_last_error_ (vm);
+}
+
+const gchar *
+mix_vm_get_last_error_string (const mix_vm_t *vm)
+{
+ return mix_vm_get_error_string (mix_vm_get_last_error (vm));
+}
+
+const gchar *
+mix_vm_get_error_string (mix_vm_error_t code)
+{
+ static const gchar *errors[] = {
+ N_("No error"),
+ N_("Invalid memory address"),
+ N_("Invalid device number"),
+ N_("Invalid fspec"),
+ N_("Invalid M-value"),
+ N_("Cannot access device"),
+ N_("Cannot access device for reading"),
+ N_("Cannot access device for writing"),
+ N_("Unexpected error"),
+ N_("Unknow error code")
+ };
+
+ return errors[(code < 0 || code > MIX_VM_ERROR_UNEXPECTED)
+ ? MIX_VM_ERROR_UNEXPECTED + 1 : code];
+}
+
+/* Breakpoints */
+gulong
+mix_vm_get_break_lineno (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, 0);
+ if (vm->address_table == NULL)
+ return 0;
+ else
+ {
+ gpointer loc = GUINT_TO_POINTER ((guint)get_loc_ (vm));
+ return GPOINTER_TO_UINT (g_tree_lookup (vm->address_table,loc));
+ }
+}
+
+typedef struct
+{
+ mix_vm_t *vm;
+ guint lineno;
+ gint result;
+} bp_traverse_t;
+
+static gint
+set_break_ (gpointer key, gpointer value, gpointer data)
+{
+ bp_traverse_t *tr = (bp_traverse_t *)data;
+ if (GPOINTER_TO_UINT (key) >= tr->lineno)
+ {
+ bp_set_ (tr->vm, mix_short_new (GPOINTER_TO_UINT (value)));
+ tr->lineno = GPOINTER_TO_UINT (key);
+ tr->result = MIX_VM_BP_OK;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gint /* if >0 the line no. of the break point */
+mix_vm_set_breakpoint (mix_vm_t *vm, guint lineno)
+{
+ bp_traverse_t tr;
+
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ if (!vm->line_table) return MIX_VM_BP_NDEBUG;
+ tr.lineno = lineno;
+ tr.vm = vm;
+ tr.result = MIX_VM_BP_INV_LINE;
+ g_tree_foreach (vm->line_table, set_break_, (gpointer)&tr);
+ if (tr.result == MIX_VM_BP_OK)
+ return tr.lineno;
+ else
+ return tr.result;
+}
+
+gint
+mix_vm_set_breakpoint_address (mix_vm_t *vm, guint address)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ if (address >= MIX_VM_CELL_NO)
+ return MIX_VM_BP_INV_ADDRESS;
+ else
+ bp_set_ (vm, mix_short_new (address));
+ return MIX_VM_BP_OK;
+}
+
+gboolean
+mix_vm_has_breakpoint_at_address (const mix_vm_t *vm, guint address)
+{
+ g_return_val_if_fail (vm != NULL, FALSE);
+ if (address >= MIX_VM_CELL_NO) return FALSE;
+ return (bp_is_set_ (vm, address));
+}
+
+static gint
+clear_break_ (gpointer key, gpointer value, gpointer data)
+{
+ bp_traverse_t *tr = (bp_traverse_t *)data;
+ if (GPOINTER_TO_UINT (key) == tr->lineno)
+ {
+ bp_clear_ (tr->vm, mix_short_new (GPOINTER_TO_UINT (value)));
+ tr->result = MIX_VM_BP_OK;
+ return TRUE;
+ }
+ else if (GPOINTER_TO_UINT (key) > tr->lineno)
+ return TRUE;
+
+ return FALSE;
+}
+
+gint /* one of MIX_VM_BP_ */
+mix_vm_clear_breakpoint (mix_vm_t *vm, guint lineno)
+{
+ bp_traverse_t tr;
+
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ if (!vm->line_table) return MIX_VM_BP_NDEBUG;
+ tr.lineno = lineno;
+ tr.vm = vm;
+ tr.result = MIX_VM_BP_INV_LINE;
+ g_tree_foreach (vm->line_table, clear_break_, (gpointer)&tr);
+ return tr.result;
+}
+
+gint
+mix_vm_clear_breakpoint_address (mix_vm_t *vm, guint address)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ if (address >= MIX_VM_CELL_NO)
+ return MIX_VM_BP_INV_ADDRESS;
+ else
+ bp_clear_ (vm, mix_short_new (address));
+ return MIX_VM_BP_OK;
+}
+
+void
+mix_vm_clear_all_breakpoints (mix_vm_t *vm)
+{
+ g_return_if_fail (vm != NULL);
+ bp_clear_all_ (vm);
+ mix_predicate_list_clear (get_pred_list_ (vm));
+}
+
+
+gboolean
+mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred)
+{
+ g_return_val_if_fail (vm != NULL, FALSE);
+ g_return_val_if_fail (pred != NULL, FALSE);
+ mix_predicate_list_add (get_pred_list_ (vm), pred);
+ return TRUE;
+}
+
+gboolean
+mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred)
+{
+ g_return_val_if_fail (vm != NULL, FALSE);
+ g_return_val_if_fail (pred != NULL, FALSE);
+ return mix_predicate_list_remove (get_pred_list_ (vm), pred);
+}
+
+const gchar *
+mix_vm_get_last_breakpoint_message (const mix_vm_t *vm)
+{
+ const mix_predicate_t *last = NULL;
+ g_return_val_if_fail (vm != NULL, NULL);
+ if ((last = mix_predicate_list_last_true_eval (get_pred_list_ (vm))) != NULL)
+ return mix_predicate_get_message (last);
+ return NULL;
+}
+
+mix_predicate_type_t
+mix_vm_get_last_conditional_breakpoint_type (const mix_vm_t *vm)
+{
+ const mix_predicate_t *last = NULL;
+ g_return_val_if_fail (vm != NULL, MIX_PRED_INVALID);
+ last = mix_predicate_list_last_true_eval (get_pred_list_ (vm));
+ return last? mix_predicate_get_type (last) : MIX_PRED_INVALID;
+}
+
+/* Get the vm uptime, defined as the time spent executing instructions */
+mix_time_t
+mix_vm_get_uptime (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, 0);
+ return mix_vm_clock_get_time (get_clock_ (vm));
+}
+
+/* Get the list of addresses for executed instructions */
+const GSList *
+mix_vm_get_backtrace (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ return get_address_list_ (vm);
+}
diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h
new file mode 100644
index 0000000..12b082a
--- /dev/null
+++ b/mixlib/mix_vm.h
@@ -0,0 +1,255 @@
+/* ---------------------- mix_vm.h :
+ * Types and functions implementing the MIX virtual machine
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_VM_H
+#define MIX_VM_H
+
+#include "mix_types.h"
+#include "mix_ins.h"
+#include "mix_device.h"
+#include "mix_code_file.h"
+#include "mix_src_file.h"
+#include "mix_symbol_table.h"
+#include "mix_vm_clock.h"
+
+/* Comparison flag */
+typedef enum { mix_LESS, mix_EQ, mix_GREAT } mix_cmpflag_t;
+
+/* Number of memory cells in the virtual machine */
+enum { MIX_VM_CELL_NO = 4000 };
+
+/* Opaque type for the mix virtual machine */
+typedef struct mix_vm_t mix_vm_t;
+
+/* Create/destroy a mix vm */
+extern mix_vm_t *
+mix_vm_new(void);
+
+extern void
+mix_vm_delete(mix_vm_t * vm);
+
+/* connect devices to a virtual machine */
+extern mix_device_t * /* previously connected device */
+mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device);
+
+/* get device */
+extern mix_device_t *
+mix_vm_get_device (const mix_vm_t *vm, mix_device_type_t dev);
+
+/* install a device factory for automatic connection */
+typedef mix_device_t * (* mix_device_factory_t) (mix_device_type_t device);
+extern void
+mix_vm_set_device_factory (mix_vm_t *vm, mix_device_factory_t factory);
+
+/* Reset a vm (set state as of a newly created one) */
+extern void
+mix_vm_reset(mix_vm_t * vm);
+
+/* Set start address for execution */
+extern void
+mix_vm_set_start_addr(mix_vm_t *vm, mix_address_t addr);
+
+/* Access to the vm's registers */
+extern mix_word_t
+mix_vm_get_rA(const mix_vm_t *vm);
+
+extern mix_word_t
+mix_vm_get_rX(const mix_vm_t *vm);
+
+extern mix_short_t
+mix_vm_get_rJ(const mix_vm_t *vm);
+
+extern mix_short_t
+mix_vm_get_rI(const mix_vm_t *vm, guint idx);
+
+extern void
+mix_vm_set_rA(mix_vm_t *vm, mix_word_t value);
+
+extern void
+mix_vm_set_rX(mix_vm_t *vm, mix_word_t value);
+
+extern void
+mix_vm_set_rJ(mix_vm_t *vm, mix_short_t value);
+
+extern void
+mix_vm_set_rI(mix_vm_t *vm, guint idx, mix_short_t value);
+
+/* Access to the comparison flag and overflow toggle */
+extern mix_cmpflag_t
+mix_vm_get_cmpflag(const mix_vm_t *vm);
+
+extern void
+mix_vm_set_cmpflag(mix_vm_t *vm, mix_cmpflag_t value);
+
+extern gboolean
+mix_vm_get_overflow(const mix_vm_t *vm);
+
+extern void
+mix_vm_set_overflow(mix_vm_t *vm, gboolean value);
+
+extern void
+mix_vm_toggle_overflow(mix_vm_t *vm);
+
+extern gboolean
+mix_vm_is_halted(const mix_vm_t *vm);
+
+/* Access to memory cells */
+extern mix_word_t
+mix_vm_get_addr_contents(const mix_vm_t *vm, mix_address_t addr);
+
+extern void
+mix_vm_set_addr_contents(mix_vm_t *vm, mix_address_t addr, mix_word_t value);
+
+/* Execution of instructions and programs */
+extern gboolean /* TRUE if success */
+mix_vm_exec_ins(mix_vm_t *vm, const mix_ins_t *ins);
+
+/* Load a code file into memory (-name- does not need the default extension)
+ * resetting the vm's state
+ */
+extern gboolean
+mix_vm_load_file(mix_vm_t *vm, const gchar *name);
+
+/* Get the source file object corresponding to the last loaded code file */
+extern const mix_src_file_t *
+mix_vm_get_src_file (const mix_vm_t *vm);
+
+/* Get symbol table of loaded file */
+extern const mix_symbol_table_t *
+mix_vm_get_symbol_table (const mix_vm_t *vm);
+
+/* Get current program counter */
+extern mix_address_t
+mix_vm_get_prog_count (const mix_vm_t *vm);
+
+/* Get the source line number for a given address */
+extern guint
+mix_vm_get_address_lineno (const mix_vm_t *vm, mix_address_t addr);
+
+/* Get the address for a given source line number */
+extern mix_address_t
+mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno);
+
+/* continue execution of instructions in memory */
+/* Possible outcomes */
+typedef enum {
+ MIX_VM_ERROR, /* error executing instructions */
+ MIX_VM_BREAK, /* breakpoint found */
+ MIX_VM_COND_BREAK, /* conditional breakpoint found */
+ MIX_VM_HALT, /* end of execution */
+ MIX_VM_RUNNING, /* successful instruction execution */
+ MIX_VM_LOADED, /* program loaded */
+ MIX_VM_EMPTY /* no program loaded */
+} mix_vm_status_t;
+
+/* execution errors */
+typedef enum {
+ MIX_VM_ERROR_NONE, /* no error */
+ MIX_VM_ERROR_BAD_ACCESS, /* bad memory address */
+ MIX_VM_ERROR_BAD_DEVICE_NO, /* bad device number */
+ MIX_VM_ERROR_BAD_FSPEC, /* invalid fspec */
+ MIX_VM_ERROR_BAD_M, /* invalid M-value */
+ MIX_VM_ERROR_DEV_CTL, /* error accessing device for ioctl */
+ MIX_VM_ERROR_DEV_READ, /* error accessing device for reading */
+ MIX_VM_ERROR_DEV_WRITE, /* error accessing device for writing */
+ MIX_VM_ERROR_UNEXPECTED /* unexpected error */
+} mix_vm_error_t;
+
+extern mix_vm_error_t
+mix_vm_get_last_error (const mix_vm_t *vm);
+
+extern const gchar *
+mix_vm_get_last_error_string (const mix_vm_t *vm);
+
+extern const gchar *
+mix_vm_get_error_string (mix_vm_error_t code);
+
+/* run until next breakpoint or end of execution */
+extern mix_vm_status_t
+mix_vm_run (mix_vm_t *vm);
+
+/* execute next memory instruction */
+extern mix_vm_status_t
+mix_vm_exec_next (mix_vm_t *vm);
+
+/* get the current execution status */
+extern mix_vm_status_t
+mix_vm_get_run_status (const mix_vm_t *vm);
+
+/* get the line no. of the last break or 0 if not found */
+extern gulong
+mix_vm_get_break_lineno (const mix_vm_t *vm);
+
+
+/* Breakpoints */
+/* possible error outcomes */
+enum {
+ MIX_VM_BP_ERROR = -4, /* internal error */
+ MIX_VM_BP_NDEBUG = -3, /* no debug info */
+ MIX_VM_BP_INV_ADDRESS = -2, /* address out of range */
+ MIX_VM_BP_INV_LINE = -1, /* invalid line no. */
+ MIX_VM_BP_OK = 0 /* success */
+};
+
+
+extern gint /* if >0 the line no. of the break point */
+mix_vm_set_breakpoint (mix_vm_t *vm, guint lineno);
+
+extern gint /* one of MIX_VM_BP_ */
+mix_vm_set_breakpoint_address (mix_vm_t *vm, guint address);
+
+extern gint /* one of MIX_VM_BP_ */
+mix_vm_clear_breakpoint (mix_vm_t *vm, guint lineno);
+
+extern gint /* one of MIX_VM_BP_ */
+mix_vm_clear_breakpoint_address (mix_vm_t *vm, guint address) ;
+
+extern gboolean
+mix_vm_has_breakpoint_at_address (const mix_vm_t *vm, guint address);
+
+extern void
+mix_vm_clear_all_breakpoints (mix_vm_t *vm);
+
+#include "mix_predicate.h"
+extern gboolean
+mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred);
+
+extern gboolean
+mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred);
+
+extern const gchar *
+mix_vm_get_last_breakpoint_message (const mix_vm_t *vm);
+
+extern mix_predicate_type_t
+mix_vm_get_last_conditional_breakpoint_type (const mix_vm_t *vm);
+
+/* Get the vm uptime, defined as the time spent executing instructions */
+extern mix_time_t
+mix_vm_get_uptime (const mix_vm_t *vm);
+
+/* Get the list of addresses for executed instructions */
+extern const GSList *
+mix_vm_get_backtrace (const mix_vm_t *vm);
+
+
+#endif /* MIX_VM_H */
+
diff --git a/mixlib/mix_vm_clock.c b/mixlib/mix_vm_clock.c
new file mode 100644
index 0000000..cc39992
--- /dev/null
+++ b/mixlib/mix_vm_clock.c
@@ -0,0 +1,70 @@
+/* -*-c-*- -------------- mix_vm_clock.c :
+ * Implementation of the functions declared in mix_vm_clock.h
+ * ------------------------------------------------------------------
+ * $Id: mix_vm_clock.c,v 1.3 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "mix_vm_clock.h"
+
+static const mix_time_t exec_times_[] = {
+ 1, 2, 2, 10, 12, 10, 2, 1,
+ 2, 2, 2, 2 , 2, 2, 2, 2,
+ 2, 2, 2, 2 , 2, 2, 2, 2,
+ 2, 2, 2, 2 , 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2 , 2, 2, 2, 2
+};
+
+
+/* Create/delete a clock */
+mix_vm_clock_t *
+mix_vm_clock_new ()
+{
+ mix_vm_clock_t *result = g_new (mix_vm_clock_t, 1);
+ result->time = 0;
+ return result;
+}
+
+void
+mix_vm_clock_delete (mix_vm_clock_t *clock)
+{
+ g_return_if_fail (clock != NULL);
+}
+
+/* Increase time with the units needed to execute ins */
+mix_time_t
+mix_vm_clock_add_lapse (mix_vm_clock_t *clock, const mix_ins_t *ins)
+{
+ mix_time_t t = 0;
+ g_return_val_if_fail (clock != NULL, 0);
+ if (ins != NULL)
+ {
+ t = exec_times_[ins->opcode];
+ if (ins->opcode == mix_opMOVE) {
+ t += 2 * (ins->fspec);
+ }
+ }
+ clock->time += t;
+ return t;
+}
+
diff --git a/mixlib/mix_vm_clock.h b/mixlib/mix_vm_clock.h
new file mode 100644
index 0000000..3c19973
--- /dev/null
+++ b/mixlib/mix_vm_clock.h
@@ -0,0 +1,55 @@
+/* -*-c-*- ---------------- mix_vm_clock.h :
+ * Declaration of mix_vm_clock_t, a clock for the MIX virtual machine.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/02/20 00:23:58 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_VM_CLOCK_H
+#define MIX_VM_CLOCK_H
+
+#include "mix.h"
+#include "mix_ins.h"
+
+/* the type of time unit */
+typedef gulong mix_time_t;
+
+/* the clock type */
+typedef struct mix_vm_clock_t
+{
+ mix_time_t time;
+} mix_vm_clock_t;
+
+/* Create/delete a clock */
+extern mix_vm_clock_t *
+mix_vm_clock_new ();
+
+extern void
+mix_vm_clock_delete (mix_vm_clock_t *clock);
+
+/* Increase time with the units needed to execute ins */
+extern mix_time_t /* the added lapse */
+mix_vm_clock_add_lapse (mix_vm_clock_t *clock, const mix_ins_t *ins);
+
+/* Get the time since creation */
+#define mix_vm_clock_get_time(clock) (clock? clock->time:0)
+
+#endif /* MIX_VM_CLOCK_H */
+
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c
new file mode 100644
index 0000000..350dae5
--- /dev/null
+++ b/mixlib/mix_vm_command.c
@@ -0,0 +1,641 @@
+/* -*-c-*- -------------- mix_vm_command.c :
+ * Implementation of the functions declared in mix_vm_command.h
+ * ------------------------------------------------------------------
+ * $Id: mix_vm_command.c,v 1.30 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "xmix_vm_command.h"
+#include "xmix_vm_handlers.h"
+
+#ifdef HAVE_LIBHISTORY
+# include <readline/history.h>
+#endif
+
+#ifdef HAVE_LIBREADLINE
+# include <readline/readline.h>
+#endif
+
+/* hook execution */
+static void
+exec_hook_list_ (GSList *list, mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ while (list)
+ {
+ hook_ *hook = (hook_ *)list->data;
+ if (hook)
+ (hook->func)(dis, arg, hook->data);
+ list = list->next;
+ }
+}
+
+static void
+exec_global_hook_list_ (GSList *list,
+ mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd, const gchar *arg)
+{
+ while (list)
+ {
+ global_hook_ *hook = (global_hook_ *)list->data;
+ if (hook)
+ (hook->func)(dis, cmd, arg, hook->data);
+ list = list->next;
+ }
+}
+
+/* conversion from/to commands to strings */
+const gchar *
+mix_vm_command_to_string (mix_vm_command_t cmd)
+{
+ if (cmd < MIX_CMD_INVALID) return commands_[cmd].name;
+ else return NULL;
+}
+
+mix_vm_command_t
+mix_vm_command_from_string (const gchar *name)
+{
+ gint cmd = 0;
+ while (cmd < MIX_CMD_INVALID && strcmp (name, commands_[cmd].name))
+ ++cmd;
+ return cmd;
+}
+
+/* get help string about a command */
+const gchar *
+mix_vm_command_help (mix_vm_command_t cmd)
+{
+ if (cmd < MIX_CMD_INVALID) return commands_[cmd].doc;
+ else return NULL;
+}
+
+const gchar *
+mix_vm_command_usage (mix_vm_command_t cmd)
+{
+ if (cmd < MIX_CMD_INVALID) return commands_[cmd].usage;
+ else return NULL;
+}
+
+/* create a new command dispatcher */
+static GCompletion *
+make_completions_ (void)
+{
+ GList *cmds = NULL;
+ gint k;
+
+ GCompletion *completions = g_completion_new (NULL);
+ for (k = 0; k < MIX_CMD_INVALID; ++k)
+ cmds = g_list_append (cmds, (gpointer) mix_vm_command_to_string (k));
+ g_completion_add_items (completions, cmds);
+ return completions;
+}
+
+mix_vm_cmd_dispatcher_t *
+mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */
+ FILE *err_fd /* error messages file */)
+{
+ mix_vm_cmd_dispatcher_t *result = NULL;
+ int k;
+
+ /* g_return_val_if_fail (out_fd && err_fd, NULL); */
+
+ result = g_new (mix_vm_cmd_dispatcher_t, 1);
+ result->result = TRUE;
+ result->out = out_fd;
+ result->err = err_fd;
+ result->log_msg = TRUE;
+ result->uptime = result->laptime = result->progtime = 0;
+ result->printtime = TRUE;
+ result->trace = FALSE;
+ result->program = NULL;
+ result->editor = NULL;
+ result->assembler = NULL;
+ result->eval = mix_eval_new ();
+ result->dump = mix_dump_context_new (out_fd,
+ MIX_SHORT_ZERO, MIX_SHORT_ZERO,
+ MIX_DUMP_ALL);
+ result->vm = mix_vm_new ();
+ result->global_pre = result->global_post = NULL;
+
+ for (k =0; k < MIX_CMD_INVALID; ++k)
+ result->pre_hooks[k] = result->post_hooks[k] = NULL;
+
+ result->config = NULL;
+
+ for (k = 0; k < PRNO_; ++k)
+ result->preds[k] = mix_predicate_new (k);
+
+ result->mem_preds = g_hash_table_new (NULL, NULL);
+ result->commands = g_hash_table_new (g_str_hash, g_str_equal);
+ result->completions = make_completions_ ();
+
+ return result;
+}
+
+mix_vm_cmd_dispatcher_t *
+mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
+ mix_config_t *config)
+{
+ mix_vm_cmd_dispatcher_t *result = mix_vm_cmd_dispatcher_new (out, err);
+ if (result != NULL && (result->config = config) != NULL)
+ {
+ gint hsize = 0;
+ const gchar *val = mix_config_get (result->config, TRACING_KEY_);
+ if (val) cmd_strace_ (result, val);
+ val = mix_config_get (result->config, EDITOR_KEY_);
+ if (val) mix_vm_cmd_dispatcher_set_editor (result, val);
+ val = mix_config_get (result->config, ASM_KEY_);
+ if (val) mix_vm_cmd_dispatcher_set_assembler (result, val);
+ val = mix_config_get (result->config, TIMING_KEY_);
+ if (val) cmd_stime_ (result, val);
+ val = mix_config_get_devices_dir (result->config);
+ if (!val || !mix_stat_dir (val, "devices"))
+ {
+ gchar *dirname =
+ g_path_get_dirname (mix_config_get_filename (config));
+ cmd_sddir_ (result, dirname);
+ g_free (dirname);
+ }
+ else
+ mix_device_set_dir (val);
+ val = mix_config_get (result->config, LOGGING_KEY_);
+ if (val) cmd_slog_ (result, val);
+#ifdef HAVE_LIBHISTORY
+ val = mix_config_get_history_file (result->config);
+ hsize = mix_config_get_history_size (result->config);
+ using_history ();
+ stifle_history (hsize);
+ if (val)
+ {
+ read_history ((char *)val);
+ history_set_pos (history_base + history_length - 1);
+ }
+#endif
+ }
+ return result;
+}
+
+
+/* delete (does not close the fds in the constructor) */
+static gboolean
+del_pred_ (gpointer key, gpointer val, gpointer data)
+{
+ if (val) mix_predicate_delete ((mix_predicate_t *)val);
+ return TRUE;
+}
+
+static void
+del_hook_ (gpointer data, gpointer ignored)
+{
+ if (data) g_free (data);
+}
+
+static void
+del_hook_list_ (GSList *s)
+{
+ if (s)
+ {
+ g_slist_foreach (s, del_hook_, NULL);
+ g_slist_free (s);
+ }
+}
+
+void
+mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis)
+{
+ const gchar *hfile = NULL;
+ gint k;
+
+ g_return_if_fail (dis != NULL);
+ mix_eval_delete (dis->eval);
+ mix_dump_context_delete (dis->dump);
+ mix_vm_delete (dis->vm);
+ if (dis->editor) g_free (dis->editor);
+ if (dis->editor) g_free (dis->assembler);
+#ifdef HAVE_LIBHISTORY
+ if (dis->config && (hfile = mix_config_get_history_file
+ (dis->config)))
+ write_history ((char *)hfile);
+#endif
+ for (k = 0; k < PRNO_; ++k) mix_predicate_delete (dis->preds[k]);
+ g_hash_table_foreach_remove (dis->mem_preds, del_pred_, NULL);
+ g_hash_table_destroy (dis->mem_preds);
+ g_hash_table_destroy (dis->commands);
+ g_completion_free (dis->completions);
+ for (k = 0; k < MIX_CMD_INVALID; ++k)
+ {
+ del_hook_list_ (dis->pre_hooks[k]);
+ del_hook_list_ (dis->post_hooks[k]);
+ }
+ del_hook_list_ (dis->global_pre);
+ del_hook_list_ (dis->global_post);
+ g_free (dis);
+}
+
+/* register new commands for a dispatcher */
+void
+mix_vm_cmd_dispatcher_register_new (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_info_t *cmd)
+{
+ GList *list = NULL;
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (cmd != NULL);
+ g_hash_table_insert (dis->commands, (gpointer)cmd->name, (gpointer)cmd);
+ list = g_list_append (list, (gpointer)cmd->name);
+ g_completion_add_items (dis->completions, list);
+}
+
+const GList *
+mix_vm_cmd_dispatcher_complete (const mix_vm_cmd_dispatcher_t *dis,
+ const gchar *cmd, gchar **prefix)
+{
+ char *cp;
+ GList *result;
+
+ g_return_val_if_fail (dis != NULL, NULL);
+ g_return_val_if_fail (cmd != NULL, NULL);
+
+ cp = g_strdup (cmd);
+ result = g_completion_complete (dis->completions, cp, prefix);
+ g_free (cp);
+ return result;
+}
+
+/* set/get out/error streams */
+FILE *
+mix_vm_cmd_dispatcher_get_out_stream (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis, NULL);
+ return dis->out;
+}
+
+FILE *
+mix_vm_cmd_dispatcher_get_err_stream (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis, NULL);
+ return dis->err;
+}
+
+FILE * /* old output stream */
+mix_vm_cmd_dispatcher_set_out_stream (mix_vm_cmd_dispatcher_t *dis, FILE *out)
+{
+ FILE *old = NULL;
+ g_return_val_if_fail (dis != NULL, old);
+ old = dis->out;
+ dis->out = out;
+ dis->dump->channel = out;
+ return old;
+}
+
+FILE * /* old error stream */
+mix_vm_cmd_dispatcher_set_error_stream (mix_vm_cmd_dispatcher_t *dis,
+ FILE *err)
+{
+ FILE *old = NULL;
+ g_return_val_if_fail (dis != NULL, old);
+ old = dis->err;
+ dis->err = err;
+ return old;
+}
+
+
+/* set editor and compiler templates */
+void
+mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *edit_tplt)
+{
+ g_return_if_fail (dis != NULL);
+ if (dis->editor) g_free (dis->editor);
+ dis->editor = (edit_tplt) ? g_strdup (edit_tplt) : NULL;
+ if (dis->config && dis->editor)
+ mix_config_update (dis->config, EDITOR_KEY_, dis->editor);
+}
+
+void
+mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *asm_tplt)
+{
+ g_return_if_fail (dis != NULL);
+ if (dis->assembler) g_free (dis->assembler);
+ dis->assembler = (asm_tplt) ? g_strdup (asm_tplt) : NULL;
+ if (dis->config && dis->assembler)
+ mix_config_update (dis->config, ASM_KEY_, dis->assembler);
+}
+
+const gchar *
+mix_vm_cmd_dispatcher_get_editor (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->editor;
+}
+
+const gchar *
+mix_vm_cmd_dispatcher_get_assembler (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->assembler;
+}
+
+const gchar *
+mix_vm_cmd_dispatcher_get_src_file_path (const mix_vm_cmd_dispatcher_t *dis)
+{
+ static gchar *PATH = NULL;
+
+ const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis);
+ const mix_src_file_t *f = mix_vm_get_src_file (vm);
+
+ if (PATH)
+ {
+ g_free (PATH);
+ PATH = NULL;
+ }
+
+ if (f)
+ PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT);
+
+ return PATH;
+}
+
+const gchar *
+mix_vm_cmd_dispatcher_get_program_path (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->program;
+}
+
+/* install hooks */
+void
+mix_vm_cmd_dispatcher_pre_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd,
+ mix_vm_cmd_hook_t hook, gpointer data)
+{
+ hook_ *phook;
+
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (cmd < MIX_CMD_INVALID);
+
+ phook = g_new (hook_, 1);
+ phook->func = hook;
+ phook->data = data;
+
+ dis->pre_hooks[cmd] = g_slist_append (dis->pre_hooks[cmd], phook);
+}
+
+void
+mix_vm_cmd_dispatcher_post_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd,
+ mix_vm_cmd_hook_t hook, gpointer data)
+{
+ hook_ *phook;
+
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (cmd < MIX_CMD_INVALID);
+
+ phook = g_new (hook_, 1);
+ phook->func = hook;
+ phook->data = data;
+
+ dis->post_hooks[cmd] = g_slist_append (dis->post_hooks[cmd], phook);
+}
+
+void
+mix_vm_cmd_dispatcher_global_pre_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_cmd_global_hook_t hook,
+ gpointer data)
+{
+ global_hook_ *phook;
+
+ g_return_if_fail (dis != NULL);
+
+ phook = g_new (global_hook_, 1);
+ phook->func = hook;
+ phook->data = data;
+
+ dis->global_pre = g_slist_append (dis->global_pre, phook);
+}
+
+void
+mix_vm_cmd_dispatcher_global_post_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_cmd_global_hook_t hook,
+ gpointer data)
+{
+ global_hook_ *phook;
+
+ g_return_if_fail (dis != NULL);
+
+ phook = g_new (global_hook_, 1);
+ phook->func = hook;
+ phook->data = data;
+
+ dis->global_post = g_slist_append (dis->global_post, phook);
+}
+
+/* dispatch a command */
+gboolean /* TRUE if success, FALSE otherwise */
+mix_vm_cmd_dispatcher_dispatch (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd, const gchar *arg)
+{
+ g_return_val_if_fail (dis != NULL, FALSE);
+
+ if (dis->global_pre)
+ exec_global_hook_list_ (dis->global_pre, dis, cmd, arg);
+
+ if (cmd < MIX_CMD_INVALID)
+ {
+ if (dis->pre_hooks[cmd])
+ exec_hook_list_ (dis->pre_hooks[cmd], dis, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+
+ dis->result = (commands_[cmd].func)(dis, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+
+ if (dis->post_hooks[cmd])
+ exec_hook_list_ (dis->post_hooks[cmd], dis, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+ }
+ else
+ {
+ fprintf (dis->err, _("Unknown command. Try: help\n"));
+ }
+
+ if (dis->global_post)
+ exec_global_hook_list_ (dis->global_post, dis, cmd, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+ return dis->result;
+}
+
+/* dispatch a command in text format */
+gboolean
+mix_vm_cmd_dispatcher_dispatch_text (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *text)
+{
+ gchar *cp, *arg = "";
+ int k = 0;
+
+ g_return_val_if_fail (dis != NULL, FALSE);
+ g_return_val_if_fail (text != NULL, FALSE);
+
+ cp = g_strdup (text);
+ while (cp[k] && !isspace (cp[k])) ++k;
+ if (cp[k])
+ {
+ cp[k] = '\0'; ++k;
+ while (cp[k] && isspace (cp[k])) ++k;
+ arg = cp + k;
+ }
+
+ (void) mix_vm_cmd_dispatcher_dispatch_split_text (dis, cp, arg);
+
+ g_free (cp);
+
+ return dis->result;
+}
+
+/* dispatch a command in text format, with command and arg split */
+gboolean
+mix_vm_cmd_dispatcher_dispatch_split_text (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *command,
+ const gchar *arg)
+{
+ mix_vm_command_info_t *info;
+
+ g_return_val_if_fail (dis, FALSE);
+
+ if (!command) return FALSE;
+ if (!arg) arg = "";
+
+ info = (mix_vm_command_info_t *)g_hash_table_lookup (dis->commands, command);
+
+ if (info)
+ {
+ if (dis->global_pre)
+ exec_global_hook_list_ (dis->global_pre, dis, MIX_CMD_LOCAL, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+
+ dis->result = info->func (dis, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+
+ if (dis->global_post)
+ exec_global_hook_list_ (dis->global_post, dis, MIX_CMD_LOCAL, arg);
+
+ fflush (dis->out);
+ fflush (dis->err);
+ }
+ else
+ dis->result =
+ mix_vm_cmd_dispatcher_dispatch (dis,
+ mix_vm_command_from_string (command),
+ arg);
+ return dis->result;
+}
+
+
+/* get the last dispatch's result */
+gboolean
+mix_vm_cmd_dispatcher_get_last_result (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, FALSE);
+ return dis->result;
+}
+
+/* get total uptime */
+mix_time_t
+mix_vm_cmd_dispatcher_get_uptime (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, 0);
+ return dis->uptime;
+}
+
+/* get program total time */
+mix_time_t
+mix_vm_cmd_dispatcher_get_progtime (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, 0);
+ return dis->progtime;
+}
+
+/* get time lapse */
+mix_time_t
+mix_vm_cmd_dispatcher_get_laptime (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, 0);
+ return dis->laptime;
+}
+
+/* toggle time printing */
+void
+mix_vm_cmd_dispatcher_print_time (mix_vm_cmd_dispatcher_t * dis, gboolean print)
+{
+ g_return_if_fail (dis != NULL);
+ dis->printtime = print;
+}
+
+/* get the mix vm */
+const mix_vm_t *
+mix_vm_cmd_dispatcher_get_vm (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->vm;
+}
+
+/* src file info */
+gulong
+mix_vm_cmd_dispatcher_get_src_file_lineno (const mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, 0);
+ return mix_vm_get_break_lineno (dis->vm);
+}
+
+const gchar *
+mix_vm_cmd_dispatcher_get_src_file_line (const mix_vm_cmd_dispatcher_t *dis,
+ gulong line, gboolean cr)
+{
+ const mix_src_file_t *file;
+ g_return_val_if_fail (dis != NULL, NULL);
+
+ file = mix_vm_get_src_file (dis->vm);
+
+ if (line == 0 || file == NULL) return cr? "" : "\n";
+
+ if (cr)
+ return mix_src_file_get_line (file, line);
+ else
+ {
+ enum {BUFF_SIZE = 256};
+ static gchar BUFFER[BUFF_SIZE];
+ int len =
+ g_snprintf (BUFFER, BUFF_SIZE, "%s", mix_src_file_get_line (file, line));
+ if (len > 0 && BUFFER[len - 1] == '\n') BUFFER[len - 1] = '\0';
+ return BUFFER;
+ }
+}
+
+
diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h
new file mode 100644
index 0000000..1ff561f
--- /dev/null
+++ b/mixlib/mix_vm_command.h
@@ -0,0 +1,256 @@
+/* -*-c-*- ---------------- mix_vm_command.h :
+ * declarations for mix_vm_command_t, describing commands issued to a vm
+ * ------------------------------------------------------------------
+ * $Id: mix_vm_command.h,v 1.15 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIX_VM_COMMAND_H
+#define MIX_VM_COMMAND_H
+
+#include <stdio.h>
+#include "mix.h"
+#include "mix_vm.h"
+#include "mix_config.h"
+
+/* mix_vm_cmd_dispatcher encapsulates a virtual machine and helper
+ objects, providing a command driven interface with output to
+ provided files (in the posix sense).
+*/
+typedef struct mix_vm_cmd_dispatcher_t mix_vm_cmd_dispatcher_t;
+
+/* mix_vm_cmd_dispatcher understands the commands of this type */
+typedef enum {
+ MIX_CMD_HELP = 0, /* echo help message */
+ MIX_CMD_LOAD, /* load a mix program */
+ MIX_CMD_EDIT, /* edit mixal source */
+ MIX_CMD_PEDIT, /* print editor command */
+ MIX_CMD_SEDIT, /* set editor command*/
+ MIX_CMD_COMPILE, /* compile mixal source */
+ MIX_CMD_PASM, /* print compiler command */
+ MIX_CMD_SASM, /* set assembler command */
+ MIX_CMD_RUN, /* run a loaded program */
+ MIX_CMD_NEXT, /* run next instruction */
+ MIX_CMD_PSTAT, /* print current vm status */
+ MIX_CMD_LOC, /* print location pointer */
+ MIX_CMD_PSYM, /* print symbol */
+ MIX_CMD_PREG, /* print registry */
+ MIX_CMD_PFLAGS, /* print comp and overf flags */
+ MIX_CMD_PALL, /* print all registers and flags */
+ MIX_CMD_PMEM, /* print memory cells */
+ MIX_CMD_SREG, /* set register value */
+ MIX_CMD_SCMP, /* set comparison flag value */
+ MIX_CMD_SOVER, /* set overflow toggle value */
+ MIX_CMD_SMEM, /* set memory cell value */
+ MIX_CMD_SSYM, /* set symbol value */
+ MIX_CMD_SBP, /* set breakpoint at lineno */
+ MIX_CMD_CBP, /* clear breakpoint at lineno */
+ MIX_CMD_SBPA, /* set breakpoint at address */
+ MIX_CMD_CBPA, /* clear breakpoint at address */
+ MIX_CMD_SBPR, /* set breakpoint on register changed */
+ MIX_CMD_CBPR, /* clear breakpoint on register changed */
+ MIX_CMD_SBPM, /* set breakpoint on mem cell changed */
+ MIX_CMD_CBPM, /* clear breakpoint on mem cell changed */
+ MIX_CMD_SBPC, /* set breakpoint on comp flag changed */
+ MIX_CMD_CBPC, /* clear breakpoint on comp flag changed */
+ MIX_CMD_SBPO, /* set breakpoint on overflow toggled */
+ MIX_CMD_CBPO, /* clear breakpoint on overflow toggled */
+ MIX_CMD_CABP, /* clear all breakpoints */
+ MIX_CMD_WEVAL, /* evaluate a w-expression */
+ MIX_CMD_W2D, /* print word in decimal notation */
+ MIX_CMD_STRACE, /* enable/disable instruction traces */
+ MIX_CMD_PBT, /* print backtrace */
+ MIX_CMD_STIME, /* enable/disable timing statistics */
+ MIX_CMD_PTIME, /* print current time statistics */
+ MIX_CMD_SDDIR, /* set device directory */
+ MIX_CMD_PDDIR, /* print current device directory */
+ MIX_CMD_SLOG, /* set on/off message logging */
+ MIX_CMD_PPROG, /* print the current program path */
+ MIX_CMD_PSRC, /* print the current program source path */
+ MIx_CMD_PLINE, /* print the current line no */
+ MIX_CMD_INVALID, /* invalid command identifier */
+ MIX_CMD_LOCAL /* locally defined command */
+} mix_vm_command_t;
+
+/* new commands definition */
+typedef gboolean (*mix_vm_cmd_function_t) (mix_vm_cmd_dispatcher_t *,
+ const gchar *);
+typedef struct {
+ const gchar *name; /* User printable name of the function. */
+ mix_vm_cmd_function_t func; /* Function to call to do the job. */
+ const char *doc; /* Documentation for this function. */
+ const char *usage; /* Usage */
+} mix_vm_command_info_t;
+
+/* hook functions, to be invoked before and/or after command execution */
+typedef void (*mix_vm_cmd_hook_t)(mix_vm_cmd_dispatcher_t *dis,
+ const gchar *arg, gpointer data);
+
+/* global hook functions */
+typedef void (*mix_vm_cmd_global_hook_t)(mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd,
+ const gchar *arg, gpointer data);
+
+/* conversion from/to commands to strings */
+extern const gchar *
+mix_vm_command_to_string (mix_vm_command_t cmd);
+
+extern mix_vm_command_t
+mix_vm_command_from_string (const gchar *name);
+
+/* get help string about a command */
+extern const gchar *
+mix_vm_command_help (mix_vm_command_t cmd);
+
+extern const gchar *
+mix_vm_command_usage (mix_vm_command_t cmd);
+
+/* create a new command dispatcher */
+extern mix_vm_cmd_dispatcher_t *
+mix_vm_cmd_dispatcher_new (FILE *out, /* output messages file */
+ FILE *err /* error messages file */);
+
+extern mix_vm_cmd_dispatcher_t *
+mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
+ mix_config_t *config);
+
+/* delete (does not close the fds in the constructor) */
+extern void
+mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis);
+
+/* register new commands for a dispatcher */
+extern void
+mix_vm_cmd_dispatcher_register_new (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_info_t *cmd);
+
+/* get command completion list */
+const GList *
+mix_vm_cmd_dispatcher_complete (const mix_vm_cmd_dispatcher_t *dis,
+ const gchar *cmd, gchar **prefix);
+
+/* set/get out/error streams */
+extern FILE *
+mix_vm_cmd_dispatcher_get_out_stream (const mix_vm_cmd_dispatcher_t *dis);
+
+extern FILE *
+mix_vm_cmd_dispatcher_get_err_stream (const mix_vm_cmd_dispatcher_t *dis);
+
+extern FILE * /* old output stream */
+mix_vm_cmd_dispatcher_set_out_stream (mix_vm_cmd_dispatcher_t *dis,
+ FILE *out);
+
+extern FILE * /* old error stream */
+mix_vm_cmd_dispatcher_set_error_stream (mix_vm_cmd_dispatcher_t *dis,
+ FILE *err);
+
+/* set editor and compiler templates */
+extern void
+mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *edit_tplt);
+
+extern void
+mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *asm_tplt);
+
+extern const gchar *
+mix_vm_cmd_dispatcher_get_src_file_path (const mix_vm_cmd_dispatcher_t *dis);
+
+extern const gchar *
+mix_vm_cmd_dispatcher_get_program_path (const mix_vm_cmd_dispatcher_t *dis);
+
+extern const gchar *
+mix_vm_cmd_dispatcher_get_editor (const mix_vm_cmd_dispatcher_t *dis);
+
+extern const gchar *
+mix_vm_cmd_dispatcher_get_assembler (const mix_vm_cmd_dispatcher_t *dis);
+
+/* dispatch a command */
+extern gboolean /* TRUE if success, FALSE otherwise */
+mix_vm_cmd_dispatcher_dispatch (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd, const gchar *arg);
+
+/* dispatch a command in text format */
+extern gboolean
+mix_vm_cmd_dispatcher_dispatch_text (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *text);
+
+/* dispatch a command in text format, with command and arg split */
+extern gboolean
+mix_vm_cmd_dispatcher_dispatch_split_text (mix_vm_cmd_dispatcher_t *dis,
+ const gchar *command,
+ const gchar *arg);
+
+/* get the last dispatch's result */
+extern gboolean
+mix_vm_cmd_dispatcher_get_last_result (const mix_vm_cmd_dispatcher_t *dis);
+
+/* get total uptime */
+extern mix_time_t
+mix_vm_cmd_dispatcher_get_uptime (const mix_vm_cmd_dispatcher_t *dis);
+
+/* get program total time */
+extern mix_time_t
+mix_vm_cmd_dispatcher_get_progtime (const mix_vm_cmd_dispatcher_t *dis);
+
+/* get time lapse */
+extern mix_time_t
+mix_vm_cmd_dispatcher_get_laptime (const mix_vm_cmd_dispatcher_t *dis);
+
+/* src file info */
+extern gulong
+mix_vm_cmd_dispatcher_get_src_file_lineno (const mix_vm_cmd_dispatcher_t *dis);
+
+extern const gchar *
+mix_vm_cmd_dispatcher_get_src_file_line (const mix_vm_cmd_dispatcher_t *dis,
+ gulong line, gboolean cr);
+
+/* toggle time printing */
+extern void
+mix_vm_cmd_dispatcher_print_time (mix_vm_cmd_dispatcher_t * dis,
+ gboolean print);
+
+/* install hooks */
+extern void
+mix_vm_cmd_dispatcher_pre_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd,
+ mix_vm_cmd_hook_t hook, gpointer data);
+
+extern void
+mix_vm_cmd_dispatcher_post_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_command_t cmd,
+ mix_vm_cmd_hook_t hook, gpointer data);
+
+extern void
+mix_vm_cmd_dispatcher_global_pre_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_cmd_global_hook_t hook,
+ gpointer data);
+
+extern void
+mix_vm_cmd_dispatcher_global_post_hook (mix_vm_cmd_dispatcher_t *dis,
+ mix_vm_cmd_global_hook_t hook,
+ gpointer data);
+
+/* get the mix vm */
+extern const mix_vm_t *
+mix_vm_cmd_dispatcher_get_vm (const mix_vm_cmd_dispatcher_t *dis);
+
+
+#endif /* MIX_VM_COMMAND_H */
+
diff --git a/mixlib/mix_vm_dump.c b/mixlib/mix_vm_dump.c
new file mode 100644
index 0000000..5c0bc32
--- /dev/null
+++ b/mixlib/mix_vm_dump.c
@@ -0,0 +1,147 @@
+/* ---------------------- mix_vm_dump.c :
+ * Implementation of the functions declared in mix_vm_dump.h
+ * ------------------------------------------------------------------
+** Copyright (C) 2000 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+#include "mix.h"
+#include <unistd.h>
+#include "xmix_vm.h"
+#include "mix_vm_dump.h"
+
+/* Create/destroy a dump context */
+mix_dump_context_t *
+mix_dump_context_new(FILE *fd, mix_address_t begin, mix_address_t end,
+ guint32 options)
+{
+ mix_dump_context_t *result = NULL;
+
+ g_return_val_if_fail (fd != NULL, NULL);
+
+ if ( begin > end ) begin = end;
+ if ( end >= MEM_CELLS_NO_ ) end = MEM_CELLS_NO_;
+
+ result = g_new (mix_dump_context_t,1);
+ result->options = options;
+ result->begin = begin;
+ result->end = end;
+ result->channel = fd;
+
+ return result;
+}
+
+void
+mix_dump_context_delete (mix_dump_context_t *dc)
+{
+ g_return_if_fail (dc != NULL);
+ g_free (dc);
+}
+
+/* Use the dump context */
+#define WORD_FMT_ "%s %02d %02d %02d %02d %02d (%010ld)"
+#define SHORT_FMT_ "%s %02d %02d (%04d)"
+#define WORD_SIGN_(w) mix_word_is_negative (w)? "-":"+"
+#define SHORT_SIGN_(s) mix_short_is_negative (s)? "-":"+"
+#define WORD_ABS_(w) mix_word_magnitude (w)
+#define SHORT_ABS_(s) mix_short_magnitude (s)
+#define WORD_BYTE_(w,i) mix_byte_new (mix_word_magnitude (w)>>(6*(5-i)))
+#define SHORT_BYTE_(s,i) mix_byte_new (mix_short_magnitude (s)>>(6*(2-i)))
+#define WORD_ARGS_(w) WORD_SIGN_ (w), WORD_BYTE_ (w,1), WORD_BYTE_ (w,2), \
+ WORD_BYTE_ (w,3), WORD_BYTE_ (w,4), WORD_BYTE_ (w,5), WORD_ABS_ (w)
+#define SHORT_ARGS_(s) SHORT_SIGN_ (s), SHORT_BYTE_ (s,1), SHORT_BYTE_ (s,2), \
+ SHORT_ABS_ (s)
+
+void
+mix_vm_dump (const mix_vm_t *vm, const mix_dump_context_t *dc)
+{
+ guint j, i;
+ FILE *f;
+
+ g_return_if_fail (vm != NULL);
+ g_return_if_fail (dc != NULL);
+
+ f = dc->channel;
+
+ if ( (dc->options & MIX_DUMP_rA) == MIX_DUMP_rA )
+ {
+ mix_word_t rA = get_rA_ (vm);
+ fprintf (f, "rA: " WORD_FMT_ "\n", WORD_ARGS_ (rA));
+ }
+
+ if ( (dc->options & MIX_DUMP_rX) == MIX_DUMP_rX )
+ {
+ mix_word_t rX = get_rX_ (vm);
+ fprintf (f, "rX: " WORD_FMT_ "\n", WORD_ARGS_ (rX));
+ }
+
+ if ( (dc->options & MIX_DUMP_rJ) == MIX_DUMP_rJ )
+ {
+ mix_short_t rJ = get_rJ_ (vm);
+ fprintf (f, "rJ: " SHORT_FMT_ "\n", SHORT_ARGS_ (rJ));
+ }
+
+ for (j = 0, i = 0; j < IREG_NO_; ++j)
+ {
+ if ( (dc->options & (MIX_DUMP_rI1<<j)) == (MIX_DUMP_rI1<<j) )
+ {
+ mix_short_t rI = mix_word_to_short_fast (get_rI_ (vm, j+1));
+ fprintf (f, "rI%d: " SHORT_FMT_ "\t", j+1, SHORT_ARGS_ (rI));
+ i++;
+ }
+ if ( i%2 == 0 && i != 0 ) fprintf (f, "\n");
+ }
+
+ if ( i%2 == 1 ) fprintf (f, "\n");
+
+ if ( (dc->options & MIX_DUMP_OVER) == MIX_DUMP_OVER )
+ {
+ fprintf (f, _("Overflow: %s\n"), get_over_ (vm)? "T":"F");
+ }
+
+ if ( (dc->options & MIX_DUMP_CMP) == MIX_DUMP_CMP )
+ {
+ const gchar *val = "?";
+ switch (get_cmp_ (vm))
+ {
+ case mix_LESS:
+ val = "L";
+ break;
+ case mix_GREAT:
+ val = "G";
+ break;
+ case mix_EQ:
+ val = "E";
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ fprintf (f, _("Cmp: %s\n"), val);
+ }
+
+ if ( (dc->options & MIX_DUMP_CELLS) == MIX_DUMP_CELLS )
+ {
+ for (j = dc->begin; j < dc->end; ++j)
+ {
+ mix_word_t cell = get_cell_ (vm,j);
+ fprintf (f, "%04d: " WORD_FMT_ "\n", j, WORD_ARGS_ (cell));
+ }
+ }
+ fflush (f);
+}
+
diff --git a/mixlib/mix_vm_dump.h b/mixlib/mix_vm_dump.h
new file mode 100644
index 0000000..7f8b0c3
--- /dev/null
+++ b/mixlib/mix_vm_dump.h
@@ -0,0 +1,91 @@
+/* ---------------------- mix_vm_dump.h :
+ * This file declares types and functions for dumping the contents
+ * of a mix virtual machine.
+ * ------------------------------------------------------------------
+** Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+
+#ifndef MIX_VM_DUMP_H
+#define MIX_VM_DUMP_H
+
+#include <stdio.h>
+#include "mix_vm.h"
+
+/* Dump context: a structure defining the properties of dumping */
+typedef struct mix_dump_context_t mix_dump_context_t;
+struct mix_dump_context_t
+{
+ /* flags activating dumps (see enum below) */
+ guint32 options;
+ /* range of addresses dumped: [begin,end) */
+ mix_address_t begin;
+ mix_address_t end;
+ /* IO channel for dumping */
+ FILE *channel;
+};
+
+/* Flags for activating dumps */
+#define MIX_DUMP_NONE 0
+#define MIX_DUMP_rA 1
+#define MIX_DUMP_rX (1<<1)
+#define MIX_DUMP_rJ (1<<2)
+#define MIX_DUMP_rI1 (1<<3)
+#define MIX_DUMP_rI2 (1<<4)
+#define MIX_DUMP_rI3 (1<<5)
+#define MIX_DUMP_rI4 (1<<6)
+#define MIX_DUMP_rI5 (1<<7)
+#define MIX_DUMP_rI6 (1<<8)
+#define MIX_DUMP_rIa MIX_DUMP_rI1|MIX_DUMP_rI2|MIX_DUMP_rI3 \
+ |MIX_DUMP_rI4|MIX_DUMP_rI5|MIX_DUMP_rI6
+#define MIX_DUMP_rALL MIX_DUMP_rA|MIX_DUMP_rX|MIX_DUMP_rJ|MIX_DUMP_rIa
+#define MIX_DUMP_OVER (1<<9)
+#define MIX_DUMP_CMP (1<<10)
+#define MIX_DUMP_CELLS (1<<11)
+#define MIX_DUMP_ALL MIX_DUMP_rALL|MIX_DUMP_OVER|MIX_DUMP_CMP|MIX_DUMP_CELLS
+#define MIX_DUMP_ALL_NOMEM MIX_DUMP_rALL|MIX_DUMP_OVER|MIX_DUMP_CMP
+
+/* Default output channel (stdout) */
+#define MIX_DUMP_DEF_CHANNEL (stdout)
+
+/* Create/destroy a dump context */
+extern mix_dump_context_t *
+mix_dump_context_new (FILE *fd, mix_address_t begin, mix_address_t end,
+ guint32 options);
+
+extern void
+mix_dump_context_delete(mix_dump_context_t *dc);
+
+/* Modify an existing dump context */
+#define mix_dump_context_add_opt(dc,opt) ((dc)->options |= (opt))
+#define mix_dump_context_del_opt(dc,opt) ((dc)->options &= ~(opt))
+#define mix_dump_context_set_opt(dc,opt) ((dc)->options = (opt))
+#define mix_dump_context_range(dc,first,last) \
+do { \
+ (dc)->begin = first; \
+ (dc)->end = last; \
+} while (FALSE)
+
+
+/* Use the dump context */
+extern void
+mix_vm_dump(const mix_vm_t *vm, const mix_dump_context_t *dc);
+
+
+#endif /* MIX_VM_DUMP_H */
+
diff --git a/mixlib/testsuite/Makefile.am b/mixlib/testsuite/Makefile.am
new file mode 100644
index 0000000..834f833
--- /dev/null
+++ b/mixlib/testsuite/Makefile.am
@@ -0,0 +1,32 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.2 2001/09/29 01:53:51 jao Exp $
+
+INCLUDES = -I$(includedir) -I$(top_srcdir) -I$(top_srcdir)/mixlib
+LDADD = $(top_builddir)/mixlib/libmix.a
+
+check_PROGRAMS = mixtypest mixinstest mixvminstest mixparsertest mixdevtest mixevaltest
+TESTS = $(check_PROGRAMS)
+
+mixtypest_SOURCES = test.h mix_types_t.c
+mixinstest_SOURCES = test.h mix_ins_t.c
+mixvminstest_SOURCES = test.h mix_vm_ins_t.c
+mixparsertest_SOURCES = test.h mix_parser_t.c
+mixdevtest_SOURCES = test.h mix_device_t.c
+mixevaltest_SOURCES = test.h mix_eval_t.c
+
+
+
+
+
+
diff --git a/mixlib/testsuite/mix_device_t.c b/mixlib/testsuite/mix_device_t.c
new file mode 100644
index 0000000..8638d2f
--- /dev/null
+++ b/mixlib/testsuite/mix_device_t.c
@@ -0,0 +1,76 @@
+/* -*-c-*- -------------- mix_device_t.c :
+ * Implementation of the functions declared in mix_device_t.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <mix_device.h>
+
+/* Define VERBOSE_TEST if you want to get prints of the test */
+/* #define VERBOSE_TEST */
+#include "test.h"
+
+static int S_ = MIX_CHAR_MAX +1;
+
+int
+main (int argc, char **argv)
+{
+ mix_device_t *console;
+ size_t s;
+ mix_word_t **block;
+ mix_char_t mchars[S_];
+ gchar chars[S_];
+ int i, j;
+ int bno;
+
+
+ INIT_TEST;
+
+ console = mix_device_new (mix_dev_CONSOLE);
+ s = mix_device_block_size (console);
+ bno = S_/(s*5);
+ if (bno == 0) bno = 1;
+
+ block = g_new (mix_word_t *, bno);
+ for (i = 0; i < bno; ++i)
+ block[i] = g_new (mix_word_t, s);
+
+ for (i = 0; i < S_; ++i) {
+ chars[i] = mix_char_to_ascii (i);
+ mchars[i] = mix_ascii_to_char (chars[i]);
+ g_assert (mchars[i] == i);
+ }
+
+ for (i = 0; i < bno; ++i) {
+ for (j = 0; j < s; ++j) {
+ int n = i*s + 5*j;
+ if (n < S_)
+ block[i][j] = mix_bytes_to_word (mchars + n, 5);
+ else
+ block[i][j] = 0;
+ }
+ }
+
+ for (i = 0; i < bno; ++i) {
+ mix_device_write (console, block[i]);
+ }
+
+
+ return EXIT_SUCCESS;
+}
diff --git a/mixlib/testsuite/mix_eval_t.c b/mixlib/testsuite/mix_eval_t.c
new file mode 100644
index 0000000..9b62fd6
--- /dev/null
+++ b/mixlib/testsuite/mix_eval_t.c
@@ -0,0 +1,119 @@
+/* -*-c-*- -------------- mix_eval_t.c :
+ * Test of mix_eval_t
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/02/20 00:26:15 jose"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <mix_eval.h>
+/* Define VERBOSE_TEST if you want to get prints of the test */
+/* #define VERBOSE_TEST */
+#include "test.h"
+
+typedef struct test_case_t
+{
+ const gchar *expr;
+ gint value;
+ mix_eval_result_t result;
+} test_case_t;
+
+#define ok_case(exp,val) {exp, val, MIX_EVAL_OK}
+#define err_case(exp,err) {exp, 0, err}
+
+typedef struct sym_val_t
+{
+ const gchar *sym;
+ mix_word_t value;
+} sym_val_t;
+
+#define new_symbol(sym,val) {sym, mix_word_new (val)}
+
+int
+main(int argc, char **argv)
+{
+ size_t k;
+ mix_eval_t *eval;
+ mix_short_t loc = mix_short_new (30);
+ sym_val_t symbols[] = {
+ new_symbol ("s0", 43),
+ new_symbol ("s1", -1234),
+ new_symbol ("s2", 0),
+ new_symbol ("s3", -20),
+ new_symbol (NULL, 0)
+ };
+
+ test_case_t cases[] = {
+ ok_case ("2343", 2343),
+ ok_case ("-890", -890),
+ ok_case ("15+1015", 1030),
+ ok_case ("1-481", -480),
+ ok_case ("2300/10", 230),
+ ok_case ("24*3", 72),
+ ok_case ("2:5", 21),
+ ok_case ("1//3", 357913941),
+ ok_case ("12+*", 42),
+ ok_case ("***", 900),
+ ok_case ("1:3*2-4", 18),
+ ok_case ("-1+5*20/6", 13),
+ ok_case ("-1000(0,2),1", 1),
+ ok_case ("s0-s2*3", 129),
+ ok_case ("s3**", -600),
+ ok_case ("s3(3:5)", 20),
+ ok_case ("-s1", 1234),
+ ok_case ("s1/10+s0", 166),
+ err_case ("foo", MIX_EVAL_UNDEF_SYM),
+ err_case ("11--2", MIX_EVAL_SYNTAX),
+ err_case ("s2*foo*3", MIX_EVAL_UNDEF_SYM),
+ err_case ("12/32),1", MIX_EVAL_MIS_PAREN),
+ err_case ("2000(88)", MIX_EVAL_INV_FSPEC),
+ ok_case (NULL, 0)
+ };
+
+ INIT_TEST;
+ g_print ("Entering mix_eval test...");
+ eval = mix_eval_new ();
+
+ for (k = 0; symbols[k].sym; ++k)
+ mix_eval_set_symbol (eval, symbols[k].sym, symbols[k].value);
+
+ for (k = 0; cases[k].expr; ++k) {
+ mix_eval_result_t r = cases[k].result, s;
+ g_print ("Evaluating \"%s\" = %d ...",
+ cases[k].expr, cases[k].value);
+
+ s = mix_eval_expression_with_loc (eval, cases[k].expr, loc);
+ g_assert (s == r);
+ if ( s == MIX_EVAL_OK ) {
+ mix_word_print (mix_eval_value (eval), "... ");
+ g_print ("\n");
+ g_assert (mix_eval_value (eval) == mix_word_new(cases[k].value));
+ } else {
+ g_print ("\n------->%s, at pos %d\n",
+ mix_eval_last_error_string (eval),
+ mix_eval_last_error_pos (eval));
+ }
+ }
+ mix_eval_delete (eval);
+
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/mixlib/testsuite/mix_ins_t.c b/mixlib/testsuite/mix_ins_t.c
new file mode 100644
index 0000000..8dcc619
--- /dev/null
+++ b/mixlib/testsuite/mix_ins_t.c
@@ -0,0 +1,79 @@
+/*----------------------- mix_ins_t.c -------------------------------
+ * Tests for mix_ins.h
+ *-------------------------------------------------------------------
+** Copyright (C) 1999 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+#include <stdlib.h>
+#include <mix_ins.h>
+
+/* Define VERBOSE_TEST if you want to get prints of the test */
+/* #define VERBOSE_TEST */
+#include "test.h"
+
+
+int
+main(int argc, const char**argv)
+{
+ mix_word_t words[6];
+ mix_ins_t ins[3];
+ guint k;
+
+ INIT_TEST;
+
+ g_print("\n...ok.\nTesting mix_ins_id_t properties...\n");
+ for ( k = 0; k < mix_INVALID_INS; ++k )
+ {
+ mix_opcode_t c = mix_get_opcode_from_id(k);
+ mix_fspec_t f = mix_get_fspec_from_id(k);
+ mix_ins_id_t id = mix_get_ins_id(c,f);
+
+ g_print("%02d:%s (%1d:%1d), ",
+ c, mix_get_string_from_id(k),
+ mix_fspec_left(f), mix_fspec_right(f));
+ if ( (k+1)%3 == 0 ) g_print("\n");
+
+ g_assert(id==k);
+ }
+
+ g_print("\n...ok.\nTesting mix_ins_t properties...\n");
+ for ( k = 1; k < mix_INVALID_INS; ++k )
+ {
+ g_print("%d ",k);
+ mix_ins_fill_from_id(ins[0], k);
+ g_assert(mix_ins_id_from_ins(ins[0]) == k);
+ ins[0].address = 0x0123;
+ ins[0].index = mix_I2;
+ words[2] = mix_ins_to_word(ins);
+ g_assert(ins[0].address == mix_get_ins_address(words[2]));
+ g_assert(ins[0].index == mix_get_ins_index(words[2]));
+ g_assert(ins[0].fspec == mix_get_ins_fspec(words[2]));
+ g_assert(ins[0].opcode == mix_get_ins_opcode(words[2]));
+ g_assert(mix_word_to_ins(words[2],ins+1) == k);
+ g_assert(ins[0].address == ins[1].address);
+ g_assert(ins[0].index == ins[1].index);
+ g_assert(ins[0].fspec == ins[1].fspec);
+ g_assert(ins[0].opcode == ins[1].opcode);
+ }
+
+ g_print("\n...ok.\n");
+
+
+
+ return EXIT_SUCCESS;
+}
diff --git a/mixlib/testsuite/mix_parser_t.c b/mixlib/testsuite/mix_parser_t.c
new file mode 100644
index 0000000..215fc70
--- /dev/null
+++ b/mixlib/testsuite/mix_parser_t.c
@@ -0,0 +1,85 @@
+/* -*-c-*- -------------- mix_parser_t.c :
+ * Test of mix_parser_t
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include <stdlib.h>
+#include <mix_parser.h>
+
+/* Define VERBOSE_TEST if you want to get prints of the test */
+/* #define VERBOSE_TEST */
+#include "test.h"
+
+static const gchar * const FILES_[] = { "test1" , "taocp145"
+};
+
+static const size_t FILE_NO_ = sizeof(FILES_)/sizeof(FILES_[0]);
+
+static void
+test_code_(const gchar *name)
+{
+ mix_parser_t *parser = mix_parser_new(name);
+ mix_parser_err_t err;
+ mix_code_file_t *code;
+ mix_ins_desc_t ins;
+
+ g_assert(parser);
+ err = mix_parser_compile(parser);
+ if ( err != MIX_PERR_OK ) {
+ g_print(mix_parser_err_string(err));
+ g_print("\n");
+ }
+ g_assert(err == MIX_PERR_OK);
+ err = mix_parser_write_code(parser, name, FALSE);
+ code = mix_code_file_new_read(name);
+ g_assert(code);
+ g_message("%s: Version: %d.%d", name, mix_code_file_major_version(code),
+ mix_code_file_minor_version(code));
+ mix_short_print(mix_code_file_get_start_addr(code), "Start address: ");
+ g_print("\n");
+ while ( mix_code_file_get_ins(code, &ins) ) {
+ mix_ins_t i;
+ mix_word_to_ins_uncheck(ins.ins, i);
+ mix_short_print(ins.address, "addr: ");
+ g_print(" : ");
+ mix_ins_print(&i);
+ g_print("\n");
+ }
+
+ mix_parser_delete(parser);
+ mix_code_file_delete(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ size_t k;
+
+ INIT_TEST;
+
+ for (k = 0; k < FILE_NO_; ++k)
+ // test_code_(FILES_[k]);
+ ;
+
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/mixlib/testsuite/mix_types_t.c b/mixlib/testsuite/mix_types_t.c
new file mode 100644
index 0000000..ababead
--- /dev/null
+++ b/mixlib/testsuite/mix_types_t.c
@@ -0,0 +1,369 @@
+/*----------------------- mix_types_t.c -----------------------------
+ * Tests for mix_types.h
+ * ------------------------------------------------------------------
+*
+** Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+
+#include <stdlib.h>
+#include <mix_types.h>
+
+/* Define VERBOSE_TEST if you want to get prints of the test */
+/* #define VERBOSE_TEST */
+#include "test.h"
+
+/* compare two words */
+static gboolean
+word_compare_(mix_word_t w1, mix_word_t w2)
+{
+ if ( mix_word_magnitude(w1) == 0 )
+ return ( mix_word_magnitude(w2) == 0 );
+ else
+ return ( w1 == w2 );
+}
+
+
+/* create a word from an array of bytes and check the result */
+static void
+test_word_from_bytes_(mix_word_t *word,
+ mix_byte_t *bytes,
+ unsigned byteno,
+ const char *message)
+{
+ mix_byte_t r;
+ unsigned int k;
+
+ *word = mix_bytes_to_word(bytes,byteno);
+ mix_word_print(*word,message);
+ g_print("\n");
+ for ( k = 5-byteno; k < 5; ++k ) {
+ PRINT_BYTE(r = mix_word_get_byte(*word,k+1));
+ g_print(" (k = %d)\n",k);
+ g_assert( r == bytes[k-5+byteno] );
+ }
+}
+
+
+/* test field access */
+static void
+test_field_access_(mix_fspec_t l, mix_fspec_t r,
+ mix_word_t from, mix_word_t to)
+{
+ mix_fspec_t f = mix_fspec_new(l,r);
+ mix_word_t result;
+
+ PRINT_BYTE(l); g_print(", ");
+ PRINT_BYTE(r); g_print(", ");
+ PRINT_BYTE(f); g_print("\n ");
+ mix_word_print(from, "from: ");
+ mix_word_print(to, " to: ");
+ g_assert( mix_fspec_left(f) == l );
+ g_assert( mix_fspec_right(f) == r );
+ result = mix_word_set_field(f,from,to);
+ mix_word_print(result,"\n\tresult: ");
+ g_assert( mix_word_get_field(f,from) == mix_word_get_field(f,result) );
+ g_print("\n");
+}
+
+/* test word addition */
+static void
+test_word_add_(mix_word_t w1, mix_word_t w2)
+{
+ mix_word_t r;
+
+ r = mix_word_add(w1,w2);
+ mix_word_print(w1,"\n");
+ mix_word_print(w2,NULL);
+ mix_word_print(r," = ");
+ g_assert( word_compare_(mix_word_sub(r,w1), w2) );
+ g_assert( word_compare_(mix_word_sub(r,w2), w1) );
+ /* while asserting the following, take into account that 0 != -0
+ for mix words, although they are logically equivalent
+ */
+ g_assert( word_compare_(mix_word_sub(w1,r), mix_word_negative(w2)) );
+ g_assert( word_compare_(mix_word_sub(w2,r), mix_word_negative(w1)) );
+ g_assert( word_compare_(mix_word_add(w2,w1), r) );
+}
+
+/* test word multiplication */
+static void
+test_word_mul_(mix_word_t w1, mix_word_t w2)
+{
+ mix_word_t h, l, q, r = 0;
+ mix_word_mul(w1,w2,&h,&l);
+ mix_word_print(w1,"\n");
+ mix_word_print(w2,"*");
+ mix_word_print(h,"\n =");
+ mix_word_print(l,NULL);
+ if ( w1 != 0 ) {
+ g_assert( mix_word_div(h,l,w1,&q,&r) == FALSE );
+ g_assert( mix_word_magnitude(r) == 0 );
+ g_assert( q == w2 );
+ } else {
+ g_assert( mix_word_magnitude(l) == 0 && mix_word_magnitude(h) == 0 );
+ }
+ if ( w2 != 0 ) {
+ g_assert( mix_word_div(h,l,w2,&q,&r) == FALSE );
+ g_assert( mix_word_magnitude(r) == 0 );
+ g_assert( q == w1 );
+ } else {
+ g_assert( mix_word_magnitude(l) == 0 && mix_word_magnitude(h) == 0 );
+ }
+
+}
+
+/* test word division */
+static void
+test_word_div_(mix_word_t h, mix_word_t l, mix_word_t by)
+{
+ mix_word_t q,r;
+ gboolean overflow;
+
+ overflow = mix_word_div(h,l,by,&q,&r);
+
+ mix_word_print(h,"\n\n");
+ mix_word_print(l,NULL);
+ mix_word_print(by,"\n div by ");
+
+ if ( !overflow ) {
+ mix_word_t h1, l1, h2;
+ mix_word_print(q,"\n q = ");
+ mix_word_print(r," r = ");
+ mix_word_mul(by,q,&h1,&l1);
+ mix_word_add_and_carry(l1,r,&h2,&l1);
+ h1 = mix_word_add(h1,h2);
+ g_assert( mix_word_magnitude(r) < mix_word_magnitude(by) );
+ g_assert( word_compare_(h1,h) );
+ g_assert( mix_word_magnitude(l1) == mix_word_magnitude(l) );
+ } else
+ g_print("\n\t = overflow");
+
+}
+
+static void
+test_mix_char_(void)
+{
+ mix_char_t mchar;
+ guchar achar;
+ guint k;
+ g_print("\nTesting mix_char_t. Table of mix_chars:\n");
+
+ for (k = 0; k < MIX_CHAR_MAX + 1; ++k) {
+ mchar = k;
+ achar = mix_char_to_ascii(mchar);
+ g_print("%02d: %c, ", k, achar);
+ if ( (k+1)%5 == 0 ) g_print("\n");
+ g_assert( mchar == mix_ascii_to_char(achar) );
+ }
+
+ g_print("\nchar <-> byte conversions...\n");
+
+ for (k = 0; k < MIX_CHAR_MAX + 1; ++k) {
+ mix_byte_t c = mix_byte_new (k);
+ g_assert (c == mix_byte_to_char (mix_char_to_byte (c)));
+ }
+
+ g_print("\n");
+}
+
+
+/* main test driver for mix_types.h/c */
+
+int main(int argc, char **argv)
+{
+ unsigned int j,k;
+ mix_byte_t bytes[5] = { 0, 3, 20, 30, 40 };
+ mix_byte_t r;
+ mix_short_t ss[6];
+ mix_word_t words[6];
+
+ INIT_TEST;
+
+ g_print("Testing mix_byte_t arithmetics...\n");
+ PRINT_BYTE(bytes[0]); g_print(", ");
+ PRINT_BYTE(bytes[1]); g_print(", ");
+ PRINT_BYTE(bytes[2]); g_print(", ");
+ PRINT_BYTE(bytes[3]); g_print(", ");
+ PRINT_BYTE(bytes[4]); g_print("\n");
+ PRINT_BYTE(r = mix_byte_add(bytes[1],bytes[2]));
+ g_print("\n"); g_assert(r == 23);
+ PRINT_BYTE(r = mix_byte_add(bytes[3],bytes[4]));
+ g_print("\n"); g_assert(r == 6);
+ PRINT_BYTE(r = mix_byte_sub(bytes[0],bytes[1]));
+ g_print("\n"); g_assert(r == 61);
+ PRINT_BYTE(r = mix_byte_sub(bytes[4],bytes[3]));
+ g_print("\n"); g_assert(r == 10);
+ PRINT_BYTE(r = mix_byte_sub(bytes[1],bytes[4]));
+ g_print("\n"); g_assert(r == 27);
+ PRINT_BYTE(r = mix_byte_mul(bytes[0],bytes[1]));
+ g_print("\n"); g_assert(r == 0);
+ PRINT_BYTE(r = mix_byte_mul(bytes[1],bytes[2]));
+ g_print("\n"); g_assert(r == 60);
+ PRINT_BYTE(r = mix_byte_mul(bytes[1],bytes[4]));
+ g_print("\n"); g_assert(r == 56);
+ PRINT_BYTE(r = mix_byte_mul(bytes[4],bytes[1]));
+ g_print("\n"); g_assert(r == 56);
+ PRINT_BYTE(r = mix_byte_div(bytes[4],bytes[2]));
+ g_print("\n"); g_assert(r == 2);
+ PRINT_BYTE(r = mix_byte_div(bytes[3],bytes[2]));
+ g_print("\n"); g_assert(r == 1);
+
+ test_mix_char_();
+
+ g_print("\nTesting word<->short conversions...");
+ words[0] = mix_bytes_to_word(bytes+1,5);
+ words[1] = mix_word_negative(words[0]);
+ ss[0] = mix_word_to_short(words[0]);
+ ss[1] = mix_word_to_short(words[1]);
+ mix_word_print(words[0],"\nwords[0]=");
+ mix_word_print(words[1],"\nwords[1]=");
+ mix_short_print(ss[0],"\nss[0]=");
+ mix_short_print(ss[1],"\nss[1]=");
+ g_assert(mix_short_is_positive(ss[0]));
+ g_assert(mix_short_is_negative(ss[1]));
+ words[2] = mix_short_to_word(ss[0]);
+ words[3] = mix_short_to_word(ss[1]);
+ mix_word_print(words[2],"\nwords[2]=");
+ mix_word_print(words[3],"\nwords[3]=");
+ g_assert(mix_word_sign(words[0]) == mix_word_sign(words[2]));
+ g_assert(mix_word_sign(words[1]) == mix_word_sign(words[3]));
+ g_assert(mix_short_magnitude(ss[0]) == mix_word_magnitude(words[2]));
+ g_assert(mix_short_magnitude(ss[1]) == mix_word_magnitude(words[3]));
+ g_assert(mix_word_get_byte(words[0],4) == mix_word_get_byte(words[2],4));
+ g_assert(mix_word_get_byte(words[0],5) == mix_word_get_byte(words[2],5));
+ g_assert(mix_word_get_byte(words[1],4) == mix_word_get_byte(words[3],4));
+ g_assert(mix_word_get_byte(words[1],5) == mix_word_get_byte(words[3],5));
+ words[4] = mix_word_extract_field(mix_fspec_new(4,5),words[0]);
+ words[5] = mix_word_extract_field(mix_fspec_new(4,5),words[1]);
+ mix_word_reverse_sign(words[5]);
+ g_assert(words[4] == words[2]);
+ g_assert(words[5] == words[3]);
+
+ g_print("Testing mix_word_t creation and byte access...\n");
+ test_word_from_bytes_(words,bytes,5,"word[0] created from bytes[0-4]");
+ test_word_from_bytes_(words+1,bytes,4,"\nword[1] created from bytes[0-3]");
+ test_word_from_bytes_(words+2,bytes,3,"\nword[2] created from bytes[0-2]");
+ words[3] = mix_word_negative(words[2]);
+ g_assert( mix_word_negative(words[3]) == words[2] );
+ g_assert( mix_word_is_negative(words[3]) && !mix_word_is_negative(words[2]));
+ mix_word_print(words[3],"\nword[3] created from -word[2]");
+ test_word_from_bytes_(words+4,bytes+2,2,"\nword[2] created from bytes[2-3]");
+
+ g_print("\nTesting mix_word_t field access...\n");
+ mix_word_set_byte(words+3,1,12);
+ mix_word_set_byte(words+3,2,58);
+ g_assert( mix_word_get_byte(words[3],1) == 12 );
+ g_assert( mix_word_get_byte(words[3],2) == 58 );
+ test_field_access_(0,5,words[3],words[4]);
+ test_field_access_(1,5,words[3],words[4]);
+ test_field_access_(2,5,words[3],words[4]);
+ test_field_access_(3,5,words[3],words[4]);
+ test_field_access_(4,5,words[3],words[4]);
+ test_field_access_(5,5,words[3],words[4]);
+ test_field_access_(0,0,words[3],words[4]);
+
+ g_print("\n\nTesting mix_word_t arithmetics...\n");
+ words[0] = MIX_WORD_MAX;
+ words[1] = mix_word_negative(words[0]);
+ for ( k = 1; k < 6; ++k ) {
+ mix_word_set_byte(words+2,k,5*k);
+ mix_word_set_byte(words+4,k,10*(5-k));
+ mix_word_set_byte(words+3,k,21 + 3*k);
+ }
+ words[5] = 0;
+
+ g_print("\n***addition***");
+ for ( k = 0; k < 6; ++k )
+ for ( j = 0; j <= k; ++j ) {
+ test_word_add_(words[k],mix_word_negative(words[j]));
+ test_word_add_(words[k],words[j]);
+ }
+ g_print("\n***product***");
+ for ( k = 0; k < 6; ++k )
+ for ( j = 0; j <= k; ++j ) {
+ test_word_mul_(words[k],words[j]);
+ }
+ g_print("\n***division***");
+ for ( k = 0; k < 6; ++k ) {
+ test_word_div_(words[k],0,words[0]);
+ for ( j = 0; j <= k; ++j ) {
+ test_word_div_(k,words[j],words[j]);
+ test_word_div_(0,mix_word_add(mix_word_magnitude(words[j]),j),words[j]);
+ test_word_div_(mix_word_negative(k),words[j],words[j]);
+ }
+ }
+
+ g_print("\nTesting shift operations...\n");
+ for ( k = 0; k < 10; ++k )
+ mix_word_set_byte(words+(k/5),1+(k%5),k+1);
+
+ mix_word_print(words[0],"A = ");
+ mix_word_print(words[1],"X = ");
+ for ( k = 0; k < 11; ++k ) {
+ mix_word_t A, X;
+ unsigned int m;
+
+ mix_word_shift_left(words[0],words[1],k,&A,&X);
+ g_print("\nShift left %d:\n",k);
+ mix_word_print(A,"A ");
+ mix_word_print(X,"X ");
+ for ( m = 0; m < 10 - k; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) ==
+ mix_word_get_byte(words[(m+k)/5], ((m+k)%5)+1) );
+ for ( ; m < 10; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) == 0 );
+
+ mix_word_shift_right(words[0],words[1],k,&A,&X);
+ g_print("\nShift right %d:\n",k);
+ mix_word_print(A,"A ");
+ mix_word_print(X,"X ");
+ for ( m = 0; m < k; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) == 0 );
+ for ( ; m < 10; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) ==
+ mix_word_get_byte(words[(m-k)/5], ((m-k)%5)+1) );
+
+ mix_word_shift_left_circular(words[0],words[1],k,&A,&X);
+ g_print("\nShift left circular %d:\n",k);
+ mix_word_print(A,"A ");
+ mix_word_print(X,"X ");
+ for ( m = 0; m < 10 - k; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) ==
+ mix_word_get_byte(words[(m+k)/5], ((m+k)%5)+1) );
+ for ( ; m < 10; ++m )
+ g_assert( mix_word_get_byte( m < 5 ? A:X, (m%5)+1 ) ==
+ mix_word_get_byte(words[(m-10+k)/5], 1+((m-10+k)%5)) );
+ mix_word_shift_right_circular(A, X, k, &A, &X);
+ g_print("\nRe-shiftting right...\n");
+ mix_word_print(A, "A ");
+ mix_word_print(X, "X ");
+ g_assert(A == words[0]);
+ g_assert(X == words[1]);
+ }
+
+
+ g_print("\n");
+ return EXIT_SUCCESS;
+}
+
+
+
+
+
+
diff --git a/mixlib/testsuite/mix_vm_ins_t.c b/mixlib/testsuite/mix_vm_ins_t.c
new file mode 100644
index 0000000..458cbba
--- /dev/null
+++ b/mixlib/testsuite/mix_vm_ins_t.c
@@ -0,0 +1,505 @@
+/* ---------------------- mix_vm_ins_t.c :
+ * Tests for the virtual machine instruction handlers.
+ * ------------------------------------------------------------------
+** Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+
+#include <stdlib.h>
+/* #define VERBOSE_TEST */
+#include "test.h"
+#include "mix_vm.h"
+#include "mix_vm_dump.h"
+
+typedef struct
+{
+ mix_word_t rA_b, rA_a;
+ mix_word_t rX_b, rX_a;
+ mix_short_t rJ_b, rJ_a;
+ mix_short_t rI_b[6], rI_a[6];
+ gboolean over_b, over_a;
+ mix_cmpflag_t cmp_b, cmp_a;
+ mix_address_t begin, end;
+ mix_word_t *cells_b, *cells_a;
+ const mix_ins_t *ins;
+} test_desc_t;
+
+static void
+set_cells_(test_desc_t *t, mix_address_t begin, mix_address_t end)
+{
+ g_assert(begin <= end);
+ t->begin = begin;
+ t->end = end;
+ t->cells_b = g_new(mix_word_t,end-begin);
+ t->cells_a = g_new(mix_word_t,end-begin);
+}
+
+static void
+free_cells_(test_desc_t *t)
+{
+ g_assert(t);
+ g_free(t->cells_a);
+ g_free(t->cells_b);
+ t->cells_a = t->cells_b = NULL;
+ t->begin = t->end = 0;
+}
+
+
+static void
+fill_test_desc_(test_desc_t *t, const mix_vm_t *vm, const mix_ins_t *ins)
+{
+ guint k;
+ g_assert(t);
+ g_assert(vm);
+
+ t->rA_b = t->rA_a = mix_vm_get_rA(vm);
+ t->rX_b = t->rX_a = mix_vm_get_rX(vm);
+ t->rJ_b = t->rJ_a = mix_vm_get_rJ(vm);
+ for ( k = 0; k < 6; ++k )
+ t->rI_b[k] = t->rI_a[k] = mix_vm_get_rI(vm,k+1);
+ t->cmp_b = t->cmp_a = mix_vm_get_cmpflag(vm);
+ t->over_b = t->over_a = mix_vm_get_overflow(vm);
+
+ for (k = 0; k < t->end-t->begin; ++k)
+ t->cells_a[k] = t->cells_b[k] =
+ mix_vm_get_addr_contents(vm,t->begin+k);
+ t->ins = ins;
+}
+
+
+static void
+run_test_(test_desc_t *t, mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ guint k;
+ g_assert(t);
+ g_assert(vm);
+
+ mix_vm_set_rA(vm, t->rA_b);
+ mix_vm_set_rX(vm, t->rX_b);
+ mix_vm_set_rJ(vm, t->rJ_b);
+ for (k = 0; k < 6; ++k) mix_vm_set_rI(vm, k+1, t->rI_b[k]);
+ for (k = t->begin; k < t->end; ++k)
+ mix_vm_set_addr_contents(vm, k, t->cells_b[k-t->begin]);
+ mix_vm_set_cmpflag(vm, t->cmp_b);
+ mix_vm_set_overflow(vm, t->over_b);
+
+ mix_ins_print(t->ins);
+ if (dc) {
+ mix_dump_context_range(dc, t->begin, t->end);
+ mix_vm_dump(vm,dc);
+ }
+ k = mix_vm_exec_ins(vm, t->ins);
+ if (dc) mix_vm_dump(vm, dc);
+ g_assert(k == TRUE);
+ g_assert(mix_vm_get_rA(vm) == t->rA_a);
+ g_assert(mix_vm_get_rX(vm) == t->rX_a);
+ for (k = 0; k < 6; ++k) g_assert(mix_vm_get_rI(vm, k+1) == t->rI_a[k]);
+ g_assert(mix_vm_get_cmpflag(vm) == t->cmp_a);
+ g_assert(mix_vm_get_overflow(vm) == t->over_a);
+ for (k = t->begin; k < t->end; ++k)
+ g_assert(mix_vm_get_addr_contents(vm, k) == t->cells_a[k-t->begin]);
+}
+
+
+
+static void
+test_arithmetics_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+
+ g_print("\nTesting arithmetic instructions...\n");
+ mix_vm_reset(vm);
+ mix_ins_fill_from_id(ins,mix_ADD);
+ ins.index = 0;
+ ins.address = 1000;
+ mix_vm_set_rA(vm,mix_word_new_b(19,18,1,2,22));
+ mix_vm_set_addr_contents(vm,1000,mix_word_new_b(1,36,5,0,50));
+ set_cells_(&test,1000,1001);
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(20,54,6,3,8);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins,mix_SUB);
+ mix_vm_set_rA(vm,mix_word_new_bn(19,18,0,0,9));
+ mix_vm_set_addr_contents(vm,1000,mix_word_new_bn(31,16,2,22,0));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(11,62,2,21,55);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins,mix_MUL);
+ mix_vm_set_rA(vm,mix_word_new_b(1,1,1,1,1));
+ mix_vm_set_addr_contents(vm,1000, mix_word_new_b(1,1,1,1,1));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(0,1,2,3,4);
+ test.rX_a = mix_word_new_b(5,4,3,2,1);
+ run_test_(&test, vm, dc);
+
+ ins.fspec = mix_fspec_new(1,1);
+ mix_vm_set_rA(vm,mix_word_new_bn(0,0,0,1,48));
+ mix_vm_set_addr_contents(vm,1000,mix_word_new_bn(2,16,2,22,0));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = MIX_WORD_MINUS_ZERO;
+ test.rX_a = mix_word_new_bn(0,0,0,3,32);
+ run_test_(&test, vm, dc);
+
+ mix_vm_set_rA(vm,mix_word_new_bn(0,0,0,1,48));
+ mix_vm_set_addr_contents(vm,1000,mix_word_new_b(2,0,34,33,1));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = MIX_WORD_MINUS_ZERO;
+ test.rX_a = mix_word_new_bn(0,0,0,3,32);
+ run_test_(&test, vm, dc);
+
+ ins.fspec = mix_fspec_new(0,5);
+ mix_vm_set_rA(vm,mix_word_new_bn(50,0,1,48,4));
+ mix_vm_set_addr_contents(vm,1000,mix_word_new_bn(2,0,0,0,0));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(1,36,0,3,32);
+ test.rX_a = mix_word_new_b(8,0,0,0,0);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins,mix_DIV);
+ mix_vm_set_rA(vm,MIX_WORD_ZERO);
+ mix_vm_set_rX(vm,mix_word_new_b(0,0,0,0,17));
+ mix_vm_set_addr_contents(vm,1000, mix_word_new_b(0,0,0,0,3));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(0,0,0,0,5);
+ test.rX_a = mix_word_new_b(0,0,0,0,2);
+ run_test_(&test, vm, dc);
+
+ mix_vm_set_rA(vm,MIX_WORD_ZERO);
+ mix_vm_set_rX(vm,mix_word_new_bn(0,0,0,0,17));
+ mix_vm_set_addr_contents(vm,1000, mix_word_new_b(0,0,0,0,3));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(0,0,0,0,5);
+ test.rX_a = mix_word_new_b(0,0,0,0,2);
+ run_test_(&test, vm, dc);
+
+ mix_vm_set_rA(vm, MIX_WORD_MINUS_ZERO);
+ mix_vm_set_rX(vm, mix_word_new_b(19,19,0,3,1));
+ mix_vm_set_addr_contents(vm,1000, mix_word_new_bn(0,0,0,2,0));
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = mix_word_new_b(0,9,41,32,1);
+ test.rX_a = mix_word_new_bn(0,0,0,1,1);
+ run_test_(&test, vm, dc);
+
+ free_cells_(&test);
+}
+
+static void
+test_shift_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+
+ g_print("Testing shift instructions...\n");
+ mix_vm_reset(vm);
+ set_cells_(&test,0,0);
+ fill_test_desc_(&test,vm,&ins);
+ mix_ins_fill_from_id(ins,mix_SRAX);
+ ins.index = 0;
+ ins.address = 1;
+ test.rA_b = mix_word_new_b(1,2,3,4,5);
+ test.rX_b = mix_word_new_bn(6,7,8,9,10);
+ test.rA_a = mix_word_new_b(0,1,2,3,4);
+ test.rX_a = mix_word_new_bn(5,6,7,8,9);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_SLA);
+ ins.address = 2;
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_new_b(2,3,4,0,0);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_SRC);
+ ins.address = 4;
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_new_b(6,7,8,9,2);
+ test.rX_a = mix_word_new_bn(3,4,0,0,5);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_SRA);
+ ins.address = 2;
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_new_b(0,0,6,7,8);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_SLC);
+ ins.address = 501;
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_new_b(0,6,7,8,3);
+ test.rX_a = mix_word_new_bn(4,0,0,5,0);
+ run_test_(&test, vm, dc);
+}
+
+static void
+test_spc_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+
+ g_print("Testing special instructions...\n");
+ mix_vm_reset(vm);
+ set_cells_(&test,0,0);
+ fill_test_desc_(&test,vm,&ins);
+ mix_ins_fill_from_id(ins,mix_NUM);
+ ins.index = 0;
+ ins.address = 0;
+ test.rA_b = mix_word_new_bn(0,0,31,32,39);
+ test.rX_b = mix_word_new_b(37,57,47,30,30);
+ test.rA_a = mix_word_negative(12977700);
+ test.rX_a = test.rX_b;
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_INCA);
+ ins.address = 1;
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_negative(12977699);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_CHAR);
+ fill_test_desc_(&test, vm, &ins);
+ test.rA_a = mix_word_new_bn(30,30,31,32,39);
+ test.rX_a = mix_word_new_b(37,37,36,39,39);
+ run_test_(&test, vm, dc);
+
+ mix_ins_fill_from_id(ins, mix_HLT);
+ fill_test_desc_(&test, vm, &ins);
+ run_test_(&test, vm, dc);
+ g_assert(mix_vm_is_halted(vm));
+
+}
+
+static void
+test_move_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+ guint k;
+
+ g_print("Testing move instruction...\n");
+ mix_vm_reset(vm);
+ set_cells_(&test,0,10);
+ fill_test_desc_(&test,vm,&ins);
+ mix_ins_fill_from_id(ins,mix_MOVE);
+
+ ins.index = 0;
+ ins.address = 0;
+ ins.fspec = 5;
+ for ( k = 0; k < 5; ++k )
+ test.cells_b[k] = test.cells_a[k+5] = test.cells_a[k] =mix_word_new(100*k);
+
+ test.rI_b[0] = 5;
+ test.rI_a[0] = 10;
+ run_test_(&test,vm,dc);
+
+ free_cells_(&test);
+}
+
+
+
+static void
+test_load_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+ mix_ins_id_t ids[4] = {mix_LDA, mix_LDX, mix_LDAN, mix_LDXN};
+ mix_word_t r_a[14] = {
+ mix_word_new_bn(1,16,3,5,4),
+ mix_word_new_b(1,16,3,5,4),
+ mix_word_new_b(0,0,3,5,4),
+ mix_word_new_bn(0,0,1,16,3),
+ mix_word_new_b(0,0,0,0,5),
+ mix_word_new_b(0,0,0,0,1),
+ MIX_WORD_MINUS_ZERO,
+ mix_word_new_b(1,16,3,5,4),
+ mix_word_new_bn(1,16,3,5,4),
+ mix_word_new_bn(0,0,3,5,4),
+ mix_word_new_b(0,0,1,16,3),
+ mix_word_new_bn(0,0,0,0,5),
+ mix_word_new_bn(0,0,0,0,1),
+ MIX_WORD_ZERO
+ };
+ mix_fspec_t fs[11] = {5,13,29,3,36,9,0,0,0,0,0};
+ mix_address_t a_a[11] = {
+ MIX_SHORT_MINUS_ZERO,
+ mix_short_new_bn(0,1),
+ mix_short_new_bn(1,16),
+ mix_short_new_bn(16,3),
+ mix_short_new_bn(3,5),
+ mix_short_new_bn(5,4),
+ mix_short_new_b(1,16),
+ mix_short_new_b(16,3),
+ mix_short_new_b(5,4),
+ mix_short_new_b(5,4),
+ mix_short_new_b(3,5)
+ };
+ mix_word_t val = mix_word_new_bn(1,16,3,5,4);
+ gint j;
+
+ g_print("Testing load instructions...\n");
+ set_cells_(&test,2000,2001);
+ ins.index = 1;
+ ins.address = mix_short_negative(50);
+
+ mix_vm_reset(vm);
+ mix_vm_set_addr_contents(vm, 2000, val);
+
+ for (j = 0; j < 4; ++j)
+ {
+ gint k;
+ mix_ins_fill_from_id(ins,ids[j]);
+ for ( k = 0; k < 7; ++k ) {
+ fill_test_desc_(&test,vm,&ins);
+ ins.fspec = fs[k];
+ switch (ids[j])
+ {
+ case mix_LDA: test.rA_a = r_a[k]; break;
+ case mix_LDX: test.rX_a = r_a[k]; break;
+ case mix_LDAN: test.rA_a = r_a[k + 7]; break;
+ case mix_LDXN: test.rX_a = r_a[k + 7]; break;
+ default: g_assert_not_reached();
+ }
+ test.rI_b[0] = test.rI_a[0] = 2050;
+ run_test_(&test, vm, dc);
+ }
+ }
+
+ ins.index = 0;
+ ins.address = 2000;
+ fs[0] = 0; fs[1] = 1; fs[2] = 2; fs[3] = 3; fs[4] = 4; fs[5] = 5;
+ fs[6] = 10; fs[7] = 11; fs[8] = 37; fs[9] = 29; fs[10] = 12;
+
+ mix_vm_reset(vm);
+ mix_vm_set_addr_contents(vm, 2000, val);
+ for ( j = 0; j < 14; j++ )
+ {
+ guint k;
+ if (j == 6 || j == 7 ) continue; /* mix_LDX, mix_LDAN */
+ mix_ins_fill_from_id(ins, mix_LD1 + j);
+ for (k = 0; k < 11; ++k)
+ {
+ fill_test_desc_(&test, vm, &ins);
+ ins.fspec = fs[k];
+ if ( j < 6 )
+ test.rI_a[j] = a_a[k];
+ else /* mix_LDiN */
+ test.rI_a[j-8] = mix_short_negative (a_a[k]);
+ run_test_(&test, vm, dc);
+ }
+ }
+
+ free_cells_(&test);
+}
+
+
+static void
+test_store_(mix_vm_t *vm, mix_dump_context_t *dc)
+{
+ test_desc_t test;
+ mix_ins_t ins;
+ mix_word_t reg = mix_word_new_b(6,7,8,9,0);
+ mix_word_t add = mix_word_new_bn(1,2,3,4,5);
+ mix_word_t addr[6] = { mix_word_new_b(6,7,8,9,0),
+ mix_word_new_bn(6,7,8,9,0),
+ mix_word_new_bn(1,2,3,4,0),
+ mix_word_new_bn(1,0,3,4,5),
+ mix_word_new_bn(1,9,0,4,5),
+ mix_word_new_b(0,2,3,4,5)};
+ mix_word_t addri[6] = { mix_word_new_b(0,0,0,9,0),
+ mix_word_new_bn(0,0,0,9,0),
+ mix_word_new_bn(1,2,3,4,0),
+ mix_word_new_bn(1,0,3,4,5),
+ mix_word_new_bn(1,9,0,4,5),
+ mix_word_new_b(0,2,3,4,5)};
+ mix_word_t addrz[6] = { mix_word_new_b(0,0,0,0,0),
+ mix_word_new_bn(0,0,0,0,0),
+ mix_word_new_bn(1,2,3,4,0),
+ mix_word_new_bn(1,0,3,4,5),
+ mix_word_new_bn(1,0,0,4,5),
+ mix_word_new_b(0,2,3,4,5)};
+ mix_fspec_t fs[6] = {5,13,45,18,19,1};
+ gint i,j;
+
+ g_print("Testing store instructions...\n");
+
+ set_cells_(&test,2000,2001);
+ ins.index = 0;
+ ins.address = 2000;
+
+ mix_vm_reset(vm);
+ fill_test_desc_(&test,vm,&ins);
+ test.rA_a = test.rA_b = test.rX_a = test.rX_b = reg;
+ test.rJ_a = test.rJ_b = mix_word_to_short(reg);
+ for (j = 0; j < 6; ++j)
+ test.rI_a[j] = test.rI_b[j] = test.rJ_a;
+ test.cells_b[0] = add;
+
+ for (i = 0; i < 10; ++i)
+ {
+ mix_ins_fill_from_id(ins,mix_STA+i);
+ for (j = 0; j < 6; ++j)
+ {
+ ins.fspec = fs[j];
+ if (i == 0 || i == 7 ) /* mix_STA, mix_STX */
+ test.cells_a[0] = addr[j];
+ else if ( i < 9 ) /* mix_STi, mix_STJ */
+ test.cells_a[0] = addri[j];
+ else /* mix_STZ */
+ test.cells_a[0] = addrz[j];
+ run_test_(&test,vm,dc);
+ }
+ }
+
+ free_cells_(&test);
+}
+
+
+
+int
+main(int argc, const char **argv)
+{
+ mix_vm_t *vm;
+ mix_dump_context_t *dc;
+
+ INIT_TEST;
+
+ vm = mix_vm_new();
+
+#ifdef VERBOSE_TEST
+ dc = mix_dump_context_new(MIX_DUMP_DEF_CHANNEL, 0, 0, MIX_DUMP_ALL);
+#else
+ dc = NULL;
+#endif
+
+ test_arithmetics_(vm, dc);
+ test_shift_(vm, dc);
+ test_spc_(vm,dc);
+ test_move_(vm,dc);
+ test_load_(vm,dc);
+ test_store_(vm,dc);
+
+ mix_vm_delete(vm);
+
+#ifdef VERBOSE_TEST
+ mix_dump_context_delete(dc);
+#endif
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/mixlib/testsuite/test.h b/mixlib/testsuite/test.h
new file mode 100644
index 0000000..7f8eb0c
--- /dev/null
+++ b/mixlib/testsuite/test.h
@@ -0,0 +1,44 @@
+/*
+** Copyright (C) 1999 Free Software Foundation, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+/* Common definitions for test programs */
+
+#ifndef TEST_H
+#define TEST_H
+
+#include <glib.h>
+#include <mix.h>
+
+#define PRINT_BYTE(byte) g_print("%s = %02d",#byte,byte)
+
+#ifdef VERBOSE_TEST /* get printed information */
+#define INIT_TEST \
+ do { g_set_print_handler(NULL); mix_init_lib(); } while(FALSE);
+#else /* no printed information */
+static void
+dummy_print_f_(const gchar *m)
+{
+ /* no output */
+}
+#define INIT_TEST \
+do { g_set_print_handler(dummy_print_f_); mix_init_lib(); } while(FALSE);
+#endif /* VERBOSE_TEST */
+
+
+#endif /* TEST_H */
diff --git a/mixlib/xmix_device.c b/mixlib/xmix_device.c
new file mode 100644
index 0000000..c61ab55
--- /dev/null
+++ b/mixlib/xmix_device.c
@@ -0,0 +1,199 @@
+/* -*-c-*- -------------- xmix_device.c :
+ * Implementation of the functions declared in xmix_device.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "2001-05-10 01:10:25 jao"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "xmix_device.h"
+#include "mix_types.h"
+
+gchar *DEV_DIR_ = NULL;
+
+const char *DEV_EXT_ = ".dev";
+
+const char *DEF_NAMES_[] = {
+ "tape0", "tape1", "tape2", "tape3", "tape4", "tape5", "tape6", "tape7",
+ "disk0", "disk1", "disk2", "disk3", "disk4", "disk5", "disk6", "disk7",
+ "cardrd", "cardwr", "printer", "console", "paper"
+};
+
+const size_t SIZES_[] = {
+ 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100,
+ 16, 16, 24, 14, 14
+};
+
+const mix_device_mode_t MODES_[] = {
+ mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
+ mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
+ mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
+ mix_dev_BIN, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR,
+ mix_dev_CHAR
+};
+
+const mix_fmode_t FMODES_[] = {
+ mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
+ mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
+ mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
+ mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
+ mix_io_READ, mix_io_WRITE, mix_io_WRITE, mix_io_RDWRT, mix_io_READ
+};
+
+/* constructors */
+void
+construct_device_ (mix_device_t *result, mix_device_type_t type)
+{
+ gchar *name;
+ name = DEV_DIR_ ? g_strdup_printf ("%s/%s", DEV_DIR_, DEF_NAMES_[type])
+ : g_strdup (DEF_NAMES_[type]);
+ construct_device_with_name_ (result, type, name);
+ g_free (name);
+}
+
+
+void
+construct_device_with_name_ (mix_device_t *result,
+ mix_device_type_t type, const gchar *name)
+{
+ result->type = type;
+ if (type != mix_dev_CONSOLE)
+ {
+ result->file = MIX_IOCHANNEL(mix_file_new_with_def_ext (name,
+ FMODES_[type],
+ DEV_EXT_));
+ result->vtable = DEF_DEV_VTABLE_;
+ }
+ else
+ {
+ result->file = mix_io_new (stdout);
+ result->vtable = CONSOLE_DEV_VTABLE_;
+ }
+}
+
+
+void
+construct_device_with_file_ (mix_device_t *result,
+ mix_device_type_t type, FILE *file)
+{
+ result->type = type;
+ result->file = mix_io_new (file);
+ result->vtable = DEF_DEV_VTABLE_;
+}
+
+
+/*
+ Write a block to the device.
+*/
+static gboolean
+write_ (mix_device_t *dev, const mix_word_t *block)
+{
+ gboolean result;
+
+ if (FMODES_[dev->type] == mix_io_READ) return FALSE;
+ if (MODES_[dev->type] == mix_dev_CHAR)
+ result = mix_io_write_word_array_as_char (GET_CHANNEL_ (dev),
+ block, SIZES_[dev->type]);
+ else
+ result = mix_io_write_word_array (GET_CHANNEL_ (dev),
+ block, SIZES_[dev->type]);
+ fflush (mix_io_to_FILE (GET_CHANNEL_ (dev)));
+
+ return result;
+}
+
+static gboolean
+read_cons_ (mix_device_t *dev, mix_word_t *block)
+{
+ return mix_io_read_word_array_as_char (mix_io_new (stdin), block,
+ SIZES_[mix_dev_CONSOLE]);
+}
+
+static gboolean
+read_ (mix_device_t *dev, mix_word_t *block)
+{
+ gboolean result;
+
+ if (FMODES_[dev->type] == mix_io_WRITE) return FALSE;
+ if (MODES_[dev->type] == mix_dev_CHAR)
+ {
+ result = mix_io_read_word_array_as_char (GET_CHANNEL_ (dev),
+ block, SIZES_[dev->type]);
+ }
+ else
+ result = mix_io_read_word_array (GET_CHANNEL_ (dev),
+ block, SIZES_[dev->type]);
+
+ return result;
+}
+
+static gboolean
+ioc_ (mix_device_t *dev, mix_short_t arg)
+{
+ int m;
+ FILE *file;
+
+ m = mix_short_magnitude(arg);
+ if (mix_short_is_negative(arg)) m = -m;
+ m *= sizeof (mix_word_t) * SIZES_[dev->type];
+ file = mix_io_to_FILE (GET_CHANNEL_(dev));
+
+ if (dev->type >= mix_dev_TAPE_0 && dev->type <= mix_dev_TAPE_7)
+ {
+ if (m == 0) rewind (file);
+ else fseek (file, m, SEEK_CUR);
+ }
+ if (dev->type >= mix_dev_DISK_0 && dev->type <= mix_dev_DISK_7)
+ {
+ if (m == 0) return FALSE;
+ // position disk
+ }
+ if (dev->type == mix_dev_PAPER_TAPE)
+ {
+ if (m == 0) return FALSE;
+ rewind (file);
+ }
+ return TRUE;
+}
+
+static gboolean
+busy_ (const mix_device_t *dev)
+{
+ return (!mix_io_is_ready (GET_CHANNEL_(dev)));
+}
+
+static void
+destroy_ (mix_device_t *dev)
+{
+ if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL)
+ mix_file_delete (GET_FILE_(dev));
+}
+
+static mix_device_vtable_t VTABLE_ = {
+ write_, read_, ioc_, busy_, destroy_
+};
+
+const mix_device_vtable_t * DEF_DEV_VTABLE_ = &VTABLE_;
+
+static mix_device_vtable_t CVTABLE_ = {
+ write_, read_cons_, ioc_, busy_, destroy_
+};
+
+const mix_device_vtable_t * CONSOLE_DEV_VTABLE_ = &CVTABLE_;
diff --git a/mixlib/xmix_device.h b/mixlib/xmix_device.h
new file mode 100644
index 0000000..0eb3fa8
--- /dev/null
+++ b/mixlib/xmix_device.h
@@ -0,0 +1,96 @@
+/* -*-c-*- ---------------- xmix_device.h :
+ * Protected declarations for mix_device_t
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <2001-05-07 23:59:35 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_DEVICE_H
+#define XMIX_DEVICE_H
+
+#include "mix_file.h"
+#include "mix_device.h"
+
+/* device file directory */
+extern gchar *DEV_DIR_;
+
+/* table of overridable device operations */
+typedef gboolean (*mix_dev_write_func_t) (mix_device_t *, const mix_word_t *);
+typedef gboolean (*mix_dev_read_func_t) (mix_device_t *, mix_word_t *);
+typedef gboolean (*mix_dev_ioc_func_t) (mix_device_t *, mix_short_t);
+typedef gboolean (*mix_dev_busy_func_t) (const mix_device_t *);
+typedef void (*mix_dev_destroy_t) (mix_device_t *);
+
+typedef struct mix_device_vtable_t
+{
+ mix_dev_write_func_t write;
+ mix_dev_read_func_t read;
+ mix_dev_ioc_func_t ioc;
+ mix_dev_busy_func_t busy;
+ mix_dev_destroy_t destroy;
+} mix_device_vtable_t;
+
+/* default vtables */
+extern const mix_device_vtable_t *DEF_DEV_VTABLE_;
+extern const mix_device_vtable_t *CONSOLE_DEV_VTABLE_;
+
+/*
+ Actual definition of a mix device, which can be cast to
+ a mix file.
+*/
+struct mix_device_t
+{
+ mix_iochannel_t *file;
+ mix_device_type_t type;
+ const mix_device_vtable_t *vtable;
+};
+
+/* constructors */
+extern void
+construct_device_ (mix_device_t *dev, mix_device_type_t type);
+
+extern void
+construct_device_with_name_ (mix_device_t *dev,
+ mix_device_type_t type, const gchar *name);
+
+extern void
+construct_device_with_file_ (mix_device_t *dev,
+ mix_device_type_t type, FILE *file);
+
+
+#define GET_CHANNEL_(dev) (dev->file)
+#define GET_FILE_(dev) ((mix_file_t *)(dev->file))
+
+/* default extension for device files */
+extern const char *DEV_EXT_;
+/* default names for device files */
+extern const char *DEF_NAMES_[];
+/* block sizes for devices */
+extern const size_t SIZES_[];
+/* io modes for devices */
+extern const mix_device_mode_t MODES_[];
+/* files modes for devices */
+extern const mix_fmode_t FMODES_[];
+
+
+
+
+#endif /* XMIX_DEVICE_H */
+
diff --git a/mixlib/xmix_eval.h b/mixlib/xmix_eval.h
new file mode 100644
index 0000000..7516ed3
--- /dev/null
+++ b/mixlib/xmix_eval.h
@@ -0,0 +1,55 @@
+/* -*-c-*- ---------------- xmix_eval.h :
+ * Definition of opaque types in mix_eval.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/02/20 00:25:14 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_EVAL_H
+#define XMIX_EVAL_H
+
+#include "mix_eval.h"
+
+/* the evaluator type */
+struct mix_eval_t
+{
+ mix_symbol_table_t *table; /* symbol table */
+ gboolean towner; /* true if owns the table */
+ mix_eval_result_t result; /* last evaluation result */
+ gint errpos; /* location of last error */
+ mix_word_t value; /* last computed value */
+};
+
+/* flex scanner data/result struct */
+typedef struct mix_eval_data_
+{
+ gchar *expr;
+ const mix_symbol_table_t *table;
+ mix_word_t value;
+ mix_short_t loc;
+ gint errpos;
+} mix_eval_data_;
+
+/* flex scanner prototype */
+extern
+mix_eval_result_t mix_eval_expr (mix_eval_data_ *data);
+
+#endif /* XMIX_EVAL_H */
+
diff --git a/mixlib/xmix_io.c b/mixlib/xmix_io.c
new file mode 100644
index 0000000..a43d284
--- /dev/null
+++ b/mixlib/xmix_io.c
@@ -0,0 +1,57 @@
+/* -*-c-*- ------------------ xmix_io.c :
+ * Implementation of the functions declared in xmix_io.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "xmix_io.h"
+
+const char *io_OPENTYPE_[5] = { "r", "w", "w+", "a", "a+" };
+
+
+/* initialise a mix_iochannel from a file descriptor */
+gboolean
+io_init_from_fdesc_(mix_iochannel_t *ioc, int fdesc)
+{
+ FILE *file;
+ mix_fmode_t mode;
+ int flags = fcntl(fdesc, F_GETFL);
+
+ if ( (flags&O_RDONLY) == O_RDONLY )
+ mode = mix_io_READ;
+ else if ( (flags&O_WRONLY) == O_WRONLY )
+ mode = mix_io_WRITE;
+ else if ( (flags&O_RDWR) == O_RDWR )
+ mode = mix_io_RDWRT;
+ else
+ return FALSE;
+
+ file = fdopen(fdesc, fmode_to_type_(mode));
+ g_return_val_if_fail(file != NULL, FALSE);
+ if (mode == mix_io_RDWRT) rewind (file);
+ io_init_from_file_(ioc, file);
+
+ return TRUE;
+}
+
+
+
diff --git a/mixlib/xmix_io.h b/mixlib/xmix_io.h
new file mode 100644
index 0000000..1346559
--- /dev/null
+++ b/mixlib/xmix_io.h
@@ -0,0 +1,64 @@
+/* -*-c-*- ------------------ xmix_io.h :
+ * Implementation of mix_iochannel_t and mix_file_t
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_IOCHANNEL_H
+#define XMIX_IOCHANNEL_H
+
+#include <stdio.h>
+#include "mix_io.h"
+
+/* the actual definition of mix_iochannel_t */
+struct mix_iochannel_t
+{
+ FILE *file;
+};
+
+
+extern const char * io_OPENTYPE_[5];
+
+#define fmode_to_type_(mode) ( (mode) < 6 ? io_OPENTYPE_[(mode)]:NULL )
+
+/* initialisation */
+extern gboolean
+io_init_from_fdesc_(mix_iochannel_t *ioc, int fdesc);
+
+#define io_init_from_file_(ioc,f) (ioc)->file = f
+
+#define io_close_(ioc) fclose((ioc)->file)
+
+/* write/read data */
+#define write_data_(ioc,data,no) \
+ ( (no) == fwrite((const void*)(data), sizeof(*(data)), (no), (ioc)->file) )
+
+#define read_data_(ioc,data,no) \
+ ( (no) == fread((void*)(data), sizeof(*(data)), (no), (ioc)->file) )
+
+/* state */
+#define is_eof_(ioc) ( feof((ioc)->file) != 0 )
+#define is_ready_(ioc) ( ferror((ioc)->file) == 0 )
+
+/* conversions */
+#define io_get_FILE_(ioc) (MIX_IOCHANNEL(ioc))->file
+
+
+#endif /* XMIX_IOCHANNEL_H */
+
diff --git a/mixlib/xmix_parser.h b/mixlib/xmix_parser.h
new file mode 100644
index 0000000..51f1560
--- /dev/null
+++ b/mixlib/xmix_parser.h
@@ -0,0 +1,111 @@
+/* -*-c-*- ---------------- xmix_parser.h :
+ * Declarations for the implementation of mix_parser_t
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_PARSER_H
+#define XMIX_PARSER_H
+
+#include "mix_ins.h"
+#include "mix_file.h"
+#include "mix_symbol_table.h"
+#include "mix_parser.h"
+
+/* mix_parser_t definition */
+struct mix_parser_t
+{
+ mix_file_t *in_file; /* the source file to be compiled */
+ mix_symbol_table_t *symbol_table;
+ mix_symbol_table_t *ls_table; /* literal strings symbols */
+ guint cur_ls; /* current literal string symbol */
+ GHashTable *future_refs; /* a map from symbol name to list of addresses */
+ GTree *ins_table; /* a table of compiled instructions */
+ GSList *con_list; /* CON instructions */
+ GSList *alf_list; /* ALF instructions */
+ mix_address_t loc_count; /* current memory location during compilation */
+ mix_parser_err_t status; /* outcome of compilation */
+ guint err_line; /* line of the last error */
+ guint err_count; /* no. of errors during compilation */
+ guint warn_count; /* no. of warnings during compilation */
+ mix_address_t start; /* start address of the compiled code */
+ mix_address_t end; /* end address of the compiled code */
+};
+
+/* each node of the ins_table stores a mix_word_t with the instruction
+ and a source code line (for debugging and listing)
+*/
+typedef struct ins_node_
+{
+ mix_word_t ins;
+ guint lineno;
+} ins_node_;
+
+
+/* functions to manipulate mix_parser_t during compilation */
+
+/* access loc counter */
+#define get_ploc_(parser) ((parser)->loc_count)
+
+/* symbol table */
+/* Define a new symbol with given value
+ * and update previously set refs to this symbol
+ */
+extern mix_parser_err_t
+mix_parser_define_symbol_value (mix_parser_t *parser, const gchar *name,
+ mix_word_t value);
+
+/* Define a new symbol with value equal to the current loc_count
+ * and update previously set refs to this symbol
+ */
+extern mix_parser_err_t
+mix_parser_define_symbol_here (mix_parser_t *parser, const gchar *name);
+
+/* Set a reference to future symbol here */
+extern void
+mix_parser_set_future_ref (mix_parser_t *parser, const gchar *name);
+
+/* Redefine the value of a local symbol as the current loc_count */
+extern void
+mix_parser_manage_local_symbol (mix_parser_t *parser, const gchar *name,
+ mix_short_t value);
+
+/* Literal strings symbols */
+extern void
+mix_parser_define_ls (mix_parser_t *parser, mix_word_t value);
+
+/* Compilation */
+/* Add instruction with address the current loc_count */
+extern void
+mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
+ guint lineno);
+extern void
+mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno,
+ gboolean is_con);
+
+/* Error handling */
+extern void
+mix_parser_log_error (mix_parser_t *parser, mix_parser_err_t error,
+ gint lineno, const gchar *comment, gboolean warn);
+
+
+
+
+#endif /* XMIX_PARSER_H */
+
diff --git a/mixlib/xmix_vm.c b/mixlib/xmix_vm.c
new file mode 100644
index 0000000..d5b4e4b
--- /dev/null
+++ b/mixlib/xmix_vm.c
@@ -0,0 +1,598 @@
+/* ---------------------- xmix_vm.c :
+ * Implementation of the functions declared in xmix_vm.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include "xmix_vm.h"
+
+/* auxiliar functions */
+G_INLINE_FUNC mix_address_t
+get_M_ (const mix_vm_t *vm, const mix_ins_t *ins);
+G_INLINE_FUNC mix_word_t
+get_V_ (const mix_vm_t *vm, const mix_ins_t *ins);
+G_INLINE_FUNC mix_device_t *
+get_dev_ (mix_vm_t *vm, mix_fspec_t type);
+
+G_INLINE_FUNC mix_address_t
+get_M_ (const mix_vm_t *vm, const mix_ins_t *ins)
+{
+ if ( ins->index == 0 )
+ return ins->address;
+ else
+ return mix_short_add (ins->address,
+ mix_word_to_short_fast (get_rI_ (vm, ins->index)));
+}
+
+G_INLINE_FUNC mix_word_t
+get_V_ (const mix_vm_t *vm, const mix_ins_t *ins)
+{
+ return mix_word_get_field (ins->fspec, get_cell_ (vm, get_M_ (vm,ins)));
+}
+
+G_INLINE_FUNC mix_device_t *
+get_dev_ (mix_vm_t *vm, mix_fspec_t type)
+{
+ if (type >= BD_NO_) return NULL;
+ if (vm->devices[type] == NULL)
+ vm->devices[type] = vm->factory (type);
+ return vm->devices[type];
+}
+
+/* error macro */
+#define fail_if_not_(vm,cond,error) \
+do { \
+ if (!(cond)) \
+ { \
+ set_last_error_ (vm, error); \
+ return FALSE; \
+ } \
+} while (FALSE)
+
+#define fail_(vm,error) fail_if_not_ (vm, FALSE, error)
+
+#define fail_unexpected_(vm) fail_ (vm, MIX_VM_ERROR_UNEXPECTED)
+
+/* Instruction handlers */
+
+static gboolean
+nop_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opNOP);
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+add_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_word_t val = get_V_ (vm, ins);
+ g_assert (ins->opcode == mix_opADD || ins->opcode == mix_opSUB);
+ if ( ins->opcode == mix_opSUB ) mix_word_reverse_sign (val);
+ if ( mix_word_add_and_carry (get_rA_ (vm), val, NULL, &get_rA_ (vm)) )
+ set_over_ (vm,TRUE);
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+
+static gboolean
+mul_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opMUL);
+ mix_word_mul (get_rA_ (vm), get_V_ (vm,ins), &get_rA_ (vm), &get_rX_ (vm));
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+div_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opDIV);
+ if ( mix_word_div (get_rA_ (vm), get_rX_ (vm), get_V_ (vm,ins),
+ &get_rA_ (vm), &get_rX_ (vm)) )
+ set_over_ (vm,TRUE);
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+spc_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opSPC);
+
+ switch (mix_ins_id_from_ins (*ins)) {
+ case mix_HLT: halt_ (vm, TRUE); break;
+ case mix_CHAR:
+ {
+ guint32 num = mix_word_magnitude (get_rA_ (vm));
+ mix_char_t z = mix_ascii_to_char ('0');
+ guint i;
+ for (i = 5; 0 < i; --i, num /= 10)
+ mix_word_set_byte (&get_rX_ (vm), i, z + num % 10);
+ for (i = 5; 0 < i; --i, num /= 10)
+ mix_word_set_byte (&get_rA_ (vm), i, z + num % 10);
+ break;
+ }
+ case mix_NUM:
+ {
+ guint i;
+ mix_word_t num = MIX_WORD_ZERO;
+ mix_word_t ten = 10;
+ for (i = 1; i <= 5; ++i) {
+ mix_word_mul (ten, num, NULL, &num);
+ mix_word_add_and_carry (num, mix_word_get_byte (get_rA_ (vm),i)%10,
+ NULL, &num);
+ }
+ for (i = 1; i <= 5; ++i) {
+ mix_word_mul (ten, num, NULL, &num);
+ mix_word_add_and_carry (num, mix_word_get_byte (get_rX_ (vm),i)%10,
+ NULL, &num);
+ }
+ set_rA_ (vm, mix_word_is_negative (get_rA_ (vm)) ?
+ mix_word_negative (num) : num);
+ break;
+ }
+ default: fail_ (vm, MIX_VM_ERROR_BAD_FSPEC);
+ }
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+sla_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_short_t n = get_M_ (vm,ins);
+
+ g_assert (ins->opcode == mix_opSLx);
+
+ fail_if_not_ (vm, mix_short_is_positive (n), MIX_VM_ERROR_BAD_M);
+
+ switch ( mix_ins_id_from_ins (*ins) ) {
+ case mix_SLA:
+ mix_word_shift_left (get_rA_ (vm), MIX_WORD_ZERO, n, &get_rA_ (vm), NULL);
+ break;
+ case mix_SRA:
+ mix_word_shift_right (get_rA_ (vm), MIX_WORD_ZERO, n, &get_rA_ (vm), NULL);
+ break;
+ case mix_SLAX:
+ mix_word_shift_left (get_rA_ (vm), get_rX_ (vm), n,
+ &get_rA_ (vm), &get_rX_ (vm));
+ break;
+ case mix_SRAX:
+ mix_word_shift_right (get_rA_ (vm), get_rX_ (vm), n,
+ &get_rA_ (vm), &get_rX_ (vm));
+ break;
+ case mix_SLC:
+ mix_word_shift_left_circular (get_rA_ (vm), get_rX_ (vm), n,
+ &get_rA_ (vm), &get_rX_ (vm));
+ break;
+ case mix_SRC:
+ mix_word_shift_right_circular (get_rA_ (vm), get_rX_ (vm), n,
+ &get_rA_ (vm), &get_rX_ (vm));
+ break;
+ default:
+ fail_unexpected_ (vm);
+ }
+
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+mov_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_short_t from = get_M_ (vm,ins),
+ to = mix_word_to_short_fast (get_rI_ (vm,1));
+ guint k, delta = ins->fspec;
+
+ g_assert (ins->opcode == mix_opMOVE);
+ if (mix_short_is_positive (from)
+ && mix_short_is_positive (to)
+ && MEMOK_ (from + delta -1)
+ && MEMOK_ (to + delta - 1))
+ {
+ for (k = 0; k < delta; ++k)
+ set_cell_ (vm, to+k, get_cell_ (vm, from+k));
+ set_rI_ (vm, 1, to+delta);
+ inc_loc_ (vm);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+lda_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ gint r = 0;
+ mix_word_t val;
+ mix_ins_id_t id = mix_ins_id_from_ins (*ins);
+
+ g_assert (id >= mix_LDA && id <= mix_LDXN);
+
+ val = get_V_ (vm, ins);
+ if (id > mix_LDX) mix_word_reverse_sign (val);
+ if ( (id > mix_LDA && id < mix_LDX) || (id > mix_LDAN && id < mix_LDXN) )
+ /* Bytes 1-3 of I regs are always null */
+ val = mix_word_set_field (mix_fspec_new (1,3),MIX_WORD_ZERO,val);
+
+ switch (id) {
+ case mix_LDA: case mix_LDAN: r = A_; break;
+ case mix_LDX: case mix_LDXN: r = X_; break;
+ case mix_LD1: case mix_LD1N: r = I1_; break;
+ case mix_LD2: case mix_LD2N: r = I2_; break;
+ case mix_LD3: case mix_LD3N: r = I3_; break;
+ case mix_LD4: case mix_LD4N: r = I4_; break;
+ case mix_LD5: case mix_LD5N: r = I5_; break;
+ case mix_LD6: case mix_LD6N: r = I6_; break;
+ default: g_assert_not_reached ();
+ }
+ set_reg_ (vm, r, val);
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+
+static gboolean
+sta_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_address_t addr = get_M_ (vm, ins);
+ mix_ins_id_t id = mix_ins_id_from_ins (*ins);
+ mix_word_t from;
+
+ g_assert (id >= mix_STA && id <= mix_STZ);
+ switch (id) {
+ case mix_STA: from = get_rA_ (vm); break;
+ case mix_STX: from = get_rX_ (vm); break;
+ case mix_STJ: from = get_rJ_ (vm); break;
+ case mix_STZ: from = MIX_WORD_ZERO; break;
+ default: from = get_rI_ (vm, id - mix_ST1 + 1); break;
+ }
+ set_cell_ (vm, addr,
+ mix_word_store_field (ins->fspec, from, get_cell_ (vm, addr)));
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+jbs_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opJBUS);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+ fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL,
+ MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ if ( mix_device_busy (get_dev_ (vm, ins->fspec)) ) {
+ set_rJ_ (vm, get_loc_ (vm));
+ set_loc_ (vm, get_M_ (vm, ins));
+ } else inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+ioc_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_address_t addr;
+ mix_device_t *dev;
+
+ g_assert (ins->opcode == mix_opIOC);
+
+ addr = get_M_ (vm, ins);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ dev = get_dev_ (vm, ins->fspec);
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, mix_device_ioc (dev, addr), MIX_VM_ERROR_DEV_CTL);
+
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+inp_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_address_t addr;
+ mix_device_t *dev;
+
+ g_assert (ins->opcode == mix_opIN);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ addr = get_M_ (vm, ins);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
+ dev = get_dev_ (vm, ins->fspec);
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev),
+ MIX_VM_ERROR_BAD_ACCESS);
+
+ fail_if_not_ (vm, mix_device_read (dev, get_cell_ptr_ (vm, addr)),
+ MIX_VM_ERROR_DEV_READ);
+
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+out_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_address_t addr;
+ mix_device_t *dev;
+
+ g_assert (ins->opcode == mix_opOUT);
+
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ addr = get_M_ (vm, ins);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
+ dev = get_dev_ (vm, ins->fspec);
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev),
+ MIX_VM_ERROR_BAD_ACCESS);
+
+ fail_if_not_ (vm, mix_device_write (dev, get_cell_ptr_ (vm, addr)),
+ MIX_VM_ERROR_DEV_WRITE);
+
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+jrd_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode == mix_opJRED);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+ fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL,
+ MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ inc_loc_ (vm);
+ if ( !mix_device_busy (get_dev_ (vm, ins->fspec)) )
+ {
+ set_rJ_ (vm, get_loc_ (vm));
+ set_loc_ (vm, get_M_ (vm, ins));
+ }
+ return TRUE;
+}
+
+static gboolean
+jmp_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ gboolean jump = FALSE;
+ mix_address_t addr = get_M_ (vm, ins);
+ mix_ins_id_t id = mix_ins_id_from_ins (*ins);
+
+ g_assert (ins->opcode == mix_opJMP);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
+ switch ( id ) {
+ case mix_JMP:
+ case mix_JSJ:
+ jump = TRUE;
+ break;
+ case mix_JOV:
+ jump = get_over_ (vm);
+ if (jump) set_over_ (vm, FALSE);
+ break;
+ case mix_JNOV:
+ jump = !get_over_ (vm);
+ set_over_ (vm, FALSE);
+ break;
+ case mix_JL:
+ jump = ( get_cmp_ (vm) == mix_LESS );
+ break;
+ case mix_JE:
+ jump = ( get_cmp_ (vm) == mix_EQ );
+ break;
+ case mix_JG:
+ jump = ( get_cmp_ (vm) == mix_GREAT );
+ break;
+ case mix_JGE:
+ jump = ( get_cmp_ (vm) != mix_LESS );
+ break;
+ case mix_JNE:
+ jump = ( get_cmp_ (vm) != mix_EQ );
+ break;
+ case mix_JLE:
+ jump = ( get_cmp_ (vm) != mix_GREAT );
+ break;
+ default:
+ fail_unexpected_ (vm);
+ }
+
+ inc_loc_ (vm);
+ if ( jump ) {
+ if ( id != mix_JSJ ) set_rJ_ (vm, get_loc_ (vm));
+ set_loc_ (vm, addr);
+ }
+ return TRUE;
+}
+
+static gboolean
+jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ gboolean jump = FALSE;
+ mix_address_t addr = get_M_ (vm, ins);
+ mix_ins_id_t id = mix_ins_id_from_ins (*ins);
+ mix_word_t val;
+
+ g_assert (ins->opcode >= mix_opJAx || ins->opcode <= mix_opJXx);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
+ switch (ins->opcode) {
+ case mix_opJAx: val = get_rA_ (vm); break;
+ case mix_opJXx: val = get_rX_ (vm); break;
+ default: val = get_rI_ (vm, ins->opcode - mix_opJAx);
+ }
+
+ switch (id) {
+ case mix_JAN: case mix_JXN:
+ case mix_J1N: case mix_J2N: case mix_J3N:
+ case mix_J4N: case mix_J5N: case mix_J6N:
+ jump = mix_word_is_negative (val) && val != MIX_WORD_MINUS_ZERO;
+ break;
+ case mix_JAZ: case mix_JXZ:
+ case mix_J1Z: case mix_J2Z: case mix_J3Z:
+ case mix_J4Z: case mix_J5Z: case mix_J6Z:
+ jump = mix_word_magnitude (val) == MIX_WORD_ZERO;
+ break;
+ case mix_JAP: case mix_JXP:
+ case mix_J1P: case mix_J2P: case mix_J3P:
+ case mix_J4P: case mix_J5P: case mix_J6P:
+ jump = mix_word_is_positive (val) && val != MIX_WORD_ZERO;
+ break;
+ case mix_JANN: case mix_JXNN:
+ case mix_J1NN: case mix_J2NN: case mix_J3NN:
+ case mix_J4NN: case mix_J5NN: case mix_J6NN:
+ jump = mix_word_magnitude (val) == MIX_WORD_ZERO
+ || mix_word_is_positive (val);
+ break;
+ case mix_JANZ: case mix_JXNZ:
+ case mix_J1NZ: case mix_J2NZ: case mix_J3NZ:
+ case mix_J4NZ: case mix_J5NZ: case mix_J6NZ:
+ jump = mix_word_magnitude (val) != MIX_WORD_ZERO;
+ break;
+ case mix_JANP: case mix_JXNP:
+ case mix_J1NP: case mix_J2NP: case mix_J3NP:
+ case mix_J4NP: case mix_J5NP: case mix_J6NP:
+ jump = mix_word_magnitude (val) == MIX_WORD_ZERO
+ || mix_word_is_negative (val);
+ break;
+ default:
+ fail_unexpected_ (vm);
+ }
+
+ inc_loc_ (vm);
+ if ( jump ) {
+ set_rJ_ (vm, get_loc_ (vm));
+ set_loc_ (vm, addr);
+ }
+ return TRUE;
+}
+
+static gboolean
+ina_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ mix_word_t val = mix_short_to_word_fast (get_M_ (vm, ins));
+ mix_ins_id_t id = mix_ins_id_from_ins (*ins);
+ gint r;
+
+ g_assert (id >= mix_INCA && id <= mix_ENNX);
+
+ switch (ins->opcode) {
+ case mix_opINCA: r = A_; break;
+ case mix_opINCX: r = X_; break;
+ default: r = I1_ + ins->opcode - mix_opINC1;
+ }
+
+ switch (id) {
+ case mix_ENTA: case mix_ENTX:
+ break;
+ case mix_ENT1: case mix_ENT2: case mix_ENT3:
+ case mix_ENT4: case mix_ENT5: case mix_ENT6:
+ val = mix_word_set_field (mix_fspec_new (1,3), MIX_WORD_ZERO, val);
+ break;
+ case mix_INCA: case mix_INCX:
+ if ( mix_word_add_and_carry (val, get_reg_ (vm, r), NULL, &val) )
+ set_over_ (vm, TRUE);
+ break;
+ case mix_INC1: case mix_INC2: case mix_INC3:
+ case mix_INC4: case mix_INC5: case mix_INC6:
+ mix_word_add_and_carry (val, get_reg_ (vm,r), NULL, &val);
+ val = mix_word_set_field (mix_fspec_new (1,3), MIX_WORD_ZERO, val);
+ break;
+ case mix_DECA: case mix_DECX:
+ if ( mix_word_add_and_carry (mix_word_negative (val), get_reg_ (vm, r),
+ NULL, &val) )
+ set_over_ (vm, TRUE);
+ break;
+ case mix_DEC1: case mix_DEC2: case mix_DEC3:
+ case mix_DEC4: case mix_DEC5: case mix_DEC6:
+ mix_word_add_and_carry (mix_word_negative (val), get_reg_ (vm,r),
+ NULL, &val);
+ val = mix_word_set_field (mix_fspec_new (1,3), MIX_WORD_ZERO, val);
+ break;
+ case mix_ENN1: case mix_ENN2: case mix_ENN3:
+ case mix_ENN4: case mix_ENN5: case mix_ENN6:
+ val = mix_word_set_field (mix_fspec_new (1,3), MIX_WORD_ZERO, val);
+ /* fallthrough */
+ case mix_ENNA: case mix_ENNX:
+ mix_word_reverse_sign (val);
+ break;
+ default:
+ fail_unexpected_ (vm);
+ }
+ set_reg_ (vm, r, val);
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+static gboolean
+cmp_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
+{
+ g_assert (ins->opcode >= mix_opCMPA && ins->opcode <= mix_opCMPX);
+
+ if ( ins->fspec == 0 ) { /* shortcut: +0 == -0 */
+ set_cmp_ (vm, mix_EQ);
+ } else {
+ mix_word_t v = get_V_ (vm, ins);
+ mix_word_t reg;
+ mix_cmpflag_t flag;
+
+ switch (ins->opcode) {
+ case mix_opCMPA:
+ reg = get_rA_ (vm);
+ break;
+ case mix_opCMPX:
+ reg = get_rX_ (vm);
+ break;
+ default:
+ reg = get_rI_ (vm, ins->opcode - mix_opCMPA);
+ break;
+ }
+ reg = mix_word_get_field (ins->fspec, reg);
+ mix_word_add_and_carry (reg, mix_word_negative (v), NULL, &reg);
+ if ( mix_word_magnitude (reg) == MIX_WORD_ZERO ) flag = mix_EQ;
+ else if ( mix_word_is_positive (reg) ) flag = mix_GREAT;
+ else flag = mix_LESS;
+ set_cmp_ (vm, flag);
+ }
+ inc_loc_ (vm);
+ return TRUE;
+}
+
+ins_handler_t_ ins_handlers_[MIX_BYTE_MAX + 1] = {
+ nop_handler_, add_handler_, add_handler_, mul_handler_, div_handler_,
+ spc_handler_, sla_handler_, mov_handler_, lda_handler_, lda_handler_,
+ lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_,
+ lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_,
+ lda_handler_, lda_handler_, lda_handler_, lda_handler_, sta_handler_,
+ sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_,
+ sta_handler_, sta_handler_, sta_handler_, sta_handler_, jbs_handler_,
+ ioc_handler_, inp_handler_, out_handler_, jrd_handler_, jmp_handler_,
+ jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_,
+ jpx_handler_, jpx_handler_, jpx_handler_, ina_handler_, ina_handler_,
+ ina_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_,
+ ina_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_,
+ cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_,
+};
diff --git a/mixlib/xmix_vm.h b/mixlib/xmix_vm.h
new file mode 100644
index 0000000..7a634d4
--- /dev/null
+++ b/mixlib/xmix_vm.h
@@ -0,0 +1,139 @@
+/* ---------------------- xmix_vm.h :
+ * This file contains internal declarations used in the implementation
+ * of the mix_vm_t type.
+ * ------------------------------------------------------------------
+ * $Id: xmix_vm.h,v 1.10 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_VM_H
+#define XMIX_VM_H
+
+#include <string.h>
+
+#include "mix_symbol_table.h"
+#include "mix_device.h"
+#include "mix_src_file.h"
+#include "mix_predicate_list.h"
+#include "mix_vm.h"
+
+/* The mix_vm_t type */
+enum {
+ IREG_NO_ = 6,
+ BD_NO_ = 21,
+ MEM_CELLS_NO_ = MIX_VM_CELL_NO,
+ MEM_CELLS_MAX_ = MIX_VM_CELL_NO - 1
+};
+
+struct mix_vm_t
+{
+ mix_word_t reg[IREG_NO_+3];
+ mix_word_t cell[MEM_CELLS_NO_];
+ gboolean overflow;
+ mix_cmpflag_t cmpflag;
+ mix_short_t loc_count;
+ mix_vm_status_t status;
+ mix_vm_error_t last_error;
+ mix_device_t * devices[BD_NO_];
+ mix_address_t start_addr; /* start address of loaded file */
+ GTree *line_table; /* source line no -> address */
+ GTree *address_table; /* adress -> source line no */
+ gint8 bp[MEM_CELLS_NO_/8]; /* each bit signals a break point */
+ mix_vm_clock_t *clock; /* the vm clock */
+ mix_symbol_table_t *symbol_table;
+ mix_src_file_t *src_file; /* source of last loaded code file */
+ mix_device_factory_t factory; /* the factory for new devices */
+ mix_predicate_list_t *pred_list; /* predicates for conditional bps */
+ GSList *address_list; /* list of executed addresses */
+};
+
+/* Macros for accessing/modifying the above structure.
+ * Warning: the arguments of these macros must not have side-effects.
+ */
+#define IOK_(idx) ( (idx) > 0 && (idx) < IREG_NO_+1 )
+#define MEMOK_(addr) ( mix_short_is_positive(addr) && (addr) < MEM_CELLS_NO_ )
+#define REGOK_(r) ( (r) >= 0 && (r) < IREG_NO_ + 3 )
+
+enum { A_ = 0, X_, J_, I1_, I2_, I3_, I4_, I5_, I6_ };
+
+#define get_reg_(vm, r) ((vm)->reg[r])
+#define get_rA_(vm) get_reg_(vm, A_)
+#define get_rX_(vm) get_reg_(vm, X_)
+#define get_rJ_(vm) get_reg_(vm, J_)
+#define get_rI_(vm,idx) get_reg_(vm, I1_ + (idx) - 1)
+#define get_cell_(vm,addr) ( MEMOK_(addr) ? vm->cell[addr] : MIX_WORD_ZERO )
+#define get_cell_ptr_(vm,addr) ( MEMOK_(addr) ? (vm->cell) + addr : NULL )
+#define get_cmp_(vm) (vm->cmpflag)
+#define get_over_(vm) (vm->overflow)
+#define get_loc_(vm) (vm->loc_count)
+#define get_clock_(vm) (vm->clock)
+#define get_pred_list_(vm) (vm->pred_list)
+#define get_address_list_(vm) (vm->address_list)
+#define get_status_(vm) (vm->status)
+#define get_last_error_(vm) (vm->last_error)
+#define set_last_error_(vm,error) ((vm)->last_error = (error))
+
+#define set_reg_(vm,r,x) \
+do { \
+ if ( REGOK_(r) ) vm->reg[r] = (x); \
+} while (FALSE)
+
+#define set_rA_(vm,x) set_reg_(vm,A_,x)
+#define set_rX_(vm,x) set_reg_(vm,X_,x)
+#define set_rJ_(vm,x) set_reg_(vm,J_,(x)&MIX_SHORT_MAX)
+#define set_rI_(vm,idx,x) set_reg_(vm,(idx) + I1_ - 1,x)
+
+#define set_cell_(vm,addr,x) \
+do { \
+ if ( MEMOK_(addr) ) (vm)->cell[addr] = (x); \
+} while (FALSE)
+
+#define set_cmp_(vm,x) (vm)->cmpflag = (x)
+#define set_over_(vm,x) (vm)->overflow = (x)
+#define set_loc_(vm,x) (vm)->loc_count = (MEMOK_(x)? (x) : MIX_SHORT_ZERO)
+
+#define set_status_(vm,s) ((vm)->status = (s))
+#define is_halted_(vm) ((vm)->status == MIX_VM_HALT)
+#define halt_(vm,val) ((vm)->status = (val)? MIX_VM_HALT : MIX_VM_RUNNING)
+
+#define inc_loc_(vm) \
+do { \
+ if (++(vm->loc_count) == MEM_CELLS_NO_) \
+ { vm->loc_count--; halt_(vm, TRUE); } \
+} while(FALSE)
+
+#define set_start_(vm,val) ((vm)->start_addr = (val))
+#define reset_loc_(vm) set_loc_ (vm, vm->start_addr)
+#define update_time_(vm,ins) mix_vm_clock_add_lapse (get_clock_(vm), ins)
+
+/* Breakpoints handling */
+#define bp_clear_all_(vm) memset (vm->bp, 0, MEM_CELLS_NO_/8)
+#define bp_set_(vm,addr) vm->bp[(addr)>>3] |= 1 << ((addr)&7)
+#define bp_clear_(vm,addr) vm->bp[(addr)>>3] &= ~(1 << ((addr)&7))
+#define bp_is_set_(vm,addr) vm->bp[(addr)>>3] & (1 << ((addr)&7))
+
+/* Instruction handlers */
+typedef gboolean (*ins_handler_t_)(mix_vm_t *,const mix_ins_t *);
+
+extern ins_handler_t_ ins_handlers_[MIX_BYTE_MAX + 1];
+
+
+#endif /* XMIX_VM_H */
+
diff --git a/mixlib/xmix_vm_command.c b/mixlib/xmix_vm_command.c
new file mode 100644
index 0000000..370ffb7
--- /dev/null
+++ b/mixlib/xmix_vm_command.c
@@ -0,0 +1,64 @@
+/* -*-c-*- -------------- xmix_vm_command.c :
+ * Implementation of the functions declared in xmix_vm_command.h
+ * ------------------------------------------------------------------
+ * $Id: xmix_vm_command.c,v 1.4 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "xmix_vm_command.h"
+
+/* configuration keys */
+const gchar *TRACING_KEY_ = "Tracing";
+const gchar *TIMING_KEY_ = "Timing";
+const gchar *EDITOR_KEY_ = "Editor";
+const gchar *ASM_KEY_ = "Assembler";
+const gchar *LOGGING_KEY_ = "Logs";
+
+void
+log_message_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...)
+{
+ if (dis && fmt && dis->log_msg && dis->out)
+ {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (dis->out, fmt, args);
+ fprintf (dis->out, "\n");
+ va_end (args);
+ }
+}
+
+
+extern void
+log_error_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...)
+{
+ enum {BUFF_SIZE = 256};
+ static gchar BUFFER[256];
+
+ if (dis && fmt && dis->err)
+ {
+ va_list args;
+ va_start (args, fmt);
+ g_snprintf (BUFFER, BUFF_SIZE, "ERROR: %s\n", fmt);
+ vfprintf (dis->err, BUFFER, args);
+ va_end (args);
+ }
+}
diff --git a/mixlib/xmix_vm_command.h b/mixlib/xmix_vm_command.h
new file mode 100644
index 0000000..ae2c2e7
--- /dev/null
+++ b/mixlib/xmix_vm_command.h
@@ -0,0 +1,102 @@
+/* -*-c-*- ---------------- xmix_vm_command.h :
+ * Private type declarations form mix_vm_command
+ * ------------------------------------------------------------------
+ * $Id: xmix_vm_command.h,v 1.5 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_VM_COMMAND_H
+#define XMIX_VM_COMMAND_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "mix.h"
+#include "mix_device.h"
+#include "mix_vm.h"
+#include "mix_vm_dump.h"
+#include "mix_eval.h"
+#include "mix_predicate.h"
+#include "mix_vm_command.h"
+
+
+/* configuration keys */
+extern const gchar *TRACING_KEY_;
+extern const gchar *TIMING_KEY_;
+extern const gchar *EDITOR_KEY_;
+extern const gchar *ASM_KEY_;
+extern const gchar *LOGGING_KEY_;
+
+/* hooks */
+typedef struct
+{
+ mix_vm_cmd_hook_t func;
+ gpointer data;
+} hook_;
+
+typedef struct
+{
+ mix_vm_cmd_global_hook_t func;
+ gpointer data;
+} global_hook_;
+
+enum {PRNO_ = MIX_PRED_MEM, HOOKNO_ = MIX_CMD_INVALID};
+
+struct mix_vm_cmd_dispatcher_t
+{
+ mix_vm_t *vm; /* the virtual machine */
+ gboolean result; /* last command's outcome */
+ gchar *program; /* the name of the last loaded program */
+ gchar *editor; /* edit command line template */
+ gchar *assembler; /* compile command line template */
+ FILE *out; /* message output file */
+ FILE *err; /* error output file */
+ mix_dump_context_t *dump; /* dump context for output */
+ mix_eval_t *eval; /* evaluator for w-expressions */
+ gboolean trace; /* tracing flag */
+ gboolean printtime; /* printing times flag */
+ mix_time_t uptime; /* total running time */
+ mix_time_t laptime; /* last run time */
+ mix_time_t progtime; /* current program running time */
+ GHashTable *commands; /* local commands */
+ GCompletion *completions; /* command completion list */
+ GSList *pre_hooks[HOOKNO_]; /* Pre-command hooks */
+ GSList *post_hooks[HOOKNO_]; /* Post-command hooks */
+ GSList *global_pre; /* global pre-command hook */
+ GSList *global_post; /* global post-command hook */
+ mix_config_t *config; /* externally provided configuration */
+ mix_predicate_t *preds[PRNO_]; /* predicates for conditional breakpoints */
+ GHashTable *mem_preds; /* predicates for memory conditional bps */
+ gboolean log_msg; /* message logging activation flag*/
+};
+
+extern void
+log_message_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...);
+
+extern void
+log_error_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...);
+
+#define wants_logs_(dis) (dis)->log_msg
+
+#endif /* XMIX_VM_COMMAND_H */
+
diff --git a/mixlib/xmix_vm_handlers.c b/mixlib/xmix_vm_handlers.c
new file mode 100644
index 0000000..ba7052b
--- /dev/null
+++ b/mixlib/xmix_vm_handlers.c
@@ -0,0 +1,1387 @@
+/* -*-c-*- -------------- xmix_vm_handlers.c :
+ * Implementation of the functions declared in xmix_vm_handlers.h
+ * ------------------------------------------------------------------
+ * $Id: xmix_vm_handlers.c,v 1.10 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "xmix_vm_handlers.h"
+
+/* available commands (in the same order as the type enum) */
+mix_vm_command_info_t commands_[] = {
+ { "help", cmd_help_, N_("Display this text"), "help [COMMAND]"},
+ { "load", cmd_load_, N_("Load a MIX code file"), "load FILENAME"},
+ { "edit", cmd_edit_, N_("Edit a MIXAL source file"), "edit [FILENAME]"},
+ { "pedit", cmd_pedit_, N_("Print the external editor command"), "pedit"},
+ { "sedit", cmd_sedit_, N_("Set the external editor command"),
+ "sedit COMMAND (e.g. emacs %s)"},
+ { "compile", cmd_compile_, N_("Compile a MIXAL source file"),
+ "compile [FILENAME]"},
+ { "pasm", cmd_pasm_, N_("Print the compile command"), "pasm"},
+ { "sasm", cmd_sasm_, N_("Set the compile command"),
+ "sasm COMMAND (e.g. mixasm -g -l %s)"},
+ { "run", cmd_run_, N_("Run loaded or given MIX code file"),
+ "run [FILENAME]"},
+ { "next", cmd_next_, N_("Execute next instruction(s)"),
+ "next [NO_OF_INS]"},
+ { "pstat", cmd_pstat_, N_("Print current vm status"), "pstat"},
+ { "pc", cmd_pc_, N_("Print program counter value"), "pc" },
+ { "psym", cmd_psym_, N_("Print symbol value"), "psym [SYMBOLNAME]"},
+ { "preg", cmd_preg_, N_("Print register value"),
+ "preg [A | X | J | I[1-6]]"},
+ { "pflags", cmd_pflags_, N_("Print comparison and overflow flags"),
+ "pflags"},
+ { "pall", cmd_pall_, N_("Print all registers and flags"), "pall"},
+ { "pmem", cmd_pmem_, N_("Print memory contents in address range"),
+ "pmem FROM[-TO]"},
+ { "sreg", cmd_sreg_, N_("Set register value"),
+ "sreg A | X | J | I[1-6] VALUE"},
+ { "scmp", cmd_scmp_, N_("Set comparison flag value"), "scmp L | E | G"},
+ { "sover", cmd_sover_, N_("Set overflow flag value"), "sover T | F" },
+ { "smem", cmd_smem_, N_("Set memory contents in given address"),
+ "smem ADDRESS VALUE"},
+ { "ssym", cmd_ssym_, N_("Set a symbol\'s value"), "ssym SYMBOL WEXPR"},
+ { "sbp", cmd_sbp_, N_("Set break point at given line"), "sbp LINENO"},
+ { "cbp", cmd_cbp_, N_("Clear break point at given line"), "cbp LINENO"},
+ { "sbpa", cmd_sbpa_, N_("Set break point at given address"),
+ "sbpa ADDRESS"},
+ { "cbpa", cmd_cbpa_, N_("Clear break point at given address"),
+ "cbpa ADDRESS"},
+ { "sbpr", cmd_sbpr_, N_("Set conditional breakpoint on register change"),
+ "sbpr A | X | J | I[1-6]"},
+ { "cbpr", cmd_cbpr_, N_("Clear conditional breakpoint on register change"),
+ "sbpr A | X | J | I[1-6]"},
+ { "sbpm", cmd_sbpm_, N_("Set conditional breakpoint on mem cell change"),
+ "sbpm ADDRESS"},
+ { "cbpm", cmd_cbpm_, N_("Clear conditional breakpoint on mem cell change"),
+ "cbpm ADDRESS"},
+ { "sbpc", cmd_sbpc_,
+ N_("Set conditional breakpoint on comparison flag change"), "sbpc"},
+ { "cbpc", cmd_cbpc_,
+ N_("Clear conditional breakpoint on comparison flag change"), "cbpc"},
+ { "sbpo", cmd_sbpo_,
+ N_("Set conditional breakpoint on overflow toggled"), "sbpo"},
+ { "cbpo", cmd_cbpo_,
+ N_("Set conditional breakpoint on overflow toggled"), "cbpo"},
+ { "cabp", cmd_cabp_, N_("Clear all breakpoints"), "cabp"},
+ { "weval", cmd_weval_, N_("Evaluate a given W-expression"), "weval WEXPR"},
+ { "w2d", cmd_w2d_, N_("Convert a MIX word to its decimal value"),
+ "w2d WORD"},
+ { "strace", cmd_strace_, N_("Turn on/off instruction tracing"),
+ "strace on|off"},
+ { "pbt", cmd_pbt_, N_("Print backtrace of executed instructions"),
+ "pbt [INS_NO] (e.g pbt 5)"},
+ { "stime", cmd_stime_, N_("Turn on/off timing statistics"),
+ "stime on|off"},
+ { "ptime", cmd_ptime_, N_("Print current time statistics"), "ptime"},
+ { "sddir", cmd_sddir_, N_("Set devices directory"),"sddir NEWDIR"},
+ { "pddir", cmd_pddir_, N_("Print current devices directory"),"pddir"},
+ { "slog", cmd_slog_, N_("Turn on/off message logging"), "slog on|off"},
+ { "pprog", cmd_pprog_, N_("Print the current program path"), "pprog"},
+ { "psrc", cmd_psrc_, N_("Print the current program source path"), "psrc"},
+ { "pline", cmd_pline_,
+ N_("Print the current (or a given) program source line"), "pline [LINENO]"},
+ { NULL, NULL, NULL, NULL},
+};
+
+/* trace current instruction */
+static void
+do_trace_ (mix_vm_cmd_dispatcher_t *dis, gboolean error)
+{
+ enum {BUFFER_LEN = 128};
+ static gchar STRINS[BUFFER_LEN];
+
+ const mix_src_file_t *file = mix_vm_get_src_file (dis->vm);
+ const gchar *line = "\n";
+ mix_address_t loc = mix_vm_get_prog_count (dis->vm);
+ mix_word_t ins = mix_vm_get_addr_contents (dis->vm, loc);
+ mix_ins_t fins;
+ mix_word_to_ins_uncheck (ins, fins);
+ mix_ins_to_string_in_buffer (&fins, STRINS, BUFFER_LEN);
+
+ if (file != NULL)
+ {
+ gulong b = mix_vm_get_break_lineno (dis->vm);
+ if (b > 0) line = mix_src_file_get_line (file, b);
+ }
+
+ if (!error)
+ log_message_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line);
+ else
+ log_error_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line);
+}
+
+static void
+trace_ (mix_vm_cmd_dispatcher_t *dis)
+{
+ if (wants_logs_ (dis))
+ {
+ do_trace_ (dis, FALSE);
+ }
+}
+
+#define trace_error_(dis) do_trace_ (dis, TRUE)
+
+/* run a program tracing executed instructions */
+static int
+run_and_trace_ (mix_vm_cmd_dispatcher_t *dis)
+{
+ int k = MIX_VM_RUNNING;
+ if (!dis->trace)
+ return mix_vm_run (dis->vm);
+ else while (k == MIX_VM_RUNNING)
+ {
+ trace_ (dis);
+ k = mix_vm_exec_next (dis->vm);
+ }
+ return k;
+}
+
+/* print time statistics */
+static void
+print_time_ (mix_vm_cmd_dispatcher_t *dis)
+{
+ dis->laptime = mix_vm_get_uptime (dis->vm) - dis->uptime;
+ dis->uptime += dis->laptime;
+ dis->progtime += dis->laptime;
+ if (dis->printtime)
+ fprintf
+ (dis->out,
+ _("Elapsed time: %ld /Total program time: %ld (Total uptime: %ld)\n"),
+ dis->laptime, dis->progtime, dis->uptime);
+}
+
+
+/* commands */
+static void
+print_help_ (gpointer key, gpointer val, gpointer data)
+{
+ mix_vm_command_info_t *info = (mix_vm_command_info_t *)val;
+ if (info)
+ fprintf ((FILE *)data, "%-15s%s\n", info->name, info->doc);
+}
+
+gboolean
+cmd_help_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg && strlen (arg) > 0)
+ {
+ int i;
+ mix_vm_command_info_t *info =
+ (mix_vm_command_info_t *)g_hash_table_lookup
+ (dis->commands, (gpointer)arg);
+ for (i = 0; info == NULL && commands_[i].name; i++)
+ if (!strcmp (commands_[i].name, arg)) info = commands_ + i;
+ if (info)
+ {
+ fprintf (dis->out , _("%-15s%s.\n%-15sUsage: %s\n"),
+ info->name, info->doc, "", info->usage);
+ return TRUE;
+ }
+ fprintf (dis->out, _("No commands match `%s'\n"), arg);
+ return FALSE;
+ }
+ else
+ {
+ int i = 0;
+ fprintf (dis->out, _("Possible commands are:\n"));
+ for (i = 0; commands_[i].name; ++i)
+ fprintf (dis->out, "%-15s%s\n", commands_[i].name, commands_[i].doc);
+ g_hash_table_foreach (dis->commands, print_help_, (gpointer)dis->out);
+ return TRUE;
+ }
+}
+
+gboolean
+cmd_load_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ errno = 0;
+ if (arg == NULL || *arg == '\0')
+ {
+ log_error_ (dis, _("Missing file name"));
+ return FALSE;
+ }
+ mix_eval_remove_symbols_from_table (dis->eval,
+ mix_vm_get_symbol_table (dis->vm));
+ if (!mix_vm_load_file (dis->vm, arg) )
+ {
+ log_error_ (dis, _("Cannot load %s: "), arg);
+ if ( errno == 0 )
+ log_error_ (dis, _("Wrong file format"));
+ else
+ log_error_ (dis, "%s", strerror (errno));
+ return FALSE;
+ }
+
+ if (dis->program != arg)
+ {
+ if (dis->program) g_free (dis->program);
+ dis->program = mix_file_complete_name (arg, MIX_CODE_DEFEXT);
+ }
+
+ mix_eval_set_symbols_from_table (dis->eval,
+ mix_vm_get_symbol_table (dis->vm));
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Program loaded. Start address: %d"),
+ mix_vm_get_prog_count (dis->vm));
+
+ dis->laptime = dis->progtime = 0;
+ return TRUE;
+}
+
+gboolean
+cmd_edit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (dis->editor == NULL)
+ {
+ log_error_ (dis, _("Editor not specified (use sedit)"));
+ return FALSE;
+ }
+ if (!arg || *arg == '\0') arg = mix_vm_cmd_dispatcher_get_src_file_path (dis);
+ if (!arg)
+ {
+ log_error_ (dis, _("MIXAL source file path not found"));
+ return FALSE;
+ }
+ else
+ {
+ gchar *cmd = g_strdup_printf (dis->editor, arg);
+ if (wants_logs_ (dis)) log_message_ (dis, cmd);
+ system (cmd);
+ if (wants_logs_ (dis)) log_message_ (dis, _(" ...done"));
+ g_free (cmd);
+ return TRUE;
+ }
+}
+
+gboolean
+cmd_compile_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (dis->assembler == NULL)
+ {
+ log_error_ (dis, _("MIX assembler not specified (use sasm)"));
+ return FALSE;
+ }
+ if (!arg || *arg == '\0') arg = mix_vm_cmd_dispatcher_get_src_file_path (dis);
+ if (!arg)
+ {
+ log_error_ (dis, _("MIXAL source file path not found"));
+ return FALSE;
+ }
+ else
+ {
+ gchar *cmd = g_strdup_printf (dis->assembler, arg);
+ if (wants_logs_ (dis)) log_message_ (dis, cmd);
+ if (system (cmd) == EXIT_SUCCESS && wants_logs_ (dis))
+ log_message_ (dis, _("Successful compilation"));
+ g_free (cmd);
+ return TRUE;
+ }
+}
+
+gboolean
+cmd_run_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg != NULL && *arg != '\0' && cmd_load_ (dis, arg) != TRUE)
+ return FALSE;
+
+ if (mix_vm_is_halted (dis->vm)) cmd_load_ (dis, dis->program);
+
+ if (wants_logs_ (dis)) log_message_ (dis, _("Running ..."));
+
+ switch (run_and_trace_ (dis))
+ {
+ case MIX_VM_HALT:
+ if (wants_logs_ (dis)) log_message_ (dis, _("... done"));
+ break;
+ case MIX_VM_BREAK:
+ if (wants_logs_ (dis))
+ {
+ gulong line = mix_vm_get_break_lineno (dis->vm);
+ if (line != 0)
+ log_message_
+ (dis, _("... stopped: breakpoint at line %ld (address %d)"),
+ line, mix_vm_get_prog_count (dis->vm));
+ else
+ log_message_ (dis, _("... stopped: breakpoint at address %d"),
+ mix_vm_get_prog_count (dis->vm));
+ }
+ break;
+ case MIX_VM_COND_BREAK:
+ if (wants_logs_ (dis))
+ {
+ gulong line = mix_vm_get_break_lineno (dis->vm);
+ if (line != 0)
+ log_message_ (dis, _("... stopped: %s (line %ld, address %d)"),
+ mix_vm_get_last_breakpoint_message (dis->vm),
+ line, mix_vm_get_prog_count (dis->vm));
+ else
+ log_message_ (dis, _("... stopped: %s (address %d)"),
+ mix_vm_get_last_breakpoint_message (dis->vm),
+ mix_vm_get_prog_count (dis->vm));
+ }
+ break;
+ case MIX_VM_ERROR:
+ log_error_ (dis, _("%s:"), mix_vm_get_last_error_string (dis->vm));
+ trace_error_ (dis);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (wants_logs_ (dis)) print_time_ (dis);
+
+ return TRUE;
+}
+
+gboolean
+cmd_next_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ int ins_no = 1;
+ int k;
+
+ if ( strlen (arg) != 0 )
+ {
+ int k = 0;
+ while (isdigit (arg[k]))
+ k++;
+ if (arg[k] != '\0')
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ ins_no = atoi (arg);
+ }
+
+ if (mix_vm_is_halted (dis->vm)) cmd_load_ (dis, dis->program);
+
+ while ( ins_no-- > 0 )
+ {
+ if (dis->trace) trace_ (dis);
+ k = mix_vm_exec_next (dis->vm);
+ if (k == MIX_VM_HALT)
+ {
+ if (wants_logs_ (dis))
+ log_message_(dis, _("End of program reached at address %d"),
+ mix_vm_get_prog_count (dis->vm));
+ break;
+ }
+ else if (k == MIX_VM_ERROR)
+ {
+ log_error_ (dis, _("%s:"), mix_vm_get_last_error_string (dis->vm));
+ trace_error_ (dis);
+ break;
+ }
+ }
+ if (wants_logs_ (dis)) print_time_ (dis);
+
+ return TRUE;
+}
+
+gboolean
+cmd_pc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ fprintf (dis->out, "Current address: %d\n", mix_vm_get_prog_count (dis->vm));
+ return TRUE;
+}
+
+gboolean
+cmd_psym_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gboolean result = FALSE;
+ const mix_symbol_table_t *table = mix_eval_symbol_table (dis->eval);
+ if ( table == NULL )
+ log_error_ (dis, _("Symbol table not available"));
+ else if (arg != NULL && *arg != '\0')
+ {
+ if ( mix_symbol_table_is_defined (table, arg) )
+ {
+ mix_word_print_to_file (mix_symbol_table_value (table, arg),
+ NULL, dis->out);
+ putc ('\n', dis->out);
+ result = TRUE;
+ }
+ else
+ fprintf (dis->out, _("%s: symbol not defined\n"), arg);
+ }
+ else
+ {
+ mix_symbol_table_print (table, MIX_SYM_ROWS, dis->out, TRUE);
+ result = TRUE;
+ }
+
+ return result;
+}
+
+gboolean
+cmd_preg_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ mix_dump_context_set_opt (dis->dump, MIX_DUMP_NONE);
+ if ( strlen (arg) == 0 )
+ mix_dump_context_add_opt (dis->dump, MIX_DUMP_rALL);
+ else switch (*arg)
+ {
+ case 'A':
+ mix_dump_context_add_opt (dis->dump, MIX_DUMP_rA);
+ break;
+ case 'X':
+ mix_dump_context_add_opt (dis->dump, MIX_DUMP_rX);
+ break;
+ case 'J':
+ mix_dump_context_add_opt (dis->dump, MIX_DUMP_rJ);
+ break;
+ case 'I':
+ {
+ if ( strlen (arg) == 1 )
+ mix_dump_context_add_opt (dis->dump, MIX_DUMP_rIa);
+ else
+ {
+ static gint32 opt[] = { MIX_DUMP_rI1, MIX_DUMP_rI2,
+ MIX_DUMP_rI3, MIX_DUMP_rI4,
+ MIX_DUMP_rI5, MIX_DUMP_rI6
+ };
+ int i = arg[1] - '1';
+ if ( i < 0 || i > 5 )
+ {
+ log_error_ (dis, _("Invalid I index: %d"), i);
+ return FALSE;
+ }
+ mix_dump_context_add_opt (dis->dump, opt[i]);
+ }
+ }
+ break;
+ default:
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ mix_vm_dump (dis->vm, dis->dump);
+ return TRUE;
+}
+
+gboolean
+cmd_pflags_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ mix_dump_context_set_opt (dis->dump, MIX_DUMP_CMP | MIX_DUMP_OVER);
+ mix_vm_dump (dis->vm, dis->dump);
+ return TRUE;
+}
+
+gboolean
+cmd_pall_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ mix_dump_context_set_opt (dis->dump, MIX_DUMP_ALL_NOMEM);
+ mix_vm_dump (dis->vm, dis->dump);
+ return TRUE;
+}
+
+gboolean
+cmd_pmem_ (mix_vm_cmd_dispatcher_t *dis, const gchar *carg)
+{
+ glong begin = MIX_SHORT_ZERO, end = MIX_SHORT_ZERO;
+ int i = 0;
+ gboolean error = FALSE;
+ gchar *arg = NULL;
+
+ if ( strlen (carg) == 0 )
+ {
+ log_error_ (dis, _("Missing memory address"));
+ return FALSE;
+ }
+ arg = g_strdup (carg);
+ while (isdigit (arg[i]))
+ i++;
+ while (isspace (arg[i]))
+ i++;
+ if (arg[i] == '\0')
+ begin = end = atol (arg);
+ else if (arg[i] == '-')
+ {
+ gchar *narg;
+ arg[i++] = '\0';
+ begin = atol (arg);
+ narg = arg + i;
+ i = 0;
+ while (isdigit (narg[i]))
+ i++;
+ while (isspace (narg[i]))
+ i++;
+ if (narg[i] != '\0')
+ error = TRUE;
+ else
+ end = atol (narg);
+ }
+ else
+ error = TRUE;
+
+ if (error)
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ }
+ else if ( end < begin || end > MIX_VM_CELL_NO - 1 )
+ {
+ log_error_ (dis, _("Invalid range: %ld-%ld"), begin, end);
+ error = TRUE;
+ }
+ else
+ {
+ mix_dump_context_set_opt (dis->dump, MIX_DUMP_CELLS);
+ mix_dump_context_range (dis->dump, mix_short_new (begin),
+ mix_short_new (end + 1));
+ mix_vm_dump (dis->vm, dis->dump);
+ }
+ g_free (arg);
+ return !error;
+}
+
+gboolean
+cmd_sreg_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ int i = 0;
+ char reg = arg[0];
+ gboolean ok = TRUE;
+ long value;
+
+ i = (reg == 'I') ? 2 : 1;
+ ok = strlen (arg) > 2 && isspace (arg[i]);
+ if (ok)
+ {
+ while (isspace (arg[i])) i++;
+ ok = isdigit (arg[i]) || arg[i] == '+' || arg[i] == '-';
+ if (ok)
+ {
+ value = atol (arg + i);
+ if (arg[i] == '+' || arg[i] == '-') i++;
+ while (isdigit (arg[i])) i++;
+ ok = (arg[i] == '\0');
+ if (ok)
+ switch (reg)
+ {
+ case 'A':
+ mix_vm_set_rA (dis->vm, mix_word_new (value));
+ break;
+ case 'X':
+ mix_vm_set_rX (dis->vm, mix_word_new (value));
+ break;
+ case 'J':
+ if ( value >= 0 )
+ mix_vm_set_rJ (dis->vm, mix_short_new (value));
+ else
+ ok = FALSE;
+ break;
+ case 'I':
+ {
+ guint k = arg[1] - '0';
+ if ( k < 7 )
+ mix_vm_set_rI (dis->vm, k, mix_short_new (value));
+ else
+ ok = FALSE;
+ }
+ break;
+ default:
+ ok = FALSE;
+ }
+ }
+ }
+ if (!ok)
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ }
+
+ return ok;
+}
+
+gboolean
+cmd_scmp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gboolean ok = (strlen (arg) == 1);
+ if (ok) switch (arg[0])
+ {
+ case 'L':
+ mix_vm_set_cmpflag (dis->vm, mix_LESS);
+ break;
+ case 'E':
+ mix_vm_set_cmpflag (dis->vm, mix_EQ);
+ break;
+ case 'G':
+ mix_vm_set_cmpflag (dis->vm, mix_GREAT);
+ break;
+ default:
+ ok = FALSE;
+ }
+ if (!ok)
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ }
+
+ return ok;
+}
+
+gboolean
+cmd_sover_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gboolean ok = (strlen (arg) == 1);
+ if (ok) switch (arg[0])
+ {
+ case 'T':
+ mix_vm_set_overflow (dis->vm, TRUE);
+ break;
+ case 'F':
+ mix_vm_set_overflow (dis->vm, FALSE);
+ break;
+ default:
+ ok = FALSE;
+ }
+ if (!ok)
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ }
+
+ return ok;
+}
+
+gboolean
+cmd_smem_ (mix_vm_cmd_dispatcher_t *dis, const gchar *carg)
+{
+ gboolean ok = (strlen (carg) > 2 && isdigit (carg[0]));
+ glong addr = -1;
+ glong value = 0;
+ int k = 0;
+ gchar *arg = NULL;
+
+ if (ok)
+ {
+ arg = g_strdup (carg);
+ while (isdigit (arg[k])) k++;
+ ok = isspace (arg[k]);
+ if (ok)
+ {
+ arg[k++] = '\0';
+ addr = atol (arg);
+ ok = addr < MIX_VM_CELL_NO;
+ }
+ if (ok)
+ {
+ while (isspace (arg[k])) k++;
+ value = atol (arg + k);
+ if ( arg[k] == '+' || arg[k] == '-' ) k++;
+ while (isdigit (arg[k])) k++;
+ ok = arg[k] == '\0';
+ }
+ }
+
+ if (ok)
+ mix_vm_set_addr_contents (dis->vm, mix_short_new (addr),
+ mix_word_new (value));
+ else
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ }
+ if (arg) g_free (arg);
+
+ return ok;
+}
+
+gboolean
+cmd_ssym_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gboolean result = FALSE;
+ if (arg == NULL || strlen(arg) == 0)
+ {
+ log_error_ (dis, _("Missing arguments"));
+ }
+ else
+ {
+ gchar *a = g_strdup (arg);
+ gchar *s = strtok (a, " \t");
+ gchar *w = strtok (NULL, " \t");
+ if (w != NULL && strtok (NULL, " \t") == NULL)
+ {
+ cmd_weval_ (dis, w);
+ if (mix_eval_last_error (dis->eval) == MIX_EVAL_OK) {
+ mix_eval_set_symbol (dis->eval, s, mix_eval_value (dis->eval));
+ result = TRUE;
+ }
+ }
+ else
+ {
+ log_error_ (dis, _("Wrong argument number"));
+ }
+ g_free (a);
+ }
+ return result;
+}
+
+gboolean
+cmd_sbp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ glong lineno;
+ glong k = 0;
+ while (isdigit (arg[k])) k++;
+ if (arg[k] != '\0')
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ lineno = atol (arg);
+ switch (k = mix_vm_set_breakpoint (dis->vm, lineno))
+ {
+ case MIX_VM_BP_INV_LINE:
+ log_error_ (dis, _("Line number %ld too high"), lineno);
+ break;
+ case MIX_VM_BP_ERROR:
+ log_error_ (dis, _("Could not set breakpoint: internal error"));
+ break;
+ case MIX_VM_BP_NDEBUG:
+ log_error_ (dis, _("Could not set breakpoint: no debug info available"),
+ dis->err);
+ break;
+ default:
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Breakpoint set at line %ld"), k);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+cmd_sbpa_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ glong address;
+ glong k = 0;
+ while (isdigit (arg[k])) k++;
+ if (arg[k] != '\0')
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ address = atol (arg);
+ switch (mix_vm_set_breakpoint_address (dis->vm, address))
+ {
+ case MIX_VM_BP_INV_ADDRESS:
+ log_error_ (dis, _("Invalid address %ld"), address);
+ break;
+ case MIX_VM_BP_ERROR:
+ log_error_ (dis, _("Could not set breakpoint: internal error"));
+ break;
+ default:
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Breakpoint set at address %ld"), address);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+cmd_cbp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ glong lineno;
+ int k = 0;
+ while (isdigit (arg[k])) k++;
+ if (arg[k] != '\0')
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ lineno = atol (arg);
+ switch (mix_vm_clear_breakpoint (dis->vm, lineno))
+ {
+ case MIX_VM_BP_INV_LINE:
+ log_error_ (dis, _("No breakpoint set at line %ld"), lineno);
+ break;
+ case MIX_VM_BP_ERROR:
+ log_error_ (dis, _("Could not set breakpoint: internal error"));
+ break;
+ case MIX_VM_BP_NDEBUG:
+ log_error_ (dis, _("No debug info available"));
+ break;
+ case MIX_VM_BP_OK:
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Breakpoint cleared at line %ld"), lineno);
+ return TRUE;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ return FALSE;
+}
+
+gboolean
+cmd_cbpa_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ glong address;
+ glong k = 0;
+ while (isdigit (arg[k])) k++;
+ if (arg[k] != '\0')
+ {
+ log_error_ (dis, _("Invalid argument: %s"), arg);
+ return FALSE;
+ }
+ address = atol (arg);
+ switch (mix_vm_clear_breakpoint_address (dis->vm, address))
+ {
+ case MIX_VM_BP_INV_ADDRESS:
+ log_error_ (dis, _("Invalid address %ld"), address);
+ break;
+ case MIX_VM_BP_ERROR:
+ log_error_ (dis, _("Could not clear breakpoint: internal error"));
+ break;
+ default:
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Breakpoint cleared at address %ld"), address);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+gboolean
+cmd_cabp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (strlen (arg) != 0)
+ {
+ log_error_ (dis, _("Unexpected argument: %s"), arg);
+ return FALSE;
+ }
+ mix_vm_clear_all_breakpoints (dis->vm);
+ return TRUE;
+}
+
+gboolean
+cmd_weval_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if ( strlen (arg) == 0 )
+ {
+ log_error_ (dis, _("Missing expression"));
+ return FALSE;
+ }
+
+ if (mix_eval_expression_with_loc (dis->eval, arg,
+ mix_vm_get_prog_count (dis->vm)) ==
+ MIX_EVAL_OK)
+ {
+ mix_word_print_to_file (mix_eval_value (dis->eval), NULL, dis->out);
+ putc ('\n', dis->out);
+ return TRUE;
+ }
+ else
+ {
+ gint pos = mix_eval_last_error_pos (dis->eval);
+ gint k, len = strlen (arg);
+ g_assert(pos > -1 && pos <= len);
+ for (k = 0; k<pos; ++k) fputc (arg[k], dis->err);
+ fputc ('\n', dis->err);
+ for (k = 0; k<pos; ++k) fputc (' ', dis->err);
+ for (k = pos; k < len; ++k) fputc (arg[k], dis->err);
+ fprintf (dis->err, _("\nEvaluation error: %s\n"),
+ mix_eval_last_error_string (dis->eval));
+ return FALSE;
+ }
+}
+
+gboolean
+cmd_w2d_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if ( strlen (arg) == 0 )
+ {
+ log_error_ (dis, _("Missing expression"));
+ return FALSE;
+ }
+ else
+ {
+ gchar *cp = g_strdup (arg), *a = cp;
+ mix_byte_t bytes[5] = {0, 0, 0, 0, 0};
+ gchar *b;
+ guint k = 0;
+ gboolean is_n = (a[0] == '-'), success = TRUE;
+ if (a[0] == '+' || a[0] == '-') ++a;
+ b = strtok (a, " \t");
+ while (b != NULL && k < 5)
+ {
+ if (strlen (b) != 2 || !isdigit(b[0]) || !isdigit(b[1]))
+ {
+ log_error_ (dis, _("Incorrect byte specification: %s"), b);
+ success = FALSE;
+ b = NULL;
+ }
+ else
+ {
+ bytes[k++] = mix_byte_new (atoi (b));
+ b = strtok (NULL, " \t");
+ }
+ }
+ if (success)
+ {
+ if (strtok (NULL, "\t") != NULL)
+ {
+ log_error_ (dis,
+ _("The expression %s does not fit in a word"), arg);
+ success = FALSE;
+ }
+ else
+ {
+ mix_word_t w = mix_bytes_to_word (bytes, k);
+ fprintf (dis->out, "%s%ld\n", is_n? "-":"+",
+ mix_word_magnitude (w));
+ }
+ }
+ g_free (cp);
+
+ return success;
+ }
+}
+
+gboolean
+cmd_strace_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ static const gchar *ON = "on";
+ static const gchar *OFF = "off";
+ if (!arg || !strlen (arg))
+ {
+ log_error_ (dis, _("Missing argument"));
+ }
+ else if (!strcmp (arg, ON))
+ {
+ dis->trace = TRUE;
+ if (dis->config) mix_config_update (dis->config, TRACING_KEY_, ON);
+ }
+ else if (!strcmp (arg, OFF))
+ {
+ dis->trace = FALSE;
+ if (dis->config) mix_config_update (dis->config, TRACING_KEY_, OFF);
+ }
+ else
+ log_error_ (dis, _("Wrong argument: "), arg);
+ return TRUE;
+}
+
+gboolean
+cmd_stime_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ static const gchar *ON = "on";
+ static const gchar *OFF = "off";
+ if (!arg || !strlen (arg))
+ {
+ log_error_ (dis, _("Missing argument"));
+ }
+ else if (!strcmp (arg, ON))
+ {
+ dis->printtime = TRUE;
+ if (dis->config) mix_config_update (dis->config, TIMING_KEY_, ON);
+ }
+ else if (!strcmp (arg, OFF))
+ {
+ dis->printtime = FALSE;
+ if (dis->config) mix_config_update (dis->config, TIMING_KEY_, OFF);
+ }
+ else
+ log_error_ (dis, _("Wrong argument: "), arg);
+ return TRUE;
+}
+
+gboolean
+cmd_ptime_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ print_time_ (dis);
+ return TRUE;
+}
+
+gboolean
+cmd_pedit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ const gchar *ed = mix_vm_cmd_dispatcher_get_editor (dis);
+ if (dis)
+ fprintf (dis->out, _("Edit command: %s\n"), ed);
+ else
+ fprintf (dis->out, _("Edit command not set (use sedit)\n"));
+ return TRUE;
+}
+
+gboolean
+cmd_sedit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (!arg || !strlen (arg))
+ {
+ log_error_ (dis, _("Missing argument"));
+ return FALSE;
+ }
+ mix_vm_cmd_dispatcher_set_editor (dis, arg);
+ return TRUE;
+}
+
+gboolean
+cmd_pasm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ const gchar *ed = mix_vm_cmd_dispatcher_get_assembler (dis);
+ if (dis)
+ fprintf (dis->out, _("Compile command: %s\n"), ed);
+ else
+ fprintf (dis->out, _("Compile command not set (use sasm)\n"));
+ return TRUE;
+}
+
+gboolean
+cmd_sasm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (!arg || !strlen (arg))
+ {
+ log_error_ (dis, _("Missing argument"));
+ return FALSE;
+ }
+ mix_vm_cmd_dispatcher_set_assembler (dis, arg);
+ return TRUE;
+}
+
+gboolean
+cmd_sddir_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (!arg || !strlen (arg)) log_error_ (dis, _("Missing argument"));
+ else if (mix_device_set_dir (arg) && dis->config)
+ mix_config_set_devices_dir (dis->config, arg);
+ return TRUE;
+}
+
+gboolean
+cmd_pddir_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ fprintf (dis->out, _("Device directory: %s\n"), mix_device_get_dir ());
+ return TRUE;
+}
+
+static const gint INVALID_REG_ = -2;
+
+static mix_predicate_type_t
+get_reg_pred_ (const gchar *arg)
+{
+ mix_predicate_type_t pred = INVALID_REG_;
+
+ switch (*arg)
+ {
+ case 'A':
+ pred = MIX_PRED_REG_A;
+ break;
+ case 'X':
+ pred = MIX_PRED_REG_X;
+ break;
+ case 'J':
+ pred = MIX_PRED_REG_J;
+ break;
+ case 'I':
+ {
+ if ( strlen (arg) == 2 )
+ {
+ int i = arg[1] - '1';
+ if (i >= 0 && i < 6)
+ pred = MIX_PRED_REG_I1 - 1 + i;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return pred;
+}
+
+gboolean
+cmd_sbpr_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ mix_predicate_type_t pred = get_reg_pred_ (arg);
+ if (pred != INVALID_REG_)
+ {
+ mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[pred]);
+ if (wants_logs_ (dis))
+ log_message_ (dis,
+ _("Conditional breakpoint on r%s change set"), arg);
+ return TRUE;
+ }
+ else
+ {
+ log_error_ (dis, _("Invalid argument %s"), arg);
+ return FALSE;
+ }
+}
+
+gboolean
+cmd_cbpr_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ mix_predicate_type_t pred = get_reg_pred_ (arg);
+ if (pred != INVALID_REG_)
+ {
+ if (mix_vm_clear_conditional_breakpoint (dis->vm, dis->preds[pred]))
+ {
+ if (wants_logs_(dis))
+ log_message_ (dis,
+ _("Conditional breakpoint on r%s change removed"),
+ arg);
+ }
+ else
+ log_error_ (dis, _("No breakpoint set on r%s change"), arg);
+ return TRUE;
+ }
+ else
+ {
+ log_error_ (dis, _("Invalid argument %s"), arg);
+ return FALSE;
+ }
+}
+
+gboolean
+cmd_sbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gint add = atoi (arg);
+ gpointer key, value;
+ if (add < 0 || add > MIX_VM_CELL_NO)
+ {
+ log_error_ (dis, _("Invalid memory address: %s"), arg);
+ return FALSE;
+ }
+ if (!g_hash_table_lookup_extended (dis->mem_preds, GINT_TO_POINTER (add),
+ &key, &value))
+ {
+ mix_predicate_t *new_pred = mix_predicate_new (MIX_PRED_MEM);
+ mix_predicate_set_mem_address (new_pred, add);
+ g_hash_table_insert (dis->mem_preds,
+ GINT_TO_POINTER (add), (gpointer)new_pred);
+ mix_vm_set_conditional_breakpoint (dis->vm, new_pred);
+ }
+ if (wants_logs_ (dis))
+ log_message_ (dis, _("Conditional breakpoint on mem cell no. %d set"),
+ add);
+ return TRUE;
+}
+
+gboolean
+cmd_cbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gint add = atoi (arg);
+ gpointer key, value;
+ if (add < 0 || add > MIX_VM_CELL_NO)
+ {
+ log_error_ (dis, _("Invalid memory address: %s"), arg);
+ return FALSE;
+ }
+ if (g_hash_table_lookup_extended (dis->mem_preds, GINT_TO_POINTER (add),
+ &key, &value))
+ {
+ g_hash_table_remove (dis->mem_preds, key);
+ mix_vm_clear_conditional_breakpoint (dis->vm, (mix_predicate_t *)value);
+ mix_predicate_delete ((mix_predicate_t *)value);
+ if (wants_logs_ (dis))
+ log_message_ (dis,
+ _("Conditional breakpoint on mem cell no. %d removed"),
+ add);
+ }
+ else
+ {
+ log_error_ (dis, _("No conditional breakpoint set at address %d"),
+ add);
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_sbpo_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg && strlen (arg))
+ log_error_ (dis, _("Unexpected argument: %s"), arg);
+ else
+ {
+ mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_OVER]);
+ if (wants_logs_ (dis))
+ log_message_ (dis,
+ _("Conditional breakpoint on overflow toggled set"));
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_cbpo_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg && strlen (arg))
+ log_error_ (dis, _("Unexpected argument: %s"), arg);
+ else
+ {
+ if (mix_vm_clear_conditional_breakpoint
+ (dis->vm, dis->preds[MIX_PRED_OVER]))
+ {
+ if (wants_logs_ (dis))
+ log_message_
+ (dis, _("Conditional breakpoint on overflow toggled removed."));
+ }
+ else
+ log_error_ (dis, _("No breakpoint set on overflow toggle"));
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_sbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg && strlen (arg))
+ log_error_ (dis, _("Unexpected argument: %s"), arg);
+ else
+ {
+ mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_CMP]);
+ if (wants_logs_ (dis))
+ log_message_
+ (dis, _("Conditional breakpoint on comparison flag changed set"));
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_cbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ if (arg && strlen (arg))
+ log_error_ (dis, _("Unexpected argument: %s"), arg);
+ else
+ {
+ if (mix_vm_clear_conditional_breakpoint
+ (dis->vm, dis->preds[MIX_PRED_CMP]))
+ {
+ if (wants_logs_ (dis))
+ log_message_
+ (dis,
+ _("Conditional breakpoint on comparison flag changed removed."));
+ }
+ else
+ log_error_ (dis, _("No breakpoint set on comparison flag change"));
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_pbt_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ enum {SIZE = 256};
+ static gchar BUFFER[SIZE];
+ gint no = atoi (arg);
+ gint k = 0, address;
+ guint line;
+ const mix_src_file_t *file = mix_vm_get_src_file (dis->vm);
+ char *name =
+ file ? g_path_get_basename (mix_src_file_get_path (file)) : NULL;
+
+ const GSList *add = mix_vm_get_backtrace (dis->vm);
+ while (add && (no == 0 || k < no))
+ {
+ BUFFER[0] = '\0';
+ address = GPOINTER_TO_INT (add->data);
+ line = mix_vm_get_address_lineno (dis->vm, address);
+ if (line && file)
+ {
+ int j = 0;
+ g_snprintf (BUFFER, SIZE, "%s", mix_src_file_get_line (file, line));
+ while (!isspace (BUFFER[j])) j++;
+ BUFFER[j] = '\0';
+ }
+ if (strlen (BUFFER) == 0) g_snprintf (BUFFER, SIZE, "%d", address);
+ fprintf (dis->out, "#%d\t%s\tin %s%s:%d\n", k, BUFFER, name,
+ MIX_SRC_DEFEXT, line);
+ ++k;
+ add = add->next;
+ }
+ return TRUE;
+}
+
+gboolean
+cmd_slog_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ static const gchar *ON = "on";
+ static const gchar *OFF = "off";
+ if (arg && !strcmp (arg, ON))
+ {
+ dis->log_msg = TRUE;
+ if (dis->config) mix_config_update (dis->config, LOGGING_KEY_, ON);
+ }
+ else if (arg && !strcmp (arg, OFF))
+ {
+ dis->log_msg = FALSE;
+ if (dis->config) mix_config_update (dis->config, LOGGING_KEY_, OFF);
+ }
+ else
+ log_error_ (dis, _("Wrong argument: "), arg);
+ return TRUE;
+}
+
+gboolean
+cmd_pprog_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_program_path (dis);
+ fprintf (dis->out, path? path : _("No program currently loaded"));
+ fprintf (dis->out, "\n");
+ return (path != NULL);
+}
+
+gboolean
+cmd_psrc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ const gchar *path = mix_vm_cmd_dispatcher_get_src_file_path (dis);
+ fprintf (dis->out, path? path : _("No program currently loaded\n"));
+ fprintf (dis->out, "\n");
+ return (path != NULL);
+}
+
+gboolean
+cmd_pline_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ gulong line = 0;
+ const gchar *txt;
+
+ if (arg && strlen (arg)) line = atoi (arg);
+
+ if (line < 0)
+ {
+ log_error_ (dis, _("Invalid argument"));
+ return FALSE;
+ }
+
+ if (line == 0)
+ line = mix_vm_cmd_dispatcher_get_src_file_lineno (dis);
+
+ if (line == 0)
+ txt = "No such line (debug info not available)\n";
+ else
+ txt = mix_vm_cmd_dispatcher_get_src_file_line (dis, line, FALSE);
+
+ if (txt == NULL || strlen (txt) == 0) txt = "No such line\n";
+
+ fprintf (dis->out, "Line %ld: %s\n", line, txt);
+
+ return TRUE;
+}
+
+gboolean
+cmd_pstat_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ static const gchar *MSGS[MIX_VM_EMPTY + 1] = {
+ N_("Error loading or executing file"),
+ N_("Execution stopped: breakpoint encountered"),
+ N_("Execution stopped: conditional breakpoint encountered"),
+ N_("Program successfully terminated"),
+ N_("Execution stopped"),
+ N_("Program successfully loaded"),
+ N_("No program loaded")
+ };
+ mix_vm_status_t status =
+ mix_vm_get_run_status (mix_vm_cmd_dispatcher_get_vm (dis));
+ fprintf (dis->out, "VM status: %s\n", MSGS[status]);
+ return TRUE;
+}
diff --git a/mixlib/xmix_vm_handlers.h b/mixlib/xmix_vm_handlers.h
new file mode 100644
index 0000000..b3258f9
--- /dev/null
+++ b/mixlib/xmix_vm_handlers.h
@@ -0,0 +1,87 @@
+/* -*-c-*- ---------------- xmix_vm_handlers.h :
+ * mix_vm_cmd_dispatcher command handlers
+ * ------------------------------------------------------------------
+ * $Id: xmix_vm_handlers.h,v 1.4 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef XMIX_VM_HANDLERS_H
+#define XMIX_VM_HANDLERS_H
+
+#include "xmix_vm_command.h"
+
+/* command handlers */
+#define DEC_FUN(name) \
+ extern gboolean cmd_##name (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+
+DEC_FUN (help_);
+DEC_FUN (load_);
+DEC_FUN (run_);
+DEC_FUN (next_);
+DEC_FUN (pc_);
+DEC_FUN (psym_);
+DEC_FUN (preg_);
+DEC_FUN (pflags_);
+DEC_FUN (pall_);
+DEC_FUN (pmem_);
+DEC_FUN (sreg_);
+DEC_FUN (scmp_);
+DEC_FUN (sover_);
+DEC_FUN (smem_);
+DEC_FUN (ssym_);
+DEC_FUN (sbp_);
+DEC_FUN (sbpa_);
+DEC_FUN (cbp_);
+DEC_FUN (cbpa_);
+DEC_FUN (cabp_);
+DEC_FUN (weval_);
+DEC_FUN (w2d_);
+DEC_FUN (strace_);
+DEC_FUN (stime_);
+DEC_FUN (ptime_);
+DEC_FUN (edit_);
+DEC_FUN (compile_);
+DEC_FUN (pedit_);
+DEC_FUN (sedit_);
+DEC_FUN (pasm_);
+DEC_FUN (sasm_);
+DEC_FUN (pddir_);
+DEC_FUN (sddir_);
+DEC_FUN (sbpr_);
+DEC_FUN (sbpm_);
+DEC_FUN (sbpc_);
+DEC_FUN (sbpo_);
+DEC_FUN (cbpr_);
+DEC_FUN (cbpm_);
+DEC_FUN (cbpc_);
+DEC_FUN (cbpo_);
+DEC_FUN (pbt_);
+DEC_FUN (slog_);
+DEC_FUN (pprog_);
+DEC_FUN (psrc_);
+DEC_FUN (pline_);
+DEC_FUN (pstat_);
+
+/* default command structure */
+extern mix_vm_command_info_t commands_[];
+
+
+#endif /* XMIX_VM_HANDLERS_H */
+
diff --git a/mixutils/Makefile.am b/mixutils/Makefile.am
new file mode 100644
index 0000000..7d899d6
--- /dev/null
+++ b/mixutils/Makefile.am
@@ -0,0 +1,27 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.9 2002/04/08 00:30:34 jao Exp $
+
+if MAKE_GUILE
+INCLUDES = -I$(includedir) -I$(top_srcdir) -DMAKE_GUILE
+else
+INCLUDES = -I$(includedir) -I$(top_srcdir)
+endif
+
+LDADD = $(top_builddir)/mixlib/libmix.a $(top_builddir)/lib/libreplace.a \
+ $(top_builddir)/mixguile/libmixguile.a $(INTLLIBS)
+
+bin_PROGRAMS = mixasm mixvm
+mixasm_SOURCES = mixasm.c mixasm_comp.h mixasm_comp.c
+mixvm_SOURCES = mixvm.c mixvm_loop.h mixvm_loop.c mixvm_command.h \
+ mixvm_command.c
diff --git a/mixutils/mixasm.c b/mixutils/mixasm.c
new file mode 100644
index 0000000..78f9f1f
--- /dev/null
+++ b/mixutils/mixasm.c
@@ -0,0 +1,136 @@
+/* -*-c-*- -------------- mixasm.c:
+ * Main function of mixasm, the mix assembler
+ * ------------------------------------------------------------------
+ * $Id: mixasm.c,v 1.9 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <mixlib/mix.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+#else
+# include <lib/getopt.h>
+#endif /* HAVE_GETOPT_LONG */
+
+#include "mixasm_comp.h"
+
+enum {
+ VER_OPT = 'v',
+ HELP_OPT = 'h',
+ USAGE_OPT = 'u',
+ OUT_OPT = 'o',
+ LIST_OPT = 'l',
+ NDEBUG_OPT = 'O'
+};
+
+
+static struct option long_options_[] =
+{
+ {"version", no_argument, 0, VER_OPT},
+ {"help", no_argument, 0, HELP_OPT},
+ {"usage", no_argument, 0, USAGE_OPT},
+ {"output", required_argument, 0, OUT_OPT},
+ {"list", optional_argument, 0, VER_OPT},
+ {"ndebug", no_argument, 0, NDEBUG_OPT},
+ {0, 0, 0, 0}
+};
+
+static const gchar *USAGE_ =
+N_("Usage: %s [-vhulO] [-o OUTPUT_FILE] [--version] [--help]\n"
+ "\t[--usage] [--ndebug] [--output=OUTPUT_FILE] [--list[=LIST_FILE]] file\n");
+
+
+int
+main (int argc, char **argv)
+{
+ int c;
+ const char *prog_name = argv[0];
+ const char *src = NULL, *out = NULL, *list = NULL;
+ gboolean use_list = FALSE, debug = TRUE;
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ while (1)
+ {
+ /* -g option is still available, but is no longer used */
+ c = getopt_long (argc, argv, "vhuo:lOg", long_options_, (int*)0);
+
+ /* Detect the end of the options. */
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case HELP_OPT: case USAGE_OPT:
+ fprintf (stderr, _(USAGE_), prog_name);
+ return EXIT_SUCCESS;
+ case VER_OPT:
+ mix_print_license ("mixasm, MIX assembler");
+ return EXIT_SUCCESS;
+ case OUT_OPT:
+ out = optarg;
+ break;
+ case LIST_OPT:
+ use_list = TRUE;
+ list = optarg;
+ break;
+ case NDEBUG_OPT:
+ debug = FALSE;
+ break;
+ case 'g':
+ /* used to be the switch to create debug version, not needed anymore */
+ break;
+ case '?':
+ /* getopt already handles the output of a warning message */
+ fprintf (stderr, _("(Try: %s -h)\n"), prog_name);
+ return EXIT_FAILURE;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ if ( optind == argc )
+ {
+ fprintf (stderr, _("*** Error: Missing source file.\n"));
+ return EXIT_FAILURE;
+ }
+ if ( optind < argc-1 )
+ {
+ fprintf (stderr, _("*** Error: Too many input files.\n"));
+ return EXIT_FAILURE;
+ }
+ src = argv[optind];
+
+
+ mix_init_lib ();
+
+ c = mix_asm_compile (src, out, use_list, list, debug);
+
+ mix_release_lib ();
+
+ return c;
+
+}
+
diff --git a/mixutils/mixasm_comp.c b/mixutils/mixasm_comp.c
new file mode 100644
index 0000000..0bbf8a0
--- /dev/null
+++ b/mixutils/mixasm_comp.c
@@ -0,0 +1,72 @@
+/* -*-c-*- -------------- mixasm_comp.c :
+ * Implementation of the functions declared in mixasm_comp.h
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <mixlib/mix.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <mixlib/mix_parser.h>
+#include "mixasm_comp.h"
+
+int
+mix_asm_compile(const gchar *src, const gchar *out, gboolean use_list,
+ const gchar *list, gboolean debug)
+{
+ int result = EXIT_SUCCESS;
+ mix_parser_t *parser;
+ mix_parser_err_t error;
+
+ if ( (parser = mix_parser_new(src)) == NULL )
+ {
+ fprintf(stderr, _("*** Unable to open source file %s\n"), src);
+ return EXIT_FAILURE;
+ }
+ if ( mix_parser_compile(parser) == MIX_PERR_OK )
+ {
+ guint k;
+ if ( ( k = mix_parser_warning_count(parser) ) != 0 )
+ fprintf(stderr, _("(%d warning(s))\n"), k);
+ if ( (error = mix_parser_write_code(parser, out, debug)) != MIX_PERR_OK )
+ {
+ fprintf(stderr, _("*** Error writing output code file: %s\n"),
+ mix_parser_err_string(error));
+ result = EXIT_FAILURE;
+ }
+ else if ( use_list
+ && (error = mix_parser_write_listing(parser, list)) !=
+ MIX_PERR_OK)
+ {
+ fprintf(stderr, _("*** Error writing listing file: %s\n"),
+ mix_parser_err_string(error));
+ result = EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ fprintf(stderr, _("(%d warning(s), %d error(s))\n"),
+ mix_parser_warning_count(parser), mix_parser_err_count(parser));
+ result = EXIT_FAILURE;
+ }
+
+ mix_parser_delete(parser);
+ return result;
+}
+
+
diff --git a/mixutils/mixasm_comp.h b/mixutils/mixasm_comp.h
new file mode 100644
index 0000000..f6537f4
--- /dev/null
+++ b/mixutils/mixasm_comp.h
@@ -0,0 +1,35 @@
+/* -*-c-*- ---------------- mixasm_comp.h :
+ * Declarations of functions used to compile mix source files.
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXASM_COMP_H
+#define MIXASM_COMP_H
+
+#include <glib.h>
+
+extern int
+mix_asm_compile(const gchar *src, const gchar *out, gboolean use_list,
+ const gchar *list, gboolean debug);
+
+
+
+#endif /* MIXASM_COMP_H */
+
diff --git a/mixutils/mixvm.c b/mixutils/mixvm.c
new file mode 100644
index 0000000..a0ae443
--- /dev/null
+++ b/mixutils/mixvm.c
@@ -0,0 +1,150 @@
+/* -*-c-*- -------------- mixvm.c :
+ * Main function for mixvm, the mix vm simulator
+ * ------------------------------------------------------------------
+ * $Id: mixvm.c,v 1.10 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include <mixlib/mix.h>
+#include <mixlib/mix_vm.h>
+#include <mixlib/mix_vm_dump.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+#else
+# include <lib/getopt.h>
+#endif /* HAVE_GETOPT_LONG */
+
+#include "mixvm_loop.h"
+
+enum {
+ VER_OPT = 'v',
+ HELP_OPT = 'h',
+ USAGE_OPT = 'u',
+ RUN_OPT = 'r',
+ DUMP_OPT = 'd',
+ TIME_OPT = 't',
+ EMACS_OPT = 'e', /* used by mixvm-gud only */
+ NOINIT_OPT = 'q'
+};
+
+static const char *options_ = "vhurdt"; /* no short opt for --emacs */
+
+static struct option long_options_[] =
+{
+ {"version", no_argument, 0, VER_OPT},
+ {"help", no_argument, 0, HELP_OPT},
+ {"usage", no_argument, 0, USAGE_OPT},
+ {"run", required_argument, 0, RUN_OPT},
+ {"dump", no_argument, 0, DUMP_OPT},
+ {"time", no_argument, 0, TIME_OPT},
+ /* pek: yo! */
+ {"emacs", no_argument, 0, EMACS_OPT},
+ {"noinit", no_argument, 0, NOINIT_OPT},
+ {0, 0, 0, 0}
+};
+
+static const gchar *USAGE_ =
+N_("Usage: %s [-vhurdqt] [--version] [--help] [--noinit] [--usage]"
+ "\n\t[--run] [--dump] [--time] [MIX_FILE]\n");
+
+int
+main (int argc, char **argv)
+{
+ int c;
+ const char *prog_name = argv[0];
+ const char *in = NULL;
+ gboolean run = FALSE;
+ gboolean dump = FALSE;
+ gboolean emacs = FALSE;
+ gboolean initfile = TRUE;
+ gboolean ptime = FALSE;
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ while (1)
+ {
+ c = getopt_long (argc, argv, options_, long_options_, (int*)0);
+
+ /* Detect the end of the options. */
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case HELP_OPT: case USAGE_OPT:
+ fprintf (stderr, _(USAGE_), prog_name);
+ return EXIT_SUCCESS;
+ case VER_OPT:
+ mix_print_license ("mixvm, MIX virtual machine");
+ return EXIT_SUCCESS;
+ case RUN_OPT:
+ in = optarg;
+ run = TRUE;
+ break;
+ case DUMP_OPT:
+ dump = TRUE;
+ break;
+ case TIME_OPT:
+ ptime = TRUE;
+ break;
+ case '?':
+ /* getopt already handles the output of a warning message */
+ fprintf (stderr, _("(Try: %s -h)\n"), prog_name);
+ return EXIT_FAILURE;
+ case EMACS_OPT:
+ emacs = TRUE;
+ break;
+ case NOINIT_OPT:
+ initfile = FALSE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ if ( optind < argc-1 )
+ {
+ fprintf (stderr, _("*** Error: Too many input files.\n"));
+ return EXIT_FAILURE;
+ }
+
+ if (!in) in = argv[optind];
+
+ mix_init_lib ();
+
+ if (run) mix_vmrun (in, dump, ptime);
+ else mix_vmloop (argc, argv, initfile, in, emacs);
+
+ mix_release_lib ();
+
+ return EXIT_SUCCESS;
+
+}
+
+
+
+
diff --git a/mixutils/mixvm_command.c b/mixutils/mixvm_command.c
new file mode 100644
index 0000000..0fbe1ce
--- /dev/null
+++ b/mixutils/mixvm_command.c
@@ -0,0 +1,270 @@
+/* -*-c-*- -------------- mixvm_command.c :
+ * Implementation of the functions declared in mixvm_command.h
+ * ------------------------------------------------------------------
+ * $Id: mixvm_command.c,v 1.12 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <mixlib/mix.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <mixlib/mix.h>
+
+#ifdef HAVE_LIBREADLINE
+# include <readline/readline.h>
+# include <readline/history.h>
+# ifndef HAVE_RL_COMPLETION_MATCHES /* old versions of rl don't use rl_ */
+# define rl_completion_matches completion_matches
+# endif
+#else /* ! HAVE_LIBREADLINE */
+ typedef int Function ();
+#endif /* HAVE_LIBREADLINE */
+
+#include <mixlib/mix_vm.h>
+#include <mixlib/mix_vm_dump.h>
+#include <mixlib/mix_eval.h>
+#include <mixlib/mix_src_file.h>
+#include <mixlib/mix_vm_command.h>
+
+#ifdef MAKE_GUILE
+# include <mixguile/mixguile.h>
+static gboolean
+try_guile_ (char *line)
+{
+ if (line[0] == '(')
+ {
+ if (line[strlen (line) -1] != ')') return FALSE;
+ mixguile_interpret_command (line);
+ return TRUE;
+ }
+ return FALSE;
+}
+#else /* !MAKE_GUILE */
+# define try_guile_(ignored) FALSE
+#endif /* MAKE_GUILE */
+
+#include "mixvm_loop.h"
+#include "mixvm_command.h"
+
+/* mixvm dispatcher */
+static mix_vm_cmd_dispatcher_t *dis_ = NULL;
+static mix_config_t *config_ = NULL;
+
+/* The names of functions that actually do the manipulation. */
+#define DEC_FUN(name) \
+static gboolean cmd_##name (mix_vm_cmd_dispatcher_t *dis, const char *arg)
+
+DEC_FUN (shell_);
+DEC_FUN (quit_);
+DEC_FUN (prompt_);
+
+mix_vm_command_info_t commands[] = {
+ { "prompt", cmd_prompt_, N_("Set command prompt"), "prompt PROMPT" },
+ { "shell", cmd_shell_, N_("Execute shell command"), "shell COMMAND" },
+ { "quit", cmd_quit_, N_("Quit the program"), "quit" },
+ { (char *)NULL, (Function *)NULL, (char *)NULL }
+};
+
+
+#ifdef HAVE_LIBREADLINE
+/* readline functions */
+static char *
+mixvm_cmd_generator_ (const char *text, int state);
+
+
+/* Attempt to complete on the contents of TEXT. START and END bound the
+ region of rl_line_buffer that contains the word to complete. TEXT is
+ the word to complete. We can use the entire contents of rl_line_buffer
+ in case we want to do some simple parsing. Return the array of matches,
+ or NULL if there aren't any. */
+static char **
+mixvm_cmd_completion_ (char *text, int start, int end)
+{
+ char **matches;
+
+ matches = (char **)NULL;
+
+ /* If this word is at the start of the line, then it is a command
+ to complete. Otherwise it is the name of a file in the current
+ directory. */
+ if (start == 0)
+ matches = rl_completion_matches (text, mixvm_cmd_generator_);
+
+ return (matches);
+}
+
+/* Generator function for command completion. STATE lets us know whether
+ to start from scratch; without any state (i.e. STATE == 0), then we
+ start at the top of the list. */
+static char *
+mixvm_cmd_generator_ (const char *text, int state)
+{
+ static const GList *comp = NULL;
+ char *prefix = NULL;
+ char *name = NULL;
+
+ /* If this is a new word to complete, initialize now. */
+ if (!state)
+ {
+ if (prefix) g_free (prefix);
+ comp = mix_vm_cmd_dispatcher_complete (dis_, text, &prefix);
+ }
+
+ /* Return the next name which partially matches from the command list. */
+ if (comp)
+ {
+ name = g_strdup ((const gchar *)comp->data);
+ comp = comp->next;
+ }
+
+ return name;
+}
+#endif /* HAVE_LIBREADLINE */
+
+
+/* emacs interface */
+static void
+emacs_output_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg, gpointer data)
+{
+ /* pek: probably bad that we snag the src w/every emacs_output_,
+ however when multiple files are supported then this will
+ have to be done each time (but the info will be snagged
+ from elsewhere...) */
+ const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis);
+ const mix_src_file_t *src = mix_vm_get_src_file (vm);
+ const gchar *path = mix_src_file_get_path (src);
+
+ mix_address_t loc = mix_vm_get_prog_count (vm);
+ guint lineno = mix_vm_get_address_lineno (vm, loc);
+
+ printf ("\032\032mixvm:%s%s:%d\n", path, MIX_SRC_DEFEXT, lineno);
+ return;
+}
+
+static int
+cmd_quit_ (mix_vm_cmd_dispatcher_t *dis, const char *arg)
+{
+ puts (_("Quitting ..."));
+ if (dis_) mix_vm_cmd_dispatcher_delete (dis_);
+ if (config_) mix_config_delete (config_);
+ exit (0);
+
+ /* pek: anything needed here to make the marker disappear??? */
+ return FALSE;
+}
+
+static int
+cmd_shell_ (mix_vm_cmd_dispatcher_t *dis, const char *arg)
+{
+ system (arg);
+ return TRUE;
+}
+
+static int
+cmd_prompt_ (mix_vm_cmd_dispatcher_t *dis, const char *arg)
+{
+ if (arg && strlen (arg)) mix_vmloop_set_prompt (arg);
+ return TRUE;
+}
+
+
+/* external interface */
+static void
+init_dis_ (mix_vm_cmd_dispatcher_t *dis)
+{
+ static const gchar * envars[] = { "MDK_EDITOR", "X_EDITOR", "EDITOR",
+ "VISUAL" };
+
+ static const guint s = sizeof (envars) / sizeof (envars[0]);
+ static const gchar *editor = NULL;
+ gchar *edit = NULL;
+
+ if (!editor)
+ {
+ int k;
+ for (k = 0; k < s; k++)
+ if ( (editor = getenv (envars[k])) != NULL ) break;
+ }
+ if (!editor) editor = "vi";
+ edit = g_strconcat (editor, " %s", NULL);
+ mix_vm_cmd_dispatcher_set_editor (dis, edit);
+ g_free (edit);
+ mix_vm_cmd_dispatcher_set_assembler (dis, "mixasm %s");
+}
+
+mix_vm_cmd_dispatcher_t *
+mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs)
+{
+ int k;
+
+#ifdef HAVE_LIBREADLINE
+ /* Tell the completer that we want a crack first. */
+ rl_attempted_completion_function = (CPPFunction *)mixvm_cmd_completion_;
+#endif /* HAVE_LIBREADLINE */
+
+ /* initialise the dispatcher */
+ config_ = config;
+ dis_ = mix_vm_cmd_dispatcher_new_with_config (stdout, stderr, config_);
+
+ if ( dis_ == NULL)
+ g_error (_("Failed initialisation (no memory resources)"));
+
+ init_dis_ (dis_);
+
+ /* add local commands */
+ k = 0;
+ while (commands[k].name)
+ {
+ mix_vm_cmd_dispatcher_register_new (dis_, commands + k);
+ ++k;
+ }
+
+ /* install post hook for emacs interaction */
+ if (use_emacs)
+ {
+ mix_vm_cmd_dispatcher_post_hook (dis_, MIX_CMD_LOAD, emacs_output_, NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_, MIX_CMD_RUN, emacs_output_, NULL);
+ mix_vm_cmd_dispatcher_post_hook (dis_, MIX_CMD_NEXT, emacs_output_, NULL);
+ }
+
+ if (arg)
+ mix_vm_cmd_dispatcher_dispatch (dis_, MIX_CMD_LOAD, arg);
+
+ return dis_;
+}
+
+gboolean
+mixvm_cmd_exec (char *line)
+{
+ if (!line) return cmd_quit_(dis_, NULL);
+
+ /* strip white space */
+ line = g_strstrip(line);
+
+ if (strlen (line) == 0) return TRUE;
+
+ if (try_guile_ (line)) return TRUE;
+
+ (void)mix_vm_cmd_dispatcher_dispatch_text (dis_, line);
+
+ return TRUE;
+}
diff --git a/mixutils/mixvm_command.h b/mixutils/mixvm_command.h
new file mode 100644
index 0000000..28ff877
--- /dev/null
+++ b/mixutils/mixvm_command.h
@@ -0,0 +1,38 @@
+/* -*-c-*- ---------------- mixvm_command.h :
+ * Declarations for commands accepted by the mix virtual machine
+ * ------------------------------------------------------------------
+ * $Id: mixvm_command.h,v 1.5 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXVM_COMMAND_H
+#define MIXVM_COMMAND_H
+
+#include <mixlib/mix_config.h>
+#include <mixlib/mix_vm_command.h>
+
+extern mix_vm_cmd_dispatcher_t *
+mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs);
+
+extern gboolean
+mixvm_cmd_exec (char *line);
+
+#endif /* MIXVM_COMMAND_H */
+
diff --git a/mixutils/mixvm_loop.c b/mixutils/mixvm_loop.c
new file mode 100644
index 0000000..ef84444
--- /dev/null
+++ b/mixutils/mixvm_loop.c
@@ -0,0 +1,160 @@
+/* -*-c-*- -------------- mixvm_loop.c :
+ * Implementation of mix vm command loop.
+ * ------------------------------------------------------------------
+ * $Id: mixvm_loop.c,v 1.15 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+#include <mixlib/mix.h>
+#include <mixlib/mix_config.h>
+#include <mixlib/mix_vm.h>
+#include <mixlib/mix_device.h>
+#include <mixlib/mix_vm_dump.h>
+
+#ifdef MAKE_GUILE
+#include <mixguile/mixguile.h>
+#endif
+
+#include "mixvm_command.h"
+#include "mixvm_loop.h"
+
+#ifdef HAVE_LIBHISTORY
+# include <readline/history.h>
+#else
+# define add_history(x) ((void)0)
+#endif
+
+#ifdef HAVE_LIBREADLINE
+# include <readline/readline.h>
+#else /* !HAVE_LIBREADLINE */
+static char *
+readline (char *prompt)
+{
+ enum {LINE_LEN = 256};
+ char *line = g_new (char, LINE_LEN);
+ printf ("%s", prompt);
+ return fgets (line, LINE_LEN, stdin);
+}
+#endif /* HAVE_LIBREADLINE */
+
+/* A static variable for holding the line. */
+static char *line_read = (char *)NULL;
+
+#define PROMPT_LEN 128
+static char PROMPT[PROMPT_LEN + 1] = {'M', 'I', 'X', ' ', '>'};
+static const char *CONFIG_FILE_ = "mixvm.config";
+static const char *PROMPT_KEY_ = "Prompt";
+
+/* Read a string, and return a pointer to it. Returns NULL on EOF. */
+static char *
+rl_gets ()
+{
+ /* If the buffer has already been allocated, return the memory
+ to the free pool. */
+ if (line_read)
+ {
+ g_free (line_read);
+ line_read = (char *)NULL;
+ }
+
+ /* Get a line from the user. */
+ line_read = readline ((char *)PROMPT);
+
+ /* If the line has any text in it, save it on the history. */
+ if (line_read && *line_read)
+ add_history (line_read);
+
+ return (line_read);
+}
+
+
+/* The main command loop of the virtual machine */
+static mix_config_t *config_ = NULL;
+
+static mix_vm_cmd_dispatcher_t *
+init_mixvm_ (const gchar *file, gboolean use_emacs)
+{
+ static const gchar *HISTORY_FILE = "mixvm.history";
+ static gint HISTORY_SIZE = 100;
+ config_ = mix_config_new (NULL, CONFIG_FILE_);
+
+ mix_config_set_autosave (config_, TRUE);
+ if (!mix_config_get_history_file (config_))
+ mix_config_set_history_file (config_, HISTORY_FILE);
+ if (mix_config_get_history_size (config_) == 0)
+ mix_config_set_history_size (config_, HISTORY_SIZE);
+
+ mix_vmloop_set_prompt (mix_config_get (config_, PROMPT_KEY_));
+
+ return mixvm_cmd_init (config_, (char *)file, use_emacs);
+}
+
+void
+mix_vmloop_set_prompt (const gchar *prompt)
+{
+ if (prompt)
+ {
+ g_snprintf (PROMPT, PROMPT_LEN, "%s ", prompt);
+ mix_config_update (config_, PROMPT_KEY_, prompt);
+ }
+}
+
+static void
+loop_ (int argc, char *argv[])
+{
+ while ( mixvm_cmd_exec (rl_gets ()) )
+ ;
+ mix_config_delete (config_);
+}
+
+void
+mix_vmloop (int argc, char *argv[], gboolean initfile,
+ const gchar *file, gboolean use_emacs)
+{
+#ifdef MAKE_GUILE
+ mix_vm_cmd_dispatcher_t *dis = init_mixvm_ (file, use_emacs);
+ mixguile_init (argc, argv, initfile, loop_, dis);
+#else
+ (void) init_mixvm_ (file, use_emacs);
+ loop_ (argc, argv);
+#endif
+}
+
+/* run a program and exit */
+void
+mix_vmrun (const gchar *code_file, gboolean dump, gboolean ptime)
+{
+ gchar *time_cmd = ptime? g_strdup ("stime on") : g_strdup ("stime off");
+ gchar *run_cmd = g_strdup ("run");
+ gchar *dump_cmd = dump? g_strdup ("pall") : NULL;
+ gboolean result;
+
+ init_mixvm_ (code_file, FALSE);
+ result = mixvm_cmd_exec (time_cmd) && mixvm_cmd_exec (run_cmd);
+ if (result && dump) mixvm_cmd_exec (dump_cmd);
+ mix_config_set_autosave (config_, FALSE);
+ mix_config_delete (config_);
+ g_free(time_cmd);
+ g_free(run_cmd);
+ if (dump_cmd) g_free(dump_cmd);
+}
diff --git a/mixutils/mixvm_loop.h b/mixutils/mixvm_loop.h
new file mode 100644
index 0000000..2dabfcd
--- /dev/null
+++ b/mixutils/mixvm_loop.h
@@ -0,0 +1,38 @@
+/* -*-c-*- ---------------- mixvm_loop.h :
+ * Declarations for functions controlling the mixvm loop.
+ * ------------------------------------------------------------------
+ * $Id: mixvm_loop.h,v 1.2 2005/09/20 19:43:13 jao Exp $
+ * ------------------------------------------------------------------
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef MIXVM_LOOP_H
+#define MIXVM_LOOP_H
+
+extern void
+mix_vmloop (int argc, char *argv[], gboolean initfile,
+ const gchar *code_file, gboolean use_emacs);
+
+extern void
+mix_vmrun (const gchar *code_file, gboolean dump, gboolean ptime);
+
+extern void
+mix_vmloop_set_prompt (const gchar *prompt);
+
+#endif /* MIXVM_LOOP_H */
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 0000000..be63e78
--- /dev/null
+++ b/po/ChangeLog
@@ -0,0 +1,143 @@
+2004-07-30 Jose Antonio Ortega Ruiz <jao@gnu.org>
+
+ * de.po (Module): mike's german translation.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+
+2002-03-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.40.
+ * cat-id-tbl.c: Remove file.
+ * stamp-cat-id: Remove file.
+
+2001-09-26 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-27 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-26 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-25 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-25 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-25 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-23 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-22 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-22 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-22 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-22 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-21 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-20 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-17 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-08-17 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.39.
+
+2001-07-23 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-23 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-23 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-23 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-18 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-16 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-16 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-16 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+
+2001-07-16 gettextize <bug-gnu-utils@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.10.38.
+ * cat-id-tbl.c: Remove file.
+ * stamp-cat-id: Remove file.
+
+2000-02-08 jose antonio ortega ruiz <jaortega@retemail.es>
+
+ * ca.po: New file
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 0000000..f171d41
--- /dev/null
+++ b/po/LINGUAS
@@ -0,0 +1,2 @@
+# Set of available translations
+de
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 0000000..8b09f53
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1,25 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..c8a1a0a
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,27 @@
+# List of source files containing translatable strings.
+# Package source files
+mixutils/mixasm.c
+mixutils/mixasm_comp.c
+mixutils/mixvm.c
+mixutils/mixvm_command.c
+
+mixlib/mix.c
+mixlib/mix_config.c
+mixlib/mix_parser.c
+mixlib/mix_predicate.c
+mixlib/mix_vm_dump.c
+mixlib/mix_vm_command.c
+mixlib/mix_eval.c
+mixlib/xmix_vm_handlers.c
+
+mixgtk/mixgtk_device.c
+mixgtk/mixgtk_gen_handlers.c
+mixgtk/mixgtk_mixal.c
+mixgtk/mixgtk_mixvm.c
+mixgtk/gmixvm.c
+mixgtk/mixgtk.c
+mixgtk/mixgtk.glade
+
+mixguile/mixguile.c
+mixguile/mixguile_cmd_dispatcher.c
+
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..3df6691
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,1553 @@
+# German translation for GNU MDK.
+# Copyright (C) 2000-2005 Free Software Foundation, Inc.
+# This file is distributed under the same license as the GNU MDK package.
+# Michael Scholz <scholz-micha@gmx.de>, 2003-2004
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MDK 1.2.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2004-08-02 10:21+0200\n"
+"PO-Revision-Date: 2005-09-19 22:56+0200\n"
+"Last-Translator: Michael Scholz <scholz-micha@gmx.de>\n"
+"Language-Team: German (no team)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: mixutils/mixasm.c:59
+#, c-format
+msgid ""
+"Usage: %s [-vhulO] [-o OUTPUT_FILE] [--version] [--help]\n"
+"\t[--usage] [--ndebug] [--output=OUTPUT_FILE] [--list[=LIST_FILE]] file\n"
+msgstr ""
+"Aufruf: %s [-vhulO] [-o OUTPUT_FILE] [--version] [--help]\n"
+"\t[--usage] [--ndebug] [--output=OUTPUT_FILE] [--list[=LIST_FILE]] file\n"
+
+#: mixutils/mixasm.c:103 mixutils/mixvm.c:116
+#, c-format
+msgid "(Try: %s -h)\n"
+msgstr "(Versuche: %s -h)\n"
+
+#: mixutils/mixasm.c:112
+#, c-format
+msgid "*** Error: Missing source file.\n"
+msgstr "*** Fehler: Quelldatei fehlt.\n"
+
+#: mixutils/mixasm.c:117 mixutils/mixvm.c:131
+#, c-format
+msgid "*** Error: Too many input files.\n"
+msgstr "*** Fehler: Zu viele Eingabedateien.\n"
+
+#: mixutils/mixasm_comp.c:38
+#, c-format
+msgid "*** Unable to open source file %s\n"
+msgstr "*** Kann Quelldatei %s nicht öffnen\n"
+
+#: mixutils/mixasm_comp.c:45
+#, c-format
+msgid "(%d warning(s))\n"
+msgstr "(%d Warnung(en))\n"
+
+#: mixutils/mixasm_comp.c:48
+#, c-format
+msgid "*** Error writing output code file: %s\n"
+msgstr "*** Fehler beim Schreiben der Ausgabedatei: %s\n"
+
+#: mixutils/mixasm_comp.c:56
+#, c-format
+msgid "*** Error writing listing file: %s\n"
+msgstr "*** Fehler beim Schreiben der Listingdatei: %s\n"
+
+#: mixutils/mixasm_comp.c:63
+#, c-format
+msgid "(%d warning(s), %d error(s))\n"
+msgstr "(%d Warnungen, %d Fehler)\n"
+
+#: mixutils/mixvm.c:69
+#, c-format
+msgid ""
+"Usage: %s [-vhurdqt] [--version] [--help] [--noinit] [--usage]\n"
+"\t[--run] [--dump] [--time] [MIX_FILE]\n"
+msgstr ""
+"Aufruf: %s [-vhurdqt] [--version] [--help] [--noinit] [--usage]\n"
+"\t[--run] [--dump] [--time] [MIX_FILE]\n"
+
+#: mixutils/mixvm_command.c:81
+msgid "Set command prompt"
+msgstr "Kommandoprompt setzen"
+
+#: mixutils/mixvm_command.c:82
+msgid "Execute shell command"
+msgstr "Shellkommando ausführen"
+
+#: mixutils/mixvm_command.c:83
+msgid "Quit the program"
+msgstr "Programm beenden"
+
+#: mixutils/mixvm_command.c:166
+msgid "Quitting ..."
+msgstr "Beenden ..."
+
+#: mixutils/mixvm_command.c:229
+msgid "Failed initialisation (no memory resources)"
+msgstr "Initialisierungsfehler (keine Speicherressourcen)"
+
+#: mixlib/mix.c:66
+#, c-format
+msgid ""
+"%s (GNU MDK %s)\n"
+"\n"
+msgstr ""
+"%s (GNU MDK %s)\n"
+"\n"
+
+#: mixlib/mix.c:84
+#, c-format
+msgid "Error creating %s dir %s: %s"
+msgstr "Fehler beim Erzeugen von %s, Verzeichnis %s: %s"
+
+#: mixlib/mix.c:93
+#, c-format
+msgid "Error setting %s dir: %s is not a directory"
+msgstr "Fehler beim Setzen von %s: %s ist kein Verzeichnis"
+
+#: mixlib/mix_config.c:216
+#, c-format
+msgid "Unable to open config file %s (%s)"
+msgstr "Kann Konfigurationsdatei nicht öffnen %s (%s)"
+
+#: mixlib/mix_parser.c:37
+msgid "successful compilation"
+msgstr "Kompilation erfolgreich"
+
+#: mixlib/mix_parser.c:38
+msgid "file not yet compiled"
+msgstr "Datei ist noch nicht kompiliert"
+
+#: mixlib/mix_parser.c:39
+msgid "internal error"
+msgstr "Interner Fehler"
+
+#: mixlib/mix_parser.c:40
+msgid "unable to open MIX source file"
+msgstr "kann MIX-Quelldatei nicht öffnen"
+
+#: mixlib/mix_parser.c:41
+msgid "unable to open MIX output file"
+msgstr "kann MIX-Ausgabedatei nicht öffnen"
+
+#: mixlib/mix_parser.c:42
+msgid "unexpected end of file"
+msgstr "unerwartetes Dateiende"
+
+#: mixlib/mix_parser.c:43
+msgid "invalid location field"
+msgstr "ungültiges Location-Feld"
+
+#: mixlib/mix_parser.c:44
+msgid "duplicated symbol"
+msgstr "Symbol ist doppelt"
+
+#: mixlib/mix_parser.c:45
+msgid "symbol too long"
+msgstr "Symbol ist zu lang"
+
+#: mixlib/mix_parser.c:46
+msgid "missing operator field"
+msgstr "Operator-Feld fehlt"
+
+#: mixlib/mix_parser.c:47
+msgid "unexpected location symbol"
+msgstr "unerwartetes Location-Symbol"
+
+#: mixlib/mix_parser.c:48
+msgid "invalid address field"
+msgstr "ungültiges Adreßfeld"
+
+#: mixlib/mix_parser.c:49
+msgid "invalid index field"
+msgstr "ungültiges Index-Feld"
+
+#: mixlib/mix_parser.c:50
+msgid "invalid f-specification"
+msgstr "ungültige F-Spezifikation"
+
+#: mixlib/mix_parser.c:51
+msgid "invalid operation field"
+msgstr "ungültiges Operation-Feld"
+
+#: mixlib/mix_parser.c:52
+msgid "invalid expression"
+msgstr "ungültiger Ausdruck"
+
+#: mixlib/mix_parser.c:53
+msgid "undefined symbol"
+msgstr "Symbol nicht definiert"
+
+#: mixlib/mix_parser.c:54
+msgid "mismatched parenthesis"
+msgstr "Klammerfehler"
+
+#: mixlib/mix_parser.c:55
+msgid "unexpected f-specfication"
+msgstr "unerwartete F-Spezifikation"
+
+#: mixlib/mix_parser.c:56
+msgid "missing symbol name"
+msgstr "Symbolname fehlt"
+
+#: mixlib/mix_parser.c:57
+msgid "symbol is an instruction name"
+msgstr "Symbol ist ein Instruktionsname"
+
+#: mixlib/mix_parser.c:58
+msgid "failed write access to code file"
+msgstr "kein Schreibzugriff auf Code-Datei"
+
+#: mixlib/mix_parser.c:59
+msgid "operand of ALF pseudo instruction has less than 5 chars"
+msgstr "Operand von ALF-Pseudoinstruktion hat weniger als 5 Zeichen"
+
+#: mixlib/mix_parser.c:60
+msgid "operand of ALF pseudo instruction has more than 5 chars"
+msgstr "Operand von ALF-Pseudoinstruktion hat mehr als 5 Zeichen"
+
+#: mixlib/mix_parser.c:61
+msgid "operand of ALF pseudo instruction must be quoted"
+msgstr "Operand von ALF-Pseudoinstruktion muß in Anführungszeichen"
+
+#: mixlib/mix_parser.c:136
+msgid "No system resources"
+msgstr "Keine Systemressourcen"
+
+#: mixlib/mix_parser.c:381
+#, c-format
+msgid "\t%s\n"
+msgstr "\t%s\n"
+
+#: mixlib/mix_parser.c:381
+msgid "UNKNOWN"
+msgstr "UNBEKANNT"
+
+#: mixlib/mix_parser.c:406
+#, c-format
+msgid ""
+"*** %s%s: compilation summary ***\n"
+"\n"
+msgstr ""
+"*** %s%s: Kompilerzusammenfassung ***\n"
+"\n"
+
+#: mixlib/mix_parser.c:410
+msgid "Src Address Compiled word Symbolic rep\n"
+msgstr "Src Address Compiled word Symbolic rep\n"
+
+#: mixlib/mix_parser.c:415
+#, c-format
+msgid ""
+"\n"
+"*** Start address:\t%d\n"
+"*** End address:\t%d\n"
+msgstr ""
+"\n"
+"*** Startadresse:\t%d\n"
+"*** Endadresse:\t%d\n"
+
+#: mixlib/mix_parser.c:418
+#, c-format
+msgid ""
+"\n"
+"*** Symbol table\n"
+msgstr ""
+"\n"
+"*** Symboltabelle\n"
+
+#: mixlib/mix_parser.c:421
+#, c-format
+msgid ""
+"\n"
+"*** End of summary ***\n"
+msgstr ""
+"\n"
+"*** Ende der Zusammenfassung ***\n"
+
+#: mixlib/mix_parser.c:598
+msgid "warning"
+msgstr "Warnung"
+
+#: mixlib/mix_parser.c:598
+msgid "error"
+msgstr "Fehler"
+
+#: mixlib/mix_predicate.c:176
+#, c-format
+msgid "Register A changed to %s%ld"
+msgstr "Register A geändert zu %s%ld"
+
+#: mixlib/mix_predicate.c:181
+#, c-format
+msgid "Register X changed to %s%ld"
+msgstr "Register X geändert zu %s%ld"
+
+#: mixlib/mix_predicate.c:186
+#, c-format
+msgid "Register J changed to %d"
+msgstr "Register J geändert zu %d"
+
+#: mixlib/mix_predicate.c:191
+#, c-format
+msgid "Register I%d changed to %s%d"
+msgstr "Register I%d geändert zu %s%d"
+
+#: mixlib/mix_predicate.c:197
+#, c-format
+msgid "Comparison flag changed to %s"
+msgstr "Comparision Flag geändert zu %s"
+
+#: mixlib/mix_predicate.c:201
+#, c-format
+msgid "Overflow toggled %s"
+msgstr "Overflow gewechselt zu %s"
+
+#: mixlib/mix_predicate.c:205
+#, c-format
+msgid "Memory address %d changed to %s%ld"
+msgstr "Speicheradresse %d geändert zu %s%ld"
+
+#: mixlib/mix_vm_dump.c:113
+#, c-format
+msgid "Overflow: %s\n"
+msgstr "Overflow: %s\n"
+
+#: mixlib/mix_vm_dump.c:134
+#, c-format
+msgid "Cmp: %s\n"
+msgstr "Cmp: %s\n"
+
+#: mixlib/mix_vm_command.c:480
+#, c-format
+msgid "Unknown command. Try: help\n"
+msgstr "Unbekanntes Kommando. Versuche: help\n"
+
+#: mixlib/mix_eval.c:29
+msgid "Successful evaluation"
+msgstr "Erfolgreiche Berechnung"
+
+#: mixlib/mix_eval.c:30
+msgid "Syntax error in expression"
+msgstr "Syntaxfehler im Ausdruck"
+
+#: mixlib/mix_eval.c:31
+msgid "Out of range F-specification"
+msgstr "Außerhalb des Bereiches F-Spezifikation"
+
+#: mixlib/mix_eval.c:32
+msgid "Mismatched parenthesis"
+msgstr "Klammerfehler"
+
+#: mixlib/mix_eval.c:33
+msgid "Undefined symbol"
+msgstr "Undefiniertes Symbol"
+
+#: mixlib/mix_eval.c:34
+msgid "Internal error"
+msgstr "Interner Fehler"
+
+#: mixlib/xmix_vm_handlers.c:29
+msgid "Display this text"
+msgstr "Zeigt diesen Text"
+
+#: mixlib/xmix_vm_handlers.c:30
+msgid "Load a MIX code file"
+msgstr "Eine MIX-Datei laden"
+
+#: mixlib/xmix_vm_handlers.c:31 mixgtk/mixgtk.glade:68
+msgid "Edit a MIXAL source file"
+msgstr "Eine MIXAL-Quelldatei bearbeiten"
+
+#: mixlib/xmix_vm_handlers.c:32
+msgid "Print the external editor command"
+msgstr "Externen Editor ausgeben"
+
+#: mixlib/xmix_vm_handlers.c:33
+msgid "Set the external editor command"
+msgstr "Externen Editor setzen"
+
+#: mixlib/xmix_vm_handlers.c:35 mixgtk/mixgtk.glade:91
+msgid "Compile a MIXAL source file"
+msgstr "Eine MIXAL-Quelldatei kompilieren"
+
+#: mixlib/xmix_vm_handlers.c:37
+msgid "Print the compile command"
+msgstr "Kompilerkommando ausgeben"
+
+#: mixlib/xmix_vm_handlers.c:38
+msgid "Set the compile command"
+msgstr "Kompilerkommando setzen"
+
+#: mixlib/xmix_vm_handlers.c:40
+msgid "Run loaded or given MIX code file"
+msgstr "Starte geladene oder angegebene MIX-Datei"
+
+#: mixlib/xmix_vm_handlers.c:42
+msgid "Execute next instruction(s)"
+msgstr "Nächste Instruktion(en) ausführen"
+
+#: mixlib/xmix_vm_handlers.c:44
+msgid "Print current vm status"
+msgstr "Aktuellen VM-Status anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:45
+msgid "Print program counter value"
+msgstr "Programm-Zählerwert anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:46
+msgid "Print symbol value"
+msgstr "Symbolwert anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:47
+msgid "Print register value"
+msgstr "Registerwert anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:49
+msgid "Print comparison and overflow flags"
+msgstr "Comparison- und Overflow-Flag anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:51
+msgid "Print all registers and flags"
+msgstr "Alle Register und Flags anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:52
+msgid "Print memory contents in address range"
+msgstr "Speicherinhalt im Adreßbereich anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:54
+msgid "Set register value"
+msgstr "Registerwert setzen"
+
+#: mixlib/xmix_vm_handlers.c:56
+msgid "Set comparison flag value"
+msgstr "Comparison-Flag setzen"
+
+#: mixlib/xmix_vm_handlers.c:57
+msgid "Set overflow flag value"
+msgstr "Overflow-Flag setzen"
+
+#: mixlib/xmix_vm_handlers.c:58
+msgid "Set memory contents in given address"
+msgstr "Speicherinhalt in angegebener Adresse setzen"
+
+#: mixlib/xmix_vm_handlers.c:60
+msgid "Set a symbol's value"
+msgstr "Einen Symbolwert setzen"
+
+#: mixlib/xmix_vm_handlers.c:61
+msgid "Set break point at given line"
+msgstr "Breakpoint bei angegebener Zeile setzen"
+
+#: mixlib/xmix_vm_handlers.c:62
+msgid "Clear break point at given line"
+msgstr "Breakpoint bei angegebener Zeile löschen"
+
+#: mixlib/xmix_vm_handlers.c:63
+msgid "Set break point at given address"
+msgstr "Breakpoint bei angegebener Adresse setzen"
+
+#: mixlib/xmix_vm_handlers.c:65
+msgid "Clear break point at given address"
+msgstr "Breakpoint bei angegebener Adresse löschen"
+
+#: mixlib/xmix_vm_handlers.c:67
+msgid "Set conditional breakpoint on register change"
+msgstr "Conditional Breakpoint bei Registeränderung setzen"
+
+#: mixlib/xmix_vm_handlers.c:69
+msgid "Clear conditional breakpoint on register change"
+msgstr "Conditional Breakpoint bei Registeränderung löschen"
+
+#: mixlib/xmix_vm_handlers.c:71
+msgid "Set conditional breakpoint on mem cell change"
+msgstr "Conditional Breakpoint bei Speicherzellenänderung setzen"
+
+#: mixlib/xmix_vm_handlers.c:73
+msgid "Clear conditional breakpoint on mem cell change"
+msgstr "Conditional Breakpoint bei Speicherzellenänderung löschen"
+
+#: mixlib/xmix_vm_handlers.c:76
+msgid "Set conditional breakpoint on comparison flag change"
+msgstr "Conditional Breakpoint bei Comparison-Flag-Änderung setzen"
+
+#: mixlib/xmix_vm_handlers.c:78
+msgid "Clear conditional breakpoint on comparison flag change"
+msgstr "Conditional Breakpoint bei Comparison-Flag-Änderung löschen"
+
+#: mixlib/xmix_vm_handlers.c:80 mixlib/xmix_vm_handlers.c:82
+msgid "Set conditional breakpoint on overflow toggled"
+msgstr "Conditional Breakpoint bei Overflow-Änderung setzen"
+
+#: mixlib/xmix_vm_handlers.c:83
+msgid "Clear all breakpoints"
+msgstr "Alle Breakpoints löschen"
+
+#: mixlib/xmix_vm_handlers.c:84
+msgid "Evaluate a given W-expression"
+msgstr "W-Ausdruck berechnen"
+
+#: mixlib/xmix_vm_handlers.c:85
+msgid "Convert a MIX word to its decimal value"
+msgstr "MIX-Wort in seinen dezimalen Wert konvertieren"
+
+#: mixlib/xmix_vm_handlers.c:87
+msgid "Turn on/off instruction tracing"
+msgstr "Instruktionsmitschnitt an/aus"
+
+#: mixlib/xmix_vm_handlers.c:89
+msgid "Print backtrace of executed instructions"
+msgstr "Letzte ausgeführte Instruktionen anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:91
+msgid "Turn on/off timing statistics"
+msgstr "Zeitstatistik an/aus"
+
+#: mixlib/xmix_vm_handlers.c:93
+msgid "Print current time statistics"
+msgstr "Aktuelle Zeitstatistik anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:94
+msgid "Set devices directory"
+msgstr "Device-Verzeichnis setzen"
+
+#: mixlib/xmix_vm_handlers.c:95
+msgid "Print current devices directory"
+msgstr "Aktuelles Device-Verzeichnis anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:96
+msgid "Turn on/off message logging"
+msgstr "Message-Aufzeichnung an/aus"
+
+#: mixlib/xmix_vm_handlers.c:97
+msgid "Print the current program path"
+msgstr "Aktuellen Programmpfad anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:98
+msgid "Print the current program source path"
+msgstr "Aktuellen Programmquellpfad anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:100
+msgid "Print the current (or a given) program source line"
+msgstr "Aktuelle (oder angegebene) Programmquellzeile anzeigen"
+
+#: mixlib/xmix_vm_handlers.c:167
+#, c-format
+msgid "Elapsed time: %ld /Total program time: %ld (Total uptime: %ld)\n"
+msgstr ""
+"Vergangene Zeit: %ld /Gesamte Programmzeit: %ld (Gesamte Uptime: %ld)\n"
+
+#: mixlib/xmix_vm_handlers.c:194
+#, c-format
+msgid ""
+"%-15s%s.\n"
+"%-15sUsage: %s\n"
+msgstr ""
+"%-15s%s.\n"
+"%-15sAufruf: %s\n"
+
+#: mixlib/xmix_vm_handlers.c:198
+#, c-format
+msgid "No commands match `%s'\n"
+msgstr "Kein Kommando `%s'\n"
+
+#: mixlib/xmix_vm_handlers.c:204
+#, c-format
+msgid "Possible commands are:\n"
+msgstr "Mögliche Kommandos sind:\n"
+
+#: mixlib/xmix_vm_handlers.c:218
+msgid "Missing file name"
+msgstr "Dateiname fehlt"
+
+#: mixlib/xmix_vm_handlers.c:225
+#, c-format
+msgid "Cannot load %s: "
+msgstr "Kann %s nicht laden: "
+
+#: mixlib/xmix_vm_handlers.c:227
+msgid "Wrong file format"
+msgstr "Falsches Dateiformat"
+
+#: mixlib/xmix_vm_handlers.c:242
+#, c-format
+msgid "Program loaded. Start address: %d"
+msgstr "Programm geladen. Startadresse: %d"
+
+#: mixlib/xmix_vm_handlers.c:254
+msgid "Editor not specified (use sedit)"
+msgstr "Editor nicht angegeben (verwende sedit)"
+
+#: mixlib/xmix_vm_handlers.c:260 mixlib/xmix_vm_handlers.c:285
+msgid "MIXAL source file path not found"
+msgstr "MIXAL Quelldateipfad nicht gefunden"
+
+#: mixlib/xmix_vm_handlers.c:268
+msgid " ...done"
+msgstr " ...fertig"
+
+#: mixlib/xmix_vm_handlers.c:279
+msgid "MIX assembler not specified (use sasm)"
+msgstr "MIX-Assembler nicht angegeben (verwende sasm)"
+
+#: mixlib/xmix_vm_handlers.c:293
+msgid "Successful compilation"
+msgstr "Kompilation erfolgreich"
+
+#: mixlib/xmix_vm_handlers.c:307
+msgid "Running ..."
+msgstr "Arbeite ..."
+
+#: mixlib/xmix_vm_handlers.c:312
+msgid "... done"
+msgstr "... fertig"
+
+#: mixlib/xmix_vm_handlers.c:320
+#, c-format
+msgid "... stopped: breakpoint at line %ld (address %d)"
+msgstr "... angehalten: Breakpoint bei Zeile %ld (Adresse %d)"
+
+#: mixlib/xmix_vm_handlers.c:323
+#, c-format
+msgid "... stopped: breakpoint at address %d"
+msgstr "... angehalten: Breakpoint bei Adresse %d"
+
+#: mixlib/xmix_vm_handlers.c:332
+#, c-format
+msgid "... stopped: %s (line %ld, address %d)"
+msgstr "... angehalten: %s (Zeile %ld, Adresse %d)"
+
+#: mixlib/xmix_vm_handlers.c:336
+#, c-format
+msgid "... stopped: %s (address %d)"
+msgstr "... angehalten: %s (Adresse %d)"
+
+#: mixlib/xmix_vm_handlers.c:342 mixlib/xmix_vm_handlers.c:389
+#, c-format
+msgid "%s:"
+msgstr "%s:"
+
+#: mixlib/xmix_vm_handlers.c:368 mixlib/xmix_vm_handlers.c:472
+#: mixlib/xmix_vm_handlers.c:536 mixlib/xmix_vm_handlers.c:605
+#: mixlib/xmix_vm_handlers.c:631 mixlib/xmix_vm_handlers.c:654
+#: mixlib/xmix_vm_handlers.c:695 mixlib/xmix_vm_handlers.c:740
+#: mixlib/xmix_vm_handlers.c:772 mixlib/xmix_vm_handlers.c:800
+#: mixlib/xmix_vm_handlers.c:834
+#, c-format
+msgid "Invalid argument: %s"
+msgstr "Ungültiges Argument: %s"
+
+#: mixlib/xmix_vm_handlers.c:383
+#, c-format
+msgid "End of program reached at address %d"
+msgstr "Ende des Programmes erreicht bei Adresse %d"
+
+#: mixlib/xmix_vm_handlers.c:412
+msgid "Symbol table not available"
+msgstr "Symboltabelle fehlt"
+
+#: mixlib/xmix_vm_handlers.c:423
+#, c-format
+msgid "%s: symbol not defined\n"
+msgstr "%s: Symbol nicht definiert\n"
+
+#: mixlib/xmix_vm_handlers.c:464
+#, c-format
+msgid "Invalid I index: %d"
+msgstr "Ungültiger I-Index: %d"
+
+#: mixlib/xmix_vm_handlers.c:505
+msgid "Missing memory address"
+msgstr "Speicheradresse fehlt"
+
+#: mixlib/xmix_vm_handlers.c:540
+#, c-format
+msgid "Invalid range: %ld-%ld"
+msgstr "Ungültiger Bereich: %ld-%ld"
+
+#: mixlib/xmix_vm_handlers.c:708
+msgid "Missing arguments"
+msgstr "Argumente fehlen"
+
+#: mixlib/xmix_vm_handlers.c:725
+msgid "Wrong argument number"
+msgstr "Falsche Argumenteanzahl"
+
+#: mixlib/xmix_vm_handlers.c:747
+#, c-format
+msgid "Line number %ld too high"
+msgstr "Zeilennummer %ld zu hoch"
+
+#: mixlib/xmix_vm_handlers.c:750 mixlib/xmix_vm_handlers.c:782
+#: mixlib/xmix_vm_handlers.c:810
+msgid "Could not set breakpoint: internal error"
+msgstr "Kann Breakpoint nicht setzen: Interner Fehler"
+
+#: mixlib/xmix_vm_handlers.c:753
+msgid "Could not set breakpoint: no debug info available"
+msgstr "Kann Breakpoint nicht setzen: Debuginformationen fehlen"
+
+#: mixlib/xmix_vm_handlers.c:758
+#, c-format
+msgid "Breakpoint set at line %ld"
+msgstr "Breakpoint bei Zeile %ld gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:779 mixlib/xmix_vm_handlers.c:841
+#, c-format
+msgid "Invalid address %ld"
+msgstr "Ungültige Adresse %ld"
+
+#: mixlib/xmix_vm_handlers.c:786
+#, c-format
+msgid "Breakpoint set at address %ld"
+msgstr "Breakpoint bei Adresse %ld gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:807
+#, c-format
+msgid "No breakpoint set at line %ld"
+msgstr "Kein Breakpoint bei Zeile %ld gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:813
+msgid "No debug info available"
+msgstr "Debuginformationen fehlen"
+
+#: mixlib/xmix_vm_handlers.c:817
+#, c-format
+msgid "Breakpoint cleared at line %ld"
+msgstr "Breakpoint bei Zeile %ld gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:844
+msgid "Could not clear breakpoint: internal error"
+msgstr "Kann Breakpoint nicht löschen: Interner Fehler"
+
+#: mixlib/xmix_vm_handlers.c:848
+#, c-format
+msgid "Breakpoint cleared at address %ld"
+msgstr "Breakpoint bei Adresse %ld gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:860 mixlib/xmix_vm_handlers.c:1203
+#: mixlib/xmix_vm_handlers.c:1218 mixlib/xmix_vm_handlers.c:1238
+#: mixlib/xmix_vm_handlers.c:1253
+#, c-format
+msgid "Unexpected argument: %s"
+msgstr "Unerwartetes Argument: %s"
+
+#: mixlib/xmix_vm_handlers.c:872 mixlib/xmix_vm_handlers.c:904
+msgid "Missing expression"
+msgstr "Ausdruck fehlt"
+
+#: mixlib/xmix_vm_handlers.c:893
+#, c-format
+msgid ""
+"\n"
+"Evaluation error: %s\n"
+msgstr ""
+"\n"
+"Ausführungsfehler: %s\n"
+
+#: mixlib/xmix_vm_handlers.c:920
+#, c-format
+msgid "Incorrect byte specification: %s"
+msgstr "Falsche Bytespezifikation: %s"
+
+#: mixlib/xmix_vm_handlers.c:935
+#, c-format
+msgid "The expression %s does not fit in a word"
+msgstr "Der Ausdruck %s paßt nicht in ein Wort"
+
+#: mixlib/xmix_vm_handlers.c:958 mixlib/xmix_vm_handlers.c:982
+#: mixlib/xmix_vm_handlers.c:1022 mixlib/xmix_vm_handlers.c:1045
+#: mixlib/xmix_vm_handlers.c:1055
+msgid "Missing argument"
+msgstr "Argument fehlt"
+
+#: mixlib/xmix_vm_handlers.c:971 mixlib/xmix_vm_handlers.c:995
+#: mixlib/xmix_vm_handlers.c:1320
+msgid "Wrong argument: "
+msgstr "Falsches Argument: "
+
+#: mixlib/xmix_vm_handlers.c:1011
+#, c-format
+msgid "Edit command: %s\n"
+msgstr "Editor: %s\n"
+
+#: mixlib/xmix_vm_handlers.c:1013
+#, c-format
+msgid "Edit command not set (use sedit)\n"
+msgstr "Editor nicht gesetzt (verwende sedit)\n"
+
+#: mixlib/xmix_vm_handlers.c:1034
+#, c-format
+msgid "Compile command: %s\n"
+msgstr "Kompiler: %s\n"
+
+#: mixlib/xmix_vm_handlers.c:1036
+#, c-format
+msgid "Compile command not set (use sasm)\n"
+msgstr "Kompiler nicht gesetzt (verwende sasm)\n"
+
+#: mixlib/xmix_vm_handlers.c:1064
+#, c-format
+msgid "Device directory: %s\n"
+msgstr "Device-Verzeichnis: %s\n"
+
+#: mixlib/xmix_vm_handlers.c:1111
+#, c-format
+msgid "Conditional breakpoint on r%s change set"
+msgstr "Conditional Breakpoint bei r%s-Änderung gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1116 mixlib/xmix_vm_handlers.c:1140
+#, c-format
+msgid "Invalid argument %s"
+msgstr "Ungültiges Argument %s"
+
+#: mixlib/xmix_vm_handlers.c:1131
+#, c-format
+msgid "Conditional breakpoint on r%s change removed"
+msgstr "Conditional Breakpoint bei r%s-Änderung gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:1135
+#, c-format
+msgid "No breakpoint set on r%s change"
+msgstr "Keinen Breakpoint bei r%s-Änderung gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1152 mixlib/xmix_vm_handlers.c:1177
+#, c-format
+msgid "Invalid memory address: %s"
+msgstr "Ungültige Speicheradresse: %s"
+
+#: mixlib/xmix_vm_handlers.c:1165
+#, c-format
+msgid "Conditional breakpoint on mem cell no. %d set"
+msgstr "Conditional Breakpoint bei Speicherzelle %d gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1188
+#, c-format
+msgid "Conditional breakpoint on mem cell no. %d removed"
+msgstr "Conditional Breakpoint bei Speicherzelle %d gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:1193
+#, c-format
+msgid "No conditional breakpoint set at address %d"
+msgstr "Keinen Conditional Breakpoint bei Adresse %d gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1209
+msgid "Conditional breakpoint on overflow toggled set"
+msgstr "Conditional Breakpoint beim Overflow-Flag gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1226
+msgid "Conditional breakpoint on overflow toggled removed."
+msgstr "Conditional Breakpoint beim Overflow-Flag gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:1229
+msgid "No breakpoint set on overflow toggle"
+msgstr "Keinen Breakpoint beim Overflow-Flag gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1244
+msgid "Conditional breakpoint on comparison flag changed set"
+msgstr "Conditional Breakpoint beim Comparison-Flag gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1262
+msgid "Conditional breakpoint on comparison flag changed removed."
+msgstr "Conditional Breakpoint beim Comparison-Flag gelöscht"
+
+#: mixlib/xmix_vm_handlers.c:1265
+msgid "No breakpoint set on comparison flag change"
+msgstr "Keinen Breakpoint beim Comparison-Flag gesetzt"
+
+#: mixlib/xmix_vm_handlers.c:1328
+#, c-format
+msgid "No program currently loaded"
+msgstr "Zur Zeit kein Programm geladen"
+
+#: mixlib/xmix_vm_handlers.c:1337
+#, c-format
+msgid "No program currently loaded\n"
+msgstr "Zur Zeit kein Programm geladen\n"
+
+#: mixlib/xmix_vm_handlers.c:1352
+msgid "Invalid argument"
+msgstr "Ungültiges Argument"
+
+#: mixlib/xmix_vm_handlers.c:1375
+msgid "Error loading or executing file"
+msgstr "Fehler beim Laden oder Ausführen der Datei"
+
+#: mixlib/xmix_vm_handlers.c:1376
+msgid "Execution stopped: breakpoint encountered"
+msgstr "Ausführung angehalten: auf Breakpoint gestoßen"
+
+#: mixlib/xmix_vm_handlers.c:1377
+msgid "Execution stopped: conditional breakpoint encountered"
+msgstr "Ausführung angehalten: auf Conditional Breakpoint gestoßen"
+
+#: mixlib/xmix_vm_handlers.c:1378
+msgid "Program successfully terminated"
+msgstr "Programm erfolgreich beendet"
+
+#: mixlib/xmix_vm_handlers.c:1379
+msgid "Execution stopped"
+msgstr "Ausführung angehalten"
+
+#: mixlib/xmix_vm_handlers.c:1380
+msgid "Program successfully loaded"
+msgstr "Programm erfolgreich geladen"
+
+#: mixlib/xmix_vm_handlers.c:1381
+msgid "No program loaded"
+msgstr "Kein Programm geladen"
+
+#: mixgtk/mixgtk_device.c:543
+msgid "Devices folder"
+msgstr "Device-Verzeichnis"
+
+#: mixgtk/mixgtk_gen_handlers.c:97
+msgid "Load MIX program..."
+msgstr "MIX-Programm laden..."
+
+#: mixgtk/mixgtk_gen_handlers.c:110
+msgid "Edit MIXAL source file..."
+msgstr "MIXAL-Quelldatei bearbeiten..."
+
+#: mixgtk/mixgtk_gen_handlers.c:124
+msgid "Compile MIXAL source file..."
+msgstr "MIXAL-Quelldatei kompilieren..."
+
+#: mixgtk/mixgtk_mixal.c:340 mixgtk/mixgtk_mixal.c:341
+msgid "N/A"
+msgstr "N/A"
+
+#: mixgtk/mixgtk_mixal.c:364
+msgid "Source not available"
+msgstr "Quelle fehlt"
+
+#: mixgtk/mixgtk_mixvm.c:328
+msgid "Register A"
+msgstr "Register A"
+
+#: mixgtk/mixgtk_mixvm.c:331
+msgid "Register X"
+msgstr "Register X"
+
+#: mixgtk/mixgtk_mixvm.c:334
+msgid "Register J"
+msgstr "Register J"
+
+#: mixgtk/mixgtk_mixvm.c:340
+#, c-format
+msgid "Register I%d"
+msgstr "Register I%d"
+
+#: mixgtk/mixgtk_mixvm.c:456
+#, c-format
+msgid "Memory cell no. %d"
+msgstr "Speicherzelle %d"
+
+#: mixgtk/gmixvm.c:97
+msgid "gmixvm, GTK MIX virtual machine"
+msgstr "gmixvm, GTK MIX virtuelle Maschine"
+
+#: mixgtk/mixgtk.c:45
+msgid "Unable to load gmixvm configuration"
+msgstr "Kann gmixvm-Konfiguration nicht laden"
+
+#: mixgtk/mixgtk.c:50
+msgid "Unable to initialise application: missing glade file"
+msgstr "Kann Applikation nicht initialisieren: Glade-Datei fehlt"
+
+#: mixgtk/mixgtk.c:56
+msgid "Unable to initialise application\n"
+msgstr "Kann Applikation nicht initialisieren\n"
+
+#: mixgtk/mixgtk.glade:7
+msgid "gmixvm"
+msgstr "gmixvm"
+
+#: mixgtk/mixgtk.glade:36
+msgid "_File"
+msgstr "Datei"
+
+#: mixgtk/mixgtk.glade:45
+msgid "Load a MIX file"
+msgstr "Lade eine MIX-Datei"
+
+#: mixgtk/mixgtk.glade:46
+msgid "_Load..."
+msgstr "_Laden..."
+
+#: mixgtk/mixgtk.glade:69
+msgid "_Edit..."
+msgstr "Bearbeiten..."
+
+#: mixgtk/mixgtk.glade:92
+msgid "_Compile..."
+msgstr "Kompilieren..."
+
+#: mixgtk/mixgtk.glade:120
+msgid "Exit application"
+msgstr "Applikation beenden"
+
+#: mixgtk/mixgtk.glade:121
+msgid "E_xit"
+msgstr "Beenden"
+
+#: mixgtk/mixgtk.glade:147
+msgid "De_bug"
+msgstr "De_bug"
+
+#: mixgtk/mixgtk.glade:156
+msgid "Run program"
+msgstr "Starte Programm"
+
+#: mixgtk/mixgtk.glade:157
+msgid "_Run"
+msgstr "Starte"
+
+#: mixgtk/mixgtk.glade:179
+msgid "Execute next instruction"
+msgstr "Führe nächste Instruktion aus"
+
+#: mixgtk/mixgtk.glade:180
+msgid "_Next"
+msgstr "Weiter"
+
+#: mixgtk/mixgtk.glade:202
+msgid "Clear all set breakpoints"
+msgstr "Alle gesetzten Breakpoints löschen"
+
+#: mixgtk/mixgtk.glade:203
+msgid "_Clear breakpoints"
+msgstr "Breakpoints löschen"
+
+#: mixgtk/mixgtk.glade:225
+msgid "Show the symbol table"
+msgstr "Zeige Symboltabelle"
+
+#: mixgtk/mixgtk.glade:226
+msgid "_Symbols..."
+msgstr "_Symbole..."
+
+#: mixgtk/mixgtk.glade:252
+msgid "Vie_w"
+msgstr "Ansicht"
+
+#: mixgtk/mixgtk.glade:261
+msgid "_Toolbars"
+msgstr "_Toolbar"
+
+#: mixgtk/mixgtk.glade:270
+msgid "_Detached windows"
+msgstr "_Detached Fenster"
+
+#: mixgtk/mixgtk.glade:291 mixgtk/mixgtk.glade:356
+msgid "_Virtual machine"
+msgstr "_Virtuelle Maschine"
+
+#: mixgtk/mixgtk.glade:300 mixgtk/mixgtk.glade:365
+msgid "_Source"
+msgstr "Quelle"
+
+#: mixgtk/mixgtk.glade:309 mixgtk/mixgtk.glade:392
+msgid "_Devices"
+msgstr "_Devices"
+
+#: mixgtk/mixgtk.glade:326
+msgid "S_ettings"
+msgstr "W_erte"
+
+#: mixgtk/mixgtk.glade:335
+msgid "Change _font"
+msgstr "Font ändern"
+
+#: mixgtk/mixgtk.glade:374
+msgid "Command _prompt"
+msgstr "Kommando_prompt"
+
+#: mixgtk/mixgtk.glade:383
+msgid "Command l_og"
+msgstr "K_ommandoaufzeichnung"
+
+#: mixgtk/mixgtk.glade:401
+msgid "Symbol _list"
+msgstr "Symbol_liste"
+
+#: mixgtk/mixgtk.glade:416
+msgid "Change all fonts at once"
+msgstr "Alle Fonts auf einmal ändern"
+
+#: mixgtk/mixgtk.glade:417
+msgid "_All"
+msgstr "_Alles"
+
+#: mixgtk/mixgtk.glade:430
+msgid "Change format of binary devices output"
+msgstr "Format für binäre Device-Ausgabe ändern"
+
+#: mixgtk/mixgtk.glade:431
+msgid "_Device output..."
+msgstr "_Device-Ausgabe..."
+
+#: mixgtk/mixgtk.glade:452
+msgid "De_vices dir..."
+msgstr "De_vices-Verzeichnis..."
+
+#: mixgtk/mixgtk.glade:473
+msgid "E_xternal programs..."
+msgstr "E_xterne Programm..."
+
+#: mixgtk/mixgtk.glade:500
+msgid "Save current settings"
+msgstr "Aktuellen Werte speichern"
+
+#: mixgtk/mixgtk.glade:501
+msgid "_Save"
+msgstr "_Speichern"
+
+#: mixgtk/mixgtk.glade:522
+msgid "Toogle save settings on exit"
+msgstr "Speichern beim Beenden an/aus"
+
+#: mixgtk/mixgtk.glade:523
+msgid "Save on _exit"
+msgstr "Speichern beim B_eenden"
+
+#: mixgtk/mixgtk.glade:537
+msgid "_Help"
+msgstr "_Hilfe"
+
+#: mixgtk/mixgtk.glade:546
+msgid "_About..."
+msgstr "Über..."
+
+#: mixgtk/mixgtk.glade:593
+msgid "Load MIX program"
+msgstr "Lade MIX-Programm"
+
+#: mixgtk/mixgtk.glade:594
+msgid "Open"
+msgstr "Öffnen"
+
+#: mixgtk/mixgtk.glade:611
+msgid "Compile MIXAL source"
+msgstr "MIXAL-Quelle kompilieren"
+
+#: mixgtk/mixgtk.glade:612
+msgid "Compile"
+msgstr "Kompilieren"
+
+#: mixgtk/mixgtk.glade:629
+msgid "Edit MIXAL source"
+msgstr "MIXAL-Quelle bearbeiten"
+
+#: mixgtk/mixgtk.glade:630
+msgid "Edit"
+msgstr "Bearbeiten"
+
+#: mixgtk/mixgtk.glade:647 mixgtk/mixgtk.glade:648 mixgtk/mixgtk.glade:2147
+#: mixgtk/mixgtk.glade:2148
+msgid "Run"
+msgstr "Start"
+
+#: mixgtk/mixgtk.glade:665 mixgtk/mixgtk.glade:666 mixgtk/mixgtk.glade:2165
+msgid "Next"
+msgstr "Weiter"
+
+#: mixgtk/mixgtk.glade:683 mixgtk/mixgtk.glade:2183
+msgid "Clear breakpoints"
+msgstr "Breakpoints löschen"
+
+#: mixgtk/mixgtk.glade:684 mixgtk/mixgtk.glade:2184
+msgid "Clear"
+msgstr "Löschen"
+
+#: mixgtk/mixgtk.glade:701 mixgtk/mixgtk.glade:1969 mixgtk/mixgtk.glade:2201
+msgid "Symbol table"
+msgstr "Symboltabelle"
+
+#: mixgtk/mixgtk.glade:702 mixgtk/mixgtk.glade:2202
+msgid "Symbols"
+msgstr "Symbole"
+
+#: mixgtk/mixgtk.glade:732 mixgtk/mixgtk.glade:2362
+msgid "Device directory"
+msgstr "Device-Verzeichnis"
+
+#: mixgtk/mixgtk.glade:733
+msgid "Devdir"
+msgstr "Dev-Verz"
+
+#: mixgtk/mixgtk.glade:750 mixgtk/mixgtk.glade:2380
+msgid "Output format"
+msgstr "Ausgabeformat"
+
+#: mixgtk/mixgtk.glade:751 mixgtk/mixgtk.glade:1683
+msgid "Format"
+msgstr "Format"
+
+#: mixgtk/mixgtk.glade:768 mixgtk/mixgtk.glade:1785
+msgid "External programs"
+msgstr "Externe Programme"
+
+#: mixgtk/mixgtk.glade:769
+msgid "Programs"
+msgstr "Programme"
+
+#: mixgtk/mixgtk.glade:799
+msgid "Detach window"
+msgstr "Detach-Fenster"
+
+#: mixgtk/mixgtk.glade:800
+msgid "Detach"
+msgstr "Detach"
+
+#: mixgtk/mixgtk.glade:817
+msgid "Attach all windows"
+msgstr "Alle Fenster zuordnen"
+
+#: mixgtk/mixgtk.glade:906
+msgid "Enter MIXVM command here"
+msgstr "MIXVM-Kommando hier eingeben"
+
+#: mixgtk/mixgtk.glade:914 mixgtk/mixgtk.glade:1050 mixgtk/mixgtk.glade:1073
+#: mixgtk/mixgtk.glade:1096 mixgtk/mixgtk.glade:1119 mixgtk/mixgtk.glade:1142
+#: mixgtk/mixgtk.glade:1165 mixgtk/mixgtk.glade:1188 mixgtk/mixgtk.glade:1475
+#: mixgtk/mixgtk.glade:1867 mixgtk/mixgtk.glade:1920 mixgtk/mixgtk.glade:2585
+#: mixgtk/mixgtk.glade:2843 mixgtk/mixgtk.glade:2869 mixgtk/mixgtk.glade:2895
+#: mixgtk/mixgtk.glade:3077 mixgtk/mixgtk.glade:3103 mixgtk/mixgtk.glade:3129
+#: mixgtk/mixgtk.glade:3155 mixgtk/mixgtk.glade:3181 mixgtk/mixgtk.glade:3213
+#: mixgtk/mixgtk.glade:3452 mixgtk/mixgtk.glade:3892
+msgid "*"
+msgstr "*"
+
+#: mixgtk/mixgtk.glade:955 mixgtk/mixgtk.glade:1248
+msgid "Enter value"
+msgstr "Wert eingeben"
+
+#: mixgtk/mixgtk.glade:1048 mixgtk/mixgtk.glade:1071 mixgtk/mixgtk.glade:1094
+#: mixgtk/mixgtk.glade:1117 mixgtk/mixgtk.glade:1140 mixgtk/mixgtk.glade:1163
+#: mixgtk/mixgtk.glade:3450
+msgid "0"
+msgstr "0"
+
+#: mixgtk/mixgtk.glade:1186
+msgid "+"
+msgstr "+"
+
+#: mixgtk/mixgtk.glade:1204 mixgtk/mixgtk.glade:1757
+msgid "Decimal"
+msgstr "Dezimal"
+
+#: mixgtk/mixgtk.glade:1226
+msgid "Bytes"
+msgstr "Bytes"
+
+#: mixgtk/mixgtk.glade:1276
+msgid "MDK"
+msgstr "MDK"
+
+#: mixgtk/mixgtk.glade:1306
+msgid "GNU MIX Development Kit"
+msgstr "GNU MIX Development Kit"
+
+#: mixgtk/mixgtk.glade:1328
+msgid "label223"
+msgstr "Label 223"
+
+#: mixgtk/mixgtk.glade:1350
+msgid ""
+" Copyright (C) 2001, 2002, 2003 , 2004\n"
+"Free Software Foundation, Inc.\n"
+"\n"
+"Please, send bug reports to\n"
+"bug-mdk@gnu.org"
+msgstr ""
+" Copyright (C) 2001, 2002, 2003, 2004\n"
+"Free Software Foundation, Inc.\n"
+"\n"
+"Bitte senden Sie Bug-Reports an\n"
+"bug-mdk@gnu.org"
+
+#: mixgtk/mixgtk.glade:1375
+msgid "Go to memory cell"
+msgstr "Gehe zur Speicherzelle"
+
+#: mixgtk/mixgtk.glade:1447
+msgid "Go to address:"
+msgstr "Gehe zu Adresse:"
+
+#: mixgtk/mixgtk.glade:1497
+msgid "Select Font"
+msgstr "Wähle Font"
+
+#: mixgtk/mixgtk.glade:1546
+msgid "abcdefghijk ABCDEFGHIJK"
+msgstr "abcdefghijk ABCDEFGHIJK"
+
+#: mixgtk/mixgtk.glade:1557
+msgid "Device output format"
+msgstr "Device-Ausgabeformat"
+
+#: mixgtk/mixgtk.glade:1642
+msgid "Set all devices to current format"
+msgstr "Alle Devices auf das aktuelle Format setzen"
+
+#: mixgtk/mixgtk.glade:1644
+msgid "S_et all"
+msgstr "Alles S_etzen"
+
+#: mixgtk/mixgtk.glade:1661
+msgid "Device"
+msgstr "Device"
+
+#: mixgtk/mixgtk.glade:1705
+msgid ""
+"tape0\n"
+"tape1\n"
+"tape2\n"
+"tape3\n"
+"tape4\n"
+"tape5\n"
+"tape6\n"
+"tape7\n"
+"disk0\n"
+"disk1\n"
+"disk2\n"
+"disk3\n"
+"disk4\n"
+"disk5\n"
+"disk6\n"
+"disk7"
+msgstr ""
+"tape0\n"
+"tape1\n"
+"tape2\n"
+"tape3\n"
+"tape4\n"
+"tape5\n"
+"tape6\n"
+"tape7\n"
+"disk0\n"
+"disk1\n"
+"disk2\n"
+"disk3\n"
+"disk4\n"
+"disk5\n"
+"disk6\n"
+"disk7"
+
+#: mixgtk/mixgtk.glade:1734
+msgid "Show output as MIX words"
+msgstr "Zeige Ausgabe als MIX-Wörter"
+
+#: mixgtk/mixgtk.glade:1736
+msgid "Word"
+msgstr "Wort"
+
+#: mixgtk/mixgtk.glade:1755
+msgid "Show output as decimal numbers"
+msgstr "Zeige Ausgabe als dezimale Zahlen"
+
+#: mixgtk/mixgtk.glade:1865
+msgid "xterm -e vi %s"
+msgstr "xterm -e vi %s"
+
+#: mixgtk/mixgtk.glade:1881
+msgid "Editor command (e.g xterm -e vi %s)"
+msgstr "Editor-Befehl (z.B. xterm -e vi %s)"
+
+#: mixgtk/mixgtk.glade:1918
+msgid "mixasm %s"
+msgstr "mixasm %s"
+
+#: mixgtk/mixgtk.glade:1934
+msgid "MIX sssembler command (e.g. mixasm %s)"
+msgstr "MIX-Assembler-Befehl (z.B. mixasm %s)"
+
+#: mixgtk/mixgtk.glade:2045
+msgid "_Close"
+msgstr "Schließen"
+
+#: mixgtk/mixgtk.glade:2107
+msgid "MIXAL source"
+msgstr "MIXAL Quelle"
+
+#: mixgtk/mixgtk.glade:2166
+msgid "Step"
+msgstr "Schritt"
+
+#: mixgtk/mixgtk.glade:2232
+msgid "Source code font"
+msgstr "Quellcodefont"
+
+#: mixgtk/mixgtk.glade:2233 mixgtk/mixgtk.glade:2412 mixgtk/mixgtk.glade:2662
+msgid "Font"
+msgstr "Font"
+
+#: mixgtk/mixgtk.glade:2263
+msgid "Attach window"
+msgstr "Attach-Fenster"
+
+#: mixgtk/mixgtk.glade:2319
+msgid "Devices"
+msgstr "Devices"
+
+#: mixgtk/mixgtk.glade:2363 mixgtk/mixgtk.glade:2558
+msgid "Directory"
+msgstr "Verzeichnis"
+
+#: mixgtk/mixgtk.glade:2381
+msgid "Output"
+msgstr "Ausgabe"
+
+#: mixgtk/mixgtk.glade:2411
+msgid "Output font"
+msgstr "Ausgabefont"
+
+#: mixgtk/mixgtk.glade:2485
+msgid "Devices directory"
+msgstr "Device-Verzeichnis"
+
+#: mixgtk/mixgtk.glade:2623
+msgid "Virtual machine"
+msgstr "Virtuelle Maschine"
+
+#: mixgtk/mixgtk.glade:2758
+msgid "A"
+msgstr "A"
+
+#: mixgtk/mixgtk.glade:2784
+msgid "I1"
+msgstr "I1"
+
+#: mixgtk/mixgtk.glade:2810
+msgid "I2"
+msgstr "I2"
+
+#: mixgtk/mixgtk.glade:2915
+msgid "X"
+msgstr "X"
+
+#: mixgtk/mixgtk.glade:2941
+msgid "I3"
+msgstr "I3"
+
+#: mixgtk/mixgtk.glade:2967
+msgid "I4"
+msgstr "I4"
+
+#: mixgtk/mixgtk.glade:2993
+msgid "I5"
+msgstr "I5"
+
+#: mixgtk/mixgtk.glade:3019
+msgid "I6"
+msgstr "I6"
+
+#: mixgtk/mixgtk.glade:3045
+msgid "J"
+msgstr "J"
+
+#: mixgtk/mixgtk.glade:3244
+msgid "Registers "
+msgstr "Register "
+
+#: mixgtk/mixgtk.glade:3294
+msgid "Greater"
+msgstr "Größer"
+
+#: mixgtk/mixgtk.glade:3296
+msgid "G"
+msgstr "G"
+
+#: mixgtk/mixgtk.glade:3318
+msgid "Equal"
+msgstr "Gleich"
+
+#: mixgtk/mixgtk.glade:3320
+msgid "E"
+msgstr "E"
+
+#: mixgtk/mixgtk.glade:3343
+msgid "Lesser"
+msgstr "Kleiner"
+
+#: mixgtk/mixgtk.glade:3345
+msgid "L"
+msgstr "L"
+
+#: mixgtk/mixgtk.glade:3378
+msgid "Overflow"
+msgstr "Overflow"
+
+#: mixgtk/mixgtk.glade:3399
+msgid "Flags "
+msgstr "Flags "
+
+#: mixgtk/mixgtk.glade:3466
+msgid "View loc address"
+msgstr "Zeige Positionsadresse"
+
+#: mixgtk/mixgtk.glade:3496
+msgid "Location "
+msgstr "Position "
+
+#: mixgtk/mixgtk.glade:3547
+msgid "Uptime:"
+msgstr "Uptime:"
+
+#: mixgtk/mixgtk.glade:3570
+msgid "00000000"
+msgstr "00000000"
+
+#: mixgtk/mixgtk.glade:3593
+msgid "Elapsed:"
+msgstr "Verbraucht"
+
+#: mixgtk/mixgtk.glade:3616 mixgtk/mixgtk.glade:3662
+msgid "000000"
+msgstr "000000"
+
+#: mixgtk/mixgtk.glade:3639
+msgid "Program:"
+msgstr "Programm:"
+
+#: mixgtk/mixgtk.glade:3685
+msgid "Times "
+msgstr "Times "
+
+#: mixgtk/mixgtk.glade:3750
+msgid "Memory "
+msgstr "Speicher "
+
+#: mixgtk/mixgtk.glade:3779
+msgid "MIX Virtual Machine "
+msgstr "MIX virtuelle Maschine"
+
+#: mixgtk/mixgtk.glade:3807
+msgid "MIX Console input"
+msgstr "MIX-Konsoleeingabe"
+
+#: mixgtk/mixgtk.glade:3865
+msgid "Enter up to 70 characters"
+msgstr "Bis zu 70 Zeichen eingeben"
+
+#: mixguile/mixguile.c:74
+#, c-format
+msgid "mixguile bootstrap file %s not found\n"
+msgstr "Mixguile-Bootstrap-Datei %s nicht gefunden\n"
+
+#: mixguile/mixguile_cmd_dispatcher.c:52
+msgid "Eval Scheme command using Guile"
+msgstr "Führe Scheme-Kommando aus mit Guile"
+
+#: mixguile/mixguile_cmd_dispatcher.c:53
+msgid "Eval Scheme file using Guile"
+msgstr "Führe Scheme-Datei aus mit Guile"
diff --git a/samples/Makefile.am b/samples/Makefile.am
new file mode 100644
index 0000000..5b1ceff
--- /dev/null
+++ b/samples/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to produce Makefile.in
+
+# Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.3 2004/06/09 13:16:42 jao Exp $
+
+EXTRA_DIST = primes.result hello.mixal primes.mixal echo.mixal\
+ permutations.mixal permutations.cardrd \ No newline at end of file
diff --git a/samples/echo.mixal b/samples/echo.mixal
new file mode 100644
index 0000000..9b87adf
--- /dev/null
+++ b/samples/echo.mixal
@@ -0,0 +1,10 @@
+* read from the console
+TERM EQU 19
+MSG EQU 500
+PRINT EQU 20
+ ORIG 1000
+START IN MSG(TERM)
+* JBUS *(TERM)
+ OUT MSG(TERM)
+ HLT
+ END START
diff --git a/samples/hello.mixal b/samples/hello.mixal
new file mode 100644
index 0000000..6a4c3c1
--- /dev/null
+++ b/samples/hello.mixal
@@ -0,0 +1,11 @@
+* mixal hello world
+*
+TERM EQU 19
+ ORIG 3000
+START OUT MSG(TERM)
+ HLT
+MSG ALF "MIXAL"
+ ALF " HELL"
+ ALF "O WOR"
+ ALF "LD "
+ END START
diff --git a/samples/m.mixal b/samples/m.mixal
new file mode 100644
index 0000000..ae69b42
--- /dev/null
+++ b/samples/m.mixal
@@ -0,0 +1,25 @@
+X EQU 1000
+ ORIG 3000
+MAXIMUM STJ EXIT
+INIT ENT3 0,1
+ JMP CHANGEM
+LOOP CMPA X,3
+ JGE *+3
+CHANGEM ENT2 0,3
+ LDA X,3
+ DEC3 1
+ J3P LOOP
+EXIT JMP *
+START IN X+1(0)
+ JBUS *(0)
+ ENT1 100
+1H JMP MAXIMUM
+ LDX X,1
+ STA X,1
+ STX X,2
+ DEC1 1
+ J1P 1B
+ OUT X+1(1)
+ HLT
+ END START
+
diff --git a/samples/permutations.cardrd b/samples/permutations.cardrd
new file mode 100644
index 0000000..639c1fe
--- /dev/null
+++ b/samples/permutations.cardrd
@@ -0,0 +1,3 @@
+ ( A C F G ) ( B C D ) ( A E D )
+ ( F A D E ) ( B g F a E ) =
+
diff --git a/samples/permutations.mixal b/samples/permutations.mixal
new file mode 100644
index 0000000..2c26df5
--- /dev/null
+++ b/samples/permutations.mixal
@@ -0,0 +1,89 @@
+* multiply permutations in cycle form (taopc p. 168)
+*
+MAXWDS EQU 1200
+PERM ORIG *+MAXWDS
+ANS ORIG *+MAXWDS
+OUTBUF ORIG *+24
+CARDS EQU 16
+PRINTER EQU 18
+BEGIN IN PERM(CARDS)
+ ENT2 0
+ LDA EQUALS
+1H JBUS *(CARDS)
+ CMPA PERM+15,2
+ JE *+2
+ IN PERM+16,2(CARDS)
+ ENT1 OUTBUF
+ JBUS *(PRINTER)
+ MOVE PERM,2(16)
+ OUT OUTBUF(PRINTER)
+ JE 1F
+ INC2 16
+ CMP2 =MAXWDS-16=
+ JLE 1B
+ HLT 666
+1H INC2 15
+ ST2 SIZE
+ ENT3 0
+2H LDAN PERM,3
+ CMPA LPREN(1:5)
+ JNE 1F
+ STA PERM,3
+ INC3 1
+ LDXN PERM,3
+ JXZ *-2
+1H CMPA RPREN(1:5)
+ JNE *+2
+ STX PERM,3
+ INC3 1
+ CMP3 SIZE
+ JL 2B
+ LDA LPREN
+ ENT1 ANS
+OPEN ENT3 0
+1H LDXN PERM,3
+ JXN GO
+ INC3 1
+ CMP3 SIZE
+ JL 1B
+*
+DONE CMP1 =ANS=
+ JNE *+2
+ MOVE LPREN(2)
+ MOVE =0=
+ MOVE -1,1(22)
+ ENT3 0
+ OUT ANS,3(PRINTER)
+ INC3 24
+ LDX ANS,3
+ JXNZ *-3
+ HLT
+*
+LPREN ALF " ("
+RPREN ALF ") "
+EQUALS ALF " ="
+*
+GO MOVE LPREN
+ MOVE PERM,3
+ STX START
+SUCC STX PERM,3
+ INC3 1
+ LDXN PERM,3(1:5)
+ JXN 1F
+ JMP *-3
+5H STX 0,1
+ INC1 1
+ ENT3 0
+4H CMPX PERM,3(1:5)
+ JE SUCC
+1H INC3 1
+ CMP3 SIZE
+ JL 4B
+ CMPX START(1:5)
+ JNE 5B
+CLOSE MOVE RPREN
+ CMPA -3,1
+ JNE OPEN
+ INC1 -3
+ JMP OPEN
+ END BEGIN
diff --git a/samples/primes.mixal b/samples/primes.mixal
new file mode 100644
index 0000000..365db32
--- /dev/null
+++ b/samples/primes.mixal
@@ -0,0 +1,53 @@
+* table of primes (taopc p. 148)
+*
+L EQU 500
+OUTDEV EQU 18 the printer
+PRIME EQU -1
+BUF0 EQU 2000
+BUF1 EQU BUF0+25
+ ORIG 3000
+START IOC 0(OUTDEV)
+ LD1 =1-L=
+ LD2 =3=
+2H INC1 1
+ ST2 PRIME+L,1
+ J1Z 2F
+4H INC2 2
+ ENT3 2
+6H ENTA 0
+ ENTX 0,2
+ DIV PRIME,3
+ JXZ 4B
+ CMPA PRIME,3
+ INC3 1
+ JG 6B
+ JMP 2B
+2H OUT TITLE(OUTDEV)
+ ENT4 BUF1+10
+ ENT5 -50
+2H INC5 L+1
+4H LDA PRIME,5
+ CHAR
+ STX 0,4(1:4)
+ DEC4 1
+ DEC5 50
+ J5P 4B
+ OUT 0,4(OUTDEV)
+ LD4 24,4
+ J5N 2B
+ HLT
+* initial contents
+ ORIG PRIME+1
+ CON 2
+ ORIG BUF0-5
+TITLE ALF "FIRST"
+ ALF " FIVE"
+ ALF " HUND"
+ ALF "RED P"
+ ALF "RIMES"
+ ORIG BUF0+24
+ CON BUF1+10
+ ORIG BUF1+24
+ CON BUF0+10
+ END START
+
diff --git a/samples/primes.result b/samples/primes.result
new file mode 100644
index 0000000..1431f77
--- /dev/null
+++ b/samples/primes.result
@@ -0,0 +1,51 @@
+FIRST FIVE HUNDRED PRIMES
+ 0002 0233 0547 0877 1229 1597 1993 2371 2749 3187
+ 0003 0239 0557 0881 1231 1601 1997 2377 2753 3191
+ 0005 0241 0563 0883 1237 1607 1999 2381 2767 3203
+ 0007 0251 0569 0887 1249 1609 2003 2383 2777 3209
+ 0011 0257 0571 0907 1259 1613 2011 2389 2789 3217
+ 0013 0263 0577 0911 1277 1619 2017 2393 2791 3221
+ 0017 0269 0587 0919 1279 1621 2027 2399 2797 3229
+ 0019 0271 0593 0929 1283 1627 2029 2411 2801 3251
+ 0023 0277 0599 0937 1289 1637 2039 2417 2803 3253
+ 0029 0281 0601 0941 1291 1657 2053 2423 2819 3257
+ 0031 0283 0607 0947 1297 1663 2063 2437 2833 3259
+ 0037 0293 0613 0953 1301 1667 2069 2441 2837 3271
+ 0041 0307 0617 0967 1303 1669 2081 2447 2843 3299
+ 0043 0311 0619 0971 1307 1693 2083 2459 2851 3301
+ 0047 0313 0631 0977 1319 1697 2087 2467 2857 3307
+ 0053 0317 0641 0983 1321 1699 2089 2473 2861 3313
+ 0059 0331 0643 0991 1327 1709 2099 2477 2879 3319
+ 0061 0337 0647 0997 1361 1721 2111 2503 2887 3323
+ 0067 0347 0653 1009 1367 1723 2113 2521 2897 3329
+ 0071 0349 0659 1013 1373 1733 2129 2531 2903 3331
+ 0073 0353 0661 1019 1381 1741 2131 2539 2909 3343
+ 0079 0359 0673 1021 1399 1747 2137 2543 2917 3347
+ 0083 0367 0677 1031 1409 1753 2141 2549 2927 3359
+ 0089 0373 0683 1033 1423 1759 2143 2551 2939 3361
+ 0097 0379 0691 1039 1427 1777 2153 2557 2953 3371
+ 0101 0383 0701 1049 1429 1783 2161 2579 2957 3373
+ 0103 0389 0709 1051 1433 1787 2179 2591 2963 3389
+ 0107 0397 0719 1061 1439 1789 2203 2593 2969 3391
+ 0109 0401 0727 1063 1447 1801 2207 2609 2971 3407
+ 0113 0409 0733 1069 1451 1811 2213 2617 2999 3413
+ 0127 0419 0739 1087 1453 1823 2221 2621 3001 3433
+ 0131 0421 0743 1091 1459 1831 2237 2633 3011 3449
+ 0137 0431 0751 1093 1471 1847 2239 2647 3019 3457
+ 0139 0433 0757 1097 1481 1861 2243 2657 3023 3461
+ 0149 0439 0761 1103 1483 1867 2251 2659 3037 3463
+ 0151 0443 0769 1109 1487 1871 2267 2663 3041 3467
+ 0157 0449 0773 1117 1489 1873 2269 2671 3049 3469
+ 0163 0457 0787 1123 1493 1877 2273 2677 3061 3491
+ 0167 0461 0797 1129 1499 1879 2281 2683 3067 3499
+ 0173 0463 0809 1151 1511 1889 2287 2687 3079 3511
+ 0179 0467 0811 1153 1523 1901 2293 2689 3083 3517
+ 0181 0479 0821 1163 1531 1907 2297 2693 3089 3527
+ 0191 0487 0823 1171 1543 1913 2309 2699 3109 3529
+ 0193 0491 0827 1181 1549 1931 2311 2707 3119 3533
+ 0197 0499 0829 1187 1553 1933 2333 2711 3121 3539
+ 0199 0503 0839 1193 1559 1949 2339 2713 3137 3541
+ 0211 0509 0853 1201 1567 1951 2341 2719 3163 3547
+ 0223 0521 0857 1213 1571 1973 2347 2729 3167 3557
+ 0227 0523 0859 1217 1579 1979 2351 2731 3169 3559
+ 0229 0541 0863 1223 1583 1987 2357 2741 3181 3571
diff --git a/samples/tests/bt.mixal b/samples/tests/bt.mixal
new file mode 100644
index 0000000..00306ae
--- /dev/null
+++ b/samples/tests/bt.mixal
@@ -0,0 +1,6 @@
+ ORIG 0
+BEG JMP *+1
+ JMP *+1
+FOO JMP BAR
+BAR HLT
+ END BEG
diff --git a/samples/tests/cbp.mixal b/samples/tests/cbp.mixal
new file mode 100644
index 0000000..8c7b394
--- /dev/null
+++ b/samples/tests/cbp.mixal
@@ -0,0 +1,14 @@
+* testing conditional breakpoints
+ ORIG 2000
+START ENTA 100
+ STA 1000
+ ENTX 200
+ STX 1001
+ CMPA 1001 * cmp flag changed
+ CMPX 1000 * cmp flag changed
+ DIV 1002 * over toggle
+ HLT
+ END START
+
+
+
diff --git a/samples/tests/ldan.mixal b/samples/tests/ldan.mixal
new file mode 100644
index 0000000..d15c6a3
--- /dev/null
+++ b/samples/tests/ldan.mixal
@@ -0,0 +1,5 @@
+VAR ORIG *+1
+BEGIN LDAN VAR(1:5)
+ LDXN VAR(1:5)
+ HLT
+ END BEGIN
diff --git a/samples/tests/lockonw.mixal b/samples/tests/lockonw.mixal
new file mode 100644
index 0000000..3ddad65
--- /dev/null
+++ b/samples/tests/lockonw.mixal
@@ -0,0 +1,3 @@
+* test for bug #5654
+START CMPA =0=(1:4)
+ END START
diff --git a/samples/tests/negwrite.mixal b/samples/tests/negwrite.mixal
new file mode 100644
index 0000000..dfed659
--- /dev/null
+++ b/samples/tests/negwrite.mixal
@@ -0,0 +1,4 @@
+* test for bug #5649: invalid address in OUT
+START OUT -1(18)
+ HLT
+ END START
diff --git a/samples/tests/stress0.mixal b/samples/tests/stress0.mixal
new file mode 100644
index 0000000..d87b743
--- /dev/null
+++ b/samples/tests/stress0.mixal
@@ -0,0 +1,8 @@
+ ORIG 1999
+ST NOP
+* SYM EQU SYM+1
+SYM2 CON SYM2+1
+SYM3 ORIG SYM3+2
+SYM4 ENTA SYM4+1
+ HLT
+SYM5 END SYM5+1
diff --git a/samples/tests/stress1.mixal b/samples/tests/stress1.mixal
new file mode 100644
index 0000000..f9bc8c9
--- /dev/null
+++ b/samples/tests/stress1.mixal
@@ -0,0 +1,9 @@
+ ORIG 1999
+ST NOP
+3H EQU 69
+3H ENTA 3B
+** According to pg 151, rA should be 69, not 2000
+** "An address of 2F or 2B never refers to its own line"
+ HLT
+ END ST
+
diff --git a/samples/tests/stress2.mixal b/samples/tests/stress2.mixal
new file mode 100644
index 0000000..0c4d7d6
--- /dev/null
+++ b/samples/tests/stress2.mixal
@@ -0,0 +1,7 @@
+ ORIG 1999
+ST NOP
+SYM EQU SYM+1
+SYM2 CON SYM2+1
+SYM3 ORIG SYM3+2
+ HLT
+SYM4 END SYM4+1
diff --git a/samples/tests/stress4.mixal b/samples/tests/stress4.mixal
new file mode 100644
index 0000000..7bcdd2a
--- /dev/null
+++ b/samples/tests/stress4.mixal
@@ -0,0 +1,7 @@
+ ORIG 2000
+ST NOP
+ ENTA FUT
+** Whoa, mdk tells me FUT is never defined...
+FUT EQU 69
+ HLT
+ END ST
diff --git a/samples/tests/stress5.mixal b/samples/tests/stress5.mixal
new file mode 100644
index 0000000..fce18cb
--- /dev/null
+++ b/samples/tests/stress5.mixal
@@ -0,0 +1,17 @@
+* checking output to binary device
+OUTDEV EQU 1 device for output
+FROM EQU 1000
+TO EQU 1099
+INITVAL EQU 1
+STEP EQU 10
+ ORIG 2000
+START ENTA INITVAL
+ ST1 0
+LOOP STA FROM,1
+ INC1 1
+ INCA STEP
+ CMP1 =TO-FROM+1=
+ JNE LOOP
+ OUT FROM(OUTDEV)
+ HLT
+ END START
diff --git a/samples/tests/stress6.mixal b/samples/tests/stress6.mixal
new file mode 100644
index 0000000..a80b7c9
--- /dev/null
+++ b/samples/tests/stress6.mixal
@@ -0,0 +1,9 @@
+* checking input from binary device
+INDEV EQU 1 device for input
+OUTDEV EQU 2 device for output
+MEM EQU 1000
+ ORIG 2000
+START IN MEM(INDEV)
+ OUT MEM(OUTDEV)
+ HLT
+ END START
diff --git a/updatelog b/updatelog
new file mode 100755
index 0000000..4ac1d1c
--- /dev/null
+++ b/updatelog
@@ -0,0 +1 @@
+cvs2cl --fsf -S -P