Browse Source

First commit with most sources

Godzil 5 years ago
parent
commit
61b60f3068

+ 3 - 0
.gitmodules

@@ -0,0 +1,3 @@
+[submodule "wonx"]
+	path = wonx
+	url = https://github.com/Godzil/WonX.git

+ 340 - 0
COPYING

@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

+ 49 - 0
HISTORY.txt

@@ -0,0 +1,49 @@
+2001/04/18 version 0.33
+  - MingW32 でのコンパイル。
+  - 第二水準の一部の漢字が表示できなかったバグを修正。
+  - text_get_font を実装。
+  - Windows98/Me でウィンドウのリサイズがうまくいかないバグを修正(できたと思う)。
+
+2001/04/13 version 0.32
+  - 2 bytes 文字を含んだ文字列の表示に問題があったのを修正。
+  - 80186 エミュレーションの一部を修正(まだたくさんバグがありそう)。
+
+2001/04/12 version 0.31
+  - 恵梨沙フォントを読み込みと 2bytes 文字表示対応。
+  - version0.30 でファイルシステムが全然動かなくなってたのを修正。
+
+2001/04/08 version 0.30
+  - FsIL の creat、unlink 実装した。
+  - FsIL open 時に存在しないファイルを指定したときにファイルを作成するよう変更した。
+  - テキスト画面でパレットの設定を文字描画時から text_screen_init、text_window_init、test_set_palette 時に変更した。
+  - 縦画面モードを追加した。
+  - LCD セグメントをステータスバーに表示するようにし、lcd_set_segments、lcd_get_segments を実装した。
+  - 設定画面を追加した。
+  - その他 bug fix。
+
+2001/03/14 version 0.20
+  - FsIL の実装。まだ暫定使用でテストも不十分です。creat、unlink、mmap は未実装です。
+  - 画面表示周りのバグ修正(thanks うつろさん)。
+  - コマンドライン引数に対応した。
+  - Windows のコマンドラインからファイル名と引数を指定できるようにした。
+  - ついでにファイルドロップに対応した。
+  - ウィンドウがアクティブでないときに CPU を食わないようにした。
+  - key_wait() 内で busy-wait するのをやめた(割り込みベースになったわけではない)。
+ 
+2001/02/17 version 0.10
+ 公開をはじめた。WWGP2001 応募バージョンに比べ、動作するソフトは結構増えた。
+ 変更点は以下の通り。
+  - 80186 命令を実装した(自信なし)。
+  - デバイスコンテキスト経由の描画をやめた。
+  - キー入力に DirectInput を使うようにした。
+  - TEXT_PUT_NUMERIC で数字が描画されないバグを修正した(break 文付け忘れてたのを対処)。
+  - IlibIL、ProcIL、FsIL を実行できる仕組みにした(中身はまだ)。
+  - その他、細かい bug fix。
+
+2001/01/31 version 0.01
+ WWGP2001 に出してみる(結果は予選落ち、はは)。
+ 結構ひどい出来だった。
+
+-- 
+Copyright (C) 2001 Tomoyuki 'ZRY' Nakano
+All rights reserved.

+ 620 - 0
MMage.dsp

@@ -0,0 +1,620 @@
+# Microsoft Developer Studio Project File - Name="MMage" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** 編集しないでください **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=MMage - Win32 Debug
+!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。
+!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください
+!MESSAGE 
+!MESSAGE NMAKE /f "MMage.mak".
+!MESSAGE 
+!MESSAGE NMAKE の実行時に構成を指定できます
+!MESSAGE コマンド ライン上でマクロの設定を定義します。例:
+!MESSAGE 
+!MESSAGE NMAKE /f "MMage.mak" CFG="MMage - Win32 Debug"
+!MESSAGE 
+!MESSAGE 選択可能なビルド モード:
+!MESSAGE 
+!MESSAGE "MMage - Win32 Release" ("Win32 (x86) Application" 用)
+!MESSAGE "MMage - Win32 Debug" ("Win32 (x86) Application" 用)
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "MMage - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib comctl32.lib ole32.lib winmm.lib dxguid.lib dinput.lib /nologo /subsystem:windows /machine:I386
+
+!ELSEIF  "$(CFG)" == "MMage - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib comctl32.lib ole32.lib winmm.lib dxguid.lib dinput.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "MMage - Win32 Release"
+# Name "MMage - Win32 Debug"
+# Begin Group "wonx"
+
+# PROP Default_Filter ""
+# Begin Group "wonx_include"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\bank.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\bios.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\comm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\disp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\key.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\service.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\sound.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\system.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\system_configure.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\text.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\timer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_include\types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\wonx\bank.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\comm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\disp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\etc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\etc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\key.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\sound.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\system.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\text.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\timer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\UNIXTimer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\UNIXTimer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\UNIXTimerP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonX.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonX.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\wonx_configure.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXDisplay.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXDisplay.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXDisplayP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSerialPort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSerialPort.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSerialPortP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSystem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSystem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXSystemP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXText.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXText.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WonXTextP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWCharacter.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWCharacter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWCharacterP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWColorMap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWColorMap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWColorMapP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWDisplay.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWDisplay.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWDisplayP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWInterrupt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWInterrupt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWInterruptP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWLCDPanel.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWLCDPanel.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWLCDPanelP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWPalette.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWPalette.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWPaletteP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWScreen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWScreen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWScreenP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSerialPort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSerialPort.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSerialPortP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSprite.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSprite.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWSpriteP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWText.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWText.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWTextFonts.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWTextP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWTimer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWTimer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\WWTimerP.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\XDisplay.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\XDisplay.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wonx\XDisplayP.h
+# End Source File
+# End Group
+# Begin Group "cpu"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\cpu\cpu.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\cpu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\global.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\hardware.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\hardware.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\i186.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\instr.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpu\mytypes.h
+# End Source File
+# End Group
+# Begin Group "resource"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource\aux1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux1off.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux2.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux2off.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux3.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux3off.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\aux4.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\horizontal.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\horizontaloff.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\license.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\MMAGE.ICO
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\MMage.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\sleep.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\sleepoff.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\SMALL.ICO
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\title.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\vertical.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource\verticaloff.ico
+# End Source File
+# End Group
+# Begin Group "mmage"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\mmage\mmage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmage\mmage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmage\preference.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmage\preference.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmage\UNIXcompat.cpp
+# End Source File
+# End Group
+# Begin Group "mmvm"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\mmvm\dispbios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\filesys.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\filesys.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\kanjifont.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\kanjifont.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\keybios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\mmvm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\mmvm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\systembios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\textbios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\timerbios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\wwbios.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\wwbios.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mmvm\wwstruct.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\HISTORY.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Readme.txt
+# End Source File
+# End Target
+# End Project

+ 29 - 0
MMage.dsw

@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# 警告: このワークスペース ファイル を編集または削除しないでください!
+
+###############################################################################
+
+Project: "MMage"=.\MMage.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

+ 11 - 0
Readme.txt

@@ -0,0 +1,11 @@
+-- MiracleMage WonderWitch Emulator on Win32
+-- Source archive Readme.txt
+
+- 本ソースアーカイブは VisualC++ 6.0 Standard Edition での build 用に構成されています。
+- wonx ディレクトリ以下の各ソースファイルは、WonX1.0 のソースをを改変したものです。
+- cpu ディレクトリ以下の各ソースファイルは、PCEmu のソースの一部を改変したものです。
+- wonx、cpu ディレクトリ以外の各ソースファイルの著作権は作者である中野智行が有します。
+- 本ソフトウェアのライセンスには Gnu Public License が適用されます。詳しくは COPYING を参照してください。
+
+Copyright 2001 (C) Tomoyuki 'ZRY' Nakano
+All rights reserved.

+ 4465 - 0
cpu/cpu.c

@@ -0,0 +1,4465 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+/* This is CPU.C  It emulates the 8086 processor */
+
+#include "../mmage/mmage.h"
+
+#include "global.h"
+
+#include <stdio.h>
+
+#include "mytypes.h"
+#include "cpu.h"
+#include "instr.h"
+#include "hardware.h"
+
+#ifdef DEBUGGER
+#   include "debugger.h"
+#endif
+
+#ifdef DEBUG
+#	include <stdlib.h>
+#endif
+
+WORD wregs[8];	     /* Always little-endian */
+BYTE *bregs[16];     /* Points to bytes within wregs[] */
+unsigned sregs[4];   /* Always native machine word order */
+
+unsigned ip;	     /* Always native machine word order */
+
+
+    /* All the byte flags will either be 1 or 0 */
+
+BYTE CF, PF, ZF, TF, IF, DF;
+
+    /* All the word flags may be either none-zero (true) or zero (false) */
+
+unsigned AF, OF, SF;
+
+static UINT8 parity_table[256];
+static BYTE *ModRMRegB[256];
+static WORD *ModRMRegW[256];
+
+    /* 'Shadows' of the segment registers. Point directly into the start of the
+       segment within memory[] */
+BYTE *c_cs,*c_ds,*c_es,*c_ss,*c_stack;
+
+volatile int int_pending;   /* Interrupt pending */
+volatile int int_blocked;   /* Blocked pending */
+
+static struct
+{
+    BYTE **segment;
+    WORD *reg1;
+    WORD *reg2;
+    int offset;
+    int offset16;
+    int pad[3];	/* Make structure power of 2 bytes wide for speed */
+} ModRMRM[256];
+
+static WORD zero_word = 0;
+
+static WORD *ModRMRMWRegs[256];
+static BYTE *ModRMRMBRegs[256];
+
+void trap(void);
+
+#define PushSeg(Seg) \
+{ \
+      register unsigned tmp = (WORD)(ReadWord(&wregs[SP])-2); \
+      WriteWord(&wregs[SP],tmp); \
+      PutMemW(c_stack,tmp,sregs[Seg]); \
+}
+
+
+#define PopSeg(seg, Seg) \
+{ \
+      register unsigned tmp = ReadWord(&wregs[SP]); \
+      sregs[Seg] = GetMemW(c_stack,tmp); \
+      seg = SegToMemPtr(Seg); \
+      tmp += 2; \
+      WriteWord(&wregs[SP],tmp); \
+}
+
+
+#define PushWordReg(Reg) \
+{ \
+      register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); \
+      WORD tmp2; \
+      WriteWord(&wregs[SP],tmp1); \
+      tmp2 = ReadWord(&wregs[Reg]); \
+      PutMemW(c_stack,tmp1,tmp2); \
+}
+
+
+#define PopWordReg(Reg) \
+{ \
+      register unsigned tmp = ReadWord(&wregs[SP]); \
+      WORD tmp2 = GetMemW(c_stack,tmp); \
+      tmp += 2; \
+      WriteWord(&wregs[SP],tmp); \
+      WriteWord(&wregs[Reg],tmp2); \
+}
+
+
+#define XchgAXReg(Reg) \
+{ \
+      register unsigned tmp; \
+      tmp = wregs[Reg]; \
+      wregs[Reg] = wregs[AX]; \
+      wregs[AX] = tmp; \
+}
+
+
+#define IncWordReg(Reg) \
+{ \
+      register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
+      register unsigned tmp1 = tmp+1; \
+      SetOFW_Add(tmp1,tmp,1); \
+      SetAF(tmp1,tmp,1); \
+      SetZFW(tmp1); \
+      SetSFW(tmp1); \
+      SetPF(tmp1); \
+      WriteWord(&wregs[Reg],tmp1); \
+}
+
+
+#define DecWordReg(Reg) \
+{ \
+      register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
+      register unsigned tmp1 = tmp-1; \
+      SetOFW_Sub(tmp1,1,tmp); \
+      SetAF(tmp1,tmp,1); \
+      SetZFW(tmp1); \
+      SetSFW(tmp1); \
+      SetPF(tmp1); \
+      WriteWord(&wregs[Reg],tmp1); \
+}
+
+
+#define Logical_br8(op) \
+{ \
+      unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
+      register unsigned src = (unsigned)*GetModRMRegB(ModRM); \
+      BYTE *dest = GetModRMRMB(ModRM); \
+      register unsigned tmp = (unsigned) *dest; \
+      tmp op ## = src; \
+      CF = OF = AF = 0; \
+      SetZFB(tmp); \
+      SetSFB(tmp); \
+      SetPF(tmp); \
+      *dest = (BYTE)tmp; \
+}
+
+
+#define Logical_r8b(op) \
+{ \
+      unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
+      register unsigned src = (unsigned)*GetModRMRMB(ModRM); \
+      BYTE *dest = GetModRMRegB(ModRM); \
+      register unsigned tmp = (unsigned) *dest; \
+      tmp op ## = src; \
+      CF = OF = AF = 0; \
+      SetZFB(tmp); \
+      SetSFB(tmp); \
+      SetPF(tmp); \
+      *dest = (BYTE)tmp; \
+}
+
+
+#define Logical_wr16(op) \
+{ \
+      unsigned ModRM = GetMemInc(c_cs,ip); \
+      WORD *src = GetModRMRegW(ModRM); \
+      WORD *dest = GetModRMRMW(ModRM); \
+      register unsigned tmp1 = (unsigned)ReadWord(src); \
+      register unsigned tmp2 = (unsigned)ReadWord(dest); \
+      register unsigned tmp3 = tmp1 op tmp2; \
+      CF = OF = AF = 0; \
+      SetZFW(tmp3); \
+      SetSFW(tmp3); \
+      SetPF(tmp3); \
+      WriteWord(dest,tmp3); \
+}
+
+
+#define Logical_r16w(op) \
+{ \
+      unsigned ModRM = GetMemInc(c_cs,ip); \
+      WORD *dest = GetModRMRegW(ModRM); \
+      WORD *src = GetModRMRMW(ModRM); \
+      register unsigned tmp1 = (unsigned)ReadWord(src); \
+      register unsigned tmp2 = (unsigned)ReadWord(dest); \
+      register unsigned tmp3 = tmp1 op tmp2; \
+      CF = OF = AF = 0; \
+      SetZFW(tmp3); \
+      SetSFW(tmp3); \
+      SetPF(tmp3); \
+      WriteWord(dest,tmp3); \
+}
+
+
+#define Logical_ald8(op) \
+{ \
+      register unsigned tmp = *bregs[AL]; \
+      tmp op ## = (unsigned)GetMemInc(c_cs,ip); \
+      CF = OF = AF = 0; \
+      SetZFB(tmp); \
+      SetSFB(tmp); \
+      SetPF(tmp); \
+      *bregs[AL] = (BYTE)tmp; \
+}
+
+
+#define Logical_axd16(op) \
+{ \
+      register unsigned src; \
+      register unsigned tmp = ReadWord(&wregs[AX]); \
+      src = GetMemInc(c_cs,ip); \
+      src += GetMemInc(c_cs,ip) << 8; \
+      tmp op ## = src; \
+      CF = OF = AF = 0; \
+      SetZFW(tmp); \
+      SetSFW(tmp); \
+      SetPF(tmp); \
+      WriteWord(&wregs[AX],tmp); \
+}
+
+
+#define LogicalOp(name,symbol) \
+static INLINE2 void i_ ## name ## _br8(void) \
+{ Logical_br8(symbol); } \
+static INLINE2 void i_ ## name ## _wr16(void) \
+{ Logical_wr16(symbol); } \
+static INLINE2 void i_ ## name ## _r8b(void) \
+{ Logical_r8b(symbol); } \
+static INLINE2 void i_ ## name ## _r16w(void) \
+{ Logical_r16w(symbol); } \
+static INLINE2 void i_ ## name ## _ald8(void) \
+{ Logical_ald8(symbol); } \
+static INLINE2 void i_ ## name ## _axd16(void) \
+{ Logical_axd16(symbol); }
+
+
+#define JumpCond(name, cond) \
+static INLINE2 void i_j ## name ## (void) \
+{ \
+      register int tmp = (int)((INT8)GetMemInc(c_cs,ip)); \
+      if (cond) ip = (WORD)(ip+tmp); \
+}
+
+
+// WW BIOS �ˆ—�ƒ‹�[ƒ`ƒ“
+void int_handler(int no);
+
+void init_cpu(void)
+{
+    unsigned int i,j,c;
+
+    for (i = 0; i < 4; i++)
+    {
+        wregs[i] = 0;
+        sregs[i] = 0x70;
+    }
+    for (; i < 8; i++)
+        wregs[i] = 0;
+    
+    wregs[SP] = 0;
+    ip = 0x100;
+
+    for (i = 0;i < 256; i++)
+    {
+        for (j = i, c = 0; j > 0; j >>= 1)
+            if (j & 1) c++;
+        
+        parity_table[i] = !(c & 1);
+    }
+    
+    CF = PF = AF = ZF = SF = TF = IF = DF = OF = 0;
+    
+    bregs[AL] = (BYTE *)&wregs[AX];
+    bregs[AH] = (BYTE *)&wregs[AX]+1;
+    bregs[CL] = (BYTE *)&wregs[CX];
+    bregs[CH] = (BYTE *)&wregs[CX]+1;
+    bregs[DL] = (BYTE *)&wregs[DX];
+    bregs[DH] = (BYTE *)&wregs[DX]+1;
+    bregs[BL] = (BYTE *)&wregs[BX];
+    bregs[BH] = (BYTE *)&wregs[BX]+1;
+    
+    bregs[SPL] = (BYTE *)&wregs[SP];
+    bregs[SPH] = (BYTE *)&wregs[SP]+1;
+    bregs[BPL] = (BYTE *)&wregs[BP];
+    bregs[BPH] = (BYTE *)&wregs[BP]+1;
+    bregs[SIL] = (BYTE *)&wregs[SI];
+    bregs[SIH] = (BYTE *)&wregs[SI]+1;
+    bregs[DIL] = (BYTE *)&wregs[DI];
+    bregs[DIH] = (BYTE *)&wregs[DI]+1;
+    
+    for (i = 0; i < 256; i++)
+    {
+        ModRMRegB[i] = bregs[(i & 0x38) >> 3];
+        ModRMRegW[i] = &wregs[(i & 0x38) >> 3];
+    }
+    
+    for (i = 0; i < 0x40; i++)
+    {
+        switch (i & 7)
+        {
+        case 0:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 1:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 2:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 3:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 4:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 5:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        case 6:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        default:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
+            break;
+        }
+    }
+    
+    for (i = 0x40; i < 0x80; i++)
+    {
+        switch (i & 7)
+        {
+        case 0:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 1:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 2:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 3:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 4:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 5:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        case 6:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        default:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 0;
+            break;
+        }
+    }
+    
+    for (i = 0x80; i < 0xc0; i++)
+    {
+        switch (i & 7)
+        {
+        case 0:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 1:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 2:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 3:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 4:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[SI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 5:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &zero_word;
+            ModRMRM[i].reg2 = &wregs[DI];
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        case 6:
+            ModRMRM[i].segment = &c_ss;
+            ModRMRM[i].reg1 = &wregs[BP];
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        default:
+            ModRMRM[i].segment = &c_ds;
+            ModRMRM[i].reg1 = &wregs[BX];
+            ModRMRM[i].reg2 = &zero_word;
+            ModRMRM[i].offset = 1;
+            ModRMRM[i].offset16 = 1;
+            break;
+        }
+    }
+    
+    for (i = 0xc0; i < 0x100; i++)
+    {
+        ModRMRMWRegs[i] = &wregs[i & 7];
+        ModRMRMBRegs[i] = bregs[i & 7];
+    }
+}
+
+
+#ifdef DEBUG2
+void loc(void)
+{
+    printf("%04X:%04X ", sregs[CS], ip);
+}
+#endif
+
+static void interrupt(unsigned int_num)
+{
+//    unsigned dest_seg, dest_off,tmp1;
+
+    int_handler(int_num);
+
+    /*
+    i_pushf();
+    dest_off = GetMemW(memory,int_num*4);
+    dest_seg = GetMemW(memory,int_num*4+2);
+
+    tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+
+    PutMemW(c_stack,tmp1,sregs[CS]);
+    tmp1 = (WORD)(tmp1-2);
+    PutMemW(c_stack,tmp1,ip);
+    WriteWord(&wregs[SP],tmp1);
+
+    ip = (WORD)dest_off;
+    sregs[CS] = (WORD)dest_seg;
+    c_cs = SegToMemPtr(CS);
+*/
+
+    TF = IF = 0;    /* Turn of trap and interrupts... */
+
+}
+
+
+static void external_int(void)
+{
+    disable();
+
+#ifdef DEBUGGER
+    call_debugger(D_INT);
+#endif
+    D2(printf("Interrupt 0x%02X\n", int_pending););
+    interrupt(int_pending);
+    int_pending = 0;
+
+    enable();
+}
+
+
+#define GetModRMRegW(ModRM) (ModRMRegW[ModRM])
+#define GetModRMRegB(ModRM) (ModRMRegB[ModRM])
+
+static INLINE WORD *GetModRMRMW(unsigned ModRM)
+{
+    register unsigned dest; 
+
+    if (ModRM >= 0xc0)
+        return ModRMRMWRegs[ModRM];
+
+    dest = 0;
+
+    if (ModRMRM[ModRM].offset)
+    {
+        dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
+        if (ModRMRM[ModRM].offset16)
+            dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
+    }
+    
+    return (WORD *)(*ModRMRM[ModRM].segment +
+                    (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
+                           ReadWord(ModRMRM[ModRM].reg2) + dest));
+}
+
+
+static INLINE BYTE *GetModRMRMB(unsigned ModRM)
+{
+    register unsigned dest;
+    
+    if (ModRM >= 0xc0)
+        return ModRMRMBRegs[ModRM];
+
+    dest = 0;
+
+    if (ModRMRM[ModRM].offset)
+    {
+        dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
+        if (ModRMRM[ModRM].offset16)
+            dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
+    }
+    
+    return (*ModRMRM[ModRM].segment +
+            (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
+                   ReadWord(ModRMRM[ModRM].reg2) + dest));
+}
+
+/* i186 instructions */ 
+#include "i186.h"
+
+static INLINE2 void i_add_br8(void)
+{
+    /* Opcode 0x00 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM);
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+    
+    tmp += src;
+    
+    SetCFB_Add(tmp,tmp2);
+    SetOFB_Add(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+}
+
+
+static INLINE2 void i_add_wr16(void)
+{
+    /* Opcode 0x01 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = (unsigned)ReadWord(dest);
+    register unsigned tmp2 = (unsigned)ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1+tmp2;
+
+    SetCFW_Add(tmp3,tmp1);
+    SetOFW_Add(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_add_r8b(void)
+{
+    /* Opcode 0x02 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRMB(ModRM);
+    BYTE *dest = GetModRMRegB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp += src;
+
+    SetCFB_Add(tmp,tmp2);
+    SetOFB_Add(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+
+}
+
+
+static INLINE2 void i_add_r16w(void)
+{
+    /* Opcode 0x03 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRegW(ModRM);
+    WORD *src = GetModRMRMW(ModRM);
+    register unsigned tmp1 = (unsigned)ReadWord(dest);
+    register unsigned tmp2 = (unsigned)ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1 + tmp2;
+
+    SetCFW_Add(tmp3,tmp1);
+    SetOFW_Add(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_add_ald8(void)
+{
+    /* Opcode 0x04 */
+
+    register unsigned src = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned tmp = (unsigned)*bregs[AL];
+    register unsigned tmp2 = tmp;
+
+    tmp2 += src;
+
+    SetCFB_Add(tmp2,tmp);
+    SetOFB_Add(tmp2,src,tmp);
+    SetAF(tmp2,src,tmp);
+    SetZFB(tmp2);
+    SetSFB(tmp2);
+    SetPF(tmp2);
+
+    *bregs[AL] = (BYTE)tmp2;
+}
+
+
+static INLINE2 void i_add_axd16(void)
+{
+    /* Opcode 0x05 */
+
+    register unsigned src;
+    register unsigned tmp = ReadWord(&wregs[AX]);
+    register unsigned tmp2 = tmp;
+
+    src = GetMemInc(c_cs,ip);
+    src += GetMemInc(c_cs,ip) << 8;
+
+    tmp2 += src;
+
+    SetCFW_Add(tmp2,tmp);
+    SetOFW_Add(tmp2,tmp,src);
+    SetAF(tmp2,tmp,src);
+    SetZFW(tmp2);
+    SetSFW(tmp2);
+    SetPF(tmp2);
+
+    WriteWord(&wregs[AX],tmp2);
+}
+
+
+static INLINE2 void i_push_es(void)
+{
+    /* Opcode 0x06 */
+
+    PushSeg(ES);
+}
+
+
+static INLINE2 void i_pop_es(void)
+{
+    /* Opcode 0x07 */
+    PopSeg(c_es,ES);
+}
+
+    /* most OR instructions go here... */
+
+LogicalOp(or,|)
+
+
+static INLINE2 void i_push_cs(void)
+{
+    /* Opcode 0x0e */
+
+    PushSeg(CS);
+}
+
+
+static INLINE2 void i_adc_br8(void)
+{
+    /* Opcode 0x10 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp += src;
+
+    CF = tmp >> 8;
+
+/*    SetCFB_Add(tmp,tmp2); */
+    SetOFB_Add(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+}
+
+
+static INLINE2 void i_adc_wr16(void)
+{
+    /* Opcode 0x11 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = (unsigned)ReadWord(dest);
+    register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
+    register unsigned tmp3;
+
+    tmp3 = tmp1+tmp2;
+
+    CF = tmp3 >> 16;
+/*    SetCFW_Add(tmp3,tmp1); */
+    SetOFW_Add(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+
+}
+
+
+static INLINE2 void i_adc_r8b(void)
+{
+    /* Opcode 0x12 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
+    BYTE *dest = GetModRMRegB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp += src;
+
+    CF = tmp >> 8;
+
+/*    SetCFB_Add(tmp,tmp2); */
+    SetOFB_Add(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+}
+
+
+static INLINE2 void i_adc_r16w(void)
+{
+    /* Opcode 0x13 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRegW(ModRM);
+    WORD *src = GetModRMRMW(ModRM);
+    register unsigned tmp1 = (unsigned)ReadWord(dest);
+    register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
+    register unsigned tmp3;
+
+    tmp3 = tmp1+tmp2;
+
+    CF = tmp3 >> 16;
+
+/*    SetCFW_Add(tmp3,tmp1); */
+    SetOFW_Add(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+
+}
+
+
+static INLINE2 void i_adc_ald8(void)
+{
+    /* Opcode 0x14 */
+
+    register unsigned src = (unsigned)GetMemInc(c_cs,ip)+CF;
+    register unsigned tmp = (unsigned)*bregs[AL];
+    register unsigned tmp2 = tmp;
+
+    tmp2 += src;
+
+    CF = tmp2 >> 8;
+
+/*    SetCFB_Add(tmp2,tmp); */
+    SetOFB_Add(tmp2,src,tmp);
+    SetAF(tmp2,src,tmp);
+    SetZFB(tmp2);
+    SetSFB(tmp2);
+    SetPF(tmp2);
+
+    *bregs[AL] = (BYTE)tmp2;
+}
+
+
+static INLINE2 void i_adc_axd16(void)
+{
+    /* Opcode 0x15 */
+
+    register unsigned src;
+    register unsigned tmp = ReadWord(&wregs[AX]);
+    register unsigned tmp2 = tmp;
+
+    src = GetMemInc(c_cs,ip);
+    src += (GetMemInc(c_cs,ip) << 8)+CF;
+
+    tmp2 += src;
+
+    CF = tmp2 >> 16;
+
+/*    SetCFW_Add(tmp2,tmp); */
+    SetOFW_Add(tmp2,tmp,src);
+    SetAF(tmp2,tmp,src);
+    SetZFW(tmp2);
+    SetSFW(tmp2);
+    SetPF(tmp2);
+
+    WriteWord(&wregs[AX],tmp2);
+}
+
+
+static INLINE2 void i_push_ss(void)
+{
+    /* Opcode 0x16 */
+
+    PushSeg(SS);
+}
+
+
+static INLINE2 void i_pop_ss(void)
+{
+    /* Opcode 0x17 */
+
+    static int multiple = 0;
+
+    PopSeg(c_ss,SS);
+    c_stack = c_ss;
+    
+    if (multiple == 0)	/* prevent unlimited recursion */
+    {
+        multiple = 1;
+/*
+#ifdef DEBUGGER
+        call_debugger(D_TRACE);
+#endif
+*/
+        instruction[GetMemInc(c_cs,ip)]();
+        multiple = 0;
+    }
+}
+
+
+static INLINE2 void i_sbb_br8(void)
+{
+    /* Opcode 0x18 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    CF = (tmp & 0x100) == 0x100;
+
+/*    SetCFB_Sub(tmp,tmp2); */
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+}
+
+
+static INLINE2 void i_sbb_wr16(void)
+{
+    /* Opcode 0x19 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src)+CF;
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    CF = (tmp3 & 0x10000) == 0x10000;
+
+/*    SetCFW_Sub(tmp2,tmp1); */
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_sbb_r8b(void)
+{
+    /* Opcode 0x1a */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
+    BYTE *dest = GetModRMRegB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    CF = (tmp & 0x100) == 0x100;
+
+/*    SetCFB_Sub(tmp,tmp2); */
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+
+}
+
+
+static INLINE2 void i_sbb_r16w(void)
+{
+    /* Opcode 0x1b */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRegW(ModRM);
+    WORD *src = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src)+CF;
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    CF = (tmp3 & 0x10000) == 0x10000;
+
+/*    SetCFW_Sub(tmp2,tmp1); */
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_sbb_ald8(void)
+{
+    /* Opcode 0x1c */
+
+    register unsigned src = GetMemInc(c_cs,ip)+CF;
+    register unsigned tmp = *bregs[AL];
+    register unsigned tmp1 = tmp;
+
+    tmp1 -= src;
+
+    CF = (tmp1 & 0x100) == 0x100;
+
+/*    SetCFB_Sub(src,tmp); */
+    SetOFB_Sub(tmp1,src,tmp);
+    SetAF(tmp1,src,tmp);
+    SetZFB(tmp1);
+    SetSFB(tmp1);
+    SetPF(tmp1);
+
+    *bregs[AL] = (BYTE)tmp1;
+}
+
+
+static INLINE2 void i_sbb_axd16(void)
+{
+    /* Opcode 0x1d */
+
+    register unsigned src;
+    register unsigned tmp = ReadWord(&wregs[AX]);
+    register unsigned tmp2 = tmp;
+
+    src = GetMemInc(c_cs,ip);
+    src += (GetMemInc(c_cs,ip) << 8)+CF;
+
+    tmp2 -= src;
+
+    CF = (tmp2 & 0x10000) == 0x10000;
+
+/*    SetCFW_Sub(src,tmp); */
+    SetOFW_Sub(tmp2,src,tmp);
+    SetAF(tmp2,tmp,src);
+    SetZFW(tmp2);
+    SetSFW(tmp2);
+    SetPF(tmp2);
+
+    WriteWord(&wregs[AX],tmp2);
+}
+
+
+static INLINE2 void i_push_ds(void)
+{
+    /* Opcode 0x1e */
+
+    PushSeg(DS);
+}
+
+
+static INLINE2 void i_pop_ds(void)
+{
+    /* Opcode 0x1f */
+    PopSeg(c_ds,DS);
+}
+
+    /* most AND instructions go here... */
+
+LogicalOp(and,&)
+
+
+static INLINE2 void i_es(void)
+{
+    /* Opcode 0x26 */
+
+    c_ds = c_ss = c_es;
+
+    instruction[GetMemInc(c_cs,ip)]();
+
+    c_ds = SegToMemPtr(DS);
+    c_ss = SegToMemPtr(SS);
+}
+
+static INLINE2 void i_daa(void)
+{
+    if (AF || ((*bregs[AL] & 0xf) > 9))
+    {
+        *bregs[AL] += 6;
+        AF = 1;
+    }
+    else
+        AF = 0;
+
+    if (CF || (*bregs[AL] > 0x9f))
+    {
+        *bregs[AL] += 0x60;
+        CF = 1;
+    }
+    else
+        CF = 0;
+
+    SetPF(*bregs[AL]);
+    SetSFB(*bregs[AL]);
+    SetZFB(*bregs[AL]);
+}
+
+static INLINE2 void i_sub_br8(void)
+{
+    /* Opcode 0x28 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM);
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+
+}
+
+
+static INLINE2 void i_sub_wr16(void)
+{
+    /* Opcode 0x29 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    SetCFW_Sub(tmp2,tmp1);
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_sub_r8b(void)
+{
+    /* Opcode 0x2a */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    BYTE *dest = GetModRMRegB(ModRM);
+    register unsigned src = *GetModRMRMB(ModRM);
+    register unsigned tmp = *dest;
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    *dest = (BYTE)tmp;
+}
+
+
+static INLINE2 void i_sub_r16w(void)
+{
+    /* Opcode 0x2b */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRegW(ModRM);
+    WORD *src = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    SetCFW_Sub(tmp2,tmp1);
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+
+    WriteWord(dest, tmp3);
+}
+
+
+static INLINE2 void i_sub_ald8(void)
+{
+    /* Opcode 0x2c */
+
+    register unsigned src = GetMemInc(c_cs,ip);
+    register unsigned tmp = *bregs[AL];
+    register unsigned tmp1 = tmp;
+
+    tmp1 -= src;
+
+    SetCFB_Sub(src,tmp);
+    SetOFB_Sub(tmp1,src,tmp);
+    SetAF(tmp1,src,tmp);
+    SetZFB(tmp1);
+    SetSFB(tmp1);
+    SetPF(tmp1);
+
+    *bregs[AL] = (unsigned) tmp1;
+}
+
+
+static INLINE2 void i_sub_axd16(void)
+{
+    /* Opcode 0x2d */
+
+    register unsigned src;
+    register unsigned tmp = ReadWord(&wregs[AX]);
+    register unsigned tmp2 = tmp;
+
+    src = GetMemInc(c_cs,ip);
+    src += (GetMemInc(c_cs,ip) << 8);
+
+    tmp2 -= src;
+
+    SetCFW_Sub(src,tmp);
+    SetOFW_Sub(tmp2,src,tmp);
+    SetAF(tmp2,tmp,src);
+    SetZFW(tmp2);
+    SetSFW(tmp2);
+    SetPF(tmp2);
+
+    WriteWord(&wregs[AX],tmp2);
+}
+
+
+static INLINE2 void i_cs(void)
+{
+    /* Opcode 0x2e */
+
+    c_ds = c_ss = c_cs;
+
+    instruction[GetMemInc(c_cs,ip)]();
+
+    c_ds = SegToMemPtr(DS);
+    c_ss = SegToMemPtr(SS);
+}
+
+
+    /* most XOR instructions go here */
+
+LogicalOp(xor,^)
+
+
+static INLINE2 void i_ss(void)
+{
+    /* Opcode 0x36 */
+
+    c_ds = c_ss;
+
+    instruction[GetMemInc(c_cs,ip)]();
+
+    c_ds = SegToMemPtr(DS);
+}
+
+
+static INLINE2 void i_cmp_br8(void)
+{
+    /* Opcode 0x38 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM);
+    register unsigned tmp = *GetModRMRMB(ModRM);
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+}
+
+
+static INLINE2 void i_cmp_wr16(void)
+{
+    /* Opcode 0x39 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    SetCFW_Sub(tmp2,tmp1);
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+}
+
+
+static INLINE2 void i_cmp_r8b(void)
+{
+    /* Opcode 0x3a */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned tmp = (unsigned)*GetModRMRegB(ModRM);
+    register unsigned src = *GetModRMRMB(ModRM);
+    register unsigned tmp2 = tmp;
+
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+}
+
+static INLINE2 void i_cmp_r16w(void)
+{
+    /* Opcode 0x3b */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRegW(ModRM);
+    WORD *src = GetModRMRMW(ModRM);
+    register unsigned tmp1 = ReadWord(dest);
+    register unsigned tmp2 = ReadWord(src);
+    register unsigned tmp3;
+
+    tmp3 = tmp1-tmp2;
+
+    SetCFW_Sub(tmp2,tmp1);
+    SetOFW_Sub(tmp3,tmp2,tmp1);
+    SetAF(tmp3,tmp2,tmp1);
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+}
+
+
+static INLINE2 void i_cmp_ald8(void)
+{
+    /* Opcode 0x3c */
+
+    register unsigned src = GetMemInc(c_cs,ip);
+    register unsigned tmp = *bregs[AL];
+    register unsigned tmp1 = tmp;
+
+    tmp1 -= src;
+
+    SetCFB_Sub(src,tmp);
+    SetOFB_Sub(tmp1,src,tmp);
+    SetAF(tmp1,src,tmp);
+    SetZFB(tmp1);
+    SetSFB(tmp1);
+    SetPF(tmp1);
+}
+
+
+static INLINE2 void i_cmp_axd16(void)
+{
+    /* Opcode 0x3d */
+
+    register unsigned src;
+    register unsigned tmp = ReadWord(&wregs[AX]);
+    register unsigned tmp2 = tmp;
+
+    src = GetMemInc(c_cs,ip);
+    src += (GetMemInc(c_cs,ip) << 8);
+
+    tmp2 -= src;
+
+    SetCFW_Sub(src,tmp);
+    SetOFW_Sub(tmp2,src,tmp);
+    SetAF(tmp2,tmp,src);
+    SetZFW(tmp2);
+    SetSFW(tmp2);
+    SetPF(tmp2);
+}
+
+
+static INLINE2 void i_ds(void)
+{
+    /* Opcode 0x3e */
+
+    c_ss = c_ds;
+
+    instruction[GetMemInc(c_cs,ip)]();
+
+    c_ss = SegToMemPtr(SS);
+}
+
+
+static INLINE2 void i_inc_ax(void)
+{
+    /* Opcode 0x40 */
+    IncWordReg(AX);
+}
+
+
+static INLINE2 void i_inc_cx(void)
+{
+    /* Opcode 0x41 */
+    IncWordReg(CX);
+}
+
+
+static INLINE2 void i_inc_dx(void)
+{
+    /* Opcode 0x42 */
+    IncWordReg(DX);
+}
+
+
+static INLINE2 void i_inc_bx(void)
+{
+    /* Opcode 0x43 */
+    IncWordReg(BX);
+}
+
+
+static INLINE2 void i_inc_sp(void)
+{
+    /* Opcode 0x44 */
+    IncWordReg(SP);
+}
+
+
+static INLINE2 void i_inc_bp(void)
+{
+    /* Opcode 0x45 */
+    IncWordReg(BP);
+}
+
+
+static INLINE2 void i_inc_si(void)
+{
+    /* Opcode 0x46 */
+    IncWordReg(SI);
+}
+
+
+static INLINE2 void i_inc_di(void)
+{
+    /* Opcode 0x47 */
+    IncWordReg(DI);
+}
+
+
+static INLINE2 void i_dec_ax(void)
+{
+    /* Opcode 0x48 */
+    DecWordReg(AX);
+}
+
+
+static INLINE2 void i_dec_cx(void)
+{
+    /* Opcode 0x49 */
+    DecWordReg(CX);
+}
+
+
+static INLINE2 void i_dec_dx(void)
+{
+    /* Opcode 0x4a */
+    DecWordReg(DX);
+}
+
+
+static INLINE2 void i_dec_bx(void)
+{
+    /* Opcode 0x4b */
+    DecWordReg(BX);
+}
+
+
+static INLINE2 void i_dec_sp(void)
+{
+    /* Opcode 0x4c */
+    DecWordReg(SP);
+}
+
+
+static INLINE2 void i_dec_bp(void)
+{
+    /* Opcode 0x4d */
+    DecWordReg(BP);
+}
+
+
+static INLINE2 void i_dec_si(void)
+{
+    /* Opcode 0x4e */
+    DecWordReg(SI);
+}
+
+
+static INLINE2 void i_dec_di(void)
+{
+    /* Opcode 0x4f */
+    DecWordReg(DI);
+}
+
+
+static INLINE2 void i_push_ax(void)
+{
+    /* Opcode 0x50 */
+    PushWordReg(AX);
+}
+
+
+static INLINE2 void i_push_cx(void)
+{
+    /* Opcode 0x51 */
+    PushWordReg(CX);
+}
+
+
+static INLINE2 void i_push_dx(void)
+{
+    /* Opcode 0x52 */
+    PushWordReg(DX);
+}
+
+
+static INLINE2 void i_push_bx(void)
+{
+    /* Opcode 0x53 */
+    PushWordReg(BX);
+}
+
+
+static INLINE2 void i_push_sp(void)
+{
+    /* Opcode 0x54 */
+    PushWordReg(SP);
+}
+
+
+static INLINE2 void i_push_bp(void)
+{
+    /* Opcode 0x55 */
+    PushWordReg(BP);
+}
+
+
+
+static INLINE2 void i_push_si(void)
+{
+    /* Opcode 0x56 */
+    PushWordReg(SI);
+}
+
+
+static INLINE2 void i_push_di(void)
+{
+    /* Opcode 0x57 */
+    PushWordReg(DI);
+}
+
+
+static INLINE2 void i_pop_ax(void)
+{
+    /* Opcode 0x58 */
+    PopWordReg(AX);
+}
+
+
+static INLINE2 void i_pop_cx(void)
+{
+    /* Opcode 0x59 */
+    PopWordReg(CX);
+}
+
+
+static INLINE2 void i_pop_dx(void)
+{
+    /* Opcode 0x5a */
+    PopWordReg(DX);
+}
+
+
+static INLINE2 void i_pop_bx(void)
+{
+    /* Opcode 0x5b */
+    PopWordReg(BX);
+}
+
+
+static INLINE2 void i_pop_sp(void)
+{
+    /* Opcode 0x5c */
+    PopWordReg(SP);
+}
+
+
+static INLINE2 void i_pop_bp(void)
+{
+    /* Opcode 0x5d */
+    PopWordReg(BP);
+}
+
+
+static INLINE2 void i_pop_si(void)
+{
+    /* Opcode 0x5e */
+    PopWordReg(SI);
+}
+
+
+static INLINE2 void i_pop_di(void)
+{
+    /* Opcode 0x5f */
+    PopWordReg(DI);
+}
+
+    /* Conditional jumps from 0x70 to 0x7f */
+
+JumpCond(o, OF)                 /* 0x70 = Jump if overflow */
+JumpCond(no, !OF)               /* 0x71 = Jump if no overflow */
+JumpCond(b, CF)                 /* 0x72 = Jump if below */
+JumpCond(nb, !CF)               /* 0x73 = Jump if not below */
+JumpCond(z, ZF)                 /* 0x74 = Jump if zero */
+JumpCond(nz, !ZF)               /* 0x75 = Jump if not zero */
+JumpCond(be, CF || ZF)          /* 0x76 = Jump if below or equal */
+JumpCond(nbe, !(CF || ZF))      /* 0x77 = Jump if not below or equal */
+JumpCond(s, SF)                 /* 0x78 = Jump if sign */
+JumpCond(ns, !SF)               /* 0x79 = Jump if no sign */
+JumpCond(p, PF)                 /* 0x7a = Jump if parity */
+JumpCond(np, !PF)               /* 0x7b = Jump if no parity */
+JumpCond(l,(!(!SF)!=!(!OF))&&!ZF)    /* 0x7c = Jump if less */
+JumpCond(nl, ZF||(!(!SF) == !(!OF))) /* 0x7d = Jump if not less */
+JumpCond(le, ZF||(!(!SF) != !(!OF))) /* 0x7e = Jump if less than or equal */
+JumpCond(nle,(!(!SF)==!(!OF))&&!ZF)  /* 0x7f = Jump if not less than or equal*/
+
+
+static INLINE2 void i_80pre(void)
+{
+    /* Opcode 0x80 */
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned src = GetMemInc(c_cs,ip);
+    register unsigned tmp = *dest;
+    register unsigned tmp2;
+    
+    
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ADD eb,d8 */
+        tmp2 = src + tmp;
+        
+        SetCFB_Add(tmp2,tmp);
+        SetOFB_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFB(tmp2);
+        SetSFB(tmp2);
+        SetPF(tmp2);
+        
+        *dest = (BYTE)tmp2;
+        break;
+    case 0x08:  /* OR eb,d8 */
+        tmp |= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x10:  /* ADC eb,d8 */
+        src += CF;
+        tmp2 = src + tmp;
+        
+        CF = tmp2 >> 8;
+/*        SetCFB_Add(tmp2,tmp); */
+        SetOFB_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFB(tmp2);
+        SetSFB(tmp2);
+        SetPF(tmp2);
+        
+        *dest = (BYTE)tmp2;
+        break;
+    case 0x18:  /* SBB eb,b8 */
+        src += CF;
+        tmp2 = tmp;
+        tmp -= src;
+        
+        CF = (tmp & 0x100) == 0x100;
+
+/*        SetCFB_Sub(tmp,tmp2); */
+        SetOFB_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x20:  /* AND eb,d8 */
+        tmp &= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x28:  /* SUB eb,d8 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFB_Sub(tmp,tmp2);
+        SetOFB_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x30:  /* XOR eb,d8 */
+        tmp ^= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x38:  /* CMP eb,d8 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFB_Sub(tmp,tmp2);
+        SetOFB_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        break;
+    }
+}
+
+
+static INLINE2 void i_81pre(void)
+{
+    /* Opcode 0x81 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned src = GetMemInc(c_cs,ip);
+    register unsigned tmp = ReadWord(dest);
+    register unsigned tmp2;
+
+    src += GetMemInc(c_cs,ip) << 8;
+
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ADD ew,d16 */
+        tmp2 = src + tmp;
+        
+        SetCFW_Add(tmp2,tmp);
+        SetOFW_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFW(tmp2);
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        
+        WriteWord(dest,tmp2);
+        break;
+    case 0x08:  /* OR ew,d16 */
+        tmp |= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x10:  /* ADC ew,d16 */
+        src += CF;
+        tmp2 = src + tmp;
+        
+        CF = tmp2 >> 16;
+/*        SetCFW_Add(tmp2,tmp); */
+        SetOFW_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFW(tmp2);
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        
+        WriteWord(dest,tmp2);
+        break;
+    case 0x18:  /* SBB ew,d16 */
+        src += CF;
+        tmp2 = tmp;
+        tmp -= src;
+        
+        CF = (tmp & 0x10000) == 0x10000;
+
+/*        SetCFW_Sub(tmp,tmp2); */
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x20:  /* AND ew,d16 */
+        tmp &= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x28:  /* SUB ew,d16 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFW_Sub(tmp,tmp2);
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x30:  /* XOR ew,d16 */
+        tmp ^= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x38:  /* CMP ew,d16 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFW_Sub(tmp,tmp2);
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        break;
+    }
+}
+
+
+static INLINE2 void i_83pre(void)
+{
+    /* Opcode 0x83 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
+    register unsigned tmp = ReadWord(dest);
+    register unsigned tmp2;
+    
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ADD ew,d8 */
+        tmp2 = src + tmp;
+        
+        SetCFW_Add(tmp2,tmp);
+        SetOFW_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFW(tmp2);
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        
+        WriteWord(dest,tmp2);
+        break;
+    case 0x08:  /* OR ew,d8 */
+        tmp |= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x10:  /* ADC ew,d8 */
+        src += CF;
+        tmp2 = src + tmp;
+        
+        CF = tmp2 >> 16;
+
+/*        SetCFW_Add(tmp2,tmp); */
+        SetOFW_Add(tmp2,src,tmp);
+        SetAF(tmp2,src,tmp);
+        SetZFW(tmp2);
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        
+        WriteWord(dest,tmp2);
+        break;
+    case 0x18:  /* SBB ew,d8 */
+        src += CF;
+        tmp2 = tmp;
+        tmp -= src;
+        
+        CF = (tmp & 0x10000) == 0x10000;
+
+/*        SetCFW_Sub(tmp,tmp2); */
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x20:  /* AND ew,d8 */
+        tmp &= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x28:  /* SUB ew,d8 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFW_Sub(tmp,tmp2);
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x30:  /* XOR ew,d8 */
+        tmp ^= src;
+        
+        CF = OF = AF = 0;
+        
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+        
+    case 0x38:  /* CMP ew,d8 */
+        tmp2 = tmp;
+        tmp -= src;
+        
+        SetCFW_Sub(tmp,tmp2);
+        SetOFW_Sub(tmp,src,tmp2);
+        SetAF(tmp,src,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        break;
+    }
+}
+
+
+static INLINE2 void i_test_br8(void)
+{
+    /* Opcode 0x84 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register unsigned src = (unsigned)*GetModRMRegB(ModRM);
+    BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned) *dest;
+    tmp &= src;
+    CF = OF = AF = 0;
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+}
+
+
+static INLINE2 void i_test_wr16(void)
+{
+    /* Opcode 0x85 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *src = GetModRMRegW(ModRM);
+    WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp1 = (unsigned)ReadWord(src);
+    register unsigned tmp2 = (unsigned)ReadWord(dest);
+    register unsigned tmp3 = tmp1 & tmp2;
+    CF = OF = AF = 0;
+    SetZFW(tmp3);
+    SetSFW(tmp3);
+    SetPF(tmp3);
+}
+
+
+static INLINE2 void i_xchg_br8(void)
+{
+    /* Opcode 0x86 */
+
+    unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
+    register BYTE *src = GetModRMRegB(ModRM);
+    register BYTE *dest = GetModRMRMB(ModRM);
+    BYTE tmp;
+
+    tmp = *src;
+    *src = *dest;
+    *dest = tmp;
+}
+
+
+static INLINE2 void i_xchg_wr16(void)
+{
+    /* Opcode 0x87 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *src = (BYTE *)GetModRMRegW(ModRM);
+    register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
+    BYTE tmp1,tmp2;
+
+    tmp1 = src[0];
+    tmp2 = src[1];
+    src[0] = dest[0];
+    src[1] = dest[1];
+    dest[0] = tmp1;
+    dest[1] = tmp2;
+
+}
+
+
+static INLINE2 void i_mov_br8(void)
+{
+    /* Opcode 0x88 */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE src = *GetModRMRegB(ModRM);
+    register BYTE *dest = GetModRMRMB(ModRM);
+
+    *dest = src;
+}
+
+
+static INLINE2 void i_mov_wr16(void)
+{
+    /* Opcode 0x89 */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *src = GetModRMRegW(ModRM);
+    register WORD *dest = GetModRMRMW(ModRM);
+
+    CopyWord(dest,src);
+}
+
+
+static INLINE2 void i_mov_r8b(void)
+{
+    /* Opcode 0x8a */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *dest = GetModRMRegB(ModRM);
+    register BYTE src = *GetModRMRMB(ModRM);
+
+    *dest = src;
+}
+
+
+static INLINE2 void i_mov_r16w(void)
+{
+    /* Opcode 0x8b */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRegW(ModRM);
+    register WORD *src = GetModRMRMW(ModRM);
+
+    CopyWord(dest,src);
+}
+
+
+static INLINE2 void i_mov_wsreg(void)
+{
+    /* Opcode 0x8c */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRMW(ModRM);
+
+    WriteWord(dest,sregs[(ModRM & 0x38) >> 3]);
+}
+
+
+static INLINE2 void i_lea(void)
+{
+    /* Opcode 0x8d */
+
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register unsigned src = 0;
+    register WORD *dest = GetModRMRegW(ModRM);
+
+    if (ModRMRM[ModRM].offset)
+    {
+        src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
+        if (ModRMRM[ModRM].offset16)
+            src = (GetMemInc(c_cs,ip) << 8) + (BYTE)(src);
+    }
+
+    src += ReadWord(ModRMRM[ModRM].reg1)+ReadWord(ModRMRM[ModRM].reg2);        
+    WriteWord(dest,src);
+}
+
+
+static INLINE2 void i_mov_sregw(void)
+{
+    /* Opcode 0x8e */
+    
+    static int multiple = 0;
+    register unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *src = GetModRMRMW(ModRM);
+    
+    switch (ModRM & 0x38)
+    {
+    case 0x00:	/* mov es,... */
+        sregs[ES] = ReadWord(src);
+        c_es = SegToMemPtr(ES);
+        break;
+    case 0x18:	/* mov ds,... */
+        sregs[DS] = ReadWord(src);
+        c_ds = SegToMemPtr(DS);
+        break;
+    case 0x10:	/* mov ss,... */
+        sregs[SS] = ReadWord(src);
+        c_stack = c_ss = SegToMemPtr(SS);
+        
+        if (multiple == 0) /* Prevent unlimited recursion.. */
+        {
+            multiple = 1;
+/*
+#ifdef DEBUGGER
+            call_debugger(D_TRACE);
+#endif
+*/
+            instruction[GetMemInc(c_cs,ip)]();
+            multiple = 0;
+        }
+        
+        break;
+    case 0x08:	/* mov cs,... (hangs 486, but we'll let it through) */
+        break;
+        
+    }
+}
+
+
+static INLINE2 void i_popw(void)
+{
+    /* Opcode 0x8f */
+    
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    WORD tmp2 = GetMemW(c_stack,tmp);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+    WriteWord(dest,tmp2);
+}
+
+
+static INLINE2 void i_nop(void)
+{
+    /* Opcode 0x90 */
+}
+
+
+static INLINE2 void i_xchg_axcx(void)
+{
+    /* Opcode 0x91 */
+    XchgAXReg(CX);
+}
+
+
+static INLINE2 void i_xchg_axdx(void)
+{
+    /* Opcode 0x92 */
+    XchgAXReg(DX);
+}
+
+
+static INLINE2 void i_xchg_axbx(void)
+{
+    /* Opcode 0x93 */
+    XchgAXReg(BX);
+}
+
+
+static INLINE2 void i_xchg_axsp(void)
+{
+    /* Opcode 0x94 */
+    XchgAXReg(SP);
+}
+
+
+static INLINE2 void i_xchg_axbp(void)
+{
+    /* Opcode 0x95 */
+    XchgAXReg(BP);
+}
+
+
+static INLINE2 void i_xchg_axsi(void)
+{
+    /* Opcode 0x96 */
+    XchgAXReg(SI);
+}
+
+
+static INLINE2 void i_xchg_axdi(void)
+{
+    /* Opcode 0x97 */
+    XchgAXReg(DI);
+}
+
+static INLINE2 void i_cbw(void)
+{
+    /* Opcode 0x98 */
+
+    *bregs[AH] = (*bregs[AL] & 0x80) ? 0xff : 0;
+}
+        
+static INLINE2 void i_cwd(void)
+{
+    /* Opcode 0x99 */
+
+    wregs[DX] = (*bregs[AH] & 0x80) ? ChangeE(0xffff) : ChangeE(0);
+}
+
+
+static INLINE2 void i_call_far(void)
+{
+    register unsigned tmp, tmp1, tmp2;
+
+    tmp = GetMemInc(c_cs,ip);
+    tmp += GetMemInc(c_cs,ip) << 8;
+
+    tmp2 = GetMemInc(c_cs,ip);
+    tmp2 += GetMemInc(c_cs,ip) << 8;
+
+    tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+
+    PutMemW(c_stack,tmp1,sregs[CS]);
+    tmp1 = (WORD)(tmp1-2);
+    PutMemW(c_stack,tmp1,ip);
+
+    WriteWord(&wregs[SP],tmp1);
+
+    ip = (WORD)tmp;
+    sregs[CS] = (WORD)tmp2;
+    c_cs = SegToMemPtr(CS);
+}
+
+
+static INLINE2 void i_wait(void)
+{
+    /* Opcode 0x9b */
+    
+    return;
+}
+
+
+static INLINE2 void i_pushf(void)
+{
+    /* Opcode 0x9c */
+
+    register unsigned tmp1 = (ReadWord(&wregs[SP])-2);
+    WORD tmp2 = CompressFlags() | 0xf000;
+
+    PutMemW(c_stack,tmp1,tmp2);
+    WriteWord(&wregs[SP],tmp1);
+}
+
+
+static INLINE2 void i_popf(void)
+{
+    /* Opcode 0x9d */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    unsigned tmp2 = (unsigned)GetMemW(c_stack,tmp);
+
+    ExpandFlags(tmp2);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+    
+    if (IF && int_blocked)
+    {
+        int_pending = int_blocked;
+        int_blocked = 0;
+        D2(printf("Unblocking interrupt\n"););
+    }
+    if (TF) trap();
+}
+
+
+static INLINE2 void i_sahf(void)
+{
+    /* Opcode 0x9e */
+
+    unsigned tmp = (CompressFlags() & 0xff00) | (*bregs[AH] & 0xd5);
+
+    ExpandFlags(tmp);
+}
+
+
+static INLINE2 void i_lahf(void)
+{
+    /* Opcode 0x9f */
+
+    *bregs[AH] = CompressFlags() & 0xff;
+}
+
+static INLINE2 void i_mov_aldisp(void)
+{
+    /* Opcode 0xa0 */
+
+    register unsigned addr;
+
+    addr = GetMemInc(c_cs,ip);
+    addr += GetMemInc(c_cs, ip) << 8;
+
+    *bregs[AL] = GetMemB(c_ds, addr);
+}
+
+
+static INLINE2 void i_mov_axdisp(void)
+{
+    /* Opcode 0xa1 */
+
+    register unsigned addr;
+
+    addr = GetMemInc(c_cs, ip);
+    addr += GetMemInc(c_cs, ip) << 8;
+
+    *bregs[AL] = GetMemB(c_ds, addr);
+    *bregs[AH] = GetMemB(c_ds, addr+1);
+}
+
+
+static INLINE2 void i_mov_dispal(void)
+{
+    /* Opcode 0xa2 */
+
+    register unsigned addr;
+
+    addr = GetMemInc(c_cs,ip);
+    addr += GetMemInc(c_cs, ip) << 8;
+
+    PutMemB(c_ds, addr, *bregs[AL]);
+}
+
+
+static INLINE2 void i_mov_dispax(void)
+{
+    /* Opcode 0xa3 */
+
+    register unsigned addr;
+
+    addr = GetMemInc(c_cs, ip);
+    addr += GetMemInc(c_cs, ip) << 8;
+
+    PutMemB(c_ds, addr, *bregs[AL]);
+    PutMemB(c_ds, addr+1, *bregs[AH]);
+}
+
+
+static INLINE2 void i_movsb(void)
+{
+    /* Opcode 0xa4 */
+
+    register unsigned di = ReadWord(&wregs[DI]);
+    register unsigned si = ReadWord(&wregs[SI]);
+
+    BYTE tmp = GetMemB(c_ds,si);
+
+    PutMemB(c_es,di, tmp);
+
+    di += -2*DF +1;
+    si += -2*DF +1;
+
+    WriteWord(&wregs[DI],di);
+    WriteWord(&wregs[SI],si);
+}
+
+
+static INLINE2 void i_movsw(void)
+{
+    /* Opcode 0xa5 */
+
+    register unsigned di = ReadWord(&wregs[DI]);
+    register unsigned si = ReadWord(&wregs[SI]);
+    
+    WORD tmp = GetMemW(c_ds,si);
+
+    PutMemW(c_es,di, tmp);
+
+    di += -4*DF +2;
+    si += -4*DF +2;
+
+    WriteWord(&wregs[DI],di);
+    WriteWord(&wregs[SI],si);
+}
+
+
+static INLINE2 void i_cmpsb(void)
+{
+    /* Opcode 0xa6 */
+
+    unsigned di = ReadWord(&wregs[DI]);
+    unsigned si = ReadWord(&wregs[SI]);
+    unsigned src = GetMemB(c_es, di);
+    unsigned tmp = GetMemB(c_ds, si);
+    unsigned tmp2 = tmp;
+    
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    di += -2*DF +1;
+    si += -2*DF +1;
+
+    WriteWord(&wregs[DI],di);
+    WriteWord(&wregs[SI],si);
+}
+
+
+static INLINE2 void i_cmpsw(void)
+{
+    /* Opcode 0xa7 */
+
+    unsigned di = ReadWord(&wregs[DI]);
+    unsigned si = ReadWord(&wregs[SI]);
+    unsigned src = GetMemW(c_es, di);
+    unsigned tmp = GetMemW(c_ds, si);
+    unsigned tmp2 = tmp;
+    
+    tmp -= src;
+
+    SetCFW_Sub(tmp,tmp2);
+    SetOFW_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFW(tmp);
+    SetSFW(tmp);
+    SetPF(tmp);
+
+    di += -4*DF +2;
+    si += -4*DF +2;
+
+    WriteWord(&wregs[DI],di);
+    WriteWord(&wregs[SI],si);
+}
+
+
+static INLINE2 void i_test_ald8(void)
+{
+    /* Opcode 0xa8 */
+
+    register unsigned tmp1 = (unsigned)*bregs[AL];
+    register unsigned tmp2 = (unsigned) GetMemInc(c_cs,ip);
+
+    tmp1 &= tmp2;
+    CF = OF = AF = 0;
+    SetZFB(tmp1);
+    SetSFB(tmp1);
+    SetPF(tmp1);
+}
+
+
+static INLINE2 void i_test_axd16(void)
+{
+    /* Opcode 0xa9 */
+
+    register unsigned tmp1 = (unsigned)ReadWord(&wregs[AX]);
+    register unsigned tmp2;
+    
+    tmp2 = (unsigned) GetMemInc(c_cs,ip);
+    tmp2 += GetMemInc(c_cs,ip) << 8;
+
+    tmp1 &= tmp2;
+    CF = OF = AF = 0;
+    SetZFW(tmp1);
+    SetSFW(tmp1);
+    SetPF(tmp1);
+}
+
+static INLINE2 void i_stosb(void)
+{
+    /* Opcode 0xaa */
+
+    register unsigned di = ReadWord(&wregs[DI]);
+
+    PutMemB(c_es,di,*bregs[AL]);
+    di += -2*DF +1;
+    WriteWord(&wregs[DI],di);
+}
+
+static INLINE2 void i_stosw(void)
+{
+    /* Opcode 0xab */
+
+    register unsigned di = ReadWord(&wregs[DI]);
+
+    PutMemB(c_es,di,*bregs[AL]);
+    PutMemB(c_es,di+1,*bregs[AH]);
+    di += -4*DF +2;;
+    WriteWord(&wregs[DI],di);
+}
+
+static INLINE2 void i_lodsb(void)
+{
+    /* Opcode 0xac */
+
+    register unsigned si = ReadWord(&wregs[SI]);
+
+    *bregs[AL] = GetMemB(c_ds,si);
+    si += -2*DF +1;
+    WriteWord(&wregs[SI],si);
+}
+
+static INLINE2 void i_lodsw(void)
+{
+    /* Opcode 0xad */
+
+    register unsigned si = ReadWord(&wregs[SI]);
+    register unsigned tmp = GetMemW(c_ds,si);
+
+    si +=  -4*DF+2;
+    WriteWord(&wregs[SI],si);
+    WriteWord(&wregs[AX],tmp);
+}
+    
+static INLINE2 void i_scasb(void)
+{
+    /* Opcode 0xae */
+
+    unsigned di = ReadWord(&wregs[DI]);
+    unsigned src = GetMemB(c_es, di);
+    unsigned tmp = *bregs[AL];
+    unsigned tmp2 = tmp;
+    
+    tmp -= src;
+
+    SetCFB_Sub(tmp,tmp2);
+    SetOFB_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFB(tmp);
+    SetSFB(tmp);
+    SetPF(tmp);
+
+    di += -2*DF +1;
+
+    WriteWord(&wregs[DI],di);
+}
+
+
+static INLINE2 void i_scasw(void)
+{
+    /* Opcode 0xaf */
+
+    unsigned di = ReadWord(&wregs[DI]);
+    unsigned src = GetMemW(c_es, di);
+    unsigned tmp = ReadWord(&wregs[AX]);
+    unsigned tmp2 = tmp;
+    
+    tmp -= src;
+
+    SetCFW_Sub(tmp,tmp2);
+    SetOFW_Sub(tmp,src,tmp2);
+    SetAF(tmp,src,tmp2);
+    SetZFW(tmp);
+    SetSFW(tmp);
+    SetPF(tmp);
+
+    di += -4*DF +2;
+
+    WriteWord(&wregs[DI],di);
+}
+
+static INLINE2 void i_mov_ald8(void)
+{
+    /* Opcode 0xb0 */
+
+    *bregs[AL] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_cld8(void)
+{
+    /* Opcode 0xb1 */
+
+    *bregs[CL] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_dld8(void)
+{
+    /* Opcode 0xb2 */
+
+    *bregs[DL] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_bld8(void)
+{
+    /* Opcode 0xb3 */
+
+    *bregs[BL] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_ahd8(void)
+{
+    /* Opcode 0xb4 */
+
+    *bregs[AH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_chd8(void)
+{
+    /* Opcode 0xb5 */
+
+    *bregs[CH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_dhd8(void)
+{
+    /* Opcode 0xb6 */
+
+    *bregs[DH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_bhd8(void)
+{
+    /* Opcode 0xb7 */
+
+    *bregs[BH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_axd16(void)
+{
+    /* Opcode 0xb8 */
+
+    *bregs[AL] = GetMemInc(c_cs,ip);
+    *bregs[AH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_cxd16(void)
+{
+    /* Opcode 0xb9 */
+
+    *bregs[CL] = GetMemInc(c_cs,ip);
+    *bregs[CH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_dxd16(void)
+{
+    /* Opcode 0xba */
+
+    *bregs[DL] = GetMemInc(c_cs,ip);
+    *bregs[DH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_bxd16(void)
+{
+    /* Opcode 0xbb */
+
+    *bregs[BL] = GetMemInc(c_cs,ip);
+    *bregs[BH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_spd16(void)
+{
+    /* Opcode 0xbc */
+
+    *bregs[SPL] = GetMemInc(c_cs,ip);
+    *bregs[SPH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_bpd16(void)
+{
+    /* Opcode 0xbd */
+
+    *bregs[BPL] = GetMemInc(c_cs,ip);
+    *bregs[BPH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_sid16(void)
+{
+    /* Opcode 0xbe */
+
+    *bregs[SIL] = GetMemInc(c_cs,ip);
+    *bregs[SIH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_did16(void)
+{
+    /* Opcode 0xbf */
+
+    *bregs[DIL] = GetMemInc(c_cs,ip);
+    *bregs[DIH] = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_ret_d16(void)
+{
+    /* Opcode 0xc2 */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    register unsigned count;
+
+    count = GetMemInc(c_cs,ip);
+    count += GetMemInc(c_cs,ip) << 8;
+
+    ip = GetMemW(c_stack,tmp);
+    tmp += count+2;
+    WriteWord(&wregs[SP],tmp);
+}
+
+
+static INLINE2 void i_ret(void)
+{
+    /* Opcode 0xc3 */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    ip = GetMemW(c_stack,tmp);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+}
+
+
+static INLINE2 void i_les_dw(void)
+{
+    /* Opcode 0xc4 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRegW(ModRM);
+    register WORD *src = GetModRMRMW(ModRM);
+    WORD tmp = ReadWord(src);
+
+    WriteWord(dest, tmp);
+    src += 1;
+    sregs[ES] = ReadWord(src);
+    c_es = SegToMemPtr(ES);
+}
+
+
+static INLINE2 void i_lds_dw(void)
+{
+    /* Opcode 0xc5 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRegW(ModRM);
+    register WORD *src = GetModRMRMW(ModRM);
+    WORD tmp = ReadWord(src);
+
+    WriteWord(dest,tmp);
+    src += 1;
+    sregs[DS] = ReadWord(src);
+    c_ds = SegToMemPtr(DS);
+}
+
+static INLINE2 void i_mov_bd8(void)
+{
+    /* Opcode 0xc6 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *dest = GetModRMRMB(ModRM);
+
+    *dest = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_mov_wd16(void)
+{
+    /* Opcode 0xc7 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
+
+    *dest++ = GetMemInc(c_cs,ip);
+    *dest = GetMemInc(c_cs,ip);
+}
+
+
+static INLINE2 void i_retf_d16(void)
+{
+    /* Opcode 0xca */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    register unsigned count;
+
+    count = GetMemInc(c_cs,ip);
+    count += GetMemInc(c_cs,ip) << 8;
+
+    ip = GetMemW(c_stack,tmp);
+    tmp = (WORD)(tmp+2);
+    sregs[CS] = GetMemW(c_stack,tmp);
+    c_cs = SegToMemPtr(CS);
+    tmp += count+2;
+    WriteWord(&wregs[SP],tmp);
+}
+
+
+static INLINE2 void i_retf(void)
+{
+    /* Opcode 0xcb */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    ip = GetMemW(c_stack,tmp);
+    tmp = (WORD)(tmp+2);
+    sregs[CS] = GetMemW(c_stack,tmp);
+    c_cs = SegToMemPtr(CS);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+}
+
+
+static INLINE2 void i_int3(void)
+{
+    /* Opcode 0xcc */
+
+    interrupt(3);
+}
+
+
+static INLINE2 void i_int(void)
+{
+    /* Opcode 0xcd */
+
+    unsigned int_num = GetMemInc(c_cs,ip);
+
+    interrupt(int_num);
+}
+
+
+static INLINE2 void i_into(void)
+{
+    /* Opcode 0xce */
+
+    if (OF)
+        interrupt(4);
+}
+
+
+static INLINE2 void i_iret(void)
+{
+    /* Opcode 0xcf */
+
+    register unsigned tmp = ReadWord(&wregs[SP]);
+    ip = GetMemW(c_stack,tmp);
+    tmp = (WORD)(tmp+2);
+    sregs[CS] = GetMemW(c_stack,tmp);
+    c_cs = SegToMemPtr(CS);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+
+    i_popf();
+#ifdef DEBUGGER
+    call_debugger(D_TRACE);
+#endif
+}    
+
+
+static INLINE2 void i_d0pre(void)
+{
+    /* Opcode 0xd0 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = *dest;
+    register unsigned tmp2 = tmp;
+
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ROL eb,1 */
+        CF = (tmp & 0x80) != 0;
+        *dest = (tmp << 1) + CF;
+        OF = !(!(tmp & 0x40)) != CF;
+        break;
+    case 0x08:  /* ROR eb,1 */
+        CF = (tmp & 0x01) != 0;
+        *dest = (tmp >> 1) + (CF << 7);
+        OF = !(!(tmp & 0x80)) != CF;
+        break;
+    case 0x10:  /* RCL eb,1 */
+        OF = (tmp ^ (tmp << 1)) & 0x80;
+        *dest = (tmp << 1) + CF;
+        CF = (tmp & 0x80) != 0;
+        break;
+    case 0x18:  /* RCR eb,1 */
+        *dest = (tmp >> 1) + (CF << 7);
+        OF = !(!(tmp & 0x80)) != CF;
+        CF = (tmp & 0x01) != 0;
+        break;
+    case 0x20:  /* SHL eb,1 */
+    case 0x30:
+        tmp += tmp;
+        
+        SetCFB_Add(tmp,tmp2);
+        SetOFB_Add(tmp,tmp2,tmp2);
+        AF = 1;
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x28:  /* SHR eb,1 */
+        CF = (tmp & 0x01) != 0;
+        OF = tmp & 0x80;
+        
+        tmp2 = tmp >> 1;
+        
+        SetSFB(tmp2);
+        SetPF(tmp2);
+        SetZFB(tmp2);
+        AF = 1;
+        *dest = (BYTE)tmp2;
+        break;
+    case 0x38:  /* SAR eb,1 */
+        CF = (tmp & 0x01) != 0;
+        OF = 0;
+        
+        tmp2 = (tmp >> 1) | (tmp & 0x80);
+        
+        SetSFB(tmp2);
+        SetPF(tmp2);
+        SetZFB(tmp2);
+        AF = 1;
+        *dest = (BYTE)tmp2;
+        break;
+    }
+}
+
+
+static INLINE2 void i_d1pre(void)
+{
+    /* Opcode 0xd1 */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp = ReadWord(dest);
+    register unsigned tmp2 = tmp;
+
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ROL ew,1 */
+        CF = (tmp & 0x8000) != 0;
+        tmp2 = (tmp << 1) + CF;
+        OF = !(!(tmp & 0x4000)) != CF;
+        WriteWord(dest,tmp2);
+        break;
+    case 0x08:  /* ROR ew,1 */
+        CF = (tmp & 0x01) != 0;
+        tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
+        OF = !(!(tmp & 0x8000)) != CF;
+        WriteWord(dest,tmp2);
+        break;
+    case 0x10:  /* RCL ew,1 */
+        tmp2 = (tmp << 1) + CF;
+        OF = (tmp ^ (tmp << 1)) & 0x8000;
+        CF = (tmp & 0x8000) != 0;
+        WriteWord(dest,tmp2);
+        break;
+    case 0x18:  /* RCR ew,1 */
+        tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
+        OF = !(!(tmp & 0x8000)) != CF;
+        CF = (tmp & 0x01) != 0;
+        WriteWord(dest,tmp2);
+        break;
+    case 0x20:  /* SHL ew,1 */
+    case 0x30:
+        tmp += tmp;
+        
+        SetCFW_Add(tmp,tmp2);
+        SetOFW_Add(tmp,tmp2,tmp2);
+        AF = 1;
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest,tmp);
+        break;
+    case 0x28:  /* SHR ew,1 */
+        CF = (tmp & 0x01) != 0;
+        OF = tmp & 0x8000;
+        
+        tmp2 = tmp >> 1;
+        
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        SetZFW(tmp2);
+        AF = 1;
+        WriteWord(dest,tmp2);
+        break;
+    case 0x38:  /* SAR ew,1 */
+        CF = (tmp & 0x01) != 0;
+        OF = 0;
+        
+        tmp2 = (tmp >> 1) | (tmp & 0x8000);
+        
+        SetSFW(tmp2);
+        SetPF(tmp2);
+        SetZFW(tmp2);
+        AF = 1;
+        WriteWord(dest,tmp2);
+        break;
+    }
+}
+
+
+static INLINE2 void i_d2pre(void)
+{
+    /* Opcode 0xd2 */
+
+    unsigned ModRM;
+    register BYTE *dest;
+    register unsigned tmp;
+    register unsigned tmp2;
+    unsigned count;
+
+    if (*bregs[CL] == 1)
+    {
+        i_d0pre();
+        D(printf("Skipping CL processing\n"););
+        return;
+    }
+
+    ModRM = GetMemInc(c_cs,ip);
+    dest = GetModRMRMB(ModRM);
+    tmp = (unsigned)*dest;
+    count = (unsigned)*bregs[CL];
+
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ROL eb,CL */
+        for (; count > 0; count--)
+        {
+            CF = (tmp & 0x80) != 0;
+            tmp = (tmp << 1) + CF;
+        }
+        *dest = (BYTE)tmp;
+        break;
+    case 0x08:  /* ROR eb,CL */
+        for (; count > 0; count--)
+        {
+            CF = (tmp & 0x01) != 0;
+            tmp = (tmp >> 1) + (CF << 7);
+        }
+        *dest = (BYTE)tmp;
+        break;
+    case 0x10:  /* RCL eb,CL */
+        for (; count > 0; count--)
+        {
+            tmp2 = CF;
+            CF = (tmp & 0x80) != 0;
+            tmp = (tmp << 1) + tmp2;
+        }
+        *dest = (BYTE)tmp;
+        break;
+    case 0x18:  /* RCR eb,CL */
+        for (; count > 0; count--)
+        {
+            tmp2 = (tmp >> 1) + (CF << 7);
+            CF = (tmp & 0x01) != 0;
+            tmp = tmp2;
+        }
+        *dest = (BYTE)tmp;
+        break;
+    case 0x20:
+    case 0x30:  /* SHL eb,CL */
+        if (count >= 9)
+        {
+            CF = 0;             /* Not sure about this... */
+            tmp = 0;
+        }
+        else
+        {
+            CF = ((tmp << (count-1)) & 0x80) != 0;
+            tmp <<= count;
+        }
+        
+        AF = 1;
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *dest = (BYTE)tmp;
+        break;
+    case 0x28:  /* SHR eb,CL */
+        if (count >= 9)
+        {
+            CF = 0;             /* Not sure about this... */
+            tmp = 0;
+        }
+        else
+        {
+            CF = ((tmp >> (count-1)) & 0x1) != 0;
+            tmp >>= count;
+        }
+        
+        SetSFB(tmp);
+        SetPF(tmp);
+        SetZFB(tmp);
+        AF = 1;
+        *dest = (BYTE)tmp;
+        break;
+    case 0x38:  /* SAR eb,CL */
+        tmp2 = tmp & 0x80;
+        CF = (((INT8)tmp >> (count-1)) & 0x01) != 0;        
+        for (; count > 0; count--)
+            tmp = (tmp >> 1) | tmp2;
+        
+        SetSFB(tmp);
+        SetPF(tmp);
+        SetZFB(tmp);
+        AF = 1;
+        *dest = (BYTE)tmp;
+        break;
+    }
+}
+
+
+static INLINE2 void i_d3pre(void)
+{
+    /* Opcode 0xd3 */
+
+    unsigned ModRM;
+    register WORD *dest;
+    register unsigned tmp;
+    register unsigned tmp2;
+    unsigned count;
+
+    if (*bregs[CL] == 1)
+    {
+        i_d1pre();
+        return;
+    }
+
+    ModRM = GetMemInc(c_cs,ip);
+    dest = GetModRMRMW(ModRM);
+    tmp = ReadWord(dest);
+    count = (unsigned)*bregs[CL];
+
+    switch (ModRM & 0x38)
+    {
+    case 0x00:  /* ROL ew,CL */
+        for (; count > 0; count--)
+        {
+            CF = (tmp & 0x8000) != 0;
+            tmp = (tmp << 1) + CF;
+        }
+        WriteWord(dest,tmp);
+        break;
+    case 0x08:  /* ROR ew,CL */
+        for (; count > 0; count--)
+        {
+            CF = (tmp & 0x01) != 0;
+            tmp = (tmp >> 1) + (CF << 15);
+        }
+        WriteWord(dest, tmp);
+        break;
+    case 0x10:  /* RCL ew,CL */
+        for (; count > 0; count--)
+        {
+            tmp2 = CF;
+            CF = (tmp & 0x8000) != 0;
+            tmp = (tmp << 1) + tmp2;
+        }
+        WriteWord(dest, tmp);
+        break;
+    case 0x18:  /* RCR ew,CL */
+        for (; count > 0; count--)
+        {
+            tmp2 = (tmp >> 1) + (CF << 15);
+            CF = (tmp & 0x01) != 0;
+            tmp = tmp2;
+        }
+        WriteWord(dest, tmp);
+        break;
+    case 0x20:
+    case 0x30:  /* SHL ew,CL */
+        if (count >= 17)
+        {
+            CF = 0;             /* Not sure about this... */
+            tmp = 0;
+        }
+        else
+        {
+            CF = ((tmp << (count-1)) & 0x8000) != 0;
+            tmp <<= count;
+        }
+        
+        AF = 1;
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(dest, tmp);
+        break;
+    case 0x28:  /* SHR ew,CL */
+        if (count >= 17)
+        {
+            CF = 0;             /* Not sure about this... */
+            tmp = 0;
+        }
+        else
+        {
+            CF = ((tmp >> (count-1)) & 0x1) != 0;
+            tmp >>= count;
+        }
+        
+        SetSFW(tmp);
+        SetPF(tmp);
+        SetZFW(tmp);
+        AF = 1;
+        WriteWord(dest, tmp);
+        break;
+    case 0x38:  /* SAR ew,CL */
+        tmp2 = tmp & 0x8000;
+        CF = (((INT16)tmp >> (count-1)) & 0x01) != 0;        
+        for (; count > 0; count--)
+            tmp = (tmp >> 1) | tmp2;
+        
+        SetSFW(tmp);
+        SetPF(tmp);
+        SetZFW(tmp);
+        AF = 1;
+        WriteWord(dest, tmp);
+        break;
+    }
+}
+
+static INLINE2 void i_aam(void)
+{
+    /* Opcode 0xd4 */
+    unsigned mult = GetMemInc(c_cs,ip);
+
+	if (mult == 0)
+        interrupt(0);
+    else
+    {
+        *bregs[AH] = *bregs[AL] / mult;
+        *bregs[AL] %= mult;
+
+        SetPF(*bregs[AL]);
+        SetZFW(wregs[AX]);
+        SetSFB(*bregs[AH]);
+    }
+}
+
+
+static INLINE2 void i_aad(void)
+{
+    /* Opcode 0xd5 */
+    unsigned mult = GetMemInc(c_cs,ip);
+
+    *bregs[AL] = *bregs[AH] * mult + *bregs[AL];
+    *bregs[AH] = 0;
+
+    SetPF(*bregs[AL]);
+    SetZFB(*bregs[AL]);
+    SF = 0;
+}
+
+static INLINE2 void i_xlat(void)
+{
+    /* Opcode 0xd7 */
+
+    unsigned dest = ReadWord(&wregs[BX])+*bregs[AL];
+    
+    *bregs[AL] = GetMemB(c_ds, dest);
+}
+
+static INLINE2 void i_escape(void)
+{
+    /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    GetModRMRMB(ModRM);
+}
+
+static INLINE2 void i_loopne(void)
+{
+    /* Opcode 0xe0 */
+
+    register int disp = (int)((INT8)GetMemInc(c_cs,ip));
+    register unsigned tmp = ReadWord(&wregs[CX])-1;
+
+    WriteWord(&wregs[CX],tmp);
+
+    if (!ZF && tmp) ip = (WORD)(ip+disp);
+}
+
+static INLINE2 void i_loope(void)
+{
+    /* Opcode 0xe1 */
+
+    register int disp = (int)((INT8)GetMemInc(c_cs,ip));
+    register unsigned tmp = ReadWord(&wregs[CX])-1;
+
+    WriteWord(&wregs[CX],tmp);
+
+    if (ZF && tmp) ip = (WORD)(ip+disp);
+}
+
+static INLINE2 void i_loop(void)
+{
+    /* Opcode 0xe2 */
+
+    register int disp = (int)((INT8)GetMemInc(c_cs,ip));
+    register unsigned tmp = ReadWord(&wregs[CX])-1;
+
+    WriteWord(&wregs[CX],tmp);
+
+    if (tmp) ip = (WORD)(ip+disp);
+}
+
+static INLINE2 void i_jcxz(void)
+{
+    /* Opcode 0xe3 */
+
+    register int disp = (int)((INT8)GetMemInc(c_cs,ip));
+    
+    if (wregs[CX] == 0)
+        ip = (WORD)(ip+disp);
+}
+
+static INLINE2 void i_inal(void)
+{
+    /* Opcode 0xe4 */
+
+    unsigned port = GetMemInc(c_cs,ip);
+
+    *bregs[AL] = read_port(port);
+}
+
+static INLINE2 void i_inax(void)
+{
+    /* Opcode 0xe5 */
+
+    unsigned port = GetMemInc(c_cs,ip);
+
+    *bregs[AL] = read_port(port);
+    *bregs[AH] = read_port(port+1);
+}
+    
+static INLINE2 void i_outal(void)
+{
+    /* Opcode 0xe6 */
+
+    unsigned port = GetMemInc(c_cs,ip);
+
+    write_port(port, *bregs[AL]);
+}
+
+static INLINE2 void i_outax(void)
+{
+    /* Opcode 0xe7 */
+
+    unsigned port = GetMemInc(c_cs,ip);
+
+    write_port(port, *bregs[AL]);
+    write_port(port+1, *bregs[AH]);
+}
+
+static INLINE2 void i_call_d16(void)
+{
+    /* Opcode 0xe8 */
+
+    register unsigned tmp;
+    register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+
+    tmp = GetMemInc(c_cs,ip);
+    tmp += GetMemInc(c_cs,ip) << 8;
+
+    PutMemW(c_stack,tmp1,ip);
+    WriteWord(&wregs[SP],tmp1);
+
+    ip = (WORD)(ip+(INT16)tmp);
+}
+
+
+static INLINE2 void i_jmp_d16(void)
+{
+    /* Opcode 0xe9 */
+
+    register int tmp = GetMemInc(c_cs,ip);
+    tmp += GetMemInc(c_cs,ip) << 8;
+
+    ip = (WORD)(ip+(INT16)tmp);
+}
+
+
+static INLINE2 void i_jmp_far(void)
+{
+    /* Opcode 0xea */
+
+    register unsigned tmp,tmp1;
+
+    tmp = GetMemInc(c_cs,ip);
+    tmp += GetMemInc(c_cs,ip) << 8;
+
+    tmp1 = GetMemInc(c_cs,ip);
+    tmp1 += GetMemInc(c_cs,ip) << 8;
+
+    sregs[CS] = (WORD)tmp1;
+    c_cs = SegToMemPtr(CS);
+    ip = (WORD)tmp;
+}
+
+
+static INLINE2 void i_jmp_d8(void)
+{
+    /* Opcode 0xeb */
+    register int tmp = (int)((INT8)GetMemInc(c_cs,ip));
+    ip = (WORD)(ip+tmp);
+}
+
+
+static INLINE2 void i_inaldx(void)
+{
+    /* Opcode 0xec */
+
+    *bregs[AL] = read_port(ReadWord(&wregs[DX]));
+}
+
+static INLINE2 void i_inaxdx(void)
+{
+    /* Opcode 0xed */
+
+    unsigned port = ReadWord(&wregs[DX]);
+
+    *bregs[AL] = read_port(port);
+    *bregs[AH] = read_port(port+1);
+}
+
+static INLINE2 void i_outdxal(void)
+{
+    /* Opcode 0xee */
+
+    write_port(ReadWord(&wregs[DX]), *bregs[AL]);
+}
+
+static INLINE2 void i_outdxax(void)
+{
+    /* Opcode 0xef */
+    unsigned port = ReadWord(&wregs[DX]);
+
+    write_port(port, *bregs[AL]);
+    write_port(port+1, *bregs[AH]);
+}
+
+static INLINE2 void i_lock(void)
+{
+    /* Opcode 0xf0 */
+}
+
+static INLINE2 void i_gobios(void)
+{
+    /* Opcode 0xf1 */
+
+    void (*routine)(void);
+    unsigned dest;
+    
+    if (GetMemInc(c_cs,ip) != 0xf1)
+        i_notdone();
+
+    dest = GetMemInc(c_cs,ip);	/* Must be re-coded sometime.... */
+    dest += (GetMemInc(c_cs,ip) << 8);
+    dest += (GetMemInc(c_cs,ip) << 16);
+    dest += (GetMemInc(c_cs,ip) << 24);
+
+    routine = (void (*)(void))dest;
+
+    routine();
+}
+
+
+static void rep(int flagval)
+{
+    /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
+       loop  to continue for CMPS and SCAS instructions. */
+
+    unsigned next = GetMemInc(c_cs,ip);
+    unsigned count = ReadWord(&wregs[CX]);
+
+    switch(next)
+    {
+    case 0x26:  /* ES: */
+        c_ss = c_ds = c_es;
+        rep(flagval);
+        c_ds = SegToMemPtr(DS);
+        c_ss = SegToMemPtr(SS);
+        break;
+    case 0x2e:  /* CS: */
+        c_ss = c_ds = c_cs;
+        rep(flagval);
+        c_ds = SegToMemPtr(DS);
+        c_ss = SegToMemPtr(SS);
+        break;
+    case 0x36:  /* SS: */
+        c_ds = c_ss;
+        rep(flagval);
+        c_ds = SegToMemPtr(DS);
+        break;
+    case 0x3e:  /* DS: */
+        c_ss = c_ds;
+        rep(flagval);
+        c_ss = SegToMemPtr(SS);
+        break;
+    case 0xa4:  /* REP MOVSB */
+        for (; count > 0; count--)
+            i_movsb();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xa5:  /* REP MOVSW */
+        for (; count > 0; count--)
+            i_movsw();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xa6:  /* REP(N)E CMPSB */
+        for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
+            i_cmpsb();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xa7:  /* REP(N)E CMPSW */
+        for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
+            i_cmpsw();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xaa:  /* REP STOSB */
+        for (; count > 0; count--)
+            i_stosb();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xab:  /* REP LODSW */
+        for (; count > 0; count--)
+            i_stosw();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xac:  /* REP LODSB */
+        for (; count > 0; count--)
+            i_lodsb();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xad:  /* REP LODSW */
+        for (; count > 0; count--)
+            i_lodsw();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xae:  /* REP(N)E SCASB */
+        for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
+            i_scasb();
+        WriteWord(&wregs[CX],count);
+        break;
+    case 0xaf:  /* REP(N)E SCASW */
+        for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
+            i_scasw();
+        WriteWord(&wregs[CX],count);
+        break;
+    default:
+        instruction[next]();
+    }
+}
+            
+
+static INLINE2 void i_repne(void)
+{
+    /* Opcode 0xf2 */
+
+    rep(0);
+}
+
+
+static INLINE2 void i_repe(void)
+{
+    /* Opcode 0xf3 */
+
+    rep(1);
+}
+
+
+static INLINE2 void i_cmc(void)
+{
+    /* Opcode 0xf5 */
+
+    CF = !CF;
+}
+
+
+static INLINE2 void i_f6pre(void)
+{
+	/* Opcode 0xf6 */
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *byte = GetModRMRMB(ModRM);
+    register unsigned tmp = (unsigned)*byte;
+    register unsigned tmp2;
+    
+    
+    switch (ModRM & 0x38)
+    {
+    case 0x00:	/* TEST Eb, data8 */
+    case 0x08:  /* ??? */
+        tmp &= GetMemInc(c_cs,ip);
+        
+        CF = OF = AF = 0;
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        break;
+        
+    case 0x10:	/* NOT Eb */
+        *byte = ~tmp;
+        break;
+        
+    case 0x18:	/* NEG Eb */
+        tmp2 = tmp;
+        tmp = -tmp;
+        
+        CF = (int)tmp2 > 0;
+        
+        SetAF(tmp,0,tmp2);
+        SetZFB(tmp);
+        SetSFB(tmp);
+        SetPF(tmp);
+        
+        *byte = tmp;
+        break;
+    case 0x20:	/* MUL AL, Eb */
+	{
+	    UINT16 result;
+	    tmp2 = *bregs[AL];
+        
+	    SetSFB(tmp2);
+	    SetPF(tmp2);
+        
+	    result = (UINT16)tmp2*tmp;
+	    WriteWord(&wregs[AX],(WORD)result);
+
+	    SetZFW(wregs[AX]);
+	    CF = OF = (*bregs[AH] != 0);
+	}
+        break;
+    case 0x28:	/* IMUL AL, Eb */
+	{
+	    INT16 result;
+        
+	    tmp2 = (unsigned)*bregs[AL];
+        
+	    SetSFB(tmp2);
+	    SetPF(tmp2);
+        
+	    result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
+	    WriteWord(&wregs[AX],(WORD)result);
+        
+	    SetZFW(wregs[AX]);
+        
+	    OF = (result >> 7 != 0) && (result >> 7 != -1);
+	    CF = !(!OF);
+	}
+        break;
+    case 0x30:	/* DIV AL, Ew */
+	{
+	    UINT16 result;
+        
+	    result = ReadWord(&wregs[AX]);
+        
+	    if (tmp)
+	    {
+            if ((result / tmp) > 0xff)
+            {
+                interrupt(0);
+                break;
+            }
+            else
+            {
+                *bregs[AH] = result % tmp;
+                *bregs[AL] = result / tmp;
+            }
+            
+	    }
+	    else
+	    {
+            interrupt(0);
+            break;
+	    }
+	}
+        break;
+    case 0x38:	/* IDIV AL, Ew */
+	{
+	    INT16 result;
+        
+	    result = ReadWord(&wregs[AX]);
+        
+	    if (tmp)
+	    {
+            tmp2 = result % (INT16)((INT8)tmp);
+            
+            if ((result /= (INT16)((INT8)tmp)) > 0xff)
+            {
+                interrupt(0);
+                break;
+            }
+            else
+            {
+                *bregs[AL] = result;
+                *bregs[AH] = tmp2;
+            }
+	    }
+	    else
+	    {
+            interrupt(0);
+            break;
+	    }
+	}
+        break;
+    }
+}
+
+
+static INLINE2 void i_f7pre(void)
+{
+	/* Opcode 0xf7 */
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    WORD *wrd = GetModRMRMW(ModRM);
+    register unsigned tmp = ReadWord(wrd);
+    register unsigned tmp2;
+    
+    
+    switch (ModRM & 0x38)
+    {
+    case 0x00:	/* TEST Ew, data16 */
+    case 0x08:  /* ??? */
+        tmp2 = GetMemInc(c_cs,ip);
+        tmp2 += GetMemInc(c_cs,ip) << 8;
+        
+        tmp &= tmp2;
+        
+        CF = OF = AF = 0;
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        break;
+        
+    case 0x10:	/* NOT Ew */
+        tmp = ~tmp;
+        WriteWord(wrd,tmp);
+        break;
+        
+    case 0x18:	/* NEG Ew */
+        tmp2 = tmp;
+        tmp = -tmp;
+        
+        CF = (int)tmp2 > 0;
+        
+        SetAF(tmp,0,tmp2);
+        SetZFW(tmp);
+        SetSFW(tmp);
+        SetPF(tmp);
+        
+        WriteWord(wrd,tmp);
+        break;
+    case 0x20:	/* MUL AX, Ew */
+	{
+	    UINT32 result;
+	    tmp2 = ReadWord(&wregs[AX]);
+        
+	    SetSFW(tmp2);
+	    SetPF(tmp2);
+
+	    result = (UINT32)tmp2*tmp;
+	    WriteWord(&wregs[AX],(WORD)result);
+        result >>= 16;
+	    WriteWord(&wregs[DX],result);
+
+	    SetZFW(wregs[AX] | wregs[DX]);
+	    CF = OF = (wregs[DX] != ChangeE(0));
+	}
+        break;
+        
+    case 0x28:	/* IMUL AX, Ew */
+	{
+	    INT32 result;
+        
+	    tmp2 = ReadWord(&wregs[AX]);
+        
+	    SetSFW(tmp2);
+	    SetPF(tmp2);
+        
+	    result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
+        OF = (result >> 15 != 0) && (result >> 15 != -1);
+
+	    WriteWord(&wregs[AX],(WORD)result);
+        result = (WORD)(result >> 16);
+	    WriteWord(&wregs[DX],result);
+
+	    SetZFW(wregs[AX] | wregs[DX]);
+        
+        CF = !(!OF);
+	}
+        break;
+    case 0x30:	/* DIV AX, Ew */
+	{
+	    UINT32 result;
+        
+	    result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
+        
+	    if (tmp)
+	    {
+            tmp2 = result % tmp;
+            if ((result / tmp) > 0xffff)
+            {
+                interrupt(0);
+                break;
+            }
+            else
+            {
+                WriteWord(&wregs[DX],tmp2);
+                result /= tmp;
+                WriteWord(&wregs[AX],result);
+            }
+	    }
+	    else
+	    {
+            interrupt(0);
+            break;
+	    }
+	}
+        break;
+    case 0x38:	/* IDIV AX, Ew */
+	{
+	    INT32 result;
+        
+	    result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
+        
+	    if (tmp)
+	    {
+            tmp2 = result % (INT32)((INT16)tmp);
+            
+            if ((result /= (INT32)((INT16)tmp)) > 0xffff)
+            {
+                interrupt(0);
+                break;
+            }
+            else
+            {
+                WriteWord(&wregs[AX],result);
+                WriteWord(&wregs[DX],tmp2);
+            }
+	    }
+	    else
+	    {
+            interrupt(0);
+            break;
+	    }
+	}
+        break;
+    }
+}
+
+
+static INLINE2 void i_clc(void)
+{
+    /* Opcode 0xf8 */
+
+    CF = 0;
+}
+
+
+static INLINE2 void i_stc(void)
+{
+	/* Opcode 0xf9 */
+
+	CF = 1;
+}
+
+
+static INLINE2 void i_cli(void)
+{
+    /* Opcode 0xfa */
+
+    IF = 0;
+}
+
+
+static INLINE2 void i_sti(void)
+{
+    /* Opcode 0xfb */
+
+    IF = 1;
+
+    if (int_blocked)
+    {
+        int_pending = int_blocked;
+        int_blocked = 0;
+        D2(printf("Unblocking interrupt\n"););
+    }
+}
+
+
+static INLINE2 void i_cld(void)
+{
+    /* Opcode 0xfc */
+
+    DF = 0;
+}
+
+
+static INLINE2 void i_std(void)
+{
+    /* Opcode 0xfd */
+
+    DF = 1;
+}
+
+
+static INLINE2 void i_fepre(void)
+{
+    /* Opcode 0xfe */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register BYTE *dest = GetModRMRMB(ModRM);
+    register unsigned tmp = *dest;
+    register unsigned tmp1;
+    
+    if ((ModRM & 0x38) == 0)
+    {
+        tmp1 = tmp+1;
+        SetOFB_Add(tmp1,tmp,1);
+    }
+    else
+    {
+        tmp1 = tmp-1;
+        SetOFB_Sub(tmp1,1,tmp);
+    }
+    
+    SetAF(tmp1,tmp,1);
+    SetZFB(tmp1);
+    SetSFB(tmp1);
+    SetPF(tmp1);
+    
+    *dest = (BYTE)tmp1;
+}
+
+
+static INLINE2 void i_ffpre(void)
+{
+    /* Opcode 0xff */
+
+    unsigned ModRM = GetMemInc(c_cs,ip);
+    register WORD *dest = GetModRMRMW(ModRM);
+    register unsigned tmp;
+    register unsigned tmp1;
+
+    switch(ModRM & 0x38)
+    {
+    case 0x00:  /* INC ew */
+        tmp = ReadWord(dest);
+        tmp1 = tmp+1;
+        
+        SetOFW_Add(tmp1,tmp,1);
+        SetAF(tmp1,tmp,1);
+        SetZFW(tmp1);
+        SetSFW(tmp1);
+        SetPF(tmp1);
+        
+        WriteWord(dest,(WORD)tmp1);
+        break;
+        
+    case 0x08:  /* DEC ew */
+        tmp = ReadWord(dest);
+        tmp1 = tmp-1;
+        
+        SetOFW_Sub(tmp1,1,tmp);
+        SetAF(tmp1,tmp,1);
+        SetZFW(tmp1);
+        SetSFW(tmp1);
+        SetPF(tmp1);
+        
+        WriteWord(dest,(WORD)tmp1);
+        break;
+        
+    case 0x10:  /* CALL ew */
+        tmp = ReadWord(dest);
+        tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+        
+        PutMemW(c_stack,tmp1,ip);
+        WriteWord(&wregs[SP],tmp1);
+        
+        ip = (WORD)tmp;
+        break;
+        
+    case 0x18:  /* CALL FAR ea */
+        tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+        
+        PutMemW(c_stack,tmp1,sregs[CS]);
+        tmp1 = (WORD)(tmp1-2);
+        PutMemW(c_stack,tmp1,ip);
+        WriteWord(&wregs[SP],tmp1);
+        
+        ip = ReadWord(dest);
+        dest++;
+        sregs[CS] = ReadWord(dest);
+        c_cs = SegToMemPtr(CS);
+        break;
+        
+    case 0x20:  /* JMP ea */
+        ip = ReadWord(dest);
+        break;
+        
+    case 0x28:  /* JMP FAR ea */
+        ip = ReadWord(dest);
+        dest++;
+        sregs[CS] = ReadWord(dest);
+        c_cs = SegToMemPtr(CS);
+        break;
+        
+    case 0x30:  /* PUSH ea */
+        tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
+        tmp = ReadWord(dest);
+        
+        PutMemW(c_stack,tmp1,tmp);
+        WriteWord(&wregs[SP],tmp1);
+        break;
+    }
+}
+
+
+static INLINE2 void i_notdone(void)
+{
+/*
+    fprintf(stderr,"Error: Unimplemented opcode %02X at cs:ip = %04X:%04X\n",
+		    c_cs[ip-1],sregs[CS],ip-1);
+    exit(1);
+*/
+	TCHAR msg[256];
+	wsprintf(msg, "Error: Unimplemented opcode %02X at cs:ip = %04X:%04X", c_cs[ip-1], sregs[CS], ip-1);
+	MessageBox(wonw32ctx->hWnd, msg, NULL, MB_OK);
+	wonw32ctx->running = FALSE;
+}
+
+
+void trap(void)
+{
+    instruction[GetMemInc(c_cs,ip)]();
+    interrupt(1);
+}
+
+
+void execute(void)
+{
+
+    c_cs = SegToMemPtr(CS);
+    c_ds = SegToMemPtr(DS);
+    c_es = SegToMemPtr(ES);
+    c_stack = c_ss = SegToMemPtr(SS);
+
+	if (int_pending)
+		external_int();
+
+#ifdef DEBUGGER
+        call_debugger(D_TRACE);
+#endif
+
+#if defined(BIGCASE) && !defined(RS6000)
+  /* Some compilers cannot handle large case statements */
+        switch(GetMemInc(c_cs,ip))
+        {
+        case 0x00:    i_add_br8(); break;
+        case 0x01:    i_add_wr16(); break;
+        case 0x02:    i_add_r8b(); break;
+        case 0x03:    i_add_r16w(); break;
+        case 0x04:    i_add_ald8(); break;
+        case 0x05:    i_add_axd16(); break;
+        case 0x06:    i_push_es(); break;
+        case 0x07:    i_pop_es(); break;
+        case 0x08:    i_or_br8(); break;
+        case 0x09:    i_or_wr16(); break;
+        case 0x0a:    i_or_r8b(); break;
+        case 0x0b:    i_or_r16w(); break;
+        case 0x0c:    i_or_ald8(); break;
+        case 0x0d:    i_or_axd16(); break;
+        case 0x0e:    i_push_cs(); break;
+        case 0x0f:    i_notdone(); break;
+        case 0x10:    i_adc_br8(); break;
+        case 0x11:    i_adc_wr16(); break;
+        case 0x12:    i_adc_r8b(); break;
+        case 0x13:    i_adc_r16w(); break;
+        case 0x14:    i_adc_ald8(); break;
+        case 0x15:    i_adc_axd16(); break;
+        case 0x16:    i_push_ss(); break;
+        case 0x17:    i_pop_ss(); break;
+        case 0x18:    i_sbb_br8(); break;
+        case 0x19:    i_sbb_wr16(); break;
+        case 0x1a:    i_sbb_r8b(); break;
+        case 0x1b:    i_sbb_r16w(); break;
+        case 0x1c:    i_sbb_ald8(); break;
+        case 0x1d:    i_sbb_axd16(); break;
+        case 0x1e:    i_push_ds(); break;
+        case 0x1f:    i_pop_ds(); break;
+        case 0x20:    i_and_br8(); break;
+        case 0x21:    i_and_wr16(); break;
+        case 0x22:    i_and_r8b(); break;
+        case 0x23:    i_and_r16w(); break;
+        case 0x24:    i_and_ald8(); break;
+        case 0x25:    i_and_axd16(); break;
+        case 0x26:    i_es(); break;
+        case 0x27:    i_daa(); break;
+        case 0x28:    i_sub_br8(); break;
+        case 0x29:    i_sub_wr16(); break;
+        case 0x2a:    i_sub_r8b(); break;
+        case 0x2b:    i_sub_r16w(); break;
+        case 0x2c:    i_sub_ald8(); break;
+        case 0x2d:    i_sub_axd16(); break;
+        case 0x2e:    i_cs(); break;
+        case 0x2f:    i_das(); break; // added
+        case 0x30:    i_xor_br8(); break;
+        case 0x31:    i_xor_wr16(); break;
+        case 0x32:    i_xor_r8b(); break;
+        case 0x33:    i_xor_r16w(); break;
+        case 0x34:    i_xor_ald8(); break;
+        case 0x35:    i_xor_axd16(); break;
+        case 0x36:    i_ss(); break;
+        case 0x37:    i_notdone(); break;
+        case 0x38:    i_cmp_br8(); break;
+        case 0x39:    i_cmp_wr16(); break;
+        case 0x3a:    i_cmp_r8b(); break;
+        case 0x3b:    i_cmp_r16w(); break;
+        case 0x3c:    i_cmp_ald8(); break;
+        case 0x3d:    i_cmp_axd16(); break;
+        case 0x3e:    i_ds(); break;
+        case 0x3f:    i_aas(); break; // added
+        case 0x40:    i_inc_ax(); break;
+        case 0x41:    i_inc_cx(); break;
+        case 0x42:    i_inc_dx(); break;
+        case 0x43:    i_inc_bx(); break;
+        case 0x44:    i_inc_sp(); break;
+        case 0x45:    i_inc_bp(); break;
+        case 0x46:    i_inc_si(); break;
+        case 0x47:    i_inc_di(); break;
+        case 0x48:    i_dec_ax(); break;
+        case 0x49:    i_dec_cx(); break;
+        case 0x4a:    i_dec_dx(); break;
+        case 0x4b:    i_dec_bx(); break;
+        case 0x4c:    i_dec_sp(); break;
+        case 0x4d:    i_dec_bp(); break;
+        case 0x4e:    i_dec_si(); break;
+        case 0x4f:    i_dec_di(); break;
+        case 0x50:    i_push_ax(); break;
+        case 0x51:    i_push_cx(); break;
+        case 0x52:    i_push_dx(); break;
+        case 0x53:    i_push_bx(); break;
+        case 0x54:    i_push_sp(); break;
+        case 0x55:    i_push_bp(); break;
+        case 0x56:    i_push_si(); break;
+        case 0x57:    i_push_di(); break;
+        case 0x58:    i_pop_ax(); break;
+        case 0x59:    i_pop_cx(); break;
+        case 0x5a:    i_pop_dx(); break;
+        case 0x5b:    i_pop_bx(); break;
+        case 0x5c:    i_pop_sp(); break;
+        case 0x5d:    i_pop_bp(); break;
+        case 0x5e:    i_pop_si(); break;
+        case 0x5f:    i_pop_di(); break;
+        case 0x60:    i_pusha(); break; /* added */
+        case 0x61:    i_popa(); break; /* added */
+        case 0x62:    i_bound(); break; /* added */
+        case 0x63:    i_notdone(); break;
+        case 0x64:    i_notdone(); break;
+        case 0x65:    i_notdone(); break;
+        case 0x66:    i_notdone(); break;
+        case 0x67:    i_notdone(); break;
+        case 0x68:    i_push_d16(); break; /* added */
+        case 0x69:    i_imul_d16(); break; /* added */
+        case 0x6a:    i_push_d8(); break; /* added */
+        case 0x6b:    i_imul_d8(); break; /* added */
+        case 0x6c:    i_insb(); break; /* added */
+        case 0x6d:    i_insw(); break; /* added */
+        case 0x6e:    i_outsb(); break; /* added */
+        case 0x6f:    i_outsw(); break; /* added */
+        case 0x70:    i_jo(); break;
+        case 0x71:    i_jno(); break;
+        case 0x72:    i_jb(); break;
+        case 0x73:    i_jnb(); break;
+        case 0x74:    i_jz(); break;
+        case 0x75:    i_jnz(); break;
+        case 0x76:    i_jbe(); break;
+        case 0x77:    i_jnbe(); break;
+        case 0x78:    i_js(); break;
+        case 0x79:    i_jns(); break;
+        case 0x7a:    i_jp(); break;
+        case 0x7b:    i_jnp(); break;
+        case 0x7c:    i_jl(); break;
+        case 0x7d:    i_jnl(); break;
+        case 0x7e:    i_jle(); break;
+        case 0x7f:    i_jnle(); break;
+        case 0x80:    i_80pre(); break;
+        case 0x81:    i_81pre(); break;
+        case 0x82:    i_notdone(); break;
+        case 0x83:    i_83pre(); break;
+        case 0x84:    i_test_br8(); break;
+        case 0x85:    i_test_wr16(); break;
+        case 0x86:    i_xchg_br8(); break;
+        case 0x87:    i_xchg_wr16(); break;
+        case 0x88:    i_mov_br8(); break;
+        case 0x89:    i_mov_wr16(); break;
+        case 0x8a:    i_mov_r8b(); break;
+        case 0x8b:    i_mov_r16w(); break;
+        case 0x8c:    i_mov_wsreg(); break;
+        case 0x8d:    i_lea(); break;
+        case 0x8e:    i_mov_sregw(); break;
+        case 0x8f:    i_popw(); break;
+        case 0x90:    i_nop(); break;
+        case 0x91:    i_xchg_axcx(); break;
+        case 0x92:    i_xchg_axdx(); break;
+        case 0x93:    i_xchg_axbx(); break;
+        case 0x94:    i_xchg_axsp(); break;
+        case 0x95:    i_xchg_axbp(); break;
+        case 0x96:    i_xchg_axsi(); break;
+        case 0x97:    i_xchg_axdi(); break;
+        case 0x98:    i_cbw(); break;
+        case 0x99:    i_cwd(); break;
+        case 0x9a:    i_call_far(); break;
+        case 0x9b:    i_wait(); break;
+        case 0x9c:    i_pushf(); break;
+        case 0x9d:    i_popf(); break;
+        case 0x9e:    i_sahf(); break;
+        case 0x9f:    i_lahf(); break;
+        case 0xa0:    i_mov_aldisp(); break;
+        case 0xa1:    i_mov_axdisp(); break;
+        case 0xa2:    i_mov_dispal(); break;
+        case 0xa3:    i_mov_dispax(); break;
+        case 0xa4:    i_movsb(); break;
+        case 0xa5:    i_movsw(); break;
+        case 0xa6:    i_cmpsb(); break;
+        case 0xa7:    i_cmpsw(); break;
+        case 0xa8:    i_test_ald8(); break;
+        case 0xa9:    i_test_axd16(); break;
+        case 0xaa:    i_stosb(); break;
+        case 0xab:    i_stosw(); break;
+        case 0xac:    i_lodsb(); break;
+        case 0xad:    i_lodsw(); break;
+        case 0xae:    i_scasb(); break;
+        case 0xaf:    i_scasw(); break;
+        case 0xb0:    i_mov_ald8(); break;
+        case 0xb1:    i_mov_cld8(); break;
+        case 0xb2:    i_mov_dld8(); break;
+        case 0xb3:    i_mov_bld8(); break;
+        case 0xb4:    i_mov_ahd8(); break;
+        case 0xb5:    i_mov_chd8(); break;
+        case 0xb6:    i_mov_dhd8(); break;
+        case 0xb7:    i_mov_bhd8(); break;
+        case 0xb8:    i_mov_axd16(); break;
+        case 0xb9:    i_mov_cxd16(); break;
+        case 0xba:    i_mov_dxd16(); break;
+        case 0xbb:    i_mov_bxd16(); break;
+        case 0xbc:    i_mov_spd16(); break;
+        case 0xbd:    i_mov_bpd16(); break;
+        case 0xbe:    i_mov_sid16(); break;
+        case 0xbf:    i_mov_did16(); break;
+        case 0xc0:    i_rotshft_bd8(); break; /* added */
+        case 0xc1:    i_rotshft_wd8(); break; /* added */
+        case 0xc2:    i_ret_d16(); break;
+        case 0xc3:    i_ret(); break;
+        case 0xc4:    i_les_dw(); break;
+        case 0xc5:    i_lds_dw(); break;
+        case 0xc6:    i_mov_bd8(); break;
+        case 0xc7:    i_mov_wd16(); break;
+        case 0xc8:    i_enter(); break; /* added */
+        case 0xc9:    i_leave(); break; /* added */
+        case 0xca:    i_retf_d16(); break;
+        case 0xcb:    i_retf(); break;
+        case 0xcc:    i_int3(); break;
+        case 0xcd:    i_int(); break;
+        case 0xce:    i_into(); break;
+        case 0xcf:    i_iret(); break;
+        case 0xd0:    i_d0pre(); break;
+        case 0xd1:    i_d1pre(); break;
+        case 0xd2:    i_d2pre(); break;
+        case 0xd3:    i_d3pre(); break;
+        case 0xd4:    i_aam(); break;
+        case 0xd5:    i_aad(); break;
+        case 0xd6:    i_notdone(); break;
+        case 0xd7:    i_xlat(); break;
+        case 0xd8:    i_escape(); break;
+        case 0xd9:    i_escape(); break;
+        case 0xda:    i_escape(); break;
+        case 0xdb:    i_escape(); break;
+        case 0xdc:    i_escape(); break;
+        case 0xdd:    i_escape(); break;
+        case 0xde:    i_escape(); break;
+        case 0xdf:    i_escape(); break;
+        case 0xe0:    i_loopne(); break;
+        case 0xe1:    i_loope(); break;
+        case 0xe2:    i_loop(); break;
+        case 0xe3:    i_jcxz(); break;
+        case 0xe4:    i_inal(); break;
+        case 0xe5:    i_inax(); break;
+        case 0xe6:    i_outal(); break;
+        case 0xe7:    i_outax(); break;
+        case 0xe8:    i_call_d16(); break;
+        case 0xe9:    i_jmp_d16(); break;
+        case 0xea:    i_jmp_far(); break;
+        case 0xeb:    i_jmp_d8(); break;
+        case 0xec:    i_inaldx(); break;
+        case 0xed:    i_inaxdx(); break;
+        case 0xee:    i_outdxal(); break;
+        case 0xef:    i_outdxax(); break;
+        case 0xf0:    i_lock(); break;
+        case 0xf1:    i_gobios(); break;
+        case 0xf2:    i_repne(); break;
+        case 0xf3:    i_repe(); break;
+        case 0xf4:    i_notdone(); break;
+        case 0xf5:    i_cmc(); break;
+        case 0xf6:    i_f6pre(); break;
+        case 0xf7:    i_f7pre(); break;
+        case 0xf8:    i_clc(); break;
+        case 0xf9:    i_stc(); break;
+        case 0xfa:    i_cli(); break;
+        case 0xfb:    i_sti(); break;
+        case 0xfc:    i_cld(); break;
+        case 0xfd:    i_std(); break;
+        case 0xfe:    i_fepre(); break;
+        case 0xff:    i_ffpre(); break;
+        };
+#else
+        instruction[GetMemInc(c_cs,ip)]();
+#endif
+}
+
+BYTE read_port(unsigned port) {
+  return 0;
+}
+
+void write_port(unsigned port, BYTE value) {
+
+}
+
+void disable() {
+
+}
+
+void enable() {
+
+}

+ 161 - 0
cpu/cpu.h

@@ -0,0 +1,161 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+/* This is CPU.H  it contains definitions for cpu.c */
+
+
+#ifndef CPU_H
+#define CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mytypes.h"
+
+#define AX 0
+#define CX 1
+#define DX 2
+#define BX 3
+#define SP 4
+#define BP 5
+#define SI 6
+#define DI 7
+
+#define AL 0
+#define CL 1
+#define DL 2
+#define BL 3
+#define AH 4
+#define CH 5
+#define DH 6
+#define BH 7
+
+#define SPL 8
+#define SPH 9
+#define BPL 10
+#define BPH 11
+#define SIL 12
+#define SIH 13
+#define DIL 14
+#define DIH 15
+
+
+#define ES 0
+#define CS 1
+#define SS 2
+#define DS 3
+
+
+/* parameter x = result, y = source 1, z = source 2 */
+
+#define SetCFB_Add(x,y) (CF = (BYTE)(x) < (BYTE)(y))
+#define SetCFW_Add(x,y) (CF = (WORD)(x) < (WORD)(y))
+#define SetCFB_Sub(y,z) (CF = (BYTE)(y) > (BYTE)(z))
+#define SetCFW_Sub(y,z) (CF = (WORD)(y) > (WORD)(z))
+#define SetZFB(x)	(ZF = !(BYTE)(x))
+#define SetZFW(x)	(ZF = !(WORD)(x))
+#define SetTF(x)	(TF = (x))
+#define SetIF(x)	(IF = (x))
+#define SetDF(x)	(DF = (x))
+#define SetAF(x,y,z)	(AF = ((x) ^ ((y) ^ (z))) & 0x10)
+#define SetPF(x)	    (PF = parity_table[(BYTE)(x)])
+#define SetOFW_Add(x,y,z)   (OF = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
+#define SetOFB_Add(x,y,z)   (OF = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
+#define SetOFW_Sub(x,y,z)   (OF = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
+#define SetOFB_Sub(x,y,z)   (OF = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
+#define SetSFW(x)	   (SF = (x) & 0x8000)
+#define SetSFB(x)	   (SF = (x) & 0x80)
+
+
+#define GetMemInc(Seg,Off) ((Seg)[(Off)++])
+
+#if defined(TEST) && defined(BSD386)
+#   define SegToMemPtr(Seg) (sregs[Seg] == 0xa000 ? (BYTE *)0xe00a0000 : \
+				sregs[Seg] == 0xb800 ? (BYTE *)0xe00b8000 : \
+					    &memory[sregs[Seg] << 4])
+#else
+#   define SegToMemPtr(Seg) (&memory[sregs[Seg] << 4])
+#endif
+
+
+#define PutMemB(Seg,Off,x) ((Seg)[(WORD)(Off)] = (BYTE)(x))
+#define GetMemB(Seg,Off) ((BYTE)(Seg)[(WORD)(Off)])
+
+#define CalcAll()
+
+#define CompressFlags() (WORD)(CF | (PF << 2) | (!(!AF) << 4) | (ZF << 6) \
+			    | (!(!SF) << 7) | (TF << 8) | (IF << 9) \
+			    | (DF << 10) | (!(!OF) << 11))
+
+#define ExpandFlags(f) \
+{ \
+      CF = (f) & 1; \
+      PF = ((f) & 4) == 4; \
+      AF = (f) & 16; \
+      ZF = ((f) & 64) == 64; \
+      SF = (f) & 128; \
+      TF = ((f) & 256) == 256; \
+      IF = ((f) & 512) == 512; \
+      DF = ((f) & 1024) == 1024; \
+      OF = (f) & 2048; \
+}
+
+
+/* ChangeE(x) changes x to little endian from the machine's natural endian
+    format and back again. Obviously there is nothing to do for little-endian
+    machines... */
+
+#if defined(LITTLE_ENDIAN)
+#   define ChangeE(x) (WORD)(x)
+#else
+#   define ChangeE(x) (WORD)(((x) << 8) | ((BYTE)((x) >> 8)))
+#endif
+
+#if defined(LITTLE_ENDIAN) && !defined(ALIGNED_ACCESS)
+#   define ReadWord(x) (*(x))
+#   define WriteWord(x,y) (*(x) = (y))
+#   define CopyWord(x,y) (*x = *y)
+#   define PutMemW(Seg,Off,x) (*(WORD *)((Seg)+(WORD)(Off)) = (WORD)(x))
+#   define GetMemW(Seg,Off) (*(WORD *)((Seg)+(WORD)(Off)))
+#else
+#   define ReadWord(x) ((WORD)(*((BYTE *)(x))) + ((WORD)(*((BYTE *)(x)+1)) << 8))
+#   define WriteWord(x,y) (*(BYTE *)(x) = (BYTE)(y), *((BYTE *)(x)+1) = (BYTE)((y) >> 8))
+#   define CopyWord(x,y) (*(BYTE *)(x) = *(BYTE *)(y), *((BYTE *)(x)+1) = *((BYTE *)(y)+1))
+#   define PutMemW(Seg,Off,x) (Seg[Off] = (BYTE)(x), Seg[(WORD)(Off)+1] = (BYTE)((x) >> 8))
+#   define GetMemW(Seg,Off) ((WORD)Seg[Off] + ((WORD)Seg[(WORD)(Off)+1] << 8))
+#endif
+
+extern WORD wregs[8];	    /* Always little-endian */
+extern BYTE *bregs[16];     /* Points to bytes within wregs[] */
+extern unsigned sregs[4];   /* Always native machine word order */
+
+extern unsigned ip;	     /* Always native machine word order */
+
+    /* All the byte flags will either be 1 or 0 */
+extern BYTE CF, PF, ZF, TF, IF, DF;
+
+    /* All the word flags may be either none-zero (true) or zero (false) */
+extern unsigned AF, OF, SF;
+
+extern BYTE *c_cs,*c_ds,*c_es,*c_ss,*c_stack;
+
+extern volatile int int_pending;
+extern volatile int int_blocked;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 84 - 0
cpu/global.h

@@ -0,0 +1,84 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+/* This is GLOBAL.H  It contains definitions for the program wide functions */
+
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mytypes.h"
+
+#ifdef ME
+#       include "uprotos.h"
+#endif
+
+#ifndef FALSE
+#    define FALSE 0
+#endif
+#ifndef TRUE
+#    define TRUE (!FALSE)
+#endif
+
+#define MEMORY_SIZE (1024*1024+65536)
+
+#ifdef INLINE_FUNCTIONS
+#    define INLINE inline
+#    define INLINE2 inline
+#else
+#    define INLINE
+#    define INLINE2
+#endif
+
+#ifdef DEBUG
+#   define D(x) x
+#else
+#   define D(x)
+#endif
+
+#ifdef DEBUG2
+#   define D2(x) x
+#else
+#   define D2(x)
+#endif
+
+#ifdef _HPUX_SOURCE
+#ifndef __hpux
+#define __hpux
+#endif
+#endif
+
+extern BYTE *memory;
+extern char *progname;
+
+void init_cpu(void);
+void execute(void);
+void exit_emu(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+
+

+ 0 - 0
cpu/hardware.c


+ 48 - 0
cpu/hardware.h

@@ -0,0 +1,48 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mytypes.h"
+
+#define PIC_TIMER    1
+#define PIC_KEYBOARD 2
+
+#define TICKSPERSEC (1193180.0/65536.0)
+
+int port60_buffer_ok(int);
+void put_scancode(BYTE *, int);
+void init_timer(void);
+
+void disable(void);
+void enable(void);
+
+void starttimer(void);
+void stoptimer(void);
+
+BYTE read_port(unsigned);
+void write_port(unsigned, BYTE);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 411 - 0
cpu/i186.h

@@ -0,0 +1,411 @@
+/* i186 instruction implement */
+
+static INLINE2 void i_pusha(void)
+{
+    /* Opcode 0x60 */
+
+	unsigned tmp;
+	unsigned tmp2;
+
+	tmp = (WORD)ReadWord(&wregs[SP]);
+	PushWordReg(AX);
+	PushWordReg(CX);
+	PushWordReg(DX);
+	PushWordReg(BX);
+	tmp2 = (WORD)ReadWord(&wregs[SP]);
+	tmp2 -= 2;
+	WriteWord(&wregs[SP], (WORD)tmp2);
+	PutMemW(c_stack, (WORD)tmp2, (WORD)tmp);
+	PushWordReg(BP);
+	PushWordReg(SI);
+	PushWordReg(DI);
+}
+
+static INLINE2 void i_popa(void)
+{
+	/* Opcode 0x61 */
+
+	unsigned tmp;
+
+	PopWordReg(DI);
+	PopWordReg(SI);
+	PopWordReg(BP);
+	tmp = (WORD)ReadWord(&wregs[SP]);
+	tmp += 2;
+	WriteWord(&wregs[SP], (WORD)tmp);
+	PopWordReg(BX);
+	PopWordReg(DX);
+	PopWordReg(CX);
+	PopWordReg(AX);
+}
+
+static INLINE2 void i_bound(void)
+{
+	/* Opcode 0x62 */
+
+	unsigned ModRM = (unsigned)GetMemInc(c_cs, ip);
+} 
+
+static INLINE2 void i_push_d16(void)
+{
+	/* Opcode 0x68 */
+	unsigned tmp1;
+	unsigned tmp2;
+
+	tmp1 = GetMemInc(c_cs, ip);
+	tmp1 |= GetMemInc(c_cs, ip) << 8;
+	tmp2 = (WORD)ReadWord(&wregs[SP]);
+	tmp2 -= 2;
+	WriteWord(&wregs[SP], (WORD)tmp2);
+	PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
+}
+
+static INLINE2 void i_imul_d16(void)
+{
+	/* Opcode 0x69 */
+	INT32 result;
+	unsigned tmp1;
+	unsigned tmp2;
+
+	unsigned ModRM = GetMemInc(c_cs, ip);
+	WORD *dest = GetModRMRegW(ModRM);
+	tmp1 = *(GetModRMRMW(ModRM));
+	tmp2 = (unsigned)GetMemInc(c_cs, ip);
+	tmp2 |= (unsigned)GetMemInc(c_cs, ip) << 8;
+
+	result = (INT16)(tmp1) * (INT16)(tmp2);
+
+	WriteWord(dest, result);
+	*dest = (INT16)result;
+
+	CF = OF = (result >> 16) > 0;
+}
+
+static INLINE2 void i_push_d8(void)
+{
+	/* Opcode 0x6a */
+	unsigned tmp1;
+	unsigned tmp2;
+
+	tmp1 = GetMemInc(c_cs, ip);
+	tmp2 = (WORD)ReadWord(&wregs[SP]);
+	tmp2 -= 2;
+	WriteWord(&wregs[SP], (WORD)tmp2);
+	PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
+}
+
+static INLINE2 void i_imul_d8(void)
+{
+	/* Opcode 0x6b */
+	INT32 result;
+	unsigned tmp1;
+	unsigned tmp2;
+
+	unsigned ModRM = GetMemInc(c_cs, ip);
+	WORD *dest = GetModRMRegW(ModRM);
+	tmp1 = *(GetModRMRMW(ModRM));
+	tmp2 = (unsigned)GetMemInc(c_cs, ip);
+
+	result = (INT16)(tmp1) * (INT16)(tmp2);
+
+	WriteWord(dest, result);
+	*dest = (INT16)result;
+
+	CF = OF = (result >> 16) > 0;
+}
+
+static INLINE2 void i_insb(void)
+{
+	/* Opcode 0x6c */
+	;
+}
+
+static INLINE2 void i_insw(void)
+{
+	/* Opcode 0x6d */
+	;
+}
+
+static INLINE2 void i_outsb(void)
+{
+	/* Opcode 0x6e */
+	;
+}
+
+static INLINE2 void i_outsw(void)
+{
+	/* Opcode 0x6f */
+	;
+}
+
+static INLINE2 void i_rotshft_bd8(void)
+{
+	/* Opcode 0xc0 */
+
+	unsigned ModRM = GetMemInc(c_cs, ip);
+	BYTE *dest = GetModRMRMB(ModRM);
+	unsigned tmp = *dest;
+	unsigned tmp2;
+	unsigned count = GetMemInc(c_cs, ip);
+	
+	switch(ModRM & 0x38) {
+	case 0x00: /* ROL r/m8, imm8 */
+		for(; count > 0; count--) {
+			CF = (tmp & 0x80) != 0;
+			tmp = (tmp << 1) + CF;
+		}
+		*dest = (BYTE)tmp;
+		break;
+	case 0x08: /* ROR r/m8, imm8 */
+		for(; count > 0; count--) {
+			CF = (tmp & 0x01) != 0;
+			tmp = (tmp >> 1) + (CF << 7);
+		}
+		*dest = (BYTE)tmp;
+		break;
+	case 0x10: /* RCL r/m8, imm8 */
+		for(; count > 0; count--) {
+			tmp2 = CF;
+			CF = (tmp & 0x80) != 0;
+			tmp = (tmp << 1) + tmp2;
+		}
+		*dest = (BYTE)tmp;
+		break;
+	case 0x18: /* RCR r/m8, imm8 */
+		for(; count > 0; count--) {
+			tmp2 = (tmp >> 1) + (CF << 7);
+			CF = (tmp & 0x01) != 0;
+			tmp = tmp2;
+		}
+		*dest = (BYTE)tmp;
+		break;
+	case 0x20: /* SHL r/m8, imm8 */
+		if(count >= 9) {
+			CF = 0;
+			tmp = 0;
+		} else {
+			CF = ((tmp << (count - 1)) & 0x80) != 0;
+			tmp <<= count;
+		}
+
+		AF = 1;
+		SetZFB(tmp);
+		SetSFB(tmp);
+		SetPF(tmp);
+
+		*dest = (BYTE)tmp;
+		break;
+	case 0x28: /* SHR r/m8, imm8 */
+		if(count >= 9) {
+			CF = 0;
+			tmp = 0;
+		} else {
+			CF = ((tmp >> (count - 1)) & 0x1) != 0;
+			tmp >>= count;
+		}
+
+		SetSFB(tmp);
+		SetPF(tmp);
+		SetZFB(tmp);
+		AF = 1;
+		*dest = (BYTE)tmp;
+		break;
+	case 0x38: /* SAR r/m8, imm8 */
+		tmp2 = tmp & 0x80;
+		CF = (((INT8)tmp >> (count - 1)) & 0x01) != 0;
+		for(; count > 0; count--)
+			tmp = (tmp >> 1) | tmp2;
+
+		SetSFB(tmp);
+		SetPF(tmp);
+		SetZFB(tmp);
+		AF = 1;
+		*dest = (BYTE)tmp;
+		break;
+
+	default:
+		break;
+	}
+}
+
+static INLINE2 void i_rotshft_wd8(void)
+{
+	/* Opcode 0xc1 */
+	unsigned ModRM = GetMemInc(c_cs, ip);
+	WORD *dest = GetModRMRMW(ModRM);
+	unsigned tmp = *dest;
+	unsigned tmp2;
+	unsigned count = GetMemInc(c_cs, ip);
+	
+	switch(ModRM & 0x38) {
+	case 0x00: /* ROL r/m16, imm8 */
+		for(; count > 0; count--) {
+			CF = (tmp & 0x80) != 0;
+			tmp = (tmp << 1) + CF;
+		}
+		*dest = (WORD)tmp;
+		break;
+	case 0x08: /* ROR r/m16, imm8 */
+		for(; count > 0; count--) {
+			CF = (tmp & 0x01) != 0;
+			tmp = (tmp >> 1) + (CF << 7);
+		}
+		*dest = (WORD)tmp;
+		break;
+	case 0x10: /* RCL r/m16, imm8 */
+		for(; count > 0; count--) {
+			tmp2 = CF;
+			CF = (tmp & 0x80) != 0;
+			tmp = (tmp << 1) + tmp2;
+		}
+		*dest = (WORD)tmp;
+		break;
+	case 0x18: /* RCR r/m16, imm8 */
+		for(; count > 0; count--) {
+			tmp2 = (tmp >> 1) + (CF << 7);
+			CF = (tmp & 0x01) != 0;
+			tmp = tmp2;
+		}
+		*dest = (WORD)tmp;
+		break;
+	case 0x20: /* SHL r/m16, imm8 */
+		if(count >= 9) {
+			CF = 0;
+			tmp = 0;
+		} else {
+			CF = ((tmp << (count - 1)) & 0x80) != 0;
+			tmp <<= count;
+		}
+
+		AF = 1;
+		SetZFB(tmp);
+		SetSFB(tmp);
+		SetPF(tmp);
+
+		*dest = (WORD)tmp;
+		break;
+	case 0x28: /* SHR r/m16, imm8 */
+		if(count >= 9) {
+			CF = 0;
+			tmp = 0;
+		} else {
+			CF = ((tmp >> (count - 1)) & 0x1) != 0;
+			tmp >>= count;
+		}
+
+		SetSFB(tmp);
+		SetPF(tmp);
+		SetZFB(tmp);
+		AF = 1;
+		*dest = (WORD)tmp;
+		break;
+	case 0x38: /* SAR r/m16, imm8 */
+		tmp2 = tmp & 0x80;
+		CF = (((INT16)tmp >> (count - 1)) & 0x01) != 0;
+		for(; count > 0; count--)
+			tmp = (tmp >> 1) | tmp2;
+
+		SetSFB(tmp);
+		SetPF(tmp);
+		SetZFB(tmp);
+		AF = 1;
+		*dest = (WORD)tmp;
+		break;
+	default:
+		break;
+	}
+}
+
+static INLINE2 void i_enter(void)
+{
+	/* Opcode 0xc8 */
+	unsigned size;
+	unsigned level;
+	unsigned tmp;
+	unsigned tmp2;
+	unsigned i;
+	
+
+	size = GetMemInc(c_cs, ip);
+	size |= GetMemInc(c_cs, ip) << 8;
+	level = GetMemInc(c_cs, ip);
+/*
+	PushWordReg(BP);
+	tmp = ReadWord(&wregs[SP]);
+	WriteWord(&wregs[BP], (WORD)tmp);
+	WriteWord(&wregs[SP], (WORD)(tmp - size));
+	for(i = 1; i < level; i++) {
+		tmp = GetMemW(c_stack, ReadWord(&wregs[BP]) - i * 2);
+		tmp2 = (WORD)(ReadWord(&wregs[SP]) - 2);
+		WriteWord(&wregs[SP], tmp2);
+		PutMemW(c_stack, tmp2, tmp);
+	}
+	if(level) {
+		PushWordReg(BP);
+	}
+	*/
+	level %= 32;
+	PushWordReg(BP);
+	tmp = (WORD)ReadWord(&wregs[SP]);
+
+	if(level > 0) {
+		for(i = 1; i < level; i++) {
+			tmp2 = (WORD)ReadWord(&wregs[BP]);
+			tmp2 -= 2;
+			WriteWord(&wregs[BP], (WORD)tmp2);
+			PushWordReg(BP);
+		}
+		tmp2 = (WORD)ReadWord(&wregs[SP]);
+		tmp2 -= 2;
+		WriteWord(&wregs[SP], (WORD)tmp2);
+		PutMemW(c_stack, tmp2, (WORD)tmp);
+	}
+
+	WriteWord(&wregs[BP], (WORD)tmp);
+	WriteWord(&wregs[SP], (WORD)(tmp - size));
+}
+
+static INLINE2 void i_leave(void)
+{
+	/* Opcode 0xc9 */
+	unsigned tmp;
+
+	tmp = ReadWord(&wregs[BP]);
+	WriteWord(&wregs[SP], (WORD)tmp);
+	PopWordReg(BP);
+}
+
+static INLINE void i_das(void)
+{
+	/* Opcode 0x2f */
+	unsigned tmp;
+
+	if(((*bregs[AL] & 0x0f) > 9) || AF) {
+		tmp = *bregs[AL] - 6;
+		*bregs[AL] = tmp;
+		CF = CF | ((tmp & 0x100) ? 1 : 0);
+		AF = 0x10;
+	} else {
+		AF = 0;
+	}
+	if((*bregs[AL] > 0x9f) || CF) {
+		*bregs[AL] = *bregs[AL] - 0x60;
+		CF = 1;
+	}
+}
+
+static INLINE void i_aas(void)
+{
+	/* Opcode 0x3f */
+
+	if(((*bregs[AL] & 0x0f) > 9) || AF) {
+		*bregs[AL] = (BYTE)(*bregs[AL] - 6);
+		*bregs[AH] = (BYTE)(*bregs[AH] - 1);
+		AF = 0x10;
+		CF = 1;
+	} else {
+		AF = 0;
+		CF = 0;
+	}
+	*bregs[AL] = *bregs[AL] & 0x0f;
+}

+ 545 - 0
cpu/instr.h

@@ -0,0 +1,545 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+/* This is INSTR.H  It contains the functions corresponding to each individual
+   instruction in the 80x86 set */
+
+/*
+  added 186 instruction by Tomoyuki 'ZRY' Nakano
+
+*/
+
+#ifndef INSTR_H
+#define INSTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static INLINE2 void i_add_br8(void);
+static INLINE2 void i_add_wr16(void);
+static INLINE2 void i_add_r8b(void);
+static INLINE2 void i_add_r16w(void);
+static INLINE2 void i_add_ald8(void);
+static INLINE2 void i_add_axd16(void);
+static INLINE2 void i_push_es(void);
+static INLINE2 void i_pop_es(void);
+static INLINE2 void i_or_br8(void);
+static INLINE2 void i_or_r8b(void);
+static INLINE2 void i_or_wr16(void);
+static INLINE2 void i_or_r16w(void);
+static INLINE2 void i_or_ald8(void);
+static INLINE2 void i_or_axd16(void);
+static INLINE2 void i_push_cs(void);
+static INLINE2 void i_adc_br8(void);
+static INLINE2 void i_adc_wr16(void);
+static INLINE2 void i_adc_r8b(void);
+static INLINE2 void i_adc_r16w(void);
+static INLINE2 void i_adc_ald8(void);
+static INLINE2 void i_adc_axd16(void);
+static INLINE2 void i_push_ss(void);
+static INLINE2 void i_pop_ss(void);
+static INLINE2 void i_sbb_br8(void);
+static INLINE2 void i_sbb_wr16(void);
+static INLINE2 void i_sbb_r8b(void);
+static INLINE2 void i_sbb_r16w(void);
+static INLINE2 void i_sbb_ald8(void);
+static INLINE2 void i_sbb_axd16(void);
+static INLINE2 void i_push_ds(void);
+static INLINE2 void i_pop_ds(void);
+static INLINE2 void i_and_br8(void);
+static INLINE2 void i_and_r8b(void);
+static INLINE2 void i_and_wr16(void);
+static INLINE2 void i_and_r16w(void);
+static INLINE2 void i_and_ald8(void);
+static INLINE2 void i_and_axd16(void);
+static INLINE2 void i_es(void);
+static INLINE2 void i_daa(void);
+static INLINE2 void i_sub_br8(void);
+static INLINE2 void i_sub_wr16(void);
+static INLINE2 void i_sub_r8b(void);
+static INLINE2 void i_sub_r16w(void);
+static INLINE2 void i_sub_ald8(void);
+static INLINE2 void i_sub_axd16(void);
+static INLINE2 void i_cs(void);
+static INLINE2 void i_xor_br8(void);
+static INLINE2 void i_xor_r8b(void);
+static INLINE2 void i_xor_wr16(void);
+static INLINE2 void i_xor_r16w(void);
+static INLINE2 void i_xor_ald8(void);
+static INLINE2 void i_xor_axd16(void);
+static INLINE2 void i_ss(void);
+static INLINE2 void i_cmp_br8(void);
+static INLINE2 void i_cmp_wr16(void);
+static INLINE2 void i_cmp_r8b(void);
+static INLINE2 void i_cmp_r16w(void);
+static INLINE2 void i_cmp_ald8(void);
+static INLINE2 void i_cmp_axd16(void);
+static INLINE2 void i_ds(void);
+static INLINE2 void i_inc_ax(void);
+static INLINE2 void i_inc_cx(void);
+static INLINE2 void i_inc_dx(void);
+static INLINE2 void i_inc_bx(void);
+static INLINE2 void i_inc_sp(void);
+static INLINE2 void i_inc_bp(void);
+static INLINE2 void i_inc_si(void);
+static INLINE2 void i_inc_di(void);
+static INLINE2 void i_dec_ax(void);
+static INLINE2 void i_dec_cx(void);
+static INLINE2 void i_dec_dx(void);
+static INLINE2 void i_dec_bx(void);
+static INLINE2 void i_dec_sp(void);
+static INLINE2 void i_dec_bp(void);
+static INLINE2 void i_dec_si(void);
+static INLINE2 void i_dec_di(void);
+static INLINE2 void i_push_ax(void);
+static INLINE2 void i_push_cx(void);
+static INLINE2 void i_push_dx(void);
+static INLINE2 void i_push_bx(void);
+static INLINE2 void i_push_sp(void);
+static INLINE2 void i_push_bp(void);
+static INLINE2 void i_push_si(void);
+static INLINE2 void i_push_di(void);
+static INLINE2 void i_pop_ax(void);
+static INLINE2 void i_pop_cx(void);
+static INLINE2 void i_pop_dx(void);
+static INLINE2 void i_pop_bx(void);
+static INLINE2 void i_pop_sp(void);
+static INLINE2 void i_pop_bp(void);
+static INLINE2 void i_pop_si(void);
+static INLINE2 void i_pop_di(void);
+static INLINE2 void i_jo(void);
+static INLINE2 void i_jno(void);
+static INLINE2 void i_jb(void);
+static INLINE2 void i_jnb(void);
+static INLINE2 void i_jz(void);
+static INLINE2 void i_jnz(void);
+static INLINE2 void i_jbe(void);
+static INLINE2 void i_jnbe(void);
+static INLINE2 void i_js(void);
+static INLINE2 void i_jns(void);
+static INLINE2 void i_jp(void);
+static INLINE2 void i_jnp(void);
+static INLINE2 void i_jl(void);
+static INLINE2 void i_jnl(void);
+static INLINE2 void i_jle(void);
+static INLINE2 void i_jnle(void);
+static INLINE2 void i_80pre(void);
+static INLINE2 void i_81pre(void);
+static INLINE2 void i_83pre(void);
+static INLINE2 void i_test_br8(void);
+static INLINE2 void i_test_wr16(void);
+static INLINE2 void i_xchg_br8(void);
+static INLINE2 void i_xchg_wr16(void);
+static INLINE2 void i_mov_br8(void);
+static INLINE2 void i_mov_r8b(void);
+static INLINE2 void i_mov_wr16(void);
+static INLINE2 void i_mov_r16w(void);
+static INLINE2 void i_mov_wsreg(void);
+static INLINE2 void i_lea(void);
+static INLINE2 void i_mov_sregw(void);
+static INLINE2 void i_notdone(void);
+static INLINE2 void i_popw(void);
+static INLINE2 void i_nop(void);
+static INLINE2 void i_xchg_axcx(void);
+static INLINE2 void i_xchg_axdx(void);
+static INLINE2 void i_xchg_axbx(void);
+static INLINE2 void i_xchg_axsp(void);
+static INLINE2 void i_xchg_axbp(void);
+static INLINE2 void i_xchg_axsi(void);
+static INLINE2 void i_xchg_axdi(void);
+static INLINE2 void i_cbw(void);
+static INLINE2 void i_cwd(void);
+static INLINE2 void i_call_far(void);
+static INLINE2 void i_pushf(void);
+static INLINE2 void i_popf(void);
+static INLINE2 void i_sahf(void);
+static INLINE2 void i_lahf(void);
+static INLINE2 void i_mov_aldisp(void);
+static INLINE2 void i_mov_axdisp(void);
+static INLINE2 void i_mov_dispal(void);
+static INLINE2 void i_mov_dispax(void);
+static INLINE2 void i_movsb(void);
+static INLINE2 void i_movsw(void);
+static INLINE2 void i_cmpsb(void);
+static INLINE2 void i_cmpsw(void);
+static INLINE2 void i_test_ald8(void);
+static INLINE2 void i_test_axd16(void);
+static INLINE2 void i_stosb(void);
+static INLINE2 void i_stosw(void);
+static INLINE2 void i_lodsb(void);
+static INLINE2 void i_lodsw(void);
+static INLINE2 void i_scasb(void);
+static INLINE2 void i_scasw(void);
+static INLINE2 void i_mov_ald8(void);
+static INLINE2 void i_mov_cld8(void);
+static INLINE2 void i_mov_dld8(void);
+static INLINE2 void i_mov_bld8(void);
+static INLINE2 void i_mov_ahd8(void);
+static INLINE2 void i_mov_chd8(void);
+static INLINE2 void i_mov_dhd8(void);
+static INLINE2 void i_mov_bhd8(void);
+static INLINE2 void i_mov_axd16(void);
+static INLINE2 void i_mov_cxd16(void);
+static INLINE2 void i_mov_dxd16(void);
+static INLINE2 void i_mov_bxd16(void);
+static INLINE2 void i_mov_spd16(void);
+static INLINE2 void i_mov_bpd16(void);
+static INLINE2 void i_mov_sid16(void);
+static INLINE2 void i_mov_did16(void);
+static INLINE2 void i_ret_d16(void);
+static INLINE2 void i_ret(void);
+static INLINE2 void i_les_dw(void);
+static INLINE2 void i_lds_dw(void);
+static INLINE2 void i_mov_bd8(void);
+static INLINE2 void i_mov_wd16(void);
+static INLINE2 void i_retf_d16(void);
+static INLINE2 void i_retf(void);
+static INLINE2 void i_int3(void);
+static INLINE2 void i_int(void);
+static INLINE2 void i_into(void);
+static INLINE2 void i_iret(void);
+static INLINE2 void i_d0pre(void);
+static INLINE2 void i_d1pre(void);
+static INLINE2 void i_d2pre(void);
+static INLINE2 void i_d3pre(void);
+static INLINE2 void i_aam(void);
+static INLINE2 void i_aad(void);
+static INLINE2 void i_xlat(void);
+static INLINE2 void i_escape(void);
+static INLINE2 void i_loopne(void);
+static INLINE2 void i_loope(void);
+static INLINE2 void i_loop(void);
+static INLINE2 void i_jcxz(void);
+static INLINE2 void i_inal(void);
+static INLINE2 void i_inax(void);
+static INLINE2 void i_outal(void);
+static INLINE2 void i_outax(void);
+static INLINE2 void i_call_d16(void);
+static INLINE2 void i_jmp_d16(void);
+static INLINE2 void i_jmp_far(void);
+static INLINE2 void i_jmp_d8(void);
+static INLINE2 void i_inaldx(void);
+static INLINE2 void i_inaxdx(void);
+static INLINE2 void i_outdxal(void);
+static INLINE2 void i_outdxax(void);
+static INLINE2 void i_lock(void);
+static INLINE2 void i_repne(void);
+static INLINE2 void i_repe(void);
+static INLINE2 void i_cmc(void);
+static INLINE2 void i_f6pre(void);
+static INLINE2 void i_f7pre(void);
+static INLINE2 void i_clc(void);
+static INLINE2 void i_stc(void);
+static INLINE2 void i_cli(void);
+static INLINE2 void i_sti(void);
+static INLINE2 void i_cld(void);
+static INLINE2 void i_std(void);
+static INLINE2 void i_fepre(void);
+static INLINE2 void i_ffpre(void);
+
+static INLINE2 void i_wait(void);
+static INLINE2 void i_gobios(void);
+
+/*
+ i186 instruction
+
+*/
+static INLINE2 void i_pusha(void);
+static INLINE2 void i_popa(void);
+static INLINE2 void i_bound(void);
+static INLINE2 void i_push_d16(void);
+static INLINE2 void i_imul_d16(void);
+static INLINE2 void i_push_d8(void);
+static INLINE2 void i_imul_d8(void);
+static INLINE2 void i_rotshft_bd8(void);
+static INLINE2 void i_rotshft_wd8(void);
+static INLINE2 void i_enter(void);
+static INLINE2 void i_leave(void);
+static INLINE2 void i_insb(void);
+static INLINE2 void i_insw(void);
+static INLINE2 void i_outsb(void);
+static INLINE2 void i_outsw(void);
+static INLINE2 void i_das(void);
+static INLINE2 void i_aas(void);
+
+
+
+void (*instruction[256])(void) =
+{
+    i_add_br8,          /* 0x00 */
+    i_add_wr16,         /* 0x01 */
+    i_add_r8b,          /* 0x02 */
+    i_add_r16w,         /* 0x03 */
+    i_add_ald8,         /* 0x04 */
+    i_add_axd16,        /* 0x05 */
+    i_push_es,          /* 0x06 */
+    i_pop_es,           /* 0x07 */
+    i_or_br8,           /* 0x08 */
+    i_or_wr16,          /* 0x09 */
+    i_or_r8b,           /* 0x0a */
+    i_or_r16w,          /* 0x0b */
+    i_or_ald8,          /* 0x0c */
+    i_or_axd16,         /* 0x0d */
+    i_push_cs,          /* 0x0e */
+    i_notdone,
+    i_adc_br8,          /* 0x10 */
+    i_adc_wr16,         /* 0x11 */
+    i_adc_r8b,          /* 0x12 */
+    i_adc_r16w,         /* 0x13 */
+    i_adc_ald8,         /* 0x14 */
+    i_adc_axd16,        /* 0x15 */
+    i_push_ss,          /* 0x16 */
+    i_pop_ss,           /* 0x17 */
+    i_sbb_br8,          /* 0x18 */
+    i_sbb_wr16,         /* 0x19 */
+    i_sbb_r8b,          /* 0x1a */
+    i_sbb_r16w,         /* 0x1b */
+    i_sbb_ald8,         /* 0x1c */
+    i_sbb_axd16,        /* 0x1d */
+    i_push_ds,          /* 0x1e */
+    i_pop_ds,           /* 0x1f */
+    i_and_br8,          /* 0x20 */
+    i_and_wr16,         /* 0x21 */
+    i_and_r8b,          /* 0x22 */
+    i_and_r16w,         /* 0x23 */
+    i_and_ald8,         /* 0x24 */
+    i_and_axd16,        /* 0x25 */
+    i_es,               /* 0x26 */
+    i_daa,              /* 0x27 */
+    i_sub_br8,          /* 0x28 */
+    i_sub_wr16,         /* 0x29 */
+    i_sub_r8b,          /* 0x2a */
+    i_sub_r16w,         /* 0x2b */
+    i_sub_ald8,         /* 0x2c */
+    i_sub_axd16,        /* 0x2d */
+    i_cs,               /* 0x2e */
+    i_das,				/* 0x2f */
+    i_xor_br8,          /* 0x30 */
+    i_xor_wr16,         /* 0x31 */
+    i_xor_r8b,          /* 0x32 */
+    i_xor_r16w,         /* 0x33 */
+    i_xor_ald8,         /* 0x34 */
+    i_xor_axd16,        /* 0x35 */
+    i_ss,               /* 0x36 */
+    i_notdone,
+    i_cmp_br8,          /* 0x38 */
+    i_cmp_wr16,         /* 0x39 */
+    i_cmp_r8b,          /* 0x3a */
+    i_cmp_r16w,         /* 0x3b */
+    i_cmp_ald8,         /* 0x3c */
+    i_cmp_axd16,        /* 0x3d */
+    i_ds,               /* 0x3e */
+    i_aas,				/* 0x3f */
+    i_inc_ax,           /* 0x40 */
+    i_inc_cx,           /* 0x41 */
+    i_inc_dx,           /* 0x42 */
+    i_inc_bx,           /* 0x43 */
+    i_inc_sp,           /* 0x44 */
+    i_inc_bp,           /* 0x45 */
+    i_inc_si,           /* 0x46 */
+    i_inc_di,           /* 0x47 */
+    i_dec_ax,           /* 0x48 */
+    i_dec_cx,           /* 0x49 */
+    i_dec_dx,           /* 0x4a */
+    i_dec_bx,           /* 0x4b */
+    i_dec_sp,           /* 0x4c */
+    i_dec_bp,           /* 0x4d */
+    i_dec_si,           /* 0x4e */
+    i_dec_di,           /* 0x4f */
+    i_push_ax,          /* 0x50 */
+    i_push_cx,          /* 0x51 */
+    i_push_dx,          /* 0x52 */
+    i_push_bx,          /* 0x53 */
+    i_push_sp,          /* 0x54 */
+    i_push_bp,          /* 0x55 */
+    i_push_si,          /* 0x56 */
+    i_push_di,          /* 0x57 */
+    i_pop_ax,           /* 0x58 */
+    i_pop_cx,           /* 0x59 */
+    i_pop_dx,           /* 0x5a */
+    i_pop_bx,           /* 0x5b */
+    i_pop_sp,           /* 0x5c */
+    i_pop_bp,           /* 0x5d */
+    i_pop_si,           /* 0x5e */
+    i_pop_di,           /* 0x5f */
+    i_pusha,			/* 0x60  added */
+    i_popa,				/* 0x61  added */
+    i_bound,			/* 0x62  added */
+    i_notdone,			/* 0x63 */
+    i_notdone,			/* 0x64 */
+    i_notdone,			/* 0x65 */
+    i_notdone,			/* 0x66 */
+    i_notdone,			/* 0x67 */
+    i_push_d16,			/* 0x68  added */
+    i_imul_d16,			/* 0x69  added */
+    i_push_d8,			/* 0x6a  added */
+    i_imul_d8,			/* 0x6b  added */
+    i_insb,				/* 0x6c  added */
+    i_insw,				/* 0x6d  added */
+    i_outsb,			/* 0x6e  added */
+    i_outsw,			/* 0x6f  added */
+    i_jo,               /* 0x70 */
+    i_jno,              /* 0x71 */
+    i_jb,               /* 0x72 */
+    i_jnb,              /* 0x73 */
+    i_jz,               /* 0x74 */
+    i_jnz,              /* 0x75 */
+    i_jbe,              /* 0x76 */
+    i_jnbe,             /* 0x77 */
+    i_js,               /* 0x78 */
+    i_jns,              /* 0x79 */
+    i_jp,               /* 0x7a */
+    i_jnp,              /* 0x7b */
+    i_jl,               /* 0x7c */
+    i_jnl,              /* 0x7d */
+    i_jle,              /* 0x7e */
+    i_jnle,             /* 0x7f */
+    i_80pre,            /* 0x80 */
+    i_81pre,            /* 0x81 */
+    i_notdone,
+    i_83pre,            /* 0x83 */
+    i_test_br8,         /* 0x84 */
+    i_test_wr16,        /* 0x85 */
+    i_xchg_br8,         /* 0x86 */
+    i_xchg_wr16,        /* 0x87 */
+    i_mov_br8,          /* 0x88 */
+    i_mov_wr16,         /* 0x89 */
+    i_mov_r8b,          /* 0x8a */
+    i_mov_r16w,         /* 0x8b */
+    i_mov_wsreg,        /* 0x8c */
+    i_lea,              /* 0x8d */
+    i_mov_sregw,        /* 0x8e */
+    i_popw,             /* 0x8f */
+    i_nop,              /* 0x90 */
+    i_xchg_axcx,        /* 0x91 */
+    i_xchg_axdx,        /* 0x92 */
+    i_xchg_axbx,        /* 0x93 */
+    i_xchg_axsp,        /* 0x94 */
+    i_xchg_axbp,        /* 0x95 */
+    i_xchg_axsi,        /* 0x97 */
+    i_xchg_axdi,        /* 0x97 */
+    i_cbw,              /* 0x98 */
+    i_cwd,              /* 0x99 */
+    i_call_far,         /* 0x9a */
+    i_wait,             /* 0x9b */
+    i_pushf,            /* 0x9c */
+    i_popf,             /* 0x9d */
+    i_sahf,             /* 0x9e */
+    i_lahf,             /* 0x9f */
+    i_mov_aldisp,       /* 0xa0 */
+    i_mov_axdisp,       /* 0xa1 */
+    i_mov_dispal,       /* 0xa2 */
+    i_mov_dispax,       /* 0xa3 */
+    i_movsb,            /* 0xa4 */
+    i_movsw,            /* 0xa5 */
+    i_cmpsb,            /* 0xa6 */
+    i_cmpsw,            /* 0xa7 */
+    i_test_ald8,        /* 0xa8 */
+    i_test_axd16,       /* 0xa9 */
+    i_stosb,            /* 0xaa */
+    i_stosw,            /* 0xab */
+    i_lodsb,            /* 0xac */
+    i_lodsw,            /* 0xad */
+    i_scasb,            /* 0xae */
+    i_scasw,            /* 0xaf */
+    i_mov_ald8,         /* 0xb0 */
+    i_mov_cld8,         /* 0xb1 */
+    i_mov_dld8,         /* 0xb2 */
+    i_mov_bld8,         /* 0xb3 */
+    i_mov_ahd8,         /* 0xb4 */
+    i_mov_chd8,         /* 0xb5 */
+    i_mov_dhd8,         /* 0xb6 */
+    i_mov_bhd8,         /* 0xb7 */
+    i_mov_axd16,        /* 0xb8 */
+    i_mov_cxd16,        /* 0xb9 */
+    i_mov_dxd16,        /* 0xba */
+    i_mov_bxd16,        /* 0xbb */
+    i_mov_spd16,        /* 0xbc */
+    i_mov_bpd16,        /* 0xbd */
+    i_mov_sid16,        /* 0xbe */
+    i_mov_did16,        /* 0xbf */
+    i_rotshft_bd8,		/* 0xc0  added */
+    i_rotshft_wd8,		/* 0xc1  added */
+    i_ret_d16,          /* 0xc2 */
+    i_ret,              /* 0xc3 */
+    i_les_dw,           /* 0xc4 */
+    i_lds_dw,           /* 0xc5 */
+    i_mov_bd8,          /* 0xc6 */
+    i_mov_wd16,         /* 0xc7 */
+    i_enter,			/* 0xc8  added */
+    i_leave,			/* 0xc9  added */
+    i_retf_d16,         /* 0xca */
+    i_retf,             /* 0xcb */
+    i_int3,             /* 0xcc */
+    i_int,              /* 0xcd */
+    i_into,             /* 0xce */
+    i_iret,             /* 0xcf */
+    i_d0pre,            /* 0xd0 */
+    i_d1pre,            /* 0xd1 */
+    i_d2pre,            /* 0xd2 */
+    i_d3pre,            /* 0xd3 */
+    i_aam,              /* 0xd4 */
+    i_aad,              /* 0xd5 */
+    i_notdone,
+    i_xlat,             /* 0xd7 */
+    i_escape,           /* 0xd8 */
+    i_escape,           /* 0xd9 */
+    i_escape,           /* 0xda */
+    i_escape,           /* 0xdb */
+    i_escape,           /* 0xdc */
+    i_escape,           /* 0xdd */
+    i_escape,           /* 0xde */
+    i_escape,           /* 0xdf */
+    i_loopne,           /* 0xe0 */
+    i_loope,            /* 0xe1 */
+    i_loop,             /* 0xe2 */
+    i_jcxz,             /* 0xe3 */
+    i_inal,             /* 0xe4 */
+    i_inax,             /* 0xe5 */
+    i_outal,            /* 0xe6 */
+    i_outax,            /* 0xe7 */
+    i_call_d16,         /* 0xe8 */
+    i_jmp_d16,          /* 0xe9 */
+    i_jmp_far,          /* 0xea */
+    i_jmp_d8,           /* 0xeb */
+    i_inaldx,           /* 0xec */
+    i_inaxdx,           /* 0xed */
+    i_outdxal,          /* 0xee */
+    i_outdxax,          /* 0xef */
+    i_lock,             /* 0xf0 */
+    i_gobios,           /* 0xf1 */
+    i_repne,            /* 0xf2 */
+    i_repe,             /* 0xf3 */
+    i_notdone,
+    i_cmc,              /* 0xf5 */
+    i_f6pre,            /* 0xf6 */
+    i_f7pre,            /* 0xf7 */
+    i_clc,              /* 0xf8 */
+    i_stc,              /* 0xf9 */
+    i_cli,              /* 0xfa */
+    i_sti,              /* 0xfb */
+    i_cld,              /* 0xfc */
+    i_std,              /* 0xfd */
+    i_fepre,            /* 0xfe */
+    i_ffpre             /* 0xff */
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 55 - 0
cpu/mytypes.h

@@ -0,0 +1,55 @@
+/****************************************************************************
+*                                                                           *
+*                            Third Year Project                             *
+*                                                                           *
+*                            An IBM PC Emulator                             *
+*                          For Unix and X Windows                           *
+*                                                                           *
+*                             By David Hedley                               *
+*                                                                           *
+*                                                                           *
+* This program is Copyrighted.  Consult the file COPYRIGHT for more details *
+*                                                                           *
+****************************************************************************/
+
+/* This is MYTYPES.H  It contains definitions for the basic types to ease
+   portability */
+
+
+#ifndef MYTYPES_H
+#define MYTYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef signed char INT8;
+typedef unsigned char UINT8;
+typedef signed short INT16;
+typedef unsigned short UINT16;
+
+#ifndef _WINDOWS
+
+typedef signed long INT32;
+typedef unsigned long UINT32;
+
+
+typedef UINT8 BYTE;
+typedef UINT16 WORD;
+typedef UINT32 DWORD;
+
+#else
+
+#include <windows.h>
+#define LITTLE_ENDIAN
+#define ALIGNED_ACCESS
+//#define BIGCASE
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 95 - 0
mingw/Makefile

@@ -0,0 +1,95 @@
+.SUFFIXES: .rc .res .ro .cpp .obj
+CC=e:/mingw/gcc-2.95.2/bin/gcc.exe
+CPP=e:/mingw/gcc-2.95.2/bin/g++.exe
+CFLAGS=-c -mno-cygwin -mwindows -mpentiumpro -Ie:/mingw/directx/include \
+	-DNDEBUG -DINT32=int \
+	-DUINT32=DWORD -D_WIN32 -D_WINDOWS -D_WIN32_WINNT=0x400 \
+	-DINLINE_FUNCTIONS -O9 -fvtable-thunks # -DSHOW_RENDERTIME 
+LDFLAGS=-O9 -mno-cygwin -mwindows 
+LIBS=-ldinput -lcomctl32 -lole32 -lwinmm
+RES=rc.exe
+GORC=e:/mingw/Gorcjorg/GORC.EXE
+
+WONX_OBJS=bank.o comm.o disp.o etc.o key.o sound.o \
+	system.o text.o timer.o UNIXTimer.o WonX.o \
+	WWDisplay.o WonXSerialPort.o WonXSystem.o \
+	WWText.o WWCharacter.o WWColorMap.o WWDisplay.o \
+	WWInterrupt.o WWLCDPanel.o WWPalette.o WWScreen.o \
+	WWSerialPort.o WWSprite.o WWText.o WWTextFonts.o \
+	WWTimer.o XDisplay.o
+
+CPU_OBJS=cpu.o hardware.o
+
+RESOURCES=MMage.obj
+
+MMAGE_OBJS=mmage.o preference.o UNIXcompat.o
+
+MMVM_OBJS=dispbios.o filesys.o kanjifont.o keybios.o \
+	 mmvm.o systembios.o textbios.o timerbios.o wwbios.o
+
+.c.o:
+	$(CC) $(CFLAGS) -o $@ $<
+.cpp.o:
+	$(CPP) $(CFLAGS) -o $@ $<
+.rc.res:
+	$(RES) -l0x411 -d"NDEBUG" -fo$@ -r $<
+.res.obj:
+	$(GORC) -o -fo$@ $<
+
+all: MMage.exe
+
+clean:
+	rm -f *.o *.obj *.res MMage.exe
+
+MMage.exe: $(WONX_OBJS) $(CPU_OBJS) $(RESOURCES) $(MMAGE_OBJS) $(MMVM_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(WONX_OBJS) $(CPU_OBJS) $(MMAGE_OBJS) $(MMVM_OBJS) $(RESOURCES) $(LIBS)
+
+bank.o: ../wonx/bank.c
+comm.o: ../wonx/comm.c
+disp.o: ../wonx/disp.c
+etc.o: ../wonx/etc.c
+key.o: ../wonx/key.c
+sound.o: ../wonx/sound.c
+system.o: ../wonx/system.c
+text.o: ../wonx/text.c
+timer.o: ../wonx/timer.c
+UNIXTimer.o: ../wonx/UNIXTimer.c
+WonX.o: ../wonx/WonX.c
+WonXDisplay.o: ../wonx/WonXDisplay.c
+WonXSerialPort.o: ../wonx/WonXSerialPort.c
+WonXSystem.o: ../wonx/WonXSystem.c
+WonXText.o: ../wonx/WonXText.c
+WWCharacter.o: ../wonx/WWCharacter.c
+WWColorMap.o: ../wonx/WWColorMap.c
+WWDisplay.o: ../wonx/WWDisplay.c
+WWInterrupt.o: ../wonx/WWInterrupt.c
+WWLCDPanel.o: ../wonx/WWLCDPanel.c
+WWPalette.o: ../wonx/WWPalette.c
+WWScreen.o: ../wonx/WWScreen.c
+WWSerialPort.o: ../wonx/WWSerialPort.c
+WWSprite.o: ../wonx/WWSprite.c
+WWText.o: ../wonx/WWText.c
+WWTextFonts.o: ../wonx/WWTextFonts.c
+WWTimer.o: ../wonx/WWTimer.c
+XDisplay.o: ../wonx/XDisplay.c
+
+cpu.o: ../cpu/cpu.c
+hardware.o: ../cpu/hardware.c
+
+MMage.obj: MMage.res
+
+MMage.res: ../resource/MMage.rc
+
+mmage.o: ../mmage/mmage.cpp
+preference.o: ../mmage/preference.cpp
+UNIXcompat.o: ../mmage/UNIXcompat.cpp
+
+dispbios.o: ../mmvm/dispbios.cpp
+filesys.o: ../mmvm/filesys.cpp
+kanjifont.o: ../mmvm/kanjifont.cpp
+keybios.o: ../mmvm/keybios.cpp
+mmvm.o: ../mmvm/mmvm.cpp
+systembios.o: ../mmvm/systembios.cpp
+textbios.o: ../mmvm/textbios.cpp
+timerbios.o: ../mmvm/timerbios.cpp
+wwbios.o: ../mmvm/wwbios.cpp

+ 38 - 0
mmage/UNIXcompat.cpp

@@ -0,0 +1,38 @@
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../wonx/UNIXTimerP.h"
+#include "../wonx/UNIXTimer.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+static _UNIXTimer ut;
+
+UNIXTimer UNIXTimer_Create(int auto_preset, int interval, void *parameter, UNIXTimerCallBack callback) {
+	return &ut;
+}
+
+UNIXTimer UNIXTimer_Destroy(UNIXTimer unix_timer) {
+	return NULL;
+}
+
+int UNIXTimer_Pause(UNIXTimer unix_timer) {
+	return 0;
+}
+
+int UNIXTimer_Unpause(UNIXTimer unix_timer) {
+	return 0;
+}
+
+int UNIXTimer_ON(UNIXTimer unix_timer) {
+	return 0;	
+}
+
+int UNIXTimer_OFF(UNIXTimer unix_timer) {
+	return 0;
+}

+ 1034 - 0
mmage/mmage.cpp

@@ -0,0 +1,1034 @@
+// WonW32.cpp : DLL アプリケーション用のエントリ ポイントを定義します。
+//
+
+//#define SHOW_RENDERTIME
+#define INITGUID
+
+#include "mmage.h"
+
+#include <windows.h>
+#include <commctrl.h>
+#include <tchar.h>
+#include <ctype.h>
+
+#define DIRECTDRAW_VERSION 0x0500
+#define DIRECTINPUT_VERSION 0x0500
+
+#include <ddraw.h>
+#include <dinput.h>
+
+#include "../resource/resource.h"
+#include "preference.h"
+#include "../mmvm/mmvm.h"
+
+extern "C" {
+#include "../wonx/wonx.h"
+#include "../wonx/wonxdisplay.h"
+#include "../wonx/xdisplay.h"
+#include "../wonx/xdisplayp.h"
+#include "../wonx/wwlcdpanel.h"
+
+#include "../cpu/mytypes.h"
+#include "../cpu/global.h"
+#include "../cpu/cpu.h"
+}
+
+typedef struct {
+	WonXDisplay wonx_display;
+	XDisplay x_display;
+	WWLCDPanel ww_lcd_panel;
+	WWScreen ww_screen[2];
+	WWDisplay ww_display;
+} WONXOBJECT, *LPWONXOBJECT;
+
+
+#define MAX_LOADSTRING 100
+
+static WONW32CONTEXT context;
+static WONXOBJECT wonxobject;
+LPWONW32CONTEXT wonw32ctx = &context;
+static LPWONXOBJECT wonxobj = &wonxobject;
+static HBITMAP titlebmp;
+static HWND statusbar;
+#define LCD_SLEEP 0
+#define LCD_VERTICAL 1
+#define LCD_HORIZONTAL 2
+#define LCD_AUX1 3
+#define LCD_AUX2 4
+#define LCD_AUX3 5
+static HICON lcdseg[6][2];
+
+BOOL ddInit;
+static LPDIRECTDRAW lpDD;
+static LPDIRECTDRAWSURFACE lpDDSPrimary;
+static LPDIRECTDRAWSURFACE screen[2];
+static LPDIRECTDRAWCLIPPER lpClip;
+#define COLORKEY (RGB(0x00, 0x00, 0x00))
+#define SafeRelease(x) if (x) { x->Release(); x=NULL;}
+
+extern "C" {
+extern LPDIRECTINPUTDEVICE lpDIDevice;
+}
+LPDIRECTINPUT lpDI;
+LPDIRECTINPUTDEVICE lpDIDevice;
+
+static COLORREF w32colors[] = {
+	COLORKEY,
+	RGB(0xff, 0xff, 0xff),
+	RGB(0xef, 0xef, 0xef),
+	RGB(0xdf, 0xdf, 0xdf),
+	RGB(0xcf, 0xcf, 0xcf),
+	RGB(0xbf, 0xbf, 0xbf),
+	RGB(0xaf, 0xaf, 0xaf),
+	RGB(0x9f, 0x9f, 0x9f),
+	RGB(0x8f, 0x8f, 0x8f),
+	RGB(0x7f, 0x7f, 0x7f),
+	RGB(0x6f, 0x6f, 0x6f),
+	RGB(0x5f, 0x5f, 0x5f),
+	RGB(0x4f, 0x4f, 0x4f),
+	RGB(0x3f, 0x3f, 0x3f),
+	RGB(0x2f, 0x2f, 0x2f),
+	RGB(0x1f, 0x1f, 0x1f),
+	RGB(0x0f, 0x0f, 0x0f),
+};
+
+static BYTE ddclrs[17][4];
+static BYTE ddclrkey[4];
+static int bytesPerPixel;
+static LONG pitch[2];
+
+static TCHAR szTitle[MAX_LOADSTRING];				// タイトル バー テキスト
+static TCHAR szWindowClass[MAX_LOADSTRING];			// タイトル バー テキスト
+
+static ATOM			MyRegisterClass( HINSTANCE hInstance );
+static BOOL			InitInstance( HINSTANCE, int );
+static LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
+static LRESULT CALLBACK	About( HWND, UINT, WPARAM, LPARAM );
+static LRESULT CALLBACK	License( HWND, UINT, WPARAM, LPARAM );
+
+
+static void W32Display_DrawLCDWindow(HWND hWnd, WonXDisplay display);
+static void DrawScreen(LPBYTE surfm, int screenno, LONG pitch);
+static void DrawSprite(LPBYTE surfm, WWSprite sprite, LONG pitch);
+static BOOL InitDDraw();
+static BOOL InitDInput();
+static int GetMaskInfo(DWORD bitmask, int *lpShift);
+static void SetWindowSize();
+
+int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
+	MSG msg;
+	HACCEL hAccelTable;
+	int i, skip = 0;
+	int drawline;
+	DDSURFACEDESC lockedSurface[2];
+	RECT dr;
+	RECT sr[2];
+	DDBLTFX ddbltfx;
+
+	GetCurrentDirectory(MAX_PATH, mmconfig->workingdir);
+	LoadConfig();
+
+	if(!CreateVM())
+		return FALSE;
+
+	if (!WonX_IsCreated())
+		WonX_Create();
+
+	wonxobj->wonx_display = WonX_GetWonXDisplay();
+	wonxobj->x_display = WonXDisplay_GetXDisplay(wonxobj->wonx_display);
+	wonxobj->ww_display = WonXDisplay_GetWWDisplay(wonxobj->wonx_display);
+	wonxobj->ww_lcd_panel = WWDisplay_GetLCDPanel(wonxobj->ww_display);
+	wonxobj->ww_screen[0] = WWDisplay_GetScreen(wonxobj->ww_display, 0);
+	wonxobj->ww_screen[1] = WWDisplay_GetScreen(wonxobj->ww_display, 1);
+
+	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
+	LoadString(hInstance, IDC_MMAGE, szWindowClass, MAX_LOADSTRING);
+	MyRegisterClass( hInstance );
+	if( !InitInstance( hInstance, nCmdShow ) ) 
+	{
+		return FALSE;
+	}
+
+	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MMAGE);
+
+	ddInit = InitDDraw();
+	if(!ddInit) {
+		MessageBox(wonw32ctx->hWnd, "DirectDraw の初期化に失敗しました。", NULL, MB_OK);
+		return FALSE;
+	}
+	if(!InitDInput()) {
+		MessageBox(wonw32ctx->hWnd, "DirectInput の初期化に失敗しました。", NULL, MB_OK);
+		return TRUE;
+	}
+ 
+	wonw32ctx->syncperiod = 1000/75;
+	wonw32ctx->syncevent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	wonw32ctx->running = FALSE;
+	wonw32ctx->loaded = FALSE;
+
+	XDisplay_SetColorMapPrint(wonxobj->x_display, 0);
+	XDisplay_SetPalettePrint(wonxobj->x_display, 0);
+	XDisplay_SetCharacterPrint(wonxobj->x_display, 0);
+	XDisplay_SetSpritePrint(wonxobj->x_display, 0);
+
+	wonw32ctx->title = CreateCompatibleDC(GetDC(wonw32ctx->hWnd));
+	titlebmp = (HBITMAP)LoadBitmap(wonw32ctx->hInst, MAKEINTRESOURCE(IDB_TITLE));
+	SelectObject(wonw32ctx->title, titlebmp);
+
+	InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
+	UpdateWindow(wonw32ctx->hWnd);
+
+	lockedSurface[0].dwSize = sizeof(lockedSurface[0]);
+	lockedSurface[1].dwSize = sizeof(lockedSurface[1]);
+
+	if(lstrlen(lpCmdLine)) {
+		LPTSTR str;
+		TCHAR filename[MAX_PATH + 1];
+		BOOL quote = FALSE;
+
+		str = lpCmdLine;
+		i = 0;
+		while(*str) {
+			if(_istspace(*str) && !quote) {
+				*str = TEXT('\0');
+				str++;
+				break;
+			} else if(quote && (*str == TEXT('\"') || *str == TEXT('\''))) {
+				quote = FALSE;
+			} else if(!quote && (*str == TEXT('\"') || *str == TEXT('\''))) {
+				quote = TRUE;
+			} else {
+				filename[i] = *str;
+				i++;
+			}
+			str++;
+		}
+		filename[i] = TEXT('\0');
+		OpenAndRun(filename, str);
+	}
+
+	DragAcceptFiles(wonw32ctx->hWnd,TRUE);
+
+	drawline = 0;
+	ZeroMemory(&ddbltfx, sizeof(ddbltfx));
+	ddbltfx.dwSize = sizeof(ddbltfx);
+	sr[MMCONFIG_HORIZONTAL].top = sr[MMCONFIG_HORIZONTAL].left = 0;
+	sr[MMCONFIG_HORIZONTAL].right = wonw32ctx->ww_lcd_width;
+	sr[MMCONFIG_HORIZONTAL].bottom = wonw32ctx->ww_lcd_height;
+	sr[MMCONFIG_VERTICAL].top = sr[MMCONFIG_VERTICAL].left = 0;
+	sr[MMCONFIG_VERTICAL].right = wonw32ctx->ww_lcd_height;
+	sr[MMCONFIG_VERTICAL].bottom = wonw32ctx->ww_lcd_width;
+
+#ifdef SHOW_RENDERTIME
+	DWORD oldt, t;
+	BOOL showrt = TRUE;
+	TCHAR rtmsg[256];
+#endif
+
+	// メイン メッセージ ループ:
+	while(TRUE) {
+		WWSprite sprite;
+		POINT p;
+		LPBYTE border;
+
+		// ウィンドウがアクティブでないとき
+		if(!wonw32ctx->active || (wonw32ctx->active && !wonw32ctx->running)) {
+			if(GetMessage(&msg, NULL, 0, 0)) {
+				if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) {
+					TranslateMessage( &msg );
+					DispatchMessage( &msg );
+				}
+			}
+			if(msg.message == WM_QUIT)
+				break;
+
+			continue;
+		}
+
+		// ウィンドウがアクティブなとき
+		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+			if(msg.message == WM_QUIT)
+				break;
+
+			if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) {
+				TranslateMessage( &msg );
+				DispatchMessage( &msg );
+			}
+
+		} else {
+#ifdef SHOW_RENDERTIME
+			oldt = timeGetTime();
+#endif
+			screen[1]->Lock(NULL, &lockedSurface[0], DDLOCK_WAIT|DDLOCK_NOSYSLOCK, NULL);
+			pitch[0] = lockedSurface[0].lPitch;
+
+			screen[2]->Lock(NULL, &lockedSurface[1], DDLOCK_WAIT|DDLOCK_NOSYSLOCK, NULL);
+			pitch[1] = lockedSurface[1].lPitch;
+
+			DrawScreen((BYTE *)lockedSurface[0].lpSurface, 0, pitch[0]);
+			DrawScreen((BYTE *)lockedSurface[1].lpSurface, 1, pitch[1]);
+
+			if(WWDisplay_GetSpriteEnable(wonxobj->ww_display)) {
+				for(i = WWDisplay_GetSpriteCount(wonxobj->ww_display) - 1; i >= 0; i--) {
+					sprite = WWDisplay_GetSprite(wonxobj->ww_display, i + WWDisplay_GetSpriteStart(wonxobj->ww_display));
+					if(!WWSprite_GetPriority(sprite)) {
+						DrawSprite((BYTE *)lockedSurface[0].lpSurface, sprite, pitch[0]);
+					} else {
+						DrawSprite((BYTE *)lockedSurface[1].lpSurface, sprite, pitch[1]);
+					}
+				}
+			}
+
+			screen[1]->Unlock(lockedSurface[0].lpSurface);
+			screen[2]->Unlock(lockedSurface[1].lpSurface);
+
+			border = (LPBYTE)&ddclrs[WWColorMap_GetLCDColor(WWDisplay_GetColorMap(wonxobj->ww_display), WWDisplay_GetBorder(wonxobj->ww_display)) + 1];
+
+			ddbltfx.dwFillColor =   (border[0] << 24)
+				                  | (border[1] << 16)
+								  | (border[2] <<  8)
+								  |  border[3];
+
+			screen[0]->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &ddbltfx);
+			screen[0]->BltFast(0, 0, screen[1], NULL, DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
+			screen[0]->BltFast(0, 0, screen[2], NULL, DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
+
+			ZeroMemory(&p, sizeof(p));
+			ClientToScreen(wonw32ctx->hWnd, &p);
+			dr.left = p.x;
+			dr.top = p.y;
+			dr.right = dr.left + wonw32ctx->winwidth + 1;
+			dr.bottom = dr.top + wonw32ctx->winheight + 1;
+			lpDDSPrimary->Blt(&dr, screen[0], &sr[mmconfig->horizontal], DDBLT_WAIT, NULL);
+			PulseEvent(wonw32ctx->syncevent);
+#ifdef SHOW_RENDERTIME
+			if(showrt) {
+				t = timeGetTime();
+				wsprintf(rtmsg, TEXT("1 フレーム描画にかかった時間は %d msec"), t - oldt);
+				MessageBox(wonw32ctx->hWnd, rtmsg, TEXT("描画時間"), MB_OK);
+				showrt = FALSE;
+			}
+#endif
+		}
+	}
+
+	if(wonw32ctx->running)
+		StopExecution(1000);
+
+	DeleteObject(titlebmp);
+	DeleteDC(wonw32ctx->title);
+
+	SafeRelease(lpDI);
+	SafeRelease(lpDIDevice);
+	for(i = 2; i >= 0; i--) {
+		SafeRelease(screen[i]);
+	}
+
+	SafeRelease(lpDDSPrimary);
+	SafeRelease(lpDD);
+
+	CloseHandle(wonw32ctx->syncevent);
+	
+	if(wonw32ctx->hWnd != INVALID_HANDLE_VALUE)
+		DestroyWindow(wonw32ctx->hWnd);
+	free(memory);
+
+	SaveConfig();
+
+	return msg.wParam;	
+	
+}
+
+static BOOL InitDDraw() {
+	DDSURFACEDESC ddsd;
+	DDPIXELFORMAT ddpf;
+	DDCOLORKEY key;
+
+	int rsz, gsz, bsz;
+	int rsh, gsh, bsh;
+	int r, g, b;
+	DWORD compiledPixel;
+	int i;
+
+	HINSTANCE dddll;
+	typedef HRESULT (WINAPI *DDC)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter); 
+
+	DDC ddc;
+
+	dddll = LoadLibrary(TEXT("ddraw.dll"));
+	ddc = (DDC)GetProcAddress(dddll, TEXT("DirectDrawCreate"));
+	if(!ddc)
+		return FALSE;
+
+	if(ddc(NULL, &lpDD, NULL) != DD_OK) {
+		return FALSE;
+	}
+	if(lpDD->SetCooperativeLevel(wonw32ctx->hWnd, DDSCL_NORMAL) != DD_OK) {
+		return FALSE;
+	}
+	if(lpDD->CreateClipper(NULL, &lpClip, NULL) != DD_OK) {
+		return FALSE;
+	}
+	lpClip->SetHWnd(0, wonw32ctx->hWnd);
+	ZeroMemory(&ddsd, sizeof(ddsd));
+	ddsd.dwSize = sizeof(ddsd);
+	ddsd.dwFlags = DDSD_CAPS;
+	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+	if(lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL) != DD_OK) {
+		return FALSE;
+	}
+	lpDDSPrimary->SetClipper(lpClip);
+
+	ZeroMemory(&ddsd, sizeof(ddsd));
+
+	ddsd.dwSize = sizeof(ddsd);
+	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+	ddsd.dwWidth = ddsd.dwHeight = max(wonw32ctx->ww_lcd_width, wonw32ctx->ww_lcd_height);
+
+	for(i = 0; i < 3; i++) {
+		if(lpDD->CreateSurface(&ddsd, &screen[i], NULL) != DD_OK) {
+			return FALSE;
+		}
+	}
+
+	// Caliculate compiled pixel value for surface
+	ZeroMemory(&ddpf, sizeof(ddpf));
+	ddpf.dwSize = sizeof(ddpf);
+	lpDDSPrimary->GetPixelFormat(&ddpf);
+
+	bytesPerPixel = ddpf.dwRGBBitCount / 8;
+	if(bytesPerPixel == 1) {
+		MessageBox(wonw32ctx->hWnd, "256 色モードでは動作しません。", NULL, MB_OK);
+		return FALSE;
+	}
+
+	rsz = GetMaskInfo(ddpf.dwRBitMask, &rsh);
+	gsz = GetMaskInfo(ddpf.dwGBitMask, &gsh);
+	bsz = GetMaskInfo(ddpf.dwBBitMask, &bsh);
+
+	for(i = 0; i < 17; i++) {
+		r = GetRValue(w32colors[i]);
+		g = GetGValue(w32colors[i]);
+		b = GetBValue(w32colors[i]);
+
+		r >>= (8-rsz);
+		g >>= (8-gsz);
+		b >>= (8-bsz);
+		r <<= rsh;
+		g <<= gsh;
+		b <<= bsh;
+
+		compiledPixel = (DWORD)(r | g | b);
+		ddclrs[i][3] = (BYTE) compiledPixel;
+		ddclrs[i][2] = (BYTE)(compiledPixel >>= 8);
+		ddclrs[i][1] = (BYTE)(compiledPixel >>= 8);
+		ddclrs[i][0] = (BYTE)(compiledPixel >>= 8);
+	}
+	r = GetRValue(COLORKEY);
+	g = GetGValue(COLORKEY);
+	b = GetBValue(COLORKEY);
+	r >>= (8-rsz);
+	g >>= (8-gsz);
+	b >>= (8-bsz);
+	r <<= rsh;
+	g <<= gsh;
+	b <<= bsh;
+	compiledPixel = (DWORD)(r | g | b);
+	for(i = 0; i < 3; i++) {
+		key.dwColorSpaceHighValue = key.dwColorSpaceLowValue = compiledPixel;
+		screen[i]->SetColorKey(DDCKEY_SRCBLT, &key);
+	}
+	ddclrkey[3] = (BYTE) compiledPixel;
+	ddclrkey[2] = (BYTE)(compiledPixel >>= 8);
+	ddclrkey[1] = (BYTE)(compiledPixel >>= 8);
+	ddclrkey[0] = (BYTE)(compiledPixel >>= 8);
+
+	return TRUE;
+}
+
+static BOOL InitDInput() {
+	HINSTANCE didll;
+	typedef HRESULT (WINAPI *DICA)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter);
+	DICA dica;
+
+	didll = LoadLibrary(TEXT("dinput.dll"));
+	dica = (DICA)GetProcAddress(didll, TEXT("DirectInputCreateA"));
+
+	if(!dica)
+		return FALSE;
+
+	if(FAILED((dica)(wonw32ctx->hInst, DIRECTINPUT_VERSION, &lpDI, NULL))) {
+		return FALSE;
+	}		 
+	if(FAILED(lpDI->CreateDevice(GUID_SysKeyboard, &lpDIDevice, NULL))) { 
+		return FALSE;
+	}
+	if(FAILED(lpDIDevice->SetDataFormat(&c_dfDIKeyboard))) {
+		return FALSE;
+	}
+	if(FAILED(lpDIDevice->SetCooperativeLevel(wonw32ctx->hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) {
+		return FALSE;
+	}
+	lpDIDevice->Acquire();
+
+	return TRUE;
+}
+
+static int GetMaskInfo(DWORD bitmask, int *lpShift) {
+	int precision, shift;
+
+	precision = shift = 0;
+	// count the zeros on right hand side
+	while(!(bitmask & 0x01L)) {
+		bitmask >>= 1;
+		shift++;
+	}
+
+	// count the ones on right hand side
+	while(bitmask & 0x01L) {
+		bitmask >>= 1;
+		precision++;
+	}
+	*lpShift = shift;
+	return precision;
+}
+
+//
+//  関数: MyRegisterClass()
+//
+//  用途: ウィンドウ クラスの登録
+//
+//  コメント:
+//
+//    この関数およびその使用はこのコードを Windows 95 で先に追加された
+//    'RegisterClassEx' 関数と Win32 システムの互換性を保持したい場合に
+//    のみ必要となります。アプリケーションが、アプリケーションに関連付け
+//    られたスモール アイコンを取得できるよう、この関数を呼び出すことは
+//    重要です。
+//
+ATOM MyRegisterClass( HINSTANCE hInstance )
+{
+	WNDCLASSEX wcex;
+
+	wcex.cbSize = sizeof(WNDCLASSEX); 
+
+	wcex.style		= CS_HREDRAW | CS_VREDRAW;
+	wcex.lpfnWndProc	= (WNDPROC)WndProc;
+	wcex.cbClsExtra		= 0;
+	wcex.cbWndExtra		= 0;
+	wcex.hInstance		= hInstance;
+	wcex.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MMAGE));
+	wcex.hCursor		= LoadCursor((HINSTANCE)NULL, IDC_ARROW);
+	wcex.hbrBackground = (HBRUSH)NULL;
+	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MMAGE);
+	wcex.lpszClassName	= szWindowClass;
+	wcex.hIconSm		= LoadIcon((HINSTANCE)wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
+
+	return RegisterClassEx( &wcex );
+}
+
+//
+//   関数: InitInstance(HANDLE, int)
+//
+//   用途: インスタンス ハンドルの保存とメイン ウィンドウの作成
+//
+//   コメント:
+//
+//        この関数では、インスタンス ハンドルをグローバル変数に保存し、プログラムの
+//        メイン ウィンドウを作成し表示します。
+//
+BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
+{
+	WWLCDPanel ww_lcd_panel;
+	INITCOMMONCONTROLSEX icce;
+
+	ZeroMemory(&icce, sizeof(icce));
+	icce.dwSize = sizeof(icce);
+	icce.dwICC = ICC_DATE_CLASSES | ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&icce);
+	wonw32ctx->hInst = hInstance; // グローバル変数にインスタンス ハンドルを保存します
+
+	ww_lcd_panel = WWDisplay_GetLCDPanel(WonXDisplay_GetWWDisplay(WonX_GetWonXDisplay()));
+
+	wonw32ctx->ww_lcd_width = WWLCDPanel_GetWidth(ww_lcd_panel);
+	wonw32ctx->ww_lcd_height = WWLCDPanel_GetHeight(ww_lcd_panel);
+
+	wonw32ctx->hWnd = CreateWindow(szWindowClass, THIS_APP_TITLE, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, CW_USEDEFAULT, 0, 
+		CW_USEDEFAULT, 0,	
+		NULL, NULL, hInstance, NULL);
+
+	if( !wonw32ctx->hWnd ) {
+		return FALSE;
+	}
+
+	lcdseg[LCD_SLEEP][0] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_SLEEPOFF));
+	lcdseg[LCD_VERTICAL][0]= LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_VERTICALOFF));
+	lcdseg[LCD_HORIZONTAL][0] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_HORIZONTALOFF));
+	lcdseg[LCD_AUX1][0] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX1OFF));
+	lcdseg[LCD_AUX2][0] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX2OFF));
+	lcdseg[LCD_AUX3][0] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX3OFF));
+
+	lcdseg[LCD_SLEEP][1] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_SLEEP));
+	lcdseg[LCD_VERTICAL][1]= LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_VERTICAL));
+	lcdseg[LCD_HORIZONTAL][1] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_HORIZONTAL));
+	lcdseg[LCD_AUX1][1] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX1));
+	lcdseg[LCD_AUX2][1] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX2));
+	lcdseg[LCD_AUX3][1] = LoadIcon(wonw32ctx->hInst, MAKEINTRESOURCE(IDI_AUX3));
+
+	statusbar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM,
+					NULL, wonw32ctx->hWnd, 0);
+	SendMessage(statusbar, SB_SETMINHEIGHT, (WPARAM)16, 0);
+
+	if(!statusbar) {
+		return FALSE;
+	}
+
+	SetWindowSize();
+	switch(mmconfig->viewsize) {
+		case 1:
+			CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_X1, IDM_X4, IDM_X1, MF_BYCOMMAND);
+			break;
+		case 2:
+			CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_X1, IDM_X4, IDM_X2, MF_BYCOMMAND);
+			break;
+		case 3:
+			CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_X1, IDM_X4, IDM_X3, MF_BYCOMMAND);
+			break;
+		case 4:
+			CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_X1, IDM_X4, IDM_X4, MF_BYCOMMAND);
+			break;
+	}
+	if(mmconfig->horizontal)
+		CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_HORIZONTAL, IDM_VERTICAL, IDM_HORIZONTAL, MF_BYCOMMAND);
+	else
+		CheckMenuRadioItem(GetMenu(wonw32ctx->hWnd), IDM_HORIZONTAL, IDM_VERTICAL, IDM_VERTICAL, MF_BYCOMMAND);
+
+	ShowWindow( wonw32ctx->hWnd, nCmdShow );
+	UpdateWindow( wonw32ctx->hWnd );
+
+	return TRUE;
+}
+
+void SetWindowSize() {
+	int width, height;
+	RECT r;
+
+	wonw32ctx->winwidth = (mmconfig->horizontal ? wonw32ctx->ww_lcd_width : wonw32ctx->ww_lcd_height) * mmconfig->viewsize;
+	wonw32ctx->winheight = (mmconfig->horizontal ? wonw32ctx->ww_lcd_height : wonw32ctx->ww_lcd_width) * mmconfig->viewsize;
+
+	GetWindowRect(statusbar, &r);
+	width = wonw32ctx->winwidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
+	height = wonw32ctx->winheight + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYFIXEDFRAME) * 2
+		+ (r.bottom - r.top);
+
+	SetWindowPos(wonw32ctx->hWnd, 0, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER);
+}
+
+//
+//  関数: WndProc(HWND, unsigned, WORD, LONG)
+//
+//  用途: メイン ウィンドウのメッセージを処理します。
+//
+//  WM_COMMAND	- アプリケーション メニューの処理
+//  WM_PAINT	- メイン ウィンドウの描画
+//  WM_DESTROY	- 終了メッセージの通知とリターン
+//
+//
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+	int wmId, wmEvent;
+	BOOL handled = TRUE;
+	HMENU menu;
+	HDROP hdrop;
+	TCHAR drpfile[MAX_PATH + 1];
+	int sbsize[2];
+	LPDRAWITEMSTRUCT lpdi;
+
+	menu = GetMenu(hWnd);
+
+	switch( message ) 
+	{
+		case WM_COMMAND:
+			wmId    = LOWORD(wParam); 
+			wmEvent = HIWORD(wParam); 
+			// メニュー選択の解析:
+			switch( wmId ) 
+			{
+				case IDM_ABOUT:
+				   DialogBox(wonw32ctx->hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
+				   break;
+				case IDM_LICENSE:
+				   DialogBox(wonw32ctx->hInst, (LPCTSTR)IDD_LICENSE, hWnd, (DLGPROC)License);
+				   break;
+				case IDM_EXIT:
+					PostQuitMessage( 0 );
+				   break;
+
+				case IDM_OPEN:
+					OpenDlgAndRun();
+					break;
+
+				case IDM_RESTART:
+					if(!wonw32ctx->running && wonw32ctx->loaded)
+						Restart();
+					break;
+
+				case IDM_STOP:
+					if(wonw32ctx->running)
+						StopExecution(5000);
+					break;
+
+				case IDM_OPENWEB:
+					ShellExecute(NULL, NULL, THIS_APP_URL, NULL, NULL, SW_SHOWNORMAL);
+					break;
+
+				case IDM_X1:
+					mmconfig->viewsize = 1;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_X1, IDM_X4, IDM_X1, MF_BYCOMMAND);
+					break;
+				case IDM_X2:
+					mmconfig->viewsize = 2;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_X1, IDM_X4, IDM_X2, MF_BYCOMMAND);
+					break;
+				case IDM_X3:
+					mmconfig->viewsize = 3;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_X1, IDM_X4, IDM_X3, MF_BYCOMMAND);
+					break;
+				case IDM_X4:
+					mmconfig->viewsize = 4;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_X1, IDM_X4, IDM_X4, MF_BYCOMMAND);
+					break;
+
+				case IDM_HORIZONTAL:
+					mmconfig->horizontal = MMCONFIG_HORIZONTAL;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_HORIZONTAL, IDM_VERTICAL, IDM_HORIZONTAL, MF_BYCOMMAND);
+					break;
+				case IDM_VERTICAL:
+					mmconfig->horizontal = MMCONFIG_VERTICAL;
+					SetWindowSize();
+					CheckMenuRadioItem(menu, IDM_HORIZONTAL, IDM_VERTICAL, IDM_VERTICAL, MF_BYCOMMAND);
+					break;
+
+				case IDM_PREFERENCE:
+					OpenPreferenceDlg();
+					break;
+
+				default:
+					handled = FALSE;
+			}
+			break;
+
+		case WM_PAINT:
+			if(wonw32ctx->running) {
+				SendMessage(statusbar, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("実行中"));
+			} else {
+				SendMessage(statusbar, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT(""));
+				W32Display_DrawLCDWindow(hWnd, WonX_GetWonXDisplay());
+			}
+			handled = FALSE;
+			break;
+
+		case WM_SIZE:
+			sbsize[0] = LOWORD(lParam) - 100;
+			sbsize[1] = LOWORD(lParam);
+			SendMessage(statusbar, SB_SETPARTS, 2, (LPARAM)sbsize);
+			SendMessage(statusbar, WM_SIZE, wParam, lParam);
+			SendMessage(statusbar, SB_SETTEXT, (WPARAM)1 | SBT_OWNERDRAW, (LPARAM)NULL);
+			break;
+
+		case WM_DRAWITEM:
+			lpdi = (LPDRAWITEMSTRUCT)lParam;
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left     , lpdi->rcItem.top,
+				lcdseg[LCD_SLEEP][mmvm->lcdseg & (1 << LCD_SLEEP) ? 1 : 0] , 16, 16, 0, NULL, DI_IMAGE);
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left + 16, lpdi->rcItem.top,
+				lcdseg[LCD_VERTICAL][mmvm->lcdseg & (1 << LCD_VERTICAL) ? 1 : 0], 16, 16, 0, NULL, DI_IMAGE);
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left + 32, lpdi->rcItem.top,
+				lcdseg[LCD_HORIZONTAL][mmvm->lcdseg & (1 << LCD_HORIZONTAL) ? 1 : 0], 16, 16, 0, NULL, DI_IMAGE);
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left + 48, lpdi->rcItem.top,
+				lcdseg[LCD_AUX1][mmvm->lcdseg & (1 << LCD_AUX1) ? 1 : 0], 16, 16, 0, NULL, DI_IMAGE);
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left + 64, lpdi->rcItem.top,
+				lcdseg[LCD_AUX2][mmvm->lcdseg & (1 << LCD_AUX2) ? 1 : 0], 16, 16, 0, NULL, DI_IMAGE);
+			DrawIconEx(lpdi->hDC, lpdi->rcItem.left + 80, lpdi->rcItem.top,
+				lcdseg[LCD_AUX3][mmvm->lcdseg & (1 << LCD_AUX3) ? 1 : 0], 16, 16, 0, NULL, DI_IMAGE);
+			break;
+
+		case WM_ENTERMENULOOP:
+			if(wonw32ctx->running) {
+				EnableMenuItem(menu, IDM_STOP, MF_BYCOMMAND | MF_ENABLED);
+			} else {
+				EnableMenuItem(menu, IDM_STOP, MF_BYCOMMAND | MF_GRAYED);
+			}
+			if(wonw32ctx->loaded) {
+				EnableMenuItem(menu, IDM_RESTART, MF_BYCOMMAND | MF_ENABLED);
+			} else {
+				EnableMenuItem(menu, IDM_RESTART, MF_BYCOMMAND | MF_GRAYED);
+			}
+			break;
+
+		case WM_DROPFILES:
+			hdrop=(HDROP) wParam;
+
+			DragQueryFile(hdrop, 0, drpfile, MAX_PATH);
+			OpenAndRun(drpfile, TEXT(""));
+
+			DragFinish(hdrop);
+			break;
+
+		case WM_NCACTIVATE:
+			wonw32ctx->active = (BOOL) wParam;
+			if(wonw32ctx->running) {
+				if(wonw32ctx->active) {
+					ResumeThread(wonw32ctx->cputhread);
+				} else {
+#ifndef _DEBUG
+					SuspendThread(wonw32ctx->cputhread);
+#endif
+				}
+			}
+			handled = FALSE;
+			break;
+
+		case WM_CLOSE:
+			PostQuitMessage( 0 );
+			break;
+
+		default:
+			handled = FALSE;
+			break;
+   }
+
+	if(handled)
+		return FALSE;
+	else
+		return DefWindowProc( hWnd, message, wParam, lParam );
+}
+
+// バージョン情報ボックス用メッセージ ハンドラ
+LRESULT CALLBACK About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+	switch( message )
+	{
+		case WM_INITDIALOG:
+				return TRUE;
+
+		case WM_COMMAND:
+			if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL ) 
+			{
+				EndDialog(hDlg, LOWORD(wParam));
+				return TRUE;
+			}
+			break;
+	}
+    return FALSE;
+}
+
+// ライセンス情報ボックス用メッセージ ハンドラ
+LRESULT CALLBACK License( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+	HRSRC rsc;
+	LPCTSTR msg;
+	HWND msgwnd;
+
+	switch( message )
+	{
+		case WM_INITDIALOG:
+			rsc = FindResource(NULL, MAKEINTRESOURCE(IDR_LICENSE), TEXT("TEXT"));
+			msg = (LPCTSTR)LoadResource(NULL, rsc);
+			msgwnd = GetDlgItem(hDlg, IDC_LICENSE);
+			SetWindowText(msgwnd, msg);
+			return TRUE;
+
+		case WM_COMMAND:
+			if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL ) 
+			{
+				EndDialog(hDlg, LOWORD(wParam));
+				return TRUE;
+			}
+			break;
+	}
+    return FALSE;
+}
+
+static void W32Display_DrawLCDWindow(HWND hWnd, WonXDisplay display) {
+	HDC hdc;
+	RECT dr, sr;
+	POINT p;
+
+	if(!ddInit)
+		return;
+
+	p.x = p.y = 0;
+	ClientToScreen(wonw32ctx->hWnd, &p);
+	dr.left = p.x;
+	dr.top = p.y;
+	dr.right = dr.left + wonw32ctx->winwidth;
+	dr.bottom = dr.top + wonw32ctx->winheight;
+	sr.left = sr.top = 0;
+	sr.right = wonw32ctx->ww_lcd_width;
+	sr.bottom = wonw32ctx->ww_lcd_height;
+
+	screen[0]->GetDC(&hdc);
+	BitBlt(hdc, 0, 0, wonw32ctx->ww_lcd_width, wonw32ctx->ww_lcd_height, wonw32ctx->title, 0, 0, SRCCOPY);
+	screen[0]->ReleaseDC(hdc);
+
+	lpDDSPrimary->Blt(&dr, screen[0], &sr, DDBLT_WAIT, NULL);
+}
+
+static void DrawScreen(LPBYTE surfm, int screenno, LONG pitch) {
+	int surfa;
+	WWScreen screen = wonxobj->ww_screen[screenno];
+	int plt[9];
+	int *palette = &plt[1];
+
+	int pixel;
+	int x, y;
+	int sx = 0, sy = 0, ex = 0, ey = 0;
+	int mode = 0;
+	int i;
+	int rx, ry;
+	BOOL enable;
+
+	plt[0] = -1;
+	WWColorMap_GetLCDColors(WWDisplay_GetColorMap(wonxobj->ww_display), plt + 1);
+
+	if(screenno)
+		mode = WWScreen_GetMode(screen);
+
+	rx = WWScreen_GetRollX(screen);
+	ry = WWScreen_GetRollY(screen);
+
+	if ( (mode == WW_SCREEN_INSIDE_ONLY) || (mode == WW_SCREEN_OUTSIDE_ONLY) ) {
+		sx = WWScreen_GetDrawX(screen);
+		sy = WWScreen_GetDrawX(screen);
+
+		ex = sx + WWScreen_GetDrawWidth( screen);
+		ey = sy + WWScreen_GetDrawHeight(screen);
+	}
+
+	enable = WWScreen_GetEnable(screen);
+
+	surfa = 0;
+
+	if(mmconfig->horizontal) {
+		for(y = 0; y < wonw32ctx->ww_lcd_height; y++) {
+			surfa = y * pitch;
+			for (x = 0; x < wonw32ctx->ww_lcd_width; x++) {
+				pixel = enable ? WWScreen_GetPixel(screen, x + rx, y + ry) : -1;
+				if (mode == WW_SCREEN_INSIDE_ONLY) {
+					if( (x < sx) || (x > ex) || (y < sy) || (y > ey) ) {
+						pixel = -1;
+					}
+				} else if (mode == WW_SCREEN_OUTSIDE_ONLY) {
+					if ( (x >= sx) && (x <= ex) && (y >= sy) && (y <= ey) ) {
+						pixel = -1;
+					}
+				}
+				for(i = 3; i >= (4 - bytesPerPixel); i--) {
+					surfm[surfa++] = ddclrs[palette[pixel] + 1][i];
+				}
+			}
+		}
+	} else {
+		for(y = 0; y < wonw32ctx->ww_lcd_width; y++) {
+			surfa = y * pitch;
+			for (x = 0; x < wonw32ctx->ww_lcd_height; x++) {
+				pixel = enable ? WWScreen_GetPixel(screen, (wonw32ctx->ww_lcd_width - y) + rx, x + ry) : -1;
+				if (mode == WW_SCREEN_INSIDE_ONLY) {
+					if( (x < sx) || (x > ex) || (y < sy) || (y > ey) ) {
+						pixel = -1;
+					}
+				} else if (mode == WW_SCREEN_OUTSIDE_ONLY) {
+					if ( (x >= sx) && (x <= ex) && (y >= sy) && (y <= ey) ) {
+						pixel = -1;
+					}
+				}
+				for(i = 3; i >= (4 - bytesPerPixel); i--) {
+					surfm[surfa++] = ddclrs[palette[pixel] + 1][i];
+				}
+			}
+		}
+	}
+}
+
+static void DrawSprite(LPBYTE surfm, WWSprite sprite, LONG pitch) {
+	int surfa;
+	int x, y, lcd_x, lcd_y;
+	int sx, sy, ex, ey;
+	int pixel, outside;
+	WWDisplay display = wonxobj->ww_display;
+	int palette[8];
+	int i;
+
+	WWColorMap_GetLCDColors(WWDisplay_GetColorMap(display), palette);
+
+	sx = WWDisplay_GetSpriteWindowX(display) - 1;
+	sy = WWDisplay_GetSpriteWindowY(display) - 1;
+
+	ex = sx + WWDisplay_GetSpriteWindowWidth(display);
+	ey = sy + WWDisplay_GetSpriteWindowHeight(display);
+
+	for (y = 0; y < 8; y++) {
+		for (x = 0; x < 8; x++) {
+			pixel = WWSprite_GetPixel(sprite, x, y);
+
+			/* 透明色の場合 */
+			if (pixel == -1) continue;
+
+			lcd_x = WWSprite_GetX(sprite) + x;
+			lcd_y = WWSprite_GetY(sprite) + y;
+
+			if (WWDisplay_GetSpriteWindowEnable(display)) {
+				if ( (lcd_x < sx) || (lcd_y < sy) || (lcd_x > ex) || (lcd_y > ey) )
+					outside = 1;
+				else
+					outside = 0;
+
+				if (WWSprite_GetClipping(sprite)) { /* ウインドウの外側部分を表示 */
+					if (!outside) continue;
+				} else {                            /* ウインドウの内側部分を表示 */
+					if (outside) continue;
+				}
+			}
+
+			if(mmconfig->horizontal)
+				surfa = (lcd_x * bytesPerPixel) + (pitch * lcd_y);
+			else
+				surfa = (lcd_y * bytesPerPixel) + (pitch * (wonw32ctx->ww_lcd_width - lcd_x));
+
+			for(i = 3; i >= (4 - bytesPerPixel); i--) {
+				surfm[surfa++] = ddclrs[palette[pixel] + 1][i];
+			}
+		}
+	}
+
+	return;
+}
+
+#ifdef _DEBUG
+void ShowError(int code) {
+	LPVOID lpMsgBuf;
+
+	FormatMessage( 
+	    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+	    FORMAT_MESSAGE_FROM_SYSTEM | 
+	    FORMAT_MESSAGE_IGNORE_INSERTS,
+	    NULL,
+	    code,
+	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // デフォルト言語
+	    (LPTSTR) &lpMsgBuf,
+	    0,
+	    NULL 
+	);
+
+	MessageBox( NULL, (LPTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
+
+	LocalFree( lpMsgBuf );
+}
+#endif
+

+ 44 - 0
mmage/mmage.h

@@ -0,0 +1,44 @@
+#ifndef _MMAGE_H
+#define _MMAGE_H
+
+#define THIS_APP_TITLE TEXT("MiracleMage")
+#define THIS_APP_URL TEXT("http://www04.u-page.so-net.ne.jp/td5/zry/WonderWitch/MiracleMage/")
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WINVER        0x0400    // Win 9x / NT 4.0 or later
+#define _WIN32_IE     0x0300    // IE 3.0 or later
+#include <windows.h>
+
+typedef struct {
+	HINSTANCE hInst;
+	HWND hWnd;
+	HDC title;
+	HANDLE syncevent;
+	int ww_lcd_width;
+	int winwidth;
+	int ww_lcd_height;
+	int winheight;
+	int syncperiod;
+	BOOL running;
+	BOOL loaded;
+	HANDLE cputhread;
+	BOOL active;
+	int key;
+	int keyhit;
+	int oldkey;
+} WONW32CONTEXT, *LPWONW32CONTEXT;
+
+extern LPWONW32CONTEXT wonw32ctx;
+
+#ifdef _DEBUG
+void ShowError(int code);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _MMAGE_H

+ 364 - 0
mmage/preference.cpp

@@ -0,0 +1,364 @@
+#include "preference.h"
+#include "../resource/resource.h"
+
+#include <shlobj.h>
+
+#define INIFILE				TEXT("mmage.ini")
+#define INIFILE_SECTION		TEXT("MMAGE")
+#define INIFILE_KEY_VIEWSIZE		TEXT("VIEWSIZE")
+#define INIFILE_KEY_HORIZONTAL		TEXT("HORIZONTAL")
+#define INIFILE_KEY_QUERYARG		TEXT("QUERYARG")
+#define INIFILE_KEY_ARGUMENT		TEXT("ARGUMENT")
+#define INIFILE_KEY_ROM0DIR			TEXT("ROM0DIR")
+#define INIFILE_KEY_RAM0DIR			TEXT("RAM0DIR")
+#define INIFILE_KEY_OWNER_NAME		TEXT("OWNER_NAME")
+#define INIFILE_KEY_OWNER_BYEAR		TEXT("OWNER_BYEAR")
+#define INIFILE_KEY_OWNER_BMONTH	TEXT("OWNER_BMONTH")
+#define INIFILE_KEY_OWNER_BDAY		TEXT("OWNER_BDAY")
+#define INIFILE_KEY_OWNER_SEX		TEXT("OWNER_SEX")
+#define INIFILE_KEY_OWNER_BLOOD		TEXT("OWNER_BLOOD")
+
+static MMAGE_CONFIG mmconfig_struct;
+LPMMAGE_CONFIG mmconfig = &mmconfig_struct;
+
+static LRESULT CALLBACK RunningEnvDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+static LRESULT CALLBACK FileSystemDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+static LRESULT CALLBACK OwnerInfoDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+static BOOL SelectFolder(HWND hWnd, LPCTSTR title, LPTSTR path);
+
+#define NUM_DLG 3
+
+static LPCTSTR dlgtmp[NUM_DLG] = {
+	(LPCTSTR)IDD_RUNNINGENV,
+	(LPCTSTR)IDD_FILESYS,
+	(LPCTSTR)IDD_OWNERINFO,
+};
+
+static DLGPROC dlgproc[NUM_DLG] = {
+	(DLGPROC)RunningEnvDlgProc,
+	(DLGPROC)FileSystemDlgProc,
+	(DLGPROC)OwnerInfoDlgProc,
+};
+
+void OpenPreferenceDlg() {
+    PROPSHEETPAGE psp;
+    PROPSHEETHEADER psh;
+    HPROPSHEETPAGE hpsp[NUM_DLG];
+	int i;
+
+    psp.dwSize = sizeof(psp);
+    psp.dwFlags = PSP_DEFAULT;
+    psp.hInstance = wonw32ctx->hInst;
+
+	for(i = 0; i < NUM_DLG; i++) {
+		psp.pszTemplate = dlgtmp[i];
+		psp.pfnDlgProc = dlgproc[i];
+		hpsp[i] = CreatePropertySheetPage(&psp);
+	}
+
+    memset(&psh, 0, sizeof(psh));
+    psh.dwSize = sizeof(psh);
+    psh.dwFlags = PSH_NOAPPLYNOW;
+    psh.hInstance = wonw32ctx->hInst;
+    psh.hwndParent = wonw32ctx->hWnd;
+    psh.nPages = NUM_DLG;
+    psh.phpage = hpsp;
+    psh.pszCaption = TEXT("設定");
+    PropertySheet(&psh);
+    return;
+}
+
+static LRESULT CALLBACK RunningEnvDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
+	int wmId, wmEvent;
+	LPNMHDR nmhdr;
+	BOOL handled = TRUE;
+
+    switch(message) {
+        case WM_INITDIALOG:
+			CheckDlgButton(hDlg, IDC_QUERYARG, mmconfig->queryarg);
+			EnableWindow(GetDlgItem(hDlg, IDC_ARGUMENT), !mmconfig->queryarg);
+			SetWindowText(GetDlgItem(hDlg, IDC_ARGUMENT), mmconfig->argument);
+			break;
+
+		case WM_COMMAND:
+			wmId = LOWORD(wParam);
+			wmEvent = HIWORD(wParam);
+			switch(wmId) {
+				case IDC_QUERYARG:
+					EnableWindow(GetDlgItem(hDlg, IDC_ARGUMENT), !IsDlgButtonChecked(hDlg, IDC_QUERYARG));
+					break;
+
+				default:
+					handled = FALSE;
+					break;
+			}
+			break;
+
+        case WM_NOTIFY:
+            nmhdr = (NMHDR *)lParam;
+            switch(nmhdr->code) {
+                case PSN_APPLY:
+					mmconfig->queryarg = IsDlgButtonChecked(hDlg, IDC_QUERYARG);
+					GetWindowText(GetDlgItem(hDlg, IDC_ARGUMENT), mmconfig->argument, MAX_WW_ARG);
+					break;
+                default:
+                    handled = FALSE;
+					break;
+            }
+            break;
+
+		default:
+			handled = FALSE;
+			break;
+    }
+
+    return handled;
+}
+
+static LRESULT CALLBACK FileSystemDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
+	int wmId, wmEvent;
+	LPNMHDR nmhdr;
+	TCHAR dirname[MAX_PATH + 1];
+	BOOL specifydir;
+	BOOL handled = TRUE;
+
+    switch(message) {
+        case WM_INITDIALOG:
+			specifydir = (lstrlen(mmconfig->rom0dir) && lstrlen(mmconfig->ram0dir)) ? TRUE : FALSE;
+			CheckDlgButton(hDlg, IDC_SPECIFYDIR, specifydir);
+			if(specifydir) {
+				SetWindowText(GetDlgItem(hDlg, IDC_ROM0), mmconfig->rom0dir);
+				SetWindowText(GetDlgItem(hDlg, IDC_RAM0), mmconfig->ram0dir);
+			}
+			EnableWindow(GetDlgItem(hDlg, IDC_ARGUMENT), specifydir);
+			EnableWindow(GetDlgItem(hDlg, IDC_ROM0), specifydir);
+			EnableWindow(GetDlgItem(hDlg, IDC_ROM0REF), specifydir);
+			EnableWindow(GetDlgItem(hDlg, IDC_RAM0), specifydir);
+			EnableWindow(GetDlgItem(hDlg, IDC_RAM0REF), specifydir);
+			break;
+
+		case WM_COMMAND:
+			wmId = LOWORD(wParam);
+			wmEvent = HIWORD(wParam);
+			switch(wmId) {
+				case IDC_SPECIFYDIR:
+					EnableWindow(GetDlgItem(hDlg, IDC_ROM0), IsDlgButtonChecked(hDlg, IDC_SPECIFYDIR));
+					EnableWindow(GetDlgItem(hDlg, IDC_ROM0REF), IsDlgButtonChecked(hDlg, IDC_SPECIFYDIR));
+					EnableWindow(GetDlgItem(hDlg, IDC_RAM0), IsDlgButtonChecked(hDlg, IDC_SPECIFYDIR));
+					EnableWindow(GetDlgItem(hDlg, IDC_RAM0REF), IsDlgButtonChecked(hDlg, IDC_SPECIFYDIR));
+					break;
+
+				case IDC_ROM0REF:
+					if(SelectFolder(hDlg, TEXT("/rom0 ディレクトリの指定"), dirname))
+						SetWindowText(GetDlgItem(hDlg, IDC_ROM0), dirname);
+					break;
+				case IDC_RAM0REF:
+					if(SelectFolder(hDlg, TEXT("/ram0 ディレクトリの指定"), dirname))
+						SetWindowText(GetDlgItem(hDlg, IDC_RAM0), dirname);
+					break;
+
+				default:
+					handled = FALSE;
+					break;
+			}
+			break;
+
+        case WM_NOTIFY:
+            nmhdr = (NMHDR *)lParam;
+            switch(nmhdr->code) {
+                case PSN_APPLY:
+					specifydir = IsDlgButtonChecked(hDlg, IDC_SPECIFYDIR);
+					if(specifydir) {
+						if(GetWindowTextLength(GetDlgItem(hDlg, IDC_ROM0))
+							&& GetWindowTextLength(GetDlgItem(hDlg, IDC_RAM0))) {
+							GetWindowText(GetDlgItem(hDlg, IDC_ROM0), mmconfig->rom0dir, MAX_PATH);
+							GetWindowText(GetDlgItem(hDlg, IDC_RAM0), mmconfig->ram0dir, MAX_PATH);
+						} else {
+							MessageBox(hDlg, TEXT("/rom0、/ram0 のマッピングディレクトリを指定してください。"), NULL, MB_OK);
+							SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); 
+							break;
+						}
+					} else {
+						lstrcpy(mmconfig->rom0dir, TEXT(""));
+						lstrcpy(mmconfig->ram0dir, TEXT(""));
+					}
+					break;
+                default:
+                    handled = FALSE;
+					break;
+            }
+            break;
+
+		default:
+			handled = FALSE;
+			break;
+    }
+
+    return handled;
+}
+
+static LRESULT CALLBACK OwnerInfoDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
+	LPNMHDR nmhdr;
+	SYSTEMTIME day;
+	BOOL handled = TRUE;
+
+    switch(message) {
+        case WM_INITDIALOG:
+			SetWindowText(GetDlgItem(hDlg, IDC_NAME), mmconfig->ownerinfo.name);
+
+			ZeroMemory(&day, sizeof(day));
+			day.wYear = mmconfig->ownerinfo.birth_year;
+			day.wMonth = mmconfig->ownerinfo.birth_month;
+			day.wDay = mmconfig->ownerinfo.birth_day;
+			SendMessage(GetDlgItem(hDlg, IDC_BIRTHDAY), DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&day);
+
+			switch(mmconfig->ownerinfo.sex) {
+				case 0:
+					CheckDlgButton(hDlg, IDC_UNKNOWNSEX, TRUE);
+					break;
+				case 1:
+					CheckDlgButton(hDlg, IDC_MALE, TRUE);
+					break;
+				case 2:
+					CheckDlgButton(hDlg, IDC_FEMALE, TRUE);
+					break;
+				default:
+					CheckDlgButton(hDlg, IDC_UNKNOWNSEX, TRUE);
+					break;
+			}
+
+			switch(mmconfig->ownerinfo.bloodtype) {
+				case 0:
+					CheckDlgButton(hDlg, IDC_UNKNOWNBLOOD, TRUE);
+					break;
+				case 1:
+					CheckDlgButton(hDlg, IDC_BLOODA, TRUE);
+					break;
+				case 2:
+					CheckDlgButton(hDlg, IDC_BLOODB, TRUE);
+					break;
+				case 3:
+					CheckDlgButton(hDlg, IDC_BLOODO, TRUE);
+					break;
+				case 4:
+					CheckDlgButton(hDlg, IDC_BLOODAB, TRUE);
+					break;
+				default:
+					CheckDlgButton(hDlg, IDC_UNKNOWNBLOOD, TRUE);
+					break;
+			}
+
+			break;
+
+        case WM_NOTIFY:
+            nmhdr = (NMHDR *)lParam;
+            switch(nmhdr->code) {
+                case PSN_APPLY:
+					GetWindowText(GetDlgItem(hDlg, IDC_NAME), mmconfig->ownerinfo.name, 16);
+
+					SendMessage(GetDlgItem(hDlg, IDC_BIRTHDAY), DTM_GETSYSTEMTIME, 0, (LPARAM)&day);
+					mmconfig->ownerinfo.birth_year = day.wYear;
+					mmconfig->ownerinfo.birth_month = (char)day.wMonth;
+					mmconfig->ownerinfo.birth_day = (char)day.wDay;
+
+					if(IsDlgButtonChecked(hDlg, IDC_UNKNOWNSEX))
+						mmconfig->ownerinfo.sex = 0;
+					else if(IsDlgButtonChecked(hDlg, IDC_MALE))
+						mmconfig->ownerinfo.sex = 1;
+					else if(IsDlgButtonChecked(hDlg, IDC_FEMALE))
+						mmconfig->ownerinfo.sex = 2;
+					
+					if(IsDlgButtonChecked(hDlg, IDC_UNKNOWNBLOOD))
+						mmconfig->ownerinfo.bloodtype = 0;
+					else if(IsDlgButtonChecked(hDlg, IDC_BLOODA))
+						mmconfig->ownerinfo.bloodtype = 1;
+					else if(IsDlgButtonChecked(hDlg, IDC_BLOODB))
+						mmconfig->ownerinfo.bloodtype = 2;
+					else if(IsDlgButtonChecked(hDlg, IDC_BLOODO))
+						mmconfig->ownerinfo.bloodtype = 3;
+					else if(IsDlgButtonChecked(hDlg, IDC_BLOODAB))
+						mmconfig->ownerinfo.bloodtype = 4;
+
+                    break;
+
+                default:
+                    handled = FALSE;
+					break;
+            }
+            break;
+
+		default:
+			handled = FALSE;
+			break;
+    }
+
+    return handled;
+}
+
+static BOOL SelectFolder(HWND hWnd, LPCTSTR title, LPTSTR path) {
+    BROWSEINFO  binfo;
+    LPITEMIDLIST idlist;
+
+    binfo.hwndOwner = hWnd;
+    binfo.pidlRoot = NULL;
+    binfo.pszDisplayName = path;
+    binfo.lpszTitle = title;
+    binfo.ulFlags = BIF_RETURNONLYFSDIRS; 
+    binfo.lpfn = NULL;
+    binfo.lParam = NULL;          
+    binfo.iImage = (int)NULL;
+
+    idlist = SHBrowseForFolder(&binfo);
+    if (idlist) {
+        SHGetPathFromIDList(idlist,path);
+        CoTaskMemFree(idlist);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+void LoadConfig() {
+	TCHAR inifile[MAX_PATH + 1];
+
+	wsprintf(inifile, TEXT("%s\\%s"), mmconfig->workingdir, INIFILE);
+
+	mmconfig->viewsize = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_VIEWSIZE, 1, inifile);
+	mmconfig->horizontal = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_HORIZONTAL, MMCONFIG_HORIZONTAL, inifile);
+	mmconfig->queryarg = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_QUERYARG, TRUE, inifile);
+	GetPrivateProfileString(INIFILE_SECTION, INIFILE_KEY_ROM0DIR, TEXT(""), mmconfig->rom0dir, MAX_PATH, inifile);
+	GetPrivateProfileString(INIFILE_SECTION, INIFILE_KEY_RAM0DIR, TEXT(""), mmconfig->ram0dir, MAX_PATH, inifile);
+	GetPrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_NAME, TEXT(""), mmconfig->ownerinfo.name, 16, inifile);
+	mmconfig->ownerinfo.birth_year = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_OWNER_BYEAR, 1970, inifile);
+	mmconfig->ownerinfo.birth_month = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_OWNER_BMONTH, 1, inifile);
+	mmconfig->ownerinfo.birth_day = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_OWNER_BDAY, 1, inifile);
+	mmconfig->ownerinfo.sex = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_OWNER_SEX, 0, inifile);
+	mmconfig->ownerinfo.bloodtype = GetPrivateProfileInt(INIFILE_SECTION, INIFILE_KEY_OWNER_BLOOD, 0, inifile);
+}
+
+void SaveConfig() {
+	TCHAR inifile[MAX_PATH + 1];
+	TCHAR tmp[5];
+
+	wsprintf(inifile, TEXT("%s\\%s"), mmconfig->workingdir, INIFILE);
+
+	wsprintf(tmp, TEXT("%1d"), mmconfig->viewsize);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_VIEWSIZE, tmp, inifile);
+	wsprintf(tmp, TEXT("%1d"), mmconfig->horizontal);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_HORIZONTAL, tmp, inifile);
+	wsprintf(tmp, TEXT("%1d"), mmconfig->queryarg);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_QUERYARG, tmp, inifile);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_ROM0DIR, mmconfig->rom0dir, inifile);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_RAM0DIR, mmconfig->ram0dir, inifile);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_NAME, mmconfig->ownerinfo.name, inifile);
+	wsprintf(tmp, TEXT("%4d"), mmconfig->ownerinfo.birth_year);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_BYEAR, tmp, inifile);
+	wsprintf(tmp, TEXT("%2d"), mmconfig->ownerinfo.birth_month);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_BMONTH, tmp, inifile);
+	wsprintf(tmp, TEXT("%2d"), mmconfig->ownerinfo.birth_day);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_BDAY, tmp, inifile);
+	wsprintf(tmp, TEXT("%1d"), mmconfig->ownerinfo.sex);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_SEX, tmp, inifile);
+	wsprintf(tmp, TEXT("%1d"), mmconfig->ownerinfo.bloodtype);
+	WritePrivateProfileString(INIFILE_SECTION, INIFILE_KEY_OWNER_BLOOD, tmp, inifile);
+}

+ 37 - 0
mmage/preference.h

@@ -0,0 +1,37 @@
+#ifndef _PREFERENCE_H
+#define _PREFERENCE_H
+
+#include "mmage.h"
+#include "../mmvm/wwstruct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+	MMCONFIG_VERTICAL = 0,
+	MMCONFIG_HORIZONTAL,
+};
+
+typedef struct {
+	TCHAR workingdir[MAX_PATH + 1];
+	int viewsize;
+	int horizontal;
+	BOOL queryarg;
+	TCHAR argument[MAX_WW_ARG];
+	TCHAR rom0dir[MAX_PATH + 1];
+	TCHAR ram0dir[MAX_PATH + 1];
+	WW_OWNERINFO ownerinfo;
+} MMAGE_CONFIG, *LPMMAGE_CONFIG;
+
+extern LPMMAGE_CONFIG mmconfig;
+
+void LoadConfig();
+void OpenPreferenceDlg();
+void SaveConfig();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifdef _PREFERENCE_H

+ 174 - 0
mmvm/dispbios.cpp

@@ -0,0 +1,174 @@
+#include "../mmage/mmage.h"
+#include "mmvm.h"
+#include "wwbios.h"
+
+extern "C" {
+#include "../wonx/wonx_include/disp.h"
+}
+
+enum {
+    DISPLAY_CONTROL = 0,
+    DISPLAY_STATUS,
+    FONT_SET_MONODATA,
+    FONT_SET_COLORDATA,
+    FONT_GET_DATA,
+    FONT_SET_COLOR,
+    FONT_GET_COLOR,
+    SCREEN_SET_CHAR,
+    SCREEN_GET_CHAR,
+    SCREEN_FILL_CHAR,
+    SCREEN_FILL_ATTR,
+    SPRITE_SET_RANGE,
+    SPRITE_SET_CHAR,
+    SPRITE_GET_CHAR,
+    SPRITE_SET_LOCATION,
+    SPRITE_GET_LOCATION,
+    SPRITE_SET_CHAR_LOCATION,
+    SPRITE_GET_CHAR_LOCATION,
+    SPRITE_SET_DATA,
+    SCREEN_SET_SCROLL,
+    SCREEN_GET_SCROLL,
+    SCREEN2_SET_WINDOW,
+    SCREEN2_GET_WINDOW,
+    SPRITE_SET_WINDOW,
+    SPRITE_GET_WINDOW,
+    PALETTE_SET_COLOR,
+    PALETTE_GET_COLOR,
+    LCD_SET_COLOR,
+    LCD_GET_COLOR,
+    LCD_SET_SEGMENTS,
+    LCD_GET_SEGMENTS,
+    LCD_SET_SLEEP,
+    LCD_GET_SLEEP,
+    SCREEN_SET_VRAM,
+    SPRITE_SET_VRAM,
+};
+
+void disp_handler(int func_no) {
+	int tmp;
+
+	switch(func_no) {
+		case DISPLAY_CONTROL:
+			display_control(wregs[BX]);
+			break;
+		case DISPLAY_STATUS:
+			wregs[AX] = display_status();
+			break;
+		case FONT_SET_MONODATA:
+			font_set_monodata(wregs[BX], wregs[CX], c_ds + wregs[DX]);
+			break;
+		case FONT_SET_COLORDATA:
+			font_set_colordata(wregs[BX], wregs[CX], c_ds + wregs[DX]);
+			break;
+		case FONT_GET_DATA:
+			font_get_data(wregs[BX], wregs[CX], c_ds + wregs[DX]);
+			break;
+		case FONT_SET_COLOR:
+			font_set_color(wregs[BX]);
+			break;
+		case FONT_GET_COLOR:
+			wregs[AX] = font_get_color();
+			break;
+		case SCREEN_SET_CHAR:
+			screen_set_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH],
+				(unsigned short *)(c_ds + wregs[DX]));
+			break;
+		case SCREEN_GET_CHAR:
+			screen_get_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH],
+				(unsigned short *)(c_ds + wregs[DX]));
+			break;
+		case SCREEN_FILL_CHAR:
+			screen_fill_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
+			break;
+		case SCREEN_FILL_ATTR:
+			screen_fill_attr(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX], wregs[SI]);
+			break;
+		case SPRITE_SET_RANGE:
+			sprite_set_range(wregs[BX], wregs[CX]);
+			break;
+		case SPRITE_SET_CHAR:
+			sprite_set_char(wregs[BX], wregs[CX]);
+			break;
+		case SPRITE_GET_CHAR:
+			wregs[AX] = sprite_get_char(wregs[BX]);
+			break;
+		case SPRITE_SET_LOCATION:
+			sprite_set_location(wregs[BX], *bregs[DL], *bregs[DH]);
+			break;
+		case SPRITE_GET_LOCATION:
+			wregs[AX] = sprite_get_location(wregs[BX]);
+			break;
+		case SPRITE_SET_CHAR_LOCATION:
+			sprite_set_char_location(wregs[BX], wregs[CX], *bregs[DL], *bregs[DH]);
+			break;
+		case SPRITE_GET_CHAR_LOCATION:
+			tmp = sprite_get_char_location(wregs[BX]);
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case SPRITE_SET_DATA:
+			sprite_set_data(wregs[BX], wregs[CX], (unsigned long *)(c_ds + wregs[DX]));
+			break;
+		case SCREEN_SET_SCROLL:
+			screen_set_scroll(*bregs[AL], *bregs[BL], *bregs[BH]);
+			break;
+		case SCREEN_GET_SCROLL:
+			wregs[AX] = screen_get_scroll(*bregs[AL]);
+			break;
+		case SCREEN2_SET_WINDOW:
+			screen2_set_window(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
+			break;
+		case SCREEN2_GET_WINDOW:
+			tmp = screen2_get_window();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case SPRITE_SET_WINDOW:
+			sprite_set_window(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
+			break;
+		case SPRITE_GET_WINDOW:
+			tmp = sprite_get_window();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case PALETTE_SET_COLOR:
+			palette_set_color(wregs[BX], wregs[CX]);
+			break;
+		case PALETTE_GET_COLOR:
+			wregs[AX] = palette_get_color(wregs[BX]);
+			break;
+		case LCD_SET_COLOR:
+			lcd_set_color(wregs[BX], wregs[CX]);
+			break;
+		case LCD_GET_COLOR:
+			tmp = lcd_get_color();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case LCD_SET_SEGMENTS:
+//			lcd_set_segments(wregs[BX]);
+			mmvm->lcdseg = wregs[BX];
+			InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
+			UpdateWindow(wonw32ctx->hWnd);
+			break;
+		case LCD_GET_SEGMENTS:
+//			wregs[AX] = lcd_get_segments();
+			wregs[AX] = mmvm->lcdseg;
+			break;
+		case LCD_SET_SLEEP:
+			lcd_set_sleep(wregs[BX]);
+			break;
+		case LCD_GET_SLEEP:
+			wregs[AX] = lcd_get_sleep();
+			break;
+		case SCREEN_SET_VRAM:
+			screen_set_vram(*bregs[AL], wregs[BX]);
+			break;
+		case SPRITE_SET_VRAM:
+			sprite_set_vram(wregs[BX]);
+			break;
+
+		default:
+			break;
+	}
+}

+ 745 - 0
mmvm/filesys.cpp

@@ -0,0 +1,745 @@
+#ifdef _DEBUG
+#include "../mmage/mmage.h" // for ShowError()
+#endif
+
+#include "../mmage/preference.h"
+#include "filesys.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <tchar.h>
+
+#ifdef __GNUC__
+#if defined(_MBCS)
+#define _tmakepath _makepath
+#define _tsplitpath _splitpath
+#elif defined(_UNICODE)
+#define _tmakepath _wmakepath
+#define _tsplitpath _wplitpath
+#else
+#define _tmakepath _makepath
+#define _tsplitpath _splitpath
+#endif
+#endif
+
+extern LPMMVM mmvm;
+
+typedef struct {
+	LPTSTR rom0names[ROM0FS_NUM_ENTRIES];
+	LPTSTR ram0names[RAM0FS_NUM_ENTRIES];
+	HANDLE fd[OPEN_MAX];
+	TCHAR rom0dirname[MAX_PATH];
+	TCHAR ram0dirname[MAX_PATH];
+} FILETABLE, *LPFILETABLE;
+
+static TCHAR rom0names[ROM0FS_NUM_ENTRIES][MAX_PATH + 1];
+static TCHAR ram0names[RAM0FS_NUM_ENTRIES][MAX_PATH + 1];
+
+static FILETABLE ftable_struct;
+static LPFILETABLE ftable = &ftable_struct;
+
+static void InitFent(WW_FS fs);
+static WW_FARPTR wwfs_entries(WW_FS fs);
+static WW_INT wwfs_n_entries(WW_FS fs);
+static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep);
+static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep);
+static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname);
+static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms);
+static WW_INT wwfs_close(WW_INT fd);
+static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len);
+static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len);
+static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin);
+static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode);
+static WW_INT wwfs_freeze(WW_FS fs, char *fname);
+static WW_INT wwfs_melt(WW_FS fs, char *fname);
+static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep);
+static WW_INT wwfs_unlink(WW_FS fs, char *fname);
+static WW_INT wwfs_newfs(WW_FS fs);
+static WW_INT wwfs_defrag(WW_FS fs);
+static WW_LONG wwfs_space(WW_FS fs);
+
+// fs からファイル名 fname のエントリを取得(内部関数)
+static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n);
+
+void InitFilesys(LPMMVM mmvm) {
+	HANDLE ffile;
+	TCHAR ffind[MAX_PATH + 1];
+	TCHAR w32path[MAX_PATH + 1];
+    WIN32_FIND_DATA fdata;
+ 	TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR];
+	int i;
+
+	// initialize file entries
+	for(i = 0; i < ROOTFS_NUM_ENTRIES; i++) {
+		InitFent(&(mmvm->swork->_root_fs_entries[i]));
+	}
+	for(i = 0; i < ROM0FS_NUM_ENTRIES; i++) {
+		InitFent(&(mmvm->swork->_rom0_fs_entries[i]));
+		ftable->rom0names[i] = &rom0names[i][0];
+	}
+	for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
+		InitFent(&(mmvm->swork->_ram0_fs_entries[i]));
+		ftable->ram0names[i] = &ram0names[i][0];
+	}
+
+	// setup root fs
+	for(i = 0; i < DIRENT_NUM; i++) {
+		mmvm->swork->_root_fs_entries[i].mode = FMODE_DIR|FMODE_R|FMODE_W|FMODE_X;
+		mmvm->swork->_root_fs_entries[i].handler.il = GETFARPTR(mmvm->il->fs);
+	}
+	strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROOT].name, ".");
+	mmvm->swork->_root_fs_entries[DIRENT_ROOT].count = DIRENT_NUM;
+	strcpy(mmvm->swork->_root_fs_entries[DIRENT_KERN].name, "kern");
+	mmvm->swork->_root_fs_entries[DIRENT_KERN].count = 0;
+	strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROM0].name, "rom0");
+	mmvm->swork->_root_fs_entries[DIRENT_ROM0].count = ROM0FS_NUM_ENTRIES;
+	strcpy(mmvm->swork->_root_fs_entries[DIRENT_RAM0].name, "ram0");
+	mmvm->swork->_root_fs_entries[DIRENT_RAM0].count = RAM0FS_NUM_ENTRIES;
+
+	// initialize file handles
+	for(i = 0; i < OPEN_MAX; i++) {
+		if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
+			CloseHandle(ftable->fd[i]);
+			ftable->fd[i] = INVALID_HANDLE_VALUE;
+		}
+		mmvm->swork->_openfiles[i].omode = 0;
+	}
+
+	// initialize /rom0 file entries
+	i = 0;
+	if(_tcslen(mmconfig->rom0dir)) {
+		_stprintf(ffind, TEXT("%s\\*"), mmconfig->rom0dir);
+		_tcscpy(ftable->rom0dirname, mmconfig->rom0dir);
+	} else {
+		_stprintf(ffind, TEXT("%s\\rom0\\*"), mmconfig->workingdir);
+		_stprintf(ftable->rom0dirname, TEXT("%s\\rom0\\"), mmconfig->workingdir);
+	}
+	_tsplitpath(ffind, drive, dir, NULL, NULL);
+	ffile = FindFirstFile(ffind, &fdata);
+	if(ffile != INVALID_HANDLE_VALUE) {
+		do {
+			if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+				strncpy(mmvm->swork->_rom0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
+				mmvm->swork->_rom0_fs_entries[i].count = 0;
+				mmvm->swork->_rom0_fs_entries[i].mode = FMODE_R;
+				mmvm->swork->_rom0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
+				mmvm->swork->_rom0_fs_entries[i].len = fdata.nFileSizeLow;
+				_tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
+				_tcscpy(ftable->rom0names[i], w32path);
+				i++;
+				if(i > ROM0FS_NUM_ENTRIES)
+					break;
+			}
+		} while(FindNextFile(ffile, &fdata));
+		FindClose(ffile);
+	}
+
+	// initialize /ram0 file entries
+	i = 0;
+	if(_tcslen(mmconfig->ram0dir)) {
+		_stprintf(ffind, TEXT("%s\\*"), mmconfig->ram0dir);
+		_tcscpy(ftable->ram0dirname, mmconfig->ram0dir);
+	} else {
+		_stprintf(ffind, TEXT("%s\\ram0\\*"), mmconfig->workingdir);
+		_stprintf(ftable->ram0dirname, TEXT("%s\\ram0\\"), mmconfig->workingdir);
+	}
+	_tsplitpath(ffind, drive, dir, NULL, NULL);
+	ffile = FindFirstFile(ffind, &fdata);
+	if(ffile != INVALID_HANDLE_VALUE) {
+		do {
+			if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+				strncpy(mmvm->swork->_ram0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
+				mmvm->swork->_ram0_fs_entries[i].count = 0;
+				mmvm->swork->_ram0_fs_entries[i].mode = FMODE_R|FMODE_W;
+				mmvm->swork->_ram0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
+				mmvm->swork->_ram0_fs_entries[i].len = fdata.nFileSizeLow;
+				_tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
+				_tcscpy(ftable->ram0names[i], w32path);
+				i++;
+				if(i > RAM0FS_NUM_ENTRIES)
+					break;
+			}
+		} while(FindNextFile(ffile, &fdata));
+		FindClose(ffile);
+	}
+
+}
+
+void CloseFilesys() {
+	int i;
+
+	for(i = 0; i < OPEN_MAX; i++) {
+		if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
+			CloseHandle(ftable->fd[i]);
+			ftable->fd[i] = INVALID_HANDLE_VALUE;
+		}
+		mmvm->swork->_openfiles[i].omode = 0;
+	}
+}
+
+void HandleFsIL(LPMMVM mmvm) {
+	WW_FARPTR p, ret;
+	WW_INT n, mode, perms, fd, len, origin;
+	WW_FS fs, fep;
+	char *fname, *buf;
+	WW_LONG offset;
+
+	switch(ip) {
+ 	case 0: // ILInfo far *super._get_info();
+		wregs[DX] = GETSEG(mmvm->il->fs);
+		wregs[AX] = 0x0100;
+		break;
+
+	case 1: // fent_t far *(far *_entries)(FS fs);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		ret = wwfs_entries(fs);
+		wregs[AX] = ret.segoff.off;
+		wregs[DX] = ret.segoff.seg;
+
+		break;
+
+	case 2: //  int (far *_n_entries)(FS fs);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_n_entries(fs);
+
+		break;
+
+    case 3: // int (far *_getent)(FS fs, int n, fent_t far *fep);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		n = *((WW_INT *)GetArgAddr(4));
+		p = *((WW_FARPTR *)GetArgAddr(6));
+		fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_getent(fs, n, fep);
+
+		break;
+
+    case 4: // int (far *_findent)(FS fs, char far *fname, fent_t far *fep);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(8));
+		fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_findent(fs, fname, fep);
+
+		break;
+
+    case 5: // void far *(far *_mmap)(FS fs, char far *fname);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		ret = wwfs_mmap(fs, fname);
+		wregs[AX] = ret.segoff.off;
+		wregs[DX] = ret.segoff.seg;
+		
+		break;
+
+    case 6: // int (far *_open)(FS fs, char far *fname, int mode, int perms);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		mode = *((WW_INT *)GetArgAddr(8));
+		perms = *((WW_INT *)GetArgAddr(10));
+		wregs[AX] = wwfs_open(fs, fname, mode, perms);
+
+		break;
+
+    case 7:  // int (far *_close)(int fd);
+		fd = *((WW_INT *)GetArgAddr(0));
+		wregs[AX] = wwfs_close(fd);
+
+		break;
+
+    case 8: // int (far *_read)(int fd, char far *buf, int len);
+		fd = *((WW_INT *)GetArgAddr(0));
+		p = *((WW_FARPTR *)GetArgAddr(2));
+		buf = (char *)&memory[FARPTR2ADDR(p)];
+		len = *((WW_INT *)GetArgAddr(6));
+		wregs[AX] = wwfs_read(fd, buf, len);
+
+		break;
+
+    case 9: // int (far *_write)(int fd, char far *buf, int len);
+		fd = *((WW_INT *)GetArgAddr(0));
+		p = *((WW_FARPTR *)GetArgAddr(2));
+		buf = (char *)&memory[FARPTR2ADDR(p)];
+		len = *((WW_INT *)GetArgAddr(6));
+		wregs[AX] = wwfs_write(fd, buf, len);
+
+		break;
+
+    case 10: // long (far *_lseek)(int fd, long offset, int origin);
+		fd = *((WW_INT *)GetArgAddr(0));
+		offset = *((WW_LONG *)GetArgAddr(2));
+		origin = *((WW_INT *)GetArgAddr(6));
+		ret.farptr = wwfs_lseek(fd, offset, origin);
+		wregs[AX] = ret.segoff.off;
+		wregs[DX] = ret.segoff.seg;
+
+		break;
+
+    case 11: // int (far *_chmod)(FS fs, char far *fname, int mode);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		mode = *((WW_INT *)GetArgAddr(8));
+		wregs[AX] = wwfs_chmod(fs, fname, mode);
+
+		break;
+
+    case 12: // int (far *_freeze)(FS fs, char far *fname);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_freeze(fs, fname);
+
+		break;
+
+    case 13: // int (far *_melt)(FS fs, char far *fname);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_melt(fs, fname);
+
+		break;
+
+    case 14: // int (far *_creat)(FS fs, fent_t far *fep);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_creat(fs, fep);
+
+		break;
+
+    case 15: // int (far *_unlink)(FS fs, char *fname);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		p = *((WW_FARPTR *)GetArgAddr(4));
+		fname = (char *)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_unlink(fs, fname);
+
+		break;
+
+    case 16: // int (far *_newfs)(FS fs);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_newfs(fs);
+
+		break;
+
+    case 17: // int (far *_defrag)(FS fs);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		wregs[AX] = wwfs_defrag(fs);
+
+		break;
+
+    case 18: // unsigned long (far *_space)(FS fs);
+		p = *((WW_FARPTR *)GetArgAddr(0));
+		fs = (WW_FS)&memory[FARPTR2ADDR(p)];
+		ret.farptr = wwfs_space(fs);
+		wregs[AX] = ret.segoff.off;
+		wregs[DX] = ret.segoff.seg;
+
+		break;
+
+	default:
+		break;
+	}
+
+	ILReturn();
+}
+
+static WW_FARPTR wwfs_entries(WW_FS fs) {
+	WW_FARPTR ret;
+
+	if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
+		ret.segoff.seg = SRAMWORK_SEG;
+		ret.segoff.off = (LPBYTE)(mmvm->swork->_root_fs_entries) - (LPBYTE)(mmvm->swork);
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
+		ret.segoff.seg = SRAMWORK_SEG;
+		ret.segoff.off = (LPBYTE)(mmvm->swork->_rom0_fs_entries) - (LPBYTE)(mmvm->swork);
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
+		ret.segoff.seg = SRAMWORK_SEG;
+		ret.segoff.off = (LPBYTE)(mmvm->swork->_ram0_fs_entries) - (LPBYTE)(mmvm->swork);
+	} else {
+		ret.farptr = NULL;
+	}
+
+	return ret;
+}
+
+static WW_INT wwfs_n_entries(WW_FS fs) {
+	WW_INT ret;
+
+	if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
+		ret = ROOTFS_NUM_ENTRIES;
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
+		ret = ROM0FS_NUM_ENTRIES;
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
+		ret = RAM0FS_NUM_ENTRIES;
+	} else {
+		ret = E_FS_FILE_NOT_FOUND;
+	}
+
+	return ret;
+}
+
+static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep) {
+	WW_INT ret;
+
+	if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
+		if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
+			memcpy(fep, &(mmvm->swork->_root_fs_entries[n]), sizeof(WW_FENT_T));
+			ret = E_FS_SUCCESS;
+		} else {
+			ret = E_FS_OUT_OF_BOUNDS;
+		}
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
+		if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
+			memcpy(fep, &(mmvm->swork->_rom0_fs_entries[n]), sizeof(WW_FENT_T));
+			ret = E_FS_SUCCESS;
+		} else {
+			ret = E_FS_OUT_OF_BOUNDS;
+		}
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
+		if(n >= 0 && n < RAM0FS_NUM_ENTRIES) {
+			memcpy(fep, &(mmvm->swork->_ram0_fs_entries[n]), sizeof(WW_FENT_T));
+			ret = E_FS_SUCCESS;
+		} else {
+			ret = E_FS_OUT_OF_BOUNDS;
+		}
+	} else {
+		ret = E_FS_FILE_NOT_FOUND;
+	}
+
+	return ret;
+}
+
+static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep) {
+	WW_INT ret;
+	WW_FENT_T *fents;
+	WW_INT n;
+
+	fents = findent(fs, fname, &n);
+	if(fents) {
+		memcpy(fep, &fents, sizeof(WW_FENT_T));
+		ret = E_FS_SUCCESS;
+	} else {
+		ret = E_FS_FILE_NOT_FOUND;
+	}
+
+	return ret;
+}
+
+static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname) {
+	WW_FARPTR ret;
+
+	// not supported
+	ret.farptr = 0;
+
+	return ret;
+}
+
+static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms) {
+	WW_INT ret;
+	WW_FENT_T *fents;
+	LPTSTR *fntable;
+	DWORD w32mode;
+	LPTSTR w32fname;
+	WW_INT nfent;
+	WW_FENT_T newfile;
+
+	switch(mode) {
+	case FMODE_R:
+		w32mode = GENERIC_READ;
+		break;
+	case FMODE_W:
+		w32mode = GENERIC_WRITE;
+		break;
+	case (FMODE_R|FMODE_W):
+		w32mode = (GENERIC_READ|GENERIC_WRITE);
+		break;
+	default:
+		return E_FS_PERMISSION_DENIED;
+		break;
+	}
+
+	if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
+		fntable = ftable->rom0names;
+		if(mode & FMODE_W)
+			return E_FS_PERMISSION_DENIED;
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
+		fntable = ftable->ram0names;
+	} else {
+		return E_FS_FILE_NOT_FOUND;
+	}
+
+	fents = findent(fs, fname, &nfent);
+	if(!fents) {
+		// ファイルが見つからなかったら新しいファイルを作る
+		InitFent(&newfile);
+		strncpy(newfile.name, fname, MAXPATHLEN);
+		newfile.mode = mode;
+
+		if(wwfs_creat(fs, &newfile) != E_FS_SUCCESS)
+			return E_FS_FILE_NOT_FOUND;
+
+		fents = findent(fs, fname, &nfent);
+		if(!fents)
+			return E_FS_FILE_NOT_FOUND;
+	}
+
+	w32fname = fntable[nfent];
+	for(ret = 0; ret < OPEN_MAX; ret++) {
+		if(ftable->fd[ret] == INVALID_HANDLE_VALUE)
+			break;
+	}
+
+	if(ret == OPEN_MAX) {
+		ret = E_FS_ERROR;
+	} else {
+		ftable->fd[ret] = CreateFile(w32fname, w32mode, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+		if(ftable->fd[ret] == INVALID_HANDLE_VALUE) {
+			ret = E_FS_PERMISSION_DENIED;
+		} else {
+			mmvm->swork->_openfiles[ret].fs = (WW_FS)mmvm->cwfs.farptr;
+			mmvm->swork->_openfiles[ret].fentp.segoff.seg = SRAMWORK_SEG;
+			mmvm->swork->_openfiles[ret].fentp.segoff.off = (LPBYTE)&fents - (LPBYTE)mmvm->swork;
+			mmvm->swork->_openfiles[ret].omode = mode;
+			mmvm->swork->_openfiles[ret].fpos = 0;
+			mmvm->swork->_openfiles[ret].flen = 0;
+			mmvm->swork->_openfiles[ret].floc.farptr = 0;
+			mmvm->swork->_openfiles[ret].count = 0;
+			mmvm->swork->_openfiles[ret].pcb = 1;
+			mmvm->swork->_openfiles[ret].driver.farptr = 0;
+		}
+	}
+
+	return ret;
+}
+
+static WW_INT wwfs_close(WW_INT fd) {
+	WW_INT ret;
+
+	if(!(mmvm->swork->_openfiles[fd].omode))
+		return E_FS_ERROR;
+
+	if(ftable->fd[fd] != INVALID_HANDLE_VALUE) {
+		if(CloseHandle(ftable->fd[fd]))
+			ret = E_FS_SUCCESS;
+		else
+			ret = E_FS_FILE_NOT_OPEN;
+	} else {
+		ret = E_FS_FILE_NOT_OPEN;
+	}
+	ftable->fd[fd] = INVALID_HANDLE_VALUE;
+	mmvm->swork->_openfiles[fd].omode = 0;
+
+	return ret;
+}
+
+static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len) {
+	WW_INT ret;
+	DWORD nbytes;
+
+	if(!(mmvm->swork->_openfiles[fd].omode))
+		return E_FS_ERROR;
+
+	if(!(mmvm->swork->_openfiles[fd].omode & FMODE_R))
+		return E_FS_PERMISSION_DENIED;
+
+	if(ReadFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
+		ret = (WW_INT)nbytes;
+	} else {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len) {
+	WW_INT ret;
+	DWORD nbytes;
+
+	if(!(mmvm->swork->_openfiles[fd].omode))
+		return E_FS_ERROR;
+
+	if(!(mmvm->swork->_openfiles[fd].omode & FMODE_W))
+		return E_FS_PERMISSION_DENIED;
+
+	if(WriteFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
+		ret = (WW_INT)nbytes;
+	} else {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin) {
+	WW_LONG ret;
+	DWORD w32off, w32org;
+
+	if(!(mmvm->swork->_openfiles[fd].omode))
+		return E_FS_ERROR;
+
+	switch(origin) {
+	case 0:
+		w32org = FILE_BEGIN;
+		break;
+	case 1:
+		w32org = FILE_CURRENT;
+		break;
+	case 2:
+		w32org = FILE_END;
+		break;
+	default:
+		return E_FS_OUT_OF_BOUNDS;
+		break;
+	}
+
+	if(ftable->fd[fd] == INVALID_HANDLE_VALUE) {
+		ret = E_FS_FILE_NOT_OPEN;
+	} else {
+		w32off = SetFilePointer(ftable->fd[fd], offset, NULL, w32org);
+		if(w32off != 0xFFFFFFFF)
+			ret = w32off;
+		else
+			ret = E_FS_OUT_OF_BOUNDS;
+	}
+
+	return ret;
+
+}
+
+// not yet.
+static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode) {
+	return E_FS_ERROR;
+}
+
+static WW_INT wwfs_freeze(WW_FS fs, char *fname) {
+	return E_FS_ERROR;
+}
+
+static WW_INT wwfs_melt(WW_FS fs, char *fname) {
+	return E_FS_ERROR;
+}
+
+static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep) {
+	WW_FENT_T *fent;
+	WW_INT n;
+	HANDLE newfile;
+	int i;
+
+	if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
+		return E_FS_PERMISSION_DENIED;
+
+	if(findent(fs, fep->name, &n))
+		return E_FS_ERROR;
+
+	fent = NULL;
+	for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
+		if(mmvm->swork->_ram0_fs_entries[i].count == (WW_INT)-1) {
+			fent = &(mmvm->swork->_ram0_fs_entries[i]);
+			n = i;
+			break;
+		}
+	}
+
+	if(!fent)
+		return E_FS_ERROR;
+
+	strcat(ftable->ram0names[n], ftable->ram0dirname);
+	strcat(ftable->ram0names[n], fep->name);
+
+	newfile = CreateFile(ftable->ram0names[n], GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+	if(newfile == INVALID_HANDLE_VALUE)
+		return E_FS_ERROR;
+
+	CloseHandle(newfile);
+	memcpy(fent, fep, sizeof(WW_FENT_T));
+	fent->count = 0;
+
+	return E_FS_SUCCESS;
+}
+
+static WW_INT wwfs_unlink(WW_FS fs, char *fname) {
+	WW_FENT_T *fent;
+	WW_INT n;
+
+	if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
+		return E_FS_PERMISSION_DENIED;
+
+	fent = findent(fs, fname, &n);
+	if(!fent)
+		return E_FS_FILE_NOT_FOUND;
+
+	if(!DeleteFile(ftable->ram0names[n]))
+		return E_FS_ERROR;
+
+	fent->count = (WW_INT)-1;
+
+	return E_FS_SUCCESS;
+}
+
+static WW_INT wwfs_newfs(WW_FS fs) {
+	return E_FS_ERROR;
+}
+
+static WW_INT wwfs_defrag(WW_FS fs) {
+	return E_FS_SUCCESS;
+}
+
+static WW_LONG wwfs_space(WW_FS fs) {
+	return 0x7fffffff;
+}
+
+static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n) {
+	int n_entries;
+	WW_FENT_T *fents;
+	int i;
+
+	if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
+		n_entries = ROOTFS_NUM_ENTRIES;
+		fents = mmvm->swork->_root_fs_entries;
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
+		n_entries = ROM0FS_NUM_ENTRIES;
+		fents = mmvm->swork->_rom0_fs_entries;
+	} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
+		n_entries = RAM0FS_NUM_ENTRIES;
+		fents = mmvm->swork->_ram0_fs_entries;
+	} else {
+		return NULL;
+	}
+
+	for(i = 0; i < n_entries; i++) {
+		if(fents[i].count != -1 && !strncmp(fname, fents[i].name, MAXPATHLEN)) {
+			*n = i;
+			return &fents[i];
+		}
+	}
+
+	return NULL;
+}
+
+static void InitFent(WW_FS fent) {
+	strcpy(fent->name, "");
+	strcpy(fent->info, "");
+	fent->loc = 0;
+	fent->len = 0;
+	fent->count = (WW_INT)-1;
+	fent->mode = 0;
+	fent->mtime = 0;
+	fent->handler.appid = 0;
+	fent->resource = 0xffffffff;
+}
+

+ 11 - 0
mmvm/filesys.h

@@ -0,0 +1,11 @@
+#ifndef _MMVM_FILESYS_H
+#define _MMVM_FILESYS_H
+
+#include "mmvm.h"
+#include "wwstruct.h"
+
+void InitFilesys(LPMMVM mmvm);
+void CloseFilesys();
+void HandleFsIL(LPMMVM mmvm);
+
+#endif // #ifdef _MMVM_FILESYS_H

+ 109 - 0
mmvm/kanjifont.cpp

@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include "kanjifont.h"
+
+#define NUM_OF_KANJIFONT 6877
+#define KANJIFONT_SIZE 8
+
+static unsigned char kfonts[NUM_OF_KANJIFONT * KANJIFONT_SIZE];
+static unsigned char notfound[KANJIFONT_SIZE] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
+static int font_loaded;
+
+int InitKanjiFont(char *fontfile) {
+	FILE *fp;
+	int c, i;
+
+	font_loaded = 0;
+	fp = fopen(fontfile, "rb");
+
+	if(fp != NULL) {
+		i = 0;
+		while((c = fgetc(fp)) >= 0) {
+			kfonts[i++] = (unsigned char)c;
+		}
+		if(i == NUM_OF_KANJIFONT * KANJIFONT_SIZE)
+			font_loaded = 1;
+	}
+
+	return font_loaded;
+}
+
+unsigned char *GetKanjiFont(int u, int d) {
+	int c;
+	if (u > 0x9f) u -= 0x40;
+	if (d > 0x7f) d--;
+	d -= 0x40;
+	u -= 0x81;
+	c = u * 0xbc + d;
+
+	if(!font_loaded)
+		return notfound;
+
+	if (c >= 7806) {
+		c = -1;
+	} else if(c >= 4418) {  /* 第二水準漢字 */
+		c = c + (0xda1 - 4418);
+	} else if (c >= 4375) { /* なし */
+		c = -1;
+	} else if (c >= 1410) { /* 第一水準漢字 */
+		c = c + (0x20c - 1410);
+	} else if (c >= 690) {  /* 禁止領域の文字 */
+		c = -1;
+	} else if (c >= 658) {  /* 罫線素 */
+		c = c + (0x1ec - 658);
+	} else if (c >= 612) {  /* ロシア小 */
+		c = c + (0x1cb - 612);
+	} else if (c >= 564) {  /* ロシア大 */
+		c = c + (0x1aa - 564);
+	} else if (c >= 502) {  /* ギリシャ小 */
+		c = c + (0x192 - 502);
+	} else if (c >= 470) {  /* ギリシャ大*/
+		c = c + (0x17a - 470);
+	} else if (c >= 376) {  /* カタカナ */
+		c = c + (0x124 - 376);
+	} else if (c >= 282) {  /* ひらがな */
+		c = c + (0xd1 - 282);
+	} else if (c >= 252) {  /* 英小文字 */
+		c = c + (0xb7 - 252);
+	} else if (c >= 220) {  /* 英大文字 */
+		c = c + (0x9d - 220);
+	} else if (c >= 203) {  /* 数字 */
+		c = c + (0x93 - 203);
+	} else if (c >= 187) { /* 記号(◯) */
+		c = 0x92;
+	} else if (c >= 175) { /* 記号(ʼn♯♭♪†‡¶) */
+		c = c + (0x8a - 203);
+	} else if (c >= 153) { /* 記号(∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬) */
+		c = c + (0x7b - 153);
+	} else if (c >= 135) { /* 記号(∧∨¬⇒⇔∀∃) */
+		c = c + (0x74 - 135);
+	} else if (c >= 119) { /* 記号(∈∋⊆⊇⊂⊃∪∩) */
+		c = c + (0x6c - 119);
+	} // else {} /* 記号(その他) */
+
+	if(c == -1)
+		return notfound;
+	else
+		return kfonts + (c * KANJIFONT_SIZE);
+
+}
+
+void GetKanjiFont16(int code, unsigned char *font) {
+	unsigned char *font8;
+	int i, j;
+
+	font8 = GetKanjiFont((code >> 8) & 0xff, code & 0xff);
+	for(i = 0; i < 8; i++) {
+		font[i * 2 + 1] = 0;
+		for(j = 0; j < 4; j++) {
+			font[i * 2 + 1] <<= 2;
+			if((font8[i] >> j) & 1)
+				font[i * 2 + 1] |= 3; // (11)2
+		}
+		font[i * 2] = 0;
+		for(j = 4; j < 8; j++) {
+			font[i * 2] <<= 2;
+			if((font8[i] >> j) & 1)
+				font[i * 2] |= 3; // (11)2
+		}
+	}
+}

+ 16 - 0
mmvm/kanjifont.h

@@ -0,0 +1,16 @@
+#ifndef _KANJIFONT_H
+#define _KANJIFONT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int InitKanjiFont(char *fontfile);
+unsigned char *GetKanjiFont(int u, int d);
+void GetKanjiFont16(int code, unsigned char *font);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 49 - 0
mmvm/keybios.cpp

@@ -0,0 +1,49 @@
+#include "../mmage/mmage.h"
+#include "wwbios.h"
+
+extern "C" {
+#include "../wonx/wonx_include/key.h"
+}
+
+enum {
+    KEY_PRESS_CHECK = 0,
+    KEY_HIT_CHECK,
+    KEY_WAIT,
+    KEY_SET_REPEAT,
+    KEY_GET_REPEAT,
+    KEY_HIT_CHECK_WITH_REPEAT,
+};
+
+void key_handler(int func_no) {
+	WORD ret;
+
+	switch(func_no) {
+		case KEY_PRESS_CHECK:
+			wregs[AX] = key_press_check();
+			break;
+		case KEY_HIT_CHECK:
+			wregs[AX] = key_hit_check();
+			break;
+		case KEY_WAIT:
+			// return 値が 0 のときは ip を -2 して見かけ上 wait してるようにみせかける
+			ret = key_wait();
+			if(ret) {
+				wregs[AX] = ret;
+			} else {
+				WaitForSingleObject(wonw32ctx->syncevent, INFINITE);
+				ip = ip - 2;
+			}
+			break;
+		case KEY_SET_REPEAT:
+			key_set_repeat(*bregs[BL], *bregs[BH]);
+			break;
+		case KEY_GET_REPEAT:
+			wregs[AX] = key_get_repeat();
+			break;
+		case KEY_HIT_CHECK_WITH_REPEAT:
+			wregs[AX] = key_hit_check_with_repeat();
+			break;
+		default:
+			break;
+	}
+}

+ 574 - 0
mmvm/mmvm.cpp

@@ -0,0 +1,574 @@
+#include "../mmage/mmage.h"
+#include "../mmage/preference.h"
+
+#include "../resource/resource.h"
+#include "wwstruct.h"
+#include "mmvm.h"
+#include "filesys.h"
+#include "kanjifont.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <process.h>
+#include <tchar.h>
+
+#ifdef __GNUC__
+#if defined(_MBCS)
+#define _tmakepath _makepath
+#define _tsplitpath _splitpath
+#elif defined(_UNICODE)
+#define _tmakepath _wmakepath
+#define _tsplitpath _wplitpath
+#else
+#define _tmakepath _makepath
+#define _tsplitpath _splitpath
+#endif
+#endif
+
+/* 
+  IL は CS:ip が特定アドレスになったところでトラップすることで実現する
+
+  IlibIL は 0100:0000 に配置。
+  IlibIL の関数は 0100:0000 から 1byte ずつ順に配置されているように見せる。
+    _get_info() は 0100:0000
+	_open() は 0100:0001
+	_open_system() は 0100:0002
+  という具合に。
+  Ilib の ILInfo は 0100:0100 に配置。
+  Ilib の ILInfo が指す文字列は 0100:(0100 + ILInfo のサイズ) に配置。
+    なので IL の関数の数は(_get_info() を含めて) 0x0100 個まで。
+
+  ProcIL は 0200:0000 から、FsIL は 0300:0000 から同じように配置。
+  こんなんでええんか?
+*/
+
+#define MMVM_ILIBILADDR	0x01000000
+#define MMVM_PROCILADDR	0x02000000
+#define MMVM_FSILADDR	0x03000000
+
+static MMVM_IL mmvmil_struct;
+static MMVM mmvm_struct;
+static MMVM_APPINFO appinfo_struct;
+
+LPMMVM mmvm;
+BYTE *memory;
+
+static void HandleIlibIL();
+static void HandleProcIL();
+
+static LRESULT CALLBACK GetArgument(HWND, UINT, WPARAM, LPARAM);
+static void StartThread(LPVOID arg);
+
+BOOL CreateVM() {
+	LPBYTE rom0;
+	TCHAR fontfile[MAX_PATH + 1];
+   char drive[_MAX_DRIVE + 1];
+   char dir[_MAX_DIR + 1];
+
+	mmvm =  &mmvm_struct;
+	mmvm->memory = memory = (BYTE *)malloc(MEMORYSIZE);
+	if(!memory) {
+		return FALSE;
+	}
+	memset(memory, 0, MEMORYSIZE);
+
+	mmvm->il = &mmvmil_struct;
+	mmvm->appinfo = &appinfo_struct;
+
+	mmvm->il->il.farptr = MMVM_ILIBILADDR;
+	strcpy(mmvm->il->ilinfo.className, "ILibIL");
+	strcpy(mmvm->il->ilinfo.name, "ILibIL");
+	strcpy(mmvm->il->ilinfo.version, "1.0");
+	strcpy(mmvm->il->ilinfo.description, "MMVM default ILibIL");
+	mmvm->il->ilinfo.depends = NULL;
+
+	mmvm->il->proc.farptr = MMVM_PROCILADDR;
+	strcpy(mmvm->il->procinfo.className, "ProcIL");
+	strcpy(mmvm->il->procinfo.name, "ProcIL");
+	strcpy(mmvm->il->procinfo.version, "1.0");
+	strcpy(mmvm->il->procinfo.description, "MMVM default ProcIL");
+	mmvm->il->procinfo.depends = NULL;
+	
+	mmvm->il->fs.farptr = MMVM_FSILADDR;
+	strcpy(mmvm->il->fsinfo.className, "FsIL");
+	strcpy(mmvm->il->fsinfo.name, "FsIL");
+	strcpy(mmvm->il->fsinfo.version, "1.0");
+	strcpy(mmvm->il->fsinfo.description, "MMVM default FsIL");
+	mmvm->il->fsinfo.depends = NULL;
+
+	mmvm->swork = (LPWW_SRAMWork)&memory[SRAMWORK_SEG << 4];
+	rom0 = (LPBYTE)&(mmvm->swork->_root_fs_entries[DIRENT_ROM0]);
+	mmvm->cwfs.segoff.seg = SRAMWORK_SEG;
+	mmvm->cwfs.segoff.off = rom0 - (LPBYTE)(mmvm->swork);
+
+	mmvm->lcdseg = 0;
+
+	GetModuleFileName(NULL, fontfile, MAX_PATH);
+	_tsplitpath(fontfile, drive, dir, NULL, NULL);
+	_tmakepath(fontfile, drive, dir, ELISA_FONTFILE, NULL);
+	InitKanjiFont(fontfile);
+
+	return TRUE;
+}
+
+void InitVM() {
+	LPWW_IlibIL ilil;
+	LPWW_ProcIL procil;
+	LPWW_FsIL fsil;
+	LPWW_ILInfo ilinfo, procinfo, fsinfo;
+	unsigned int tmp1;
+
+	init_cpu();
+    sregs[CS] = APP_CSEG;
+    sregs[DS] = APP_CSEG; // ここでは何に設定しても同じ
+    sregs[ES] = APP_CSEG; // ここでは何に設定しても同じ
+    sregs[SS] = STACK_SEG;
+	ip = 0;
+	c_cs = SegToMemPtr(CS);
+	c_ds = SegToMemPtr(DS);
+	c_es = SegToMemPtr(ES);
+	c_stack = c_ss = SegToMemPtr(SS);
+
+	// set return address
+	tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
+	PutMemW(c_stack, tmp1, 0x0010);
+	tmp1 = (WORD)(tmp1 - 2);
+	PutMemW(c_stack, tmp1, 0x0000);
+	WriteWord(&wregs[SP], tmp1);
+
+	ilil = (LPWW_IlibIL)&memory[FARPTR2ADDR(mmvm->il->il)];
+	ilil->super.n_methods = 2;
+	ilil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
+	ilil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0);
+	ilil->_open.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->il), 1);
+	ilil->_open_system.farptr =    SEGOFF2FARPTR(GETSEG(mmvm->il->il), 2);
+	ilinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->il) << 4 | 0x0100];
+	memcpy((LPBYTE)ilinfo + sizeof(WW_ILInfo), &mmvm->il->ilinfo, sizeof(mmvm->il->ilinfo));
+	ilinfo->className.farptr =   SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo)     );
+	ilinfo->name.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 32);
+	ilinfo->version.farptr =     SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 64);
+	ilinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 96);
+	ilinfo->depends.farptr =     SEGOFF2FARPTR(0, 0);
+
+	procil = (LPWW_ProcIL)&memory[FARPTR2ADDR(mmvm->il->proc)];
+	procil->super.n_methods = 8;
+	procil->super.link_pos.farptr = GETFARPTR(mmvm->il->proc);
+	procil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0);
+	procil->_load.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 1);
+	procil->_run.farptr =            SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 2);
+	procil->_exec.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 3);
+	procil->_exit.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 4);
+	procil->_yield.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 5);
+	procil->_suspend.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 6);
+	procil->_resume.farptr =         SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 7);
+	procil->_swap.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 8);
+	procinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->proc) << 4 | 0x0100];
+	memcpy((LPBYTE)procinfo + sizeof(WW_ILInfo), &mmvm->il->procinfo, sizeof(mmvm->il->procinfo));
+	procinfo->className.farptr =   SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo)     );
+	procinfo->name.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 32);
+	procinfo->version.farptr =     SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 64);
+	procinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 96);
+	procinfo->depends.farptr =     SEGOFF2FARPTR(0, 0);
+
+	fsil = (LPWW_FsIL)&memory[FARPTR2ADDR(mmvm->il->fs)];
+	fsil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
+	fsil->super.n_methods = 18;
+	fsil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0);
+	fsil->_entries.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 1);
+	fsil->_n_entries.farptr =      SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 2);
+	fsil->_getent.farptr =         SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 3);
+	fsil->_findent.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 4);
+	fsil->_mmap.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 5);
+	fsil->_open.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 6);
+	fsil->_close.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 7);
+	fsil->_read.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 8);
+	fsil->_write.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 9);
+	fsil->_lseek.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 10);
+	fsil->_chmod.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 11);
+	fsil->_freeze.farptr =         SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 12);
+	fsil->_melt.farptr =           SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 13);
+	fsil->_creat.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 14);
+	fsil->_unlink.farptr =         SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 15);
+	fsil->_newfs.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 16);
+	fsil->_defrag.farptr =         SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 17);
+	fsil->_space.farptr =          SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 18);
+	fsinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->fs) << 4 | 0x0100];
+	memcpy((LPBYTE)fsinfo + sizeof(WW_ILInfo), &mmvm->il->fsinfo, sizeof(mmvm->il->fsinfo));
+	fsinfo->className.farptr =   SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo)     );
+	fsinfo->name.farptr =        SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 32);
+	fsinfo->version.farptr =     SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 64);
+	fsinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 96);
+	fsinfo->depends.farptr =     SEGOFF2FARPTR(0, 0);
+
+	mmvm->lcdseg = 0;
+
+	mmvm->appinfo->loadended = FALSE;
+	mmvm->appinfo->maincalled = FALSE;
+}
+
+void UpdateVM() {
+	LPWW_PCB pcb;
+	unsigned int tmp1;
+	WORD argptr;
+	WORD argc;
+	WORD args[256];
+	int i;
+	BOOL quote;
+
+	if(sregs[CS] == GETSEG(mmvm->il->il)) {
+		HandleIlibIL();
+		return;
+	}
+	if(sregs[CS] == GETSEG(mmvm->il->proc)) {
+		HandleProcIL();
+		return;
+	}
+	if(sregs[CS] == GETSEG(mmvm->il->fs)) {
+		HandleFsIL(mmvm);
+		return;
+	}
+
+	if(sregs[CS] == 0x0010 && ip == 0x0000) { // if load routine returned
+		mmvm->appinfo->loadended = TRUE;
+		ip = wregs[AX];
+		sregs[CS] = wregs[DX];
+	    c_cs = SegToMemPtr(CS);
+		c_ds = SegToMemPtr(DS);
+		c_es = SegToMemPtr(ES);
+		c_stack = c_ss = SegToMemPtr(SS);
+
+		pcb = (LPWW_PCB)SegToMemPtr(ES);
+		// init dseg_start
+		pcb->pid = 1;
+		pcb->ppid = 0;
+		pcb->pcbid = 1;
+		pcb->ppcbid = 0;
+		pcb->cwfs.farptr = GETFARPTR(mmvm->cwfs);
+		pcb->ilib.farptr = GETFARPTR(mmvm->il->il);
+		pcb->proc.farptr = GETFARPTR(mmvm->il->proc);
+		pcb->resource.farptr = (sregs[CS] << 16) | mmvm->appinfo->fent.resource;
+		strcpy(pcb->currentdir, "/rom0");
+
+		argptr = pcb->argv;
+		argc = 0;
+		args[0] = argptr;
+		quote = FALSE;
+		for(i = 0; i < (int)strlen(mmvm->appinfo->commandline) + 1; i++) {
+			if(mmvm->appinfo->commandline[i] == TEXT('\\')) {
+				if(i < (int)strlen(mmvm->appinfo->commandline)) {
+					i++;
+					memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
+				}
+			} else if(_istspace(mmvm->appinfo->commandline[i]) && !quote) {
+				argc++;
+				memory[(FIRST_DSEG << 4) + argptr++] = TEXT('\0');
+				args[argc] = argptr;
+				while(isspace(mmvm->appinfo->commandline[i]))
+					i++;
+				if(!mmvm->appinfo->commandline[i])
+					argc--;
+				i--;
+			} else if(quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
+				quote = FALSE;
+			} else if(!quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
+				quote = TRUE;
+			} else {
+				memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
+			}
+		}
+		argc++;
+
+		// push argv
+		tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
+		PutMemW(c_stack, tmp1, argptr);
+		pcb->argv = argptr;
+
+		// set argv
+		for(i = 0; i < argc; i++) {
+			memory[(FIRST_DSEG << 4) + argptr++] =  args[i]       & 0xff;
+			memory[(FIRST_DSEG << 4) + argptr++] = (args[i] >> 8) & 0xff;
+		}
+
+		// push argc
+		tmp1 = (WORD)(tmp1 - 2);
+		PutMemW(c_stack, tmp1, argc);
+
+		// set _heap address
+		pcb->heap = argptr; 
+
+		// push return address
+		tmp1 = (WORD)(tmp1 - 2);
+		PutMemW(c_stack, tmp1, 0x0010);
+		tmp1 = (WORD)(tmp1 - 2);
+		PutMemW(c_stack, tmp1, 0x0000);
+		WriteWord(&wregs[SP], tmp1);
+
+		memcpy(&memory[FINAL_DSEG << 4], &memory[FIRST_DSEG << 4], 0x10000);
+		sregs[DS] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
+		sregs[ES] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
+		c_ds = SegToMemPtr(DS);
+		c_es = SegToMemPtr(ES);
+
+		InitFilesys(mmvm);
+	}
+
+	// main が呼ばれる直前に無理矢理 DS、ES を 0x2000 にする
+	if(mmvm->appinfo->loadended && !mmvm->appinfo->maincalled && *(c_cs + ip) == 0xe8) {
+		sregs[DS] = FINAL_DSEG;
+		sregs[ES] = FINAL_DSEG;
+		c_ds = SegToMemPtr(DS);
+		c_es = SegToMemPtr(ES);
+		mmvm->appinfo->maincalled = TRUE;
+	}
+
+}
+
+
+void OpenDlgAndRun() {
+	OPENFILENAME ofn;
+	TCHAR filename[MAX_PATH + 1];
+	TCHAR wndName[1024];
+
+	filename[0] = TEXT('\0');
+	ZeroMemory(&ofn, sizeof(OPENFILENAME));
+	ofn.lStructSize = sizeof(OPENFILENAME);
+	ofn.hwndOwner = wonw32ctx->hWnd;
+	ofn.lpstrFilter = TEXT("WonderWitch 転送形式ファイル (*.fx)\0*.fx\0すべてのファイル (*.*)\0*.*\0\0");
+	ofn.lpstrFile = filename;
+	ofn.nMaxFile = sizeof(filename);
+	ofn.Flags = OFN_FILEMUSTEXIST;
+	if(GetOpenFileName(&ofn)) {
+		if(wonw32ctx->running) {
+			StopExecution(5000);
+		}
+
+		wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
+
+		if(!wonw32ctx->loaded) {
+			SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
+			MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
+			wonw32ctx->loaded = FALSE;
+			return;
+		}
+
+		wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
+		SetWindowText(wonw32ctx->hWnd, wndName);
+
+		sprintf(mmvm->appinfo->commandline, "%s ", mmvm->appinfo->fent.name);
+		if(mmconfig->queryarg) {
+			DialogBoxParam(wonw32ctx->hInst, MAKEINTRESOURCE(IDD_ARGUMENT), wonw32ctx->hWnd, 
+				(DLGPROC)GetArgument, (LPARAM)mmvm->appinfo->commandline);
+		} else {
+			sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, mmconfig->argument);
+		}
+		RunWWApp();
+	}
+
+	return;
+}
+
+void OpenAndRun(LPCTSTR filename, LPCTSTR cmdline) {
+	TCHAR wndName[1024];
+
+	if(wonw32ctx->running) {
+		StopExecution(5000);
+	}
+
+	wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
+
+	if(!wonw32ctx->loaded) {
+		SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
+		MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
+		wonw32ctx->loaded = FALSE;
+		return;
+	}
+
+	wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
+	SetWindowText(wonw32ctx->hWnd, wndName);
+
+	sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, cmdline);
+
+	RunWWApp();
+
+	return;
+}
+
+void RunWWApp() {
+	wonw32ctx->cputhread = (HANDLE)_beginthread(StartThread, 0, NULL);
+}
+
+BOOL LoadFXFile(LPCTSTR filename, WORD seg, WW_FENT_T *fentp) {
+	LPBYTE b;
+	int c;
+	FILE *fp;
+	int i;
+
+	b = (LPBYTE)fentp;
+	fp = fopen(filename, "rb");
+	if(!fp)
+		goto error;
+	for(i = 0; i < 64; i++) {
+		if((c = fgetc(fp)) == EOF)
+			goto error;
+		b[i] = (BYTE)(c & 0xff);
+		if((i == 0) && (b[i] != 0x23)) goto error;
+		if((i == 1) && (b[i] != 0x21)) goto error;
+		if((i == 2) && (b[i] != 0x77)) goto error;
+		if((i == 3) && (b[i] != 0x73)) goto error;
+	}
+	for(i = 0; i < 64; i++) {
+		if((c = fgetc(fp)) == EOF)
+			goto error;
+		b[i] = (BYTE)(c & 0xff);
+	}
+
+	i = seg << 4;
+	while((c = fgetc(fp)) != EOF)
+		memory[i++] = (BYTE)(c & 0xff);
+
+	return TRUE;
+
+error:
+	if(fp)
+		fclose(fp);
+	return FALSE;
+}
+
+static LRESULT CALLBACK GetArgument( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+	static LPTSTR arg;
+	HWND argwnd;
+	HWND ok;
+
+	switch( message )
+	{
+		case WM_INITDIALOG:
+			arg = (LPTSTR)lParam;
+			argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
+			SetWindowText(argwnd, arg);
+			SendMessage(argwnd, EM_SETSEL, -1, 0);
+			return TRUE;
+
+		case WM_COMMAND:
+			argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
+			GetWindowText(argwnd, arg, 1024);
+			if( LOWORD(wParam) == IDOK)  {
+				if(lstrlen(arg) > 0) 
+				{
+					EndDialog(hDlg, 0);
+					return TRUE;
+				}
+			} else if(LOWORD(wParam) == IDC_ARGUMENT && HIWORD(wParam) == EN_UPDATE) {
+				ok = GetDlgItem(hDlg, IDOK);
+				if(lstrlen(arg) > 0) {
+					EnableWindow(ok, TRUE);
+				} else {
+					EnableWindow(ok, FALSE);
+				}
+				return TRUE;
+			}
+			break;
+	}
+    return FALSE;
+}
+
+void Restart() {
+	if(wonw32ctx->running) {
+		StopExecution(5000);
+	}
+	RunWWApp();
+}
+
+void StopExecution(DWORD wait) {
+	wonw32ctx->running = FALSE;
+	PulseEvent(wonw32ctx->syncevent);
+	TerminateThread(wonw32ctx->cputhread, 0);
+	if(WaitForSingleObject(wonw32ctx->cputhread, wait) != WAIT_OBJECT_0) {
+		MessageBox(wonw32ctx->hWnd, TEXT("MiracleMage 内部エラーです\nMiracleMage を再起動してください"), NULL, MB_OK);
+	}
+}
+
+void StartThread(LPVOID arg) {
+	wonw32ctx->running = TRUE;
+	InitVM();
+
+	InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
+	UpdateWindow(wonw32ctx->hWnd);
+
+	while(wonw32ctx->running) {
+		execute();
+		UpdateVM();
+	}
+
+	CloseFilesys();
+	mmvm->lcdseg = 0;
+
+	InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
+	UpdateWindow(wonw32ctx->hWnd);
+
+	_endthread();
+}
+
+
+static void HandleIlibIL() {
+	WW_FARPTR ilname;
+	WW_FARPTR ilbuf;
+
+	switch(ip) {
+	case 0: // ILInfo far *super._get_info();
+		wregs[DX] = GETSEG(mmvm->il->il);
+		wregs[AX] = 0x0100;
+		break;
+
+	case 1: // int _open(char far *ilname, IL far *ilbuf);
+	case 2: // int _open_system(char far *ilname, IL far *ilbuf);
+		ilname = *((WW_FARPTR *)GetArgAddr(0));
+		ilbuf = *((WW_FARPTR *)GetArgAddr(4));
+
+		memory[FARPTR2ADDR(ilbuf)    ] = 0;
+		memory[FARPTR2ADDR(ilbuf) + 1] = 0;
+		memory[FARPTR2ADDR(ilbuf) + 2] = 0;
+		memory[FARPTR2ADDR(ilbuf) + 3] = 0;
+
+		wregs[AX] = 0xffff;
+		break;
+
+	default:
+		wregs[AX] = 0xffff;
+		break;
+	}
+
+	ILReturn();
+}
+
+static void HandleProcIL() {
+	switch(ip) {
+	case 0: // ILInfo far *super._get_info();
+		wregs[DX] = GETSEG(mmvm->il->proc);
+		wregs[AX] = 0x0100;
+		break;
+
+	default:
+		wregs[AX] = 0xffff;
+		break;
+	}
+
+	ILReturn();
+}
+
+void ILReturn() {
+	unsigned tmp = ReadWord(&wregs[SP]);
+    ip = GetMemW(c_stack,tmp);
+    tmp = (WORD)(tmp+2);
+    sregs[CS] = GetMemW(c_stack,tmp);
+    c_cs = SegToMemPtr(CS);
+    tmp += 2;
+    WriteWord(&wregs[SP],tmp);
+}
+
+LPBYTE GetArgAddr(int pos) {
+	return c_stack + ReadWord(&wregs[SP]) + 4 + pos;
+}
+

+ 83 - 0
mmvm/mmvm.h

@@ -0,0 +1,83 @@
+#ifndef _MMVM_H
+#define _MMVM_H
+
+#include "wwstruct.h"
+extern "C" {
+#include "../cpu/mytypes.h"
+#include "../cpu/global.h"
+#include "../cpu/cpu.h"
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MEMORYSIZE (1 * 1024 * 1024)
+
+#define ELISA_FONTFILE TEXT("elisa100.fnt")
+
+#define SRAMWORK_SEG 0x1000
+#define APP_CSEG 0x3000
+#define FIRST_DSEG 0x1000
+#define FINAL_DSEG 0x2000
+#define STACK_SEG 0xF000
+
+#define DIRENT_NUM 4
+#define DIRENT_ROOT 0
+#define DIRENT_KERN 1
+#define DIRENT_ROM0 2
+#define DIRENT_RAM0 3
+
+typedef struct {
+	char className[32];
+	char name[32];
+	char version[32];
+	char description[32];
+	char **depends;
+} MMVM_ILInfo, *LPMMVM_ILInfo;
+
+typedef struct {
+	WW_FARPTR il;
+	MMVM_ILInfo ilinfo;
+	WW_FARPTR proc;
+	MMVM_ILInfo procinfo;
+	WW_FARPTR fs;
+	MMVM_ILInfo fsinfo;
+} MMVM_IL, *LPMMVM_IL;
+
+typedef struct {
+	WW_FENT_T fent;
+	TCHAR commandline[MAX_WW_ARG];
+	BOOL loadended;
+	BOOL maincalled;
+} MMVM_APPINFO, *LPMMVM_APPINFO;
+
+typedef struct {
+	LPBYTE memory;
+	LPMMVM_IL il;
+	WW_FARPTR cwfs;
+	LPWW_SRAMWork swork;
+	LPMMVM_APPINFO appinfo;
+	int lcdseg;
+} MMVM, *LPMMVM;
+
+extern LPMMVM mmvm;
+
+BOOL CreateVM();
+void InitVM();
+void UpdateVM();
+void OpenDlgAndRun();
+void OpenAndRun(LPCTSTR filename, LPCTSTR cmdline);
+void LoadAndRun();
+BOOL LoadFXFile(LPCTSTR filename, WORD addr, WW_FENT_T *fentp);
+void RunWWApp();
+void Restart();
+void StopExecution(DWORD wait);
+LPBYTE GetArgAddr(int pos);
+void ILReturn();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _MMVM_H

+ 116 - 0
mmvm/systembios.cpp

@@ -0,0 +1,116 @@
+#include "../mmage/preference.h"
+#include "wwbios.h"
+
+extern "C" {
+#include "../wonx/wonx_include/system.h"
+}
+
+enum {
+    SYS_INTERRUPT_SET_HOOK = 0,
+    SYS_INTERRUPT_RESET_HOOK,
+    SYS_WAIT,
+    SYS_GET_TICK_COUNT,
+    SYS_SLEEP,
+    SYS_SET_SLEEP_TIME,
+    SYS_GET_SLEEP_TIME,
+    SYS_SET_AWAKE_KEY,
+    SYS_GET_AWAKE_KEY,
+    SYS_SET_KEEPALIVE_INT,
+    SYS_GET_OWNERINFO,
+    SYS_SUSPEND,
+    SYS_RESUME,
+    SYS_SET_REMOTE,
+    SYS_GET_REMOTE,
+    SYS_ALLOC_IRAM,
+    SYS_FREE_IRAM,
+    SYS_GET_MY_IRAM,
+    SYS_GET_VERSION,
+    SYS_SWAP,
+    SYS_SET_RESUME,
+    SYS_GET_RESUME,
+};
+
+void system_handler(int func_no) {
+	int tmp;
+
+	switch(func_no) {
+		case SYS_INTERRUPT_SET_HOOK:
+			/*
+			sys_interrupt_set_hook(*bregs[AL], (intvector_t *)(c_ds + wregs[BX]), (intvector_t *)(c_ds + wregs[DX]));
+			*/
+			break;
+		case SYS_INTERRUPT_RESET_HOOK:
+			/*
+			sys_interrupt_reset_hook(*bregs[AL], (intvector_t *)(c_ds + wregs[BX]));
+			*/
+			break;
+		case SYS_WAIT:
+			sys_wait(wregs[CX]);
+			break;
+		case SYS_GET_TICK_COUNT:
+			tmp = sys_get_tick_count();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case SYS_SLEEP:
+			sys_sleep();
+			break;
+		case SYS_SET_SLEEP_TIME:
+			sys_set_sleep_time(*bregs[BL]);
+			break;
+		case SYS_GET_SLEEP_TIME:
+			wregs[AX] = sys_get_sleep_time();
+			break;
+		case SYS_SET_AWAKE_KEY:
+			sys_set_awake_key(wregs[BX]);
+			break;
+		case SYS_GET_AWAKE_KEY:
+			wregs[AX] = sys_get_awake_key();
+			break;
+		case SYS_SET_KEEPALIVE_INT:
+			sys_set_keepalive_int(*bregs[BL]);
+			break;
+		case SYS_GET_OWNERINFO:
+			memcpy((void *)(c_ds + wregs[DX]), (void *)&mmconfig->ownerinfo,
+				(wregs[CX] > sizeof(mmconfig->ownerinfo)) ? sizeof(mmconfig->ownerinfo) : wregs[CX]);
+//			sys_get_ownerinfo(wregs[CX], (char *)(c_ds + wregs[DX]));
+			break;
+		case SYS_SUSPEND:
+			wregs[AX] = sys_suspend(*bregs[AL]);
+			break;
+		case SYS_RESUME:
+			sys_resume(*bregs[AL]);
+			break;
+		case SYS_SET_REMOTE:
+			sys_set_remote(*bregs[AL]);
+			break;
+		case SYS_GET_REMOTE:
+			wregs[AX] = sys_get_remote();
+			break;
+		case SYS_ALLOC_IRAM:
+			wregs[AX] = (unsigned short)sys_alloc_iram((void *)wregs[BX], wregs[CX]);
+			break;
+		case SYS_FREE_IRAM:
+			sys_free_iram((void *)wregs[BX]);
+			break;
+		case SYS_GET_MY_IRAM:
+			wregs[AX] = (unsigned short)sys_get_my_iram();
+			break;
+		case SYS_GET_VERSION:
+			wregs[AX] = sys_get_version();
+			break;
+		case SYS_SWAP:
+			wregs[AX] = sys_swap(*bregs[AL]);
+			break;
+		case SYS_SET_RESUME:
+			sys_set_resume(wregs[BX]);
+			break;
+		case SYS_GET_RESUME:
+			wregs[AX] = sys_get_resume();
+			break;
+
+		default:
+			break;
+
+	}
+}

+ 117 - 0
mmvm/textbios.cpp

@@ -0,0 +1,117 @@
+#include "wwbios.h"
+
+extern "C" {
+#include "../wonx/wonx_include/text.h"
+}
+
+enum {
+    TEXT_SCREEN_INIT = 0,
+    TEXT_WINDOW_INIT,
+    TEXT_SET_MODE,
+    TEXT_GET_MODE,
+    TEXT_PUT_CHAR,
+    TEXT_PUT_STRING,
+    TEXT_PUT_SUBSTRING,
+    TEXT_PUT_NUMERIC,
+    TEXT_FILL_CHAR,
+    TEXT_SET_PALETTE,
+    TEXT_GET_PALETTE,
+    TEXT_SET_ANK_FONT,
+    TEXT_SET_SJIS_FONT,
+    TEXT_GET_FONTDATA,
+    TEXT_SET_SCREEN,
+    TEXT_GET_SCREEN,
+    CURSOR_DISPLAY,
+    CURSOR_STATUS,
+    CURSOR_SET_LOCATION,
+    CURSOR_GET_LOCATION,
+    CURSOR_SET_TYPE,
+    CURSOR_GET_TYPE,
+};
+
+void text_handler(int func_no) {
+	int tmp;
+
+	switch(func_no) {
+		case TEXT_SCREEN_INIT:
+			text_screen_init();
+			break;
+		case TEXT_WINDOW_INIT:
+			text_window_init(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
+			break;
+		case TEXT_SET_MODE:
+			text_set_mode(wregs[BX]);
+			break;
+		case TEXT_GET_MODE:
+			wregs[AX] = text_get_mode();
+			break;
+		case TEXT_PUT_CHAR:
+			text_put_char(*bregs[BL], *bregs[BH], wregs[CX]);
+			break;
+		case TEXT_PUT_STRING:
+			wregs[AX] = text_put_string(*bregs[BL], *bregs[BH], (char *)(c_ds + wregs[DX]));
+			break;
+		case TEXT_PUT_SUBSTRING:
+			text_put_substring(*bregs[BL], *bregs[BH], (char *)(c_ds + wregs[DX]), wregs[CX]);
+			break;
+		case TEXT_PUT_NUMERIC:
+			if((*bregs[CH]) & NUM_STORE) {
+				text_store_numeric((char *)(c_ds + wregs[SI]), *bregs[CL], *bregs[CH], wregs[DX]);
+			} else {
+				text_put_numeric(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
+			}
+			break;
+		case TEXT_FILL_CHAR:
+			text_fill_char(*bregs[BL], *bregs[BH], wregs[CX], wregs[DX]);
+			break;
+		case TEXT_SET_PALETTE:
+			text_set_palette(wregs[BX]);
+			break;
+		case TEXT_GET_PALETTE:
+			wregs[AX] = text_get_palette();
+			break;
+		case TEXT_SET_ANK_FONT:
+			text_set_ank_font(*bregs[BL], *bregs[BH], wregs[CX], c_ds + wregs[DX]);
+			break;
+		case TEXT_SET_SJIS_FONT:
+			text_set_sjis_font((void *)(wregs[BX] << 4 | wregs[DX]));
+			break;
+		case TEXT_GET_FONTDATA:
+			wregs[AX] = text_get_fontdata(wregs[CX], c_ds + wregs[DX]);
+			break;
+		case TEXT_SET_SCREEN:
+//			text_set_screen(wregs[BX]);  // マニュアル第 1 版は間違い
+			text_set_screen(*bregs[AL]);
+			break;
+		case TEXT_GET_SCREEN:
+			wregs[AX] = text_get_screen();
+			break;
+		case CURSOR_DISPLAY:
+			cursor_display(*bregs[AL]);
+			break;
+		case CURSOR_STATUS:
+			wregs[AX] = cursor_status();
+			break;
+		case CURSOR_SET_LOCATION:
+			cursor_set_location(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
+			break;
+		case CURSOR_GET_LOCATION:
+			tmp = cursor_get_location();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+		case CURSOR_SET_TYPE:
+			cursor_set_type(*bregs[BL], *bregs[CL]);
+			break;
+		case CURSOR_GET_TYPE:
+			tmp = cursor_get_type();
+			wregs[DX] = (tmp >> 16) & 0xffff;
+			wregs[AX] = tmp & 0xffff;
+			break;
+
+		default:
+			break;
+	}
+
+
+}

+ 59 - 0
mmvm/timerbios.cpp

@@ -0,0 +1,59 @@
+#include "wwbios.h"
+
+extern "C" {
+#include "../wonx/wonx_include/timer.h"
+}
+
+enum {
+    RTC_RESET = 0,
+    RTC_SET_DATETIME,
+    RTC_GET_DATETIME,
+    RTC_SET_DATETIME_STRUCT,
+    RTC_GET_DATETIME_STRUCT,
+    RTC_ENABLE_ALARM,
+    RTC_DISABLE_ALARM,
+    TIMER_ENABLE,
+    TIMER_DISABLE,
+    TIMER_GET_COUNT,
+};
+
+void timer_handler(int func_no) {
+
+	switch(func_no) {
+		case RTC_RESET:
+			/* WonX で未実装
+			rtc_reset();
+			*/
+			break;
+		case RTC_SET_DATETIME:
+			rtc_set_datetime(wregs[BX], wregs[CX]);
+			break;
+		case RTC_GET_DATETIME:
+			wregs[AX] = rtc_get_datetime(wregs[BX]);
+			break;
+		case RTC_SET_DATETIME_STRUCT:
+			rtc_set_datetime_struct((datetime_t *)(c_ds + wregs[DX]));
+			break;
+		case RTC_GET_DATETIME_STRUCT:
+			rtc_get_datetime_struct((datetime_t *)(c_ds + wregs[DX]));
+			break;
+		case RTC_ENABLE_ALARM:
+			rtc_enable_alarm(*bregs[BL], *bregs[BH]);
+			break;
+		case RTC_DISABLE_ALARM:
+			rtc_disable_alarm();
+			break;
+		case TIMER_ENABLE:
+			timer_enable(*bregs[AL], *bregs[BL], wregs[CX]);
+			break;
+		case TIMER_DISABLE:
+			timer_disable(*bregs[AL]);
+			break;
+		case TIMER_GET_COUNT:
+			wregs[AX] = timer_get_count(*bregs[AL]);
+			break;
+
+		default:
+			break;
+	}
+}

+ 51 - 0
mmvm/wwbios.cpp

@@ -0,0 +1,51 @@
+#include "../mmage/mmage.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "wwbios.h"
+
+void int_handler(int no) {
+	int func_no;
+	TCHAR msg[256];
+
+	func_no = *bregs[AH];
+
+	switch(no) {
+		case INT_BIOS_EXIT:
+			wonw32ctx->running = FALSE;
+			wsprintf(msg, TEXT("アプリケーションは終了しました"));
+			MessageBox(wonw32ctx->hWnd, msg, TEXT("終了"), MB_OK);
+			break;
+
+		case INT_KEY:
+			key_handler(func_no);
+			break;
+		case INT_DISP:
+			disp_handler(func_no);
+			break;
+		case INT_TEXT:
+			text_handler(func_no);
+			break;
+		case INT_SERIAL:
+//			serial_handler(func_no);
+			break;
+		case INT_SOUND:
+//			sound_handler(func_no);
+			break;
+		case INT_TIMER:
+			timer_handler(func_no);
+			break;
+		case INT_SYSTEM:
+			system_handler(func_no);
+			break;
+		case INT_BANK:
+//			bank_handler(func_no);
+			break;
+		default:
+			break;
+	}
+
+}
+

+ 44 - 0
mmvm/wwbios.h

@@ -0,0 +1,44 @@
+#ifndef _WWBIOS_H
+#define _WWBIOS_H
+
+#include <stdlib.h>
+
+#include "../cpu/mytypes.h"
+#include "../cpu/global.h"
+#include "../cpu/cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum {
+	INT_BIOS_EXIT=0x10,
+	INT_KEY,
+	INT_DISP,
+	INT_TEXT,
+	INT_SERIAL,
+	INT_SOUND,
+	INT_TIMER,
+	INT_SYSTEM,
+	INT_BANK,
+};
+
+void int_handler(int no);
+
+void key_handler(int func_no);
+void disp_handler(int func_no);
+void text_handler(int func_no);
+void serial_handler(int func_no);
+void sound_handler(int func_no);
+void timer_handler(int func_no);
+void system_handler(int func_no);
+void bank_handler(int func_no);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 214 - 0
mmvm/wwstruct.h

@@ -0,0 +1,214 @@
+#ifndef _WWSTRUCT_H
+#define _WWSTRUCT_H
+
+#include <windows.h>
+
+#define MAX_WW_ARG 256
+
+#define MAXFNAME 16
+#define MAXPATHLEN 64
+#define MAXFINFO 24
+
+#define OPEN_MAX		16		/* max open fils per process */
+
+#define BLOCKSZ			128		/* size of file block */
+
+#define	FMODE_X			(0x0001)	/* executable */
+#define	FMODE_W			(0x0002)	/* writable */
+#define	FMODE_R			(0x0004)	/* readable */
+#define	FMODE_MMAP		(0x0008)	/* disallow mmap */
+#define	FMODE_STREAM	(0x0010)	/* StreamIL instance */
+#define	FMODE_ILIB		(0x0020)	/* IL instance */
+#define	FMODE_LINK		(0x0040)	/* symbolic link */
+#define	FMODE_DIR		(0x0080)	/* directory */
+
+#define E_FS_SUCCESS		0
+#define E_FS_ERROR		0x8000
+#define E_FS_FILE_NOT_FOUND	0x8001
+#define E_FS_PERMISSION_DENIED	0x8002
+#define E_FS_OUT_OF_BOUNDS	0x8003
+#define E_FS_NO_SPACE_LEFT	0x8004
+#define E_FS_FILE_NOT_OPEN	0x8005
+
+typedef union {
+	DWORD farptr;
+	struct {
+		WORD off;
+		WORD seg;
+	} segoff;
+} WW_FARPTR;
+
+#define FARPTR2ADDR(X) ((X.segoff.seg << 4) | X.segoff.off)
+#define SEGOFF2FARPTR(SEG, OFF) ((SEG << 16 | OFF))
+#define GETSEG(X) (X.segoff.seg)
+#define GETOFF(X) (X.segoff.off)
+#define GETFARPTR(X) (X.farptr)
+
+typedef WORD WW_NEARPTR;
+typedef WORD WW_SHORT; 
+typedef WORD WW_INT;
+typedef DWORD WW_LONG;
+
+#pragma pack( push, beforewwstruct )
+#pragma pack(1)
+
+typedef struct {
+/* from startup routine
+__id		db	'TCC', 0
+__pid		dw	?
+__ppid		dw	?
+__pcbid		dw	?
+__ppcbid	dw	?
+__ilib		dd	?
+__proc		dd	?
+__cwfs		dd	?
+__currentdir	db	MAXPATHLEN dup (?)
+__argv		dw	?
+__resource	dd	?
+__heap		dw	?
+*/
+	BYTE id[4];
+	WW_INT pid;
+	WW_INT ppid;
+	WW_INT pcbid;
+	WW_INT ppcbid;
+	WW_FARPTR ilib;
+	WW_FARPTR proc;
+	WW_FARPTR cwfs;
+	char currentdir[MAXPATHLEN];
+	WW_NEARPTR argv;
+	WW_FARPTR resource;
+	WW_NEARPTR heap;
+} WW_PCB, *LPWW_PCB;
+
+typedef struct {
+    char	name[MAXFNAME];
+    char	info[MAXFINFO];
+    WW_LONG	loc;
+    WW_LONG	len;
+    WW_INT	count;
+    WW_INT	mode;
+    WW_LONG	mtime;
+    union {
+        WW_LONG	appid;
+		WW_LONG	il;	
+    } handler;
+    WW_LONG	resource;
+} WW_FENT_T, *WW_FS;
+
+
+typedef struct {
+	BYTE magic[4];
+	BYTE padding[60];
+	WW_FENT_T fent;
+} WW_FXHEADER, *LPWW_FXHEADER;
+
+
+typedef struct {
+	WW_FARPTR className;   // char far *className;
+	WW_FARPTR name;        // char far *name;
+	WW_FARPTR version;     // char far *version;
+	WW_FARPTR description; // char far *description;
+	WW_FARPTR depends;     // char far * far *depends;
+} WW_ILInfo, *LPWW_ILInfo;
+
+typedef struct { // IL struct (see sys/indirect.h)
+	WW_FARPTR link_pos;  // void far *link_pos;
+	WW_INT n_methods;  // int n_methods;
+	WW_FARPTR _get_info; // ILInfo far *(far *_get_info)(void);
+} WW_IL, *LPWW_IL;
+
+typedef struct { // IlibIL struct (see sys/indeirect.h)
+    WW_IL super;
+    WW_FARPTR _open;        // int (far *_open)(char far *ilname, IL far *ilbuf);
+    WW_FARPTR _open_system; //int (far *_open_system)(char far *ilname, IL far *ilbuf);
+} WW_IlibIL, *LPWW_IlibIL;
+
+typedef struct { // ProcIL struct (see sys/indeirect.h)
+    WW_IL super;
+    WW_FARPTR _load;    // void far *(far *_load)(char far *command);
+    WW_FARPTR _run;     // int (far *_run)(void far *entry, int argc, char far * far *argv);
+    WW_FARPTR _exec;    // int (far *_exec)(char far *command, int argc, char far * far *argv);
+    WW_FARPTR _exit;    // void (far *_exit)(int exitcode);
+    WW_FARPTR _yield;   // void (far *_yield)(void);
+    WW_FARPTR _suspend; // int (far *_suspend)(int pcbid);
+    WW_FARPTR _resume;  // void (far *_resume)(int pcbid);
+    WW_FARPTR _swap;    // int (far *_swap)(int pcbid);
+/*
+    WW_FARPTR _kill;    // int (far *_kill)(child);
+ */
+} WW_ProcIL, *LPWW_ProcIL;
+
+typedef struct { // FsIL struct (see sys/indeirect.h)
+    WW_IL super;
+    WW_FARPTR _entries;   // fent_t far *(far *_entries)(FS fs);
+    WW_FARPTR _n_entries; // int (far *_n_entries)(FS fs);
+    WW_FARPTR _getent;    // int (far *_getent)(FS fs, int n, fent_t far *fep);
+    WW_FARPTR _findent;   // int (far *_findent)(FS fs, char far *fname, fent_t far *fep);
+    WW_FARPTR _mmap;      // void far *(far *_mmap)(FS fs, char far *fname);
+    WW_FARPTR _open;      // int (far *_open)(FS fs, char far *fname, int mode, int perms);
+    WW_FARPTR _close;     // int (far *_close)(int fd);
+    WW_FARPTR _read;      // int (far *_read)(int fd, char far *buf, int len);
+    WW_FARPTR _write;     // int (far *_write)(int fd, char far *buf, int len);
+    WW_FARPTR _lseek;     // long (far *_lseek)(int fd, long offset, int origin);
+    WW_FARPTR _chmod;     // int (far *_chmod)(FS fs, char far *fname, int mode);
+    WW_FARPTR _freeze;    // int (far *_freeze)(FS fs, char far *fname);
+    WW_FARPTR _melt;      // int (far *_melt)(FS fs, char far *fname);
+    WW_FARPTR _creat;     // int (far *_creat)(FS fs, fent_t far *fep);
+    WW_FARPTR _unlink;    // int (far *_unlink)(FS fs, char far *fname);
+    WW_FARPTR _newfs;     // int (far *_newfs)(FS fs);
+    WW_FARPTR _defrag;    // int (far *_defrag)(FS fs);
+    WW_FARPTR _space;     // unsigned long (far *_space)(FS fs);
+} WW_FsIL, *LPWW_FsIL;
+
+typedef struct {
+    WW_INT _status;		// int _status;			/* status of process */
+    WW_INT _exit_code;	// int _exit_code;		/* process exit code */
+} WW_ProcControl, *LPWW_ProcControl;
+
+typedef struct {
+    WW_FS fs;			// FS		fs;		/* FS which contains the fent */
+    WW_FARPTR fentp;	// fent_t far *fentp;		/* original file entry */
+    WW_SHORT omode;		// fmode_t	omode;		/* open mode: 0 indicates free handle */
+    WW_FARPTR floc;		// floc_t 	floc;		/* file location */
+    WW_LONG flen;		// flen_t 	flen;		/* file length */
+    WW_LONG fpos;		// fpos_t	fpos;		/* current seek position */
+    WW_INT count;		// int 	count;		/* total file block count */
+    WW_FARPTR driver;	// StreamIL_p  driver;		/* stream driver for the file */
+    WW_INT pcb;			// int		pcb;		/* opening process's pcb */
+    WW_INT _reserved;	// int		_reserved;	/* reserved */
+} WW_fhandle_t, *LPWW_fhandle_t;
+
+#define MAXPROCESSES 3
+#define MAXFILES 16
+#define ROOTFS_NUM_ENTRIES 16
+#define RAM0FS_NUM_ENTRIES 24
+#define ROM0FS_NUM_ENTRIES 128
+
+typedef struct { // SRAMWork struct (see sys/oswork.h)
+    WW_PCB _opsc;						// ProcContext	_ospc;
+    WW_ProcControl _pcb[MAXPROCESSES]; // ProcControl	_pcb[MAXPROCESSES];
+    WW_INT _os_version;					// unsigned	_os_version;
+    WW_INT _last_pcb;					// unsigned	_last_pcb;
+    WW_INT _freefd;						// int		_freefd;
+    WW_fhandle_t _openfiles[MAXFILES];	// fhandle_t	_openfiles[MAXFILES];
+    char	_shell_work[128];
+    WW_FENT_T _root_fs_entries[ROOTFS_NUM_ENTRIES]; // fent_t	_root_fs_entries[ROOTFS_NUM_ENTRIES];
+    WW_FENT_T _ram0_fs_entries[RAM0FS_NUM_ENTRIES]; // fent_t	_ram0_fs_entries[RAM0FS_NUM_ENTRIES];
+    WW_FENT_T _rom0_fs_entries[ROM0FS_NUM_ENTRIES]; // fent_t	_rom0_fs_entries[ROM0FS_NUM_ENTRIES];
+    WW_FARPTR _saveports;				// unsigned char far *	_saveports;
+} WW_SRAMWork, *LPWW_SRAMWork;
+
+
+typedef struct { // 
+	char name[16];
+	WW_INT birth_year;
+	char birth_month;
+	char birth_day;
+	char sex;
+	char bloodtype;
+} WW_OWNERINFO, *LPWW_OWNERINFO;
+
+#pragma pack( pop, beforewwstruct )
+
+#endif // #ifndef _WWSTRUCT_H

BIN
resource/MMAGE.ICO


BIN
resource/MMage.rc


BIN
resource/SMALL.ICO


BIN
resource/aux1.ico


BIN
resource/aux1off.ico


BIN
resource/aux2.ico


BIN
resource/aux2off.ico


BIN
resource/aux3.ico


BIN
resource/aux3off.ico


BIN
resource/aux4.ico


BIN
resource/horizontal.ico


BIN
resource/horizontaloff.ico


+ 341 - 0
resource/license.bin

@@ -0,0 +1,341 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+

BIN
resource/sleep.ico


BIN
resource/sleepoff.ico


BIN
resource/title.bmp


BIN
resource/vertical.ico


BIN
resource/verticaloff.ico


+ 1 - 0
wonx

@@ -0,0 +1 @@
+Subproject commit 103ffe29f13c16f55d032d8789176951d1673270