OSDN Git Service

Changes to many generated files -- incorporate bochs into
authorfitzsim <fitzsim>
Tue, 27 Nov 2001 22:58:58 +0000 (22:58 +0000)
committerfitzsim <fitzsim>
Tue, 27 Nov 2001 22:58:58 +0000 (22:58 +0000)
build system and configrun-sid.

272 files changed:
sid/ChangeLog
sid/Makefile.in
sid/aclocal.m4
sid/bsp/ChangeLog
sid/bsp/Makefile.am
sid/bsp/Makefile.in
sid/bsp/aclocal.m4
sid/bsp/configrun-sid.in
sid/bsp/configure
sid/bsp/i386-elf-sid [new file with mode: 0755]
sid/bsp/pregen/ChangeLog
sid/bsp/pregen/Makefile.in
sid/bsp/pregen/arm-cma-tksm.conf
sid/bsp/pregen/arm-cma.conf
sid/bsp/pregen/arm-gloss-tksm.conf
sid/bsp/pregen/arm-gloss.conf
sid/bsp/pregen/arm-glossBE.conf
sid/bsp/pregen/arm-pid-redboot-tksm.conf
sid/bsp/pregen/arm-pid-redboot.conf
sid/bsp/pregen/arm-pid-tksm.conf
sid/bsp/pregen/arm-pid.conf
sid/bsp/pregen/arm-pidBE.conf
sid/bsp/pregen/i386-gdb.conf [new file with mode: 0644]
sid/bsp/pregen/i386-gloss.conf [new file with mode: 0644]
sid/bsp/pregen/pregen-configs.in
sid/component/CATALOG
sid/component/ChangeLog
sid/component/Makefile.in
sid/component/aclocal.m4
sid/component/bochs/ChangeLog [new file with mode: 0644]
sid/component/bochs/Makefile.am [new file with mode: 0644]
sid/component/bochs/Makefile.in [new file with mode: 0644]
sid/component/bochs/README [new file with mode: 0644]
sid/component/bochs/aclocal.m4 [new file with mode: 0644]
sid/component/bochs/bochs.h [new file with mode: 0644]
sid/component/bochs/bxversion.h [new file with mode: 0644]
sid/component/bochs/components.cxx [new file with mode: 0644]
sid/component/bochs/config.guess [new file with mode: 0644]
sid/component/bochs/config.h.in [new file with mode: 0644]
sid/component/bochs/config.sub [new file with mode: 0644]
sid/component/bochs/configure [new file with mode: 0755]
sid/component/bochs/configure.in [new file with mode: 0644]
sid/component/bochs/cpu/Makefile.am [new file with mode: 0644]
sid/component/bochs/cpu/Makefile.in [new file with mode: 0644]
sid/component/bochs/cpu/access.cc [new file with mode: 0644]
sid/component/bochs/cpu/apic.cc [new file with mode: 0644]
sid/component/bochs/cpu/arith16.cc [new file with mode: 0644]
sid/component/bochs/cpu/arith32.cc [new file with mode: 0644]
sid/component/bochs/cpu/arith8.cc [new file with mode: 0644]
sid/component/bochs/cpu/bcd.cc [new file with mode: 0644]
sid/component/bochs/cpu/bit.cc [new file with mode: 0644]
sid/component/bochs/cpu/cpu-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/cpu-sid.h [new file with mode: 0644]
sid/component/bochs/cpu/cpu.cc [new file with mode: 0644]
sid/component/bochs/cpu/cpu.h [new file with mode: 0644]
sid/component/bochs/cpu/ctrl_xfer16.cc [new file with mode: 0644]
sid/component/bochs/cpu/ctrl_xfer32-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/ctrl_xfer32.cc [new file with mode: 0644]
sid/component/bochs/cpu/ctrl_xfer8.cc [new file with mode: 0644]
sid/component/bochs/cpu/ctrl_xfer_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/data_xfer16.cc [new file with mode: 0644]
sid/component/bochs/cpu/data_xfer32.cc [new file with mode: 0644]
sid/component/bochs/cpu/data_xfer8.cc [new file with mode: 0644]
sid/component/bochs/cpu/debugstuff-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/debugstuff.cc [new file with mode: 0644]
sid/component/bochs/cpu/decode16.cc [new file with mode: 0644]
sid/component/bochs/cpu/decode32.cc [new file with mode: 0644]
sid/component/bochs/cpu/exception-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/exception.cc [new file with mode: 0644]
sid/component/bochs/cpu/fetchdecode-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/fetchdecode.cc [new file with mode: 0644]
sid/component/bochs/cpu/flag_ctrl.cc [new file with mode: 0644]
sid/component/bochs/cpu/flag_ctrl_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/init-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/init.cc [new file with mode: 0644]
sid/component/bochs/cpu/io.cc [new file with mode: 0644]
sid/component/bochs/cpu/io_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/lazy_flags.cc [new file with mode: 0644]
sid/component/bochs/cpu/lazy_flags.h [new file with mode: 0644]
sid/component/bochs/cpu/logical16.cc [new file with mode: 0644]
sid/component/bochs/cpu/logical32.cc [new file with mode: 0644]
sid/component/bochs/cpu/logical8.cc [new file with mode: 0644]
sid/component/bochs/cpu/main-hack.cc [new file with mode: 0644]
sid/component/bochs/cpu/mult16.cc [new file with mode: 0644]
sid/component/bochs/cpu/mult32.cc [new file with mode: 0644]
sid/component/bochs/cpu/mult8.cc [new file with mode: 0644]
sid/component/bochs/cpu/paging.cc [new file with mode: 0644]
sid/component/bochs/cpu/proc_ctrl.cc [new file with mode: 0644]
sid/component/bochs/cpu/protect_ctrl.cc [new file with mode: 0644]
sid/component/bochs/cpu/protect_ctrl_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/resolve16.cc [new file with mode: 0644]
sid/component/bochs/cpu/resolve32.cc [new file with mode: 0644]
sid/component/bochs/cpu/segment_ctrl.cc [new file with mode: 0644]
sid/component/bochs/cpu/segment_ctrl_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/shift16.cc [new file with mode: 0644]
sid/component/bochs/cpu/shift32.cc [new file with mode: 0644]
sid/component/bochs/cpu/shift8.cc [new file with mode: 0644]
sid/component/bochs/cpu/soft_int-sid.cc [new file with mode: 0644]
sid/component/bochs/cpu/soft_int.cc [new file with mode: 0644]
sid/component/bochs/cpu/stack16.cc [new file with mode: 0644]
sid/component/bochs/cpu/stack32.cc [new file with mode: 0644]
sid/component/bochs/cpu/stack_pro.cc [new file with mode: 0644]
sid/component/bochs/cpu/state_file.h [new file with mode: 0644]
sid/component/bochs/cpu/string.cc [new file with mode: 0644]
sid/component/bochs/cpu/tasking.cc [new file with mode: 0644]
sid/component/bochs/cpu/vm8086.cc [new file with mode: 0644]
sid/component/bochs/cpu/x86-memory-modes.cc [new file with mode: 0644]
sid/component/bochs/cpu/x86.cc [new file with mode: 0644]
sid/component/bochs/cpu/x86.h [new file with mode: 0644]
sid/component/bochs/debug/debug.h [new file with mode: 0644]
sid/component/bochs/fpu/Makefile.am [new file with mode: 0644]
sid/component/bochs/fpu/Makefile.in [new file with mode: 0644]
sid/component/bochs/fpu/PORTING [new file with mode: 0644]
sid/component/bochs/fpu/README [new file with mode: 0644]
sid/component/bochs/fpu/control_w.h [new file with mode: 0644]
sid/component/bochs/fpu/div_Xsig.S [new file with mode: 0644]
sid/component/bochs/fpu/div_Xsig.c [new file with mode: 0644]
sid/component/bochs/fpu/div_small.S [new file with mode: 0644]
sid/component/bochs/fpu/div_small.c [new file with mode: 0644]
sid/component/bochs/fpu/errors.c [new file with mode: 0644]
sid/component/bochs/fpu/exception.h [new file with mode: 0644]
sid/component/bochs/fpu/fpu.cc [new file with mode: 0644]
sid/component/bochs/fpu/fpu_arith.c [new file with mode: 0644]
sid/component/bochs/fpu/fpu_asm.h [new file with mode: 0644]
sid/component/bochs/fpu/fpu_aux.c [new file with mode: 0644]
sid/component/bochs/fpu/fpu_emu.h [new file with mode: 0644]
sid/component/bochs/fpu/fpu_entry.c [new file with mode: 0644]
sid/component/bochs/fpu/fpu_etc.c [new file with mode: 0644]
sid/component/bochs/fpu/fpu_proto.h [new file with mode: 0644]
sid/component/bochs/fpu/fpu_system.h [new file with mode: 0644]
sid/component/bochs/fpu/fpu_tags.c [new file with mode: 0644]
sid/component/bochs/fpu/fpu_trig.c [new file with mode: 0644]
sid/component/bochs/fpu/get_address.c [new file with mode: 0644]
sid/component/bochs/fpu/load_store.c [new file with mode: 0644]
sid/component/bochs/fpu/mul_Xsig.S [new file with mode: 0644]
sid/component/bochs/fpu/mul_Xsig.c [new file with mode: 0644]
sid/component/bochs/fpu/poly.h [new file with mode: 0644]
sid/component/bochs/fpu/poly_2xm1.c [new file with mode: 0644]
sid/component/bochs/fpu/poly_atan.c [new file with mode: 0644]
sid/component/bochs/fpu/poly_l2.c [new file with mode: 0644]
sid/component/bochs/fpu/poly_sin.c [new file with mode: 0644]
sid/component/bochs/fpu/poly_tan.c [new file with mode: 0644]
sid/component/bochs/fpu/polynom_Xsig.S [new file with mode: 0644]
sid/component/bochs/fpu/polynom_Xsig.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_add_sub.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_compare.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_constant.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_constant.h [new file with mode: 0644]
sid/component/bochs/fpu/reg_convert.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_divide.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_ld_str.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_mul.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_norm.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_norm.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_round.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_round.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_add.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_add.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_div.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_div.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_mul.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_mul.c [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_sub.S [new file with mode: 0644]
sid/component/bochs/fpu/reg_u_sub.c [new file with mode: 0644]
sid/component/bochs/fpu/round_Xsig.S [new file with mode: 0644]
sid/component/bochs/fpu/round_Xsig.c [new file with mode: 0644]
sid/component/bochs/fpu/shr_Xsig.S [new file with mode: 0644]
sid/component/bochs/fpu/shr_Xsig.c [new file with mode: 0644]
sid/component/bochs/fpu/status_w.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/asm/desc.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/asm/math_emu.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/asm/sigcontext.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/asm/types.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/asm/uaccess.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/kernel.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/linkage.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/mm.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/signal.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/stddef.h [new file with mode: 0644]
sid/component/bochs/fpu/stubs/linux/types.h [new file with mode: 0644]
sid/component/bochs/fpu/version.h [new file with mode: 0644]
sid/component/bochs/fpu/wmFPUemu_glue.cc [new file with mode: 0644]
sid/component/bochs/fpu/wm_shrx.S [new file with mode: 0644]
sid/component/bochs/fpu/wm_shrx.c [new file with mode: 0644]
sid/component/bochs/fpu/wm_sqrt.S [new file with mode: 0644]
sid/component/bochs/fpu/wm_sqrt.c [new file with mode: 0644]
sid/component/bochs/install-sh [new file with mode: 0644]
sid/component/bochs/instrument.h [new file with mode: 0644]
sid/component/bochs/ltconfig [new file with mode: 0644]
sid/component/bochs/ltmain.sh [new file with mode: 0644]
sid/component/bochs/memory/Makefile.am [new file with mode: 0644]
sid/component/bochs/memory/Makefile.in [new file with mode: 0644]
sid/component/bochs/memory/memory-sid.cc [new file with mode: 0644]
sid/component/bochs/memory/memory-sid.h [new file with mode: 0644]
sid/component/bochs/memory/memory.cc [new file with mode: 0644]
sid/component/bochs/memory/memory.h [new file with mode: 0644]
sid/component/bochs/memory/misc_mem.cc [new file with mode: 0644]
sid/component/bochs/missing [new file with mode: 0644]
sid/component/bochs/mkinstalldirs [new file with mode: 0644]
sid/component/bochs/stamp-h.in [new file with mode: 0644]
sid/component/cache/Makefile.in
sid/component/cgen-cpu/ChangeLog
sid/component/cgen-cpu/Makefile.am
sid/component/cgen-cpu/Makefile.in
sid/component/cgen-cpu/aclocal.m4
sid/component/cgen-cpu/configure
sid/component/cgen-cpu/m32r/ChangeLog
sid/component/cgen-cpu/m32r/Makefile.am
sid/component/cgen-cpu/m32r/Makefile.in
sid/component/cgen-cpu/m32r/m32rbf.cxx
sid/component/configure
sid/component/configure.in
sid/component/consoles/Makefile.in
sid/component/families/Makefile.in
sid/component/families/aclocal.m4
sid/component/families/configure
sid/component/gdb/ChangeLog
sid/component/gdb/Makefile.am
sid/component/gdb/Makefile.in
sid/component/gdb/sw-debug-gdb.txt [new file with mode: 0644]
sid/component/gdb/sw-debug-gdb.xml [new file with mode: 0644]
sid/component/gloss/ChangeLog
sid/component/gloss/Makefile.in
sid/component/gloss/gloss.cxx
sid/component/gloss/gloss.h
sid/component/gloss/libcygmon.h [new file with mode: 0644]
sid/component/gloss/libgloss.h
sid/component/gloss/sw-gloss-arm_angel.txt
sid/component/gloss/sw-gloss-arm_angel.xml
sid/component/glue/Makefile.in
sid/component/ide/Makefile.in
sid/component/interrupt/Makefile.in
sid/component/lcd/Makefile.in
sid/component/lcd/testsuite/ChangeLog
sid/component/lcd/testsuite/Makefile.in
sid/component/loader/Makefile.in
sid/component/mapper/Makefile.in
sid/component/mapper/testsuite/ChangeLog
sid/component/mapper/testsuite/Makefile.in
sid/component/memory/Makefile.in
sid/component/mmu/Makefile.in
sid/component/parport/Makefile.in
sid/component/profiling/Makefile.in
sid/component/rtc/Makefile.in
sid/component/sched/Makefile.in
sid/component/tconfig.in
sid/component/testsuite/Makefile.in
sid/component/timers/Makefile.in
sid/component/timers/aclocal.m4
sid/component/timers/configure
sid/component/uart/Makefile.in
sid/component/uart/testsuite/Makefile.in
sid/config/ChangeLog
sid/config/info.tcl.in
sid/config/sidtargets.m4
sid/configure
sid/configure.in
sid/demos/voice-pager/configure
sid/doc/ChangeLog
sid/doc/cdk-guide/book-cdk.sgml
sid/doc/sid-guide/book-sid.sgml
sid/include/ChangeLog
sid/include/sidcpuutil.h
sid/main/configure
sid/main/dynamic/ChangeLog
sid/main/dynamic/Makefile.am
sid/main/dynamic/Makefile.in
sid/main/dynamic/aclocal.m4
sid/main/dynamic/configure
sid/samples/Makefile.in
sid/samples/aclocal.m4
sid/samples/configure

index cca6e24..f8cec24 100644 (file)
@@ -8,10 +8,21 @@
        * Makefile.am (all-local): Create version.h file with $(VERSION) in it.
        * Makefile.in: Regenerated.
 
+2001-09-17  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       Changes to many generated files -- incorporate bochs into
+       build system and configrun-sid.
+
 2001-07-24  Ben Elliston  <bje@redhat.com>
 
        * Makefile.am (install-data-local): Remove target.
 
+2001-07-10  matthew green  <mrg@redhat.com>
+
+       * Makefile.in: Regenerate.
+       * aclocal.m4: Regenerate.
+       * configure: Regenerate.
+
 2001-06-26  Frank Ch. Eigler  <fche@redhat.com>
 
        * Makefile.am (ACLOCAL_AMFLAGS): Refer to $srcdir.
 
 2001-03-26  Frank Ch. Eigler  <fche@redhat.com>
 
-        * Makefile.am (install-data-local): Install COPYING.SID in $prefix.
-        * Makefile.in: Regenerated.
+       * Makefile.am (install-data-local): Install COPYING.SID in $prefix.
+       * Makefile.in: Regenerated.
+
+2001-03-22  Ben Elliston  <bje@redhat.com>
+
+       * Makefile.in: Regenerate.
+       * configure: Likewise.
+       * aclocal.m4: Likewise.
 
 2001-03-21  Ben Elliston  <bje@redhat.com>
 
index dc4d1c0..ec9ac31 100644 (file)
@@ -71,6 +71,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 target = @target@
 
 AUTOMAKE_OPTIONS = foreign
index 92e1f6a..5d8c921 100644 (file)
@@ -156,7 +156,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -174,6 +174,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -185,6 +186,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -197,6 +199,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -214,6 +217,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index 74ae9ed..0665708 100644 (file)
        Check for gdb components attached to processors other than the main
        cpu. Adjust the enable-threshold of target-sched accordingly.
 
+2001-10-12  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * configrun-sid.in: Add -EL as default option for x86.
+
 2001-10-04  Frank Ch. Eigler  <fche@redhat.com>
 
        * configrun-sid.in: Throughout, set boolean attributes only to
 
 2001-10-03  Frank Ch. Eigler  <fche@redhat.com>
 
-        * configrun-sid.in (gdb): Add cfgroot relationship.
+       * configrun-sid.in (gdb): Add cfgroot relationship.
 
 2001-09-27  Frank Ch. Eigler  <fche@redhat.com>
 
-        * configrun-sid.in (icache, dcache): New options.
+       * configrun-sid.in (icache, dcache): New options.
+
+2001-09-14  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * configrun-sid.in: Add x86 support.
+       * i386-elf-sid: New file.
 
 2001-08-07  Ben Elliston  <bje@redhat.com>
 
index bd12ade..5679eeb 100644 (file)
@@ -20,8 +20,14 @@ if SIDTARGET_M68K
 FAM3SCRIPTS = m68k-elf-sid
 endif
 
+
+if SIDTARGET_X86
+FAM11SCRIPTS = i386-elf-sid
+endif
+
 ALLFAMSCRIPTS = $(FAM0SCRIPTS) $(FAM1SCRIPTS) $(FAM2SCRIPTS) $(FAM3SCRIPTS) \
                $(FAM4SCRIPTS) $(FAM5SCRIPTS) $(FAM6SCRIPTS) $(FAM7SCRIPTS) \
-               $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS)
+               $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS) $(FAM11SCRIPTS) \
+               $(FAM12SCRIPTS)
 
 bin_SCRIPTS = configrun-sid $(ALLFAMSCRIPTS)
index ae26f23..b9f067b 100644 (file)
@@ -68,6 +68,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 AUTOMAKE_OPTIONS = foreign
 ACLOCAL_AMFLAGS = -I $(srcdir)/../config
@@ -80,9 +81,12 @@ SUBDIRS = . pregen
 
 @SIDTARGET_M68K_TRUE@FAM3SCRIPTS = @SIDTARGET_M68K_TRUE@m68k-elf-sid
 
+@SIDTARGET_X86_TRUE@FAM11SCRIPTS = @SIDTARGET_X86_TRUE@i386-elf-sid
+
 ALLFAMSCRIPTS = $(FAM0SCRIPTS) $(FAM1SCRIPTS) $(FAM2SCRIPTS) $(FAM3SCRIPTS) \
                $(FAM4SCRIPTS) $(FAM5SCRIPTS) $(FAM6SCRIPTS) $(FAM7SCRIPTS) \
-               $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS)
+               $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS) $(FAM11SCRIPTS) \
+               $(FAM12SCRIPTS)
 
 
 bin_SCRIPTS = configrun-sid $(ALLFAMSCRIPTS)
index 42fe72c..11c29ca 100644 (file)
@@ -156,7 +156,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -174,6 +174,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -185,6 +186,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -197,6 +199,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -214,6 +217,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index 425a42c..d67b553 100644 (file)
@@ -14,17 +14,20 @@ require 5.004;
 %cpu_comptype = (
                 "arm" => "hw-cpu-arm7t",
                 "thumb" => "hw-cpu-arm7t",
+                "x86" => "hw-cpu-x86",
                 # INSERT NEW ENTRIES HERE
                 "m32r" => "hw-cpu-m32r/d"
                 );
 
 %cpu_defaultendian = (
+                     "x86" => "-EL",
                      "m32r" => "-EB"
                      );
 
 %gloss_comptype = (
                   "arm" => "sw-gloss-arm/angel",
                   "thumb" => "sw-gloss-arm/angel",
+                  "x86" => "sw-gloss-generic/libgloss",
                   # INSERT NEW ENTRIES HERE
                   "m32r" => "sw-gloss-m32r/libgloss"
                   );
@@ -32,6 +35,7 @@ require 5.004;
 %gloss_memspecs = (
                   "arm" => "0x00000000,0x00800000",
                   "thumb" => "0x00000000,0x00800000",
+                  "x86" => "0x00000,0x500000",
                   # INSERT NEW ENTRIES HERE
                   "m32r" => "0x00000000,0x00800000"
                  );
@@ -198,6 +202,10 @@ connect-pin cpu trap-code -> gloss trap-code
 set gloss verbose? $opt_verbose
 connect-bus gloss target-memory $bus_upstream
 ";
+    if ($opt_cpu eq "x86")
+      {
+        $second_section .= "set gloss syscall-numbering-scheme cygmon\n";
+      }
 
     if ($#exec_args >= 0) {
       $second_section .= "# args
@@ -338,7 +346,8 @@ if ($opt_gdb)
                 "sched" => "sched_component_library",
                 "tclapi" => "tcl_bridge_library",
                 "timers" => "timer_component_library",
-                "uart" => "uart_component_library"
+                "uart" => "uart_component_library",
+                "x86" => "x86_component_library"
 );
 
 
@@ -456,6 +465,11 @@ connect-pin cache-flush-net output-1 -> dcache invalidate-all\n";
   $second_section .= "connect-bus cpu data-memory $bus_upstream\n";
 }
 
+if ($opt_cpu eq "x86")
+  {
+      $second_section .= "set cpu memory-mode cygmon\n";
+  }
+
 if ($opt_gprof)
   {
     $second_section .= "# gprof connections
@@ -863,7 +877,11 @@ if ($opt_cpu eq "arm")
 # --engine
 if ($opt_engine eq "pbb")
   {
-    $second_section .= "set cpu engine-type pbb\n";
+# FIXME: the x86 component should support this setting
+    if ($opt_cpu ne "x86")
+      {
+       $second_section .= "set cpu engine-type pbb\n";
+      } 
   }
 elsif ($opt_engine eq "scache")
   {
index 75aaba6..d027ef8 100755 (executable)
@@ -986,7 +986,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -1006,6 +1006,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -1016,6 +1017,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -1027,6 +1029,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -1037,7 +1040,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:1098: checking ARM family support" >&5
+echo "configure:1044: checking ARM family support" >&5
 
 
 
@@ -1050,8 +1053,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:1058: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:1128: checking MIPS family support" >&5
+echo "configure:1072: checking MIPS family support" >&5
 
 
 
@@ -1065,7 +1082,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:1142: checking M32R family support" >&5
+echo "configure:1086: checking M32R family support" >&5
 
 
 
@@ -1079,7 +1096,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:1156: checking M68K family support" >&5
+echo "configure:1100: checking M68K family support" >&5
 
 
 
@@ -1093,7 +1110,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:1186: checking PPC family support" >&5
+echo "configure:1114: checking PPC family support" >&5
 
 
 
@@ -1273,6 +1290,9 @@ s%@INSTALL@%$INSTALL%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
@@ -1293,7 +1313,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.
diff --git a/sid/bsp/i386-elf-sid b/sid/bsp/i386-elf-sid
new file mode 100755 (executable)
index 0000000..3747977
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+exec `dirname $0`/configrun-sid --cpu x86 $@
index a9879d3..9b2d986 100644 (file)
@@ -1,11 +1,29 @@
 2001-10-29  Frank Ch. Eigler  <fche@redhat.com>
 
+       * pregen-configs.in (mep): Add --tksm for some configurations.
+
+2001-10-29  Frank Ch. Eigler  <fche@redhat.com>
+
        * (*.conf): Regenerated with memory component tweaks.
 
 2001-10-26  Frank Ch. Eigler  <fche@redhat.com>
 
        * (*.conf): Regenerated with reset-net etc. tweaks.
 
+2001-10-19  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * i386-gdb.conf: New file.
+       * pregen-configs.in: Add lines for i386-gdb.conf.
+
+2001-10-17  Dave Brolley  <brolley@redhat.com>
+
+       * All configs using --gdb regenerated.
+
+2001-10-12  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * i386-gloss.conf: New file.
+       * pregen-configs.in: Add code to generate i386-gloss.conf.
+
 2001-10-04  Frank Ch. Eigler  <fche@redhat.com>
 
        * (*.conf): Regenerated without superfluous bool attr settings.
index 0b3b37d..eddd471 100644 (file)
@@ -68,6 +68,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 AUTOMAKE_OPTIONS = foreign
 ACLOCAL_AMFLAGS = -I $(srcdir)/../../config
index 943845a..1953c95 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:14 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL --tksm
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -23,6 +23,7 @@ load libsched.la sched_component_library
 load libtclapi.la tcl_bridge_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index e2638c5..956b2f6 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:13 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index 8a6758a..c03932b 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:37 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 -EL --tksm
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -23,6 +23,7 @@ load libsched.la sched_component_library
 load libtclapi.la tcl_bridge_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index 580e659..5edd263 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:11 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:37 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 -EL
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index 9cfc9f5..849d4a0 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 -EB
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index 4dd4934..04b8b5f 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.30 2001/11/08 21:55:10 fche Exp 
-# run by bje @ scooby.brisbane.redhat.com (Linux) at Sun Nov 18 22:33:00 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
 # args: --cpu=arm --no-run --board=pid7t-redboot-uart1:5000 -EL --tksm
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -23,6 +23,7 @@ load libsched.la sched_component_library
 load libtclapi.la tcl_bridge_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 # first section
 new hw-cpu-arm7t cpu
 new hw-mapper-basic cpu-mapper
index ea780a5..1f5a241 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.30 2001/11/08 21:55:10 fche Exp 
-# run by bje @ scooby.brisbane.redhat.com (Linux) at Sun Nov 18 22:33:00 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
 # args: --cpu=arm --no-run --board=pid7t-redboot-uart1:5000 -EL
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 # first section
 new hw-cpu-arm7t cpu
 new hw-mapper-basic cpu-mapper
index 772ba7a..b4ec9ce 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EL --tksm
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -23,6 +23,7 @@ load libsched.la sched_component_library
 load libtclapi.la tcl_bridge_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index e0b3e35..6e4a53d 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EL
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
index c8753c4..3354bfe 100644 (file)
@@ -1,6 +1,6 @@
 # sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp 
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
 # args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EB
 load libaudio.la audio_component_library
 load libcache.la cache_component_library
@@ -22,6 +22,7 @@ load librtc.la rtc_component_library
 load libsched.la sched_component_library
 load libtimers.la timer_component_library
 load libuart.la uart_component_library
+load libx86.la x86_component_library
 set main persistent? true
 # first section
 new hw-cpu-arm7t cpu
diff --git a/sid/bsp/pregen/i386-gdb.conf b/sid/bsp/pregen/i386-gdb.conf
new file mode 100644 (file)
index 0000000..d358c03
--- /dev/null
@@ -0,0 +1,103 @@
+# sid configuration file
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:40 EST 2001
+# args: --cpu=x86 --no-run --gdb=5000
+load libaudio.la audio_component_library
+load libcache.la cache_component_library
+load libcgencpu.la cgen_component_library
+load libconsoles.la console_component_library
+load libgdb.la gdb_component_library
+load libgloss.la gloss_component_library
+load libglue.la glue_component_library
+load libhd44780u.la hd44780u_component_library
+load libide.la ide_component_library
+load libinterrupt.la interrupt_component_library
+load libloader.la loader_component_library
+load libmapper.la mapper_component_library
+load libmemory.la mem_component_library
+load libmmu.la mmu_component_library
+load libparport.la parport_component_library
+load libprof.la prof_component_library
+load librtc.la rtc_component_library
+load libsched.la sched_component_library
+load libtimers.la timer_component_library
+load libuart.la uart_component_library
+load libx86.la x86_component_library
+set main persistent? true
+# first section
+new hw-cpu-x86 cpu
+new hw-mapper-basic cpu-mapper
+new hw-glue-sequence-8 init-sequence
+new hw-glue-sequence-1 hw-reset-net
+new hw-glue-sequence-8 deinit-sequence
+new hw-glue-sequence-1 yield-net
+new hw-glue-sequence-2 cache-flush-net
+new sid-sched-host-accurate host-sched
+new sid-sched-sim target-sched
+# gloss
+new sw-gloss-generic/libgloss gloss
+# cpu gdb
+new sw-debug-gdb cpu-gdb
+new sid-io-socket-server cpu-gdb-socket
+# memory region 1 (0x00000,0x500000)
+new hw-memory-ram/rom-basic mem1
+# second section
+# settings
+set cpu step-insn-count 10000
+set host-sched num-clients 10 # large enough?
+set target-sched num-clients 10 # large enough?
+# pin connections
+connect-pin main perform-activity -> host-sched advance
+connect-pin main perform-activity -> target-sched advance
+connect-pin main starting -> init-sequence input
+connect-pin main stopping -> deinit-sequence input
+connect-pin init-sequence output-0 -> hw-reset-net input
+connect-pin hw-reset-net output-0 -> cpu reset!
+connect-pin target-sched 0-event -> cpu step!
+connect-pin target-sched 0-control <- cpu step-cycles
+connect-pin yield-net output-0 -> cpu yield
+connect-pin yield-net output-0 -> host-sched yield
+connect-bus cpu insn-memory cpu-mapper access-port
+connect-bus cpu data-memory cpu-mapper access-port
+set cpu memory-mode cygmon
+# gloss
+relate gloss cpu cpu
+connect-pin init-sequence output-2 -> gloss reset
+connect-pin cpu trap <-> gloss trap
+connect-pin cpu trap-code -> gloss trap-code
+set gloss verbose? 0
+connect-bus gloss target-memory cpu-mapper access-port
+set gloss syscall-numbering-scheme cygmon
+# cpu-gdb
+relate cpu-gdb cpu cpu
+relate cpu-gdb cfgroot main
+relate cpu-gdb target-schedulers target-sched
+relate cpu-gdb host-schedulers host-sched
+connect-pin cpu-gdb process-signal -> main stop!
+connect-pin init-sequence output-3 -> cpu-gdb init
+connect-pin deinit-sequence output-5 -> cpu-gdb deinit
+connect-pin cpu-gdb yield -> yield-net input
+connect-pin cpu-gdb flush-icache -> cache-flush-net input
+connect-pin cache-flush-net output-1 -> cpu flush-icache
+connect-pin cpu-gdb restart -> hw-reset-net input
+set cpu-gdb exit-on-detach? 1
+# cpu-gdb-socket
+connect-pin init-sequence output-2 -> cpu-gdb-socket init
+connect-pin deinit-sequence output-6 -> cpu-gdb-socket fini
+connect-pin cpu-gdb-socket rx -> cpu-gdb remote-rx
+connect-pin cpu-gdb-socket tx <- cpu-gdb remote-tx
+connect-pin host-sched 6-event -> cpu-gdb-socket poll-event
+connect-pin host-sched 6-control <- cpu-gdb-socket poll-control
+set cpu-gdb-socket sockaddr-local 0.0.0.0:5000
+# gdb w/ gloss
+connect-pin gloss trap-chain <-> cpu-gdb trap
+connect-pin gloss trap-code-chain -> cpu-gdb trap-code
+connect-pin gloss process-signal -> cpu-gdb gloss-process-signal
+connect-pin gloss debug-tx -> cpu-gdb target-tx
+relate cpu-gdb gloss gloss
+set cpu-gdb enable-Z-packet? false
+set cpu-gdb operating-mode? false
+set cpu endian little
+# memory region 1 (0x00000,0x500000) configuration
+set mem1 size 5242880
+connect-bus cpu-mapper mem1:[0,5242879] mem1 read-write-port
diff --git a/sid/bsp/pregen/i386-gloss.conf b/sid/bsp/pregen/i386-gloss.conf
new file mode 100644 (file)
index 0000000..4420817
--- /dev/null
@@ -0,0 +1,90 @@
+# sid configuration file
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp 
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
+# args: --cpu=x86 --no-run a.out
+load libaudio.la audio_component_library
+load libcache.la cache_component_library
+load libcgencpu.la cgen_component_library
+load libconsoles.la console_component_library
+load libgdb.la gdb_component_library
+load libgloss.la gloss_component_library
+load libglue.la glue_component_library
+load libhd44780u.la hd44780u_component_library
+load libide.la ide_component_library
+load libinterrupt.la interrupt_component_library
+load libloader.la loader_component_library
+load libmapper.la mapper_component_library
+load libmemory.la mem_component_library
+load libmmu.la mmu_component_library
+load libparport.la parport_component_library
+load libprof.la prof_component_library
+load librtc.la rtc_component_library
+load libsched.la sched_component_library
+load libtimers.la timer_component_library
+load libuart.la uart_component_library
+load libx86.la x86_component_library
+# first section
+new hw-cpu-x86 cpu
+new hw-mapper-basic cpu-mapper
+new hw-glue-sequence-8 init-sequence
+new hw-glue-sequence-1 hw-reset-net
+new hw-glue-sequence-8 deinit-sequence
+new hw-glue-sequence-1 yield-net
+new hw-glue-sequence-2 cache-flush-net
+new sid-sched-host-accurate host-sched
+new sid-sched-sim target-sched
+# gloss
+new sw-gloss-generic/libgloss gloss
+# gloss <-> stdio
+new sid-io-stdio stdio
+# cpu loader
+new sw-load-elf cpu-loader
+# memory region 1 (0x00000,0x500000)
+new hw-memory-ram/rom-basic mem1
+# second section
+# settings
+set cpu step-insn-count 10000
+set host-sched num-clients 10 # large enough?
+set target-sched num-clients 10 # large enough?
+# pin connections
+connect-pin main perform-activity -> host-sched advance
+connect-pin main perform-activity -> target-sched advance
+connect-pin main starting -> init-sequence input
+connect-pin main stopping -> deinit-sequence input
+connect-pin init-sequence output-0 -> hw-reset-net input
+connect-pin hw-reset-net output-0 -> cpu reset!
+connect-pin target-sched 0-event -> cpu step!
+connect-pin target-sched 0-control <- cpu step-cycles
+connect-pin yield-net output-0 -> cpu yield
+connect-pin yield-net output-0 -> host-sched yield
+connect-bus cpu insn-memory cpu-mapper access-port
+connect-bus cpu data-memory cpu-mapper access-port
+set cpu memory-mode cygmon
+# gloss
+relate gloss cpu cpu
+connect-pin init-sequence output-2 -> gloss reset
+connect-pin cpu trap <-> gloss trap
+connect-pin cpu trap-code -> gloss trap-code
+set gloss verbose? 0
+connect-bus gloss target-memory cpu-mapper access-port
+set gloss syscall-numbering-scheme cygmon
+# gloss <-> stdio
+set host-sched 0-regular? 1
+set host-sched 0-time 150 # apprx. human perception limit
+connect-pin host-sched 0-event -> stdio poll
+connect-pin gloss debug-tx -> stdio stdout
+connect-pin gloss debug-rx <- stdio stdin
+# gloss w/o gdb
+connect-pin gloss process-signal -> main stop!
+connect-pin gloss process-signal -> yield-net input
+# cpu loader
+set cpu-loader file "a.out" 
+connect-bus cpu-loader load-accessor-data cpu-mapper access-port
+connect-bus cpu-loader load-accessor-insn cpu-mapper access-port # don't trace loading
+connect-pin init-sequence output-1 -> cpu-loader load!
+connect-pin cpu-loader start-pc-set -> cpu start-pc-set!
+connect-pin cpu-loader endian-set -> cpu endian-set!
+connect-pin cpu-loader error -> main stop!
+# memory region 1 (0x00000,0x500000) configuration
+set mem1 size 5242880
+connect-bus cpu-mapper mem1:[0,5242879] mem1 read-write-port
index 611d8c4..c928afd 100755 (executable)
@@ -65,3 +65,10 @@ mvic sid.conf arm-cma.conf
 
 crs --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL --tksm
 mvic sid.conf arm-cma-tksm.conf
+
+crs --cpu=x86 --no-run a.out
+mvic a.out.conf i386-gloss.conf
+
+crs --cpu=x86 --no-run --gdb=5000
+mvic sid.conf i386-gdb.conf
+
index 7b6684d..05c7ab9 100644 (file)
@@ -3,6 +3,7 @@ This is a current list of sid component shared libraries. $Date$
 DIRECTORY       DSO                     COMPONENT_LIBRARY                  MAINTAINERS
 
 audio           libaudio.la             audio_component_library            Red Hat
+bochs          libx86.la               x86_component_library              Red Hat
 cache          libcache.la             cache_component_library            Red Hat
 cfgroot         libconfig.la            config_component_library           Red Hat
 cgen-cpu        libcgencpu.la           cgen_component_library             Red Hat
@@ -39,6 +40,7 @@ hw-audio-sid            Fictional audio codec
 hw-cache-basic         Basic 16kb direct-mapped cache
 hw-cache-*             Other memory caches (ref. component docs)
 hw-cpu-arm7t            ARM7 / ARM7T CPU model
+hw-cpu-x86             X86 CPU model
 hw-cpu-m32r/d           M32R/D CPU model
 hw-disk-ide             IDE hard drive model (controller + drives)
 hw-glue-bus-mux         Bus multiplexer
index 5e46f4e..abc48f3 100644 (file)
@@ -1,7 +1,16 @@
+2001-11-13  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * CATALOG: Document the x86_component_library.  Add
+       hw-cpu-x86.
+
+2001-10-01  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * tconfig.in: Add x86 support.
+
 2001-09-24  Frank Ch. Eigler  <fche@redhat.com>
 
        * configure.in (lcd_libs): Set HAVE_CURSES_LIBRARY if found some
-       usable curses library.  
+       usable curses library.
        * config.in, configure: Regenerated.
 
 2001-07-25  Frank Ch. Eigler  <fche@redhat.com>
index 042eb48..9f1d84d 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -112,9 +113,9 @@ GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -187,7 +188,7 @@ uninstall-binSCRIPTS:
 @SET_MAKE@
 
 all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
 check-recursive installcheck-recursive info-recursive dvi-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
        dot_seen=no; \
@@ -304,8 +305,13 @@ distdir: $(DISTFILES)
        -rm -rf $(distdir)
        mkdir $(distdir)
        -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -328,12 +334,10 @@ info-am:
 info: info-recursive
 dvi-am:
 dvi: dvi-recursive
-check-am:
+check-am: all-am
 check: check-recursive
 installcheck-am:
 installcheck: installcheck-recursive
-install-info-am: 
-install-info: install-info-recursive
 all-recursive-am: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -396,12 +400,12 @@ all-recursive check-recursive installcheck-recursive info-recursive \
 dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
 maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
 distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info all-recursive-am install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-local all-redirect all-am all installdirs-am installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs-am installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 all-local:
index 626ea53..0cb039b 100644 (file)
@@ -648,7 +648,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -666,6 +666,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -677,6 +678,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -689,6 +691,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -706,6 +709,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
diff --git a/sid/component/bochs/ChangeLog b/sid/component/bochs/ChangeLog
new file mode 100644 (file)
index 0000000..24cf550
--- /dev/null
@@ -0,0 +1,141 @@
+2001-11-15  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * bochs.h [BX_SUPPORT_SID] (BX_VGA_MEM_READ): Change
+       expansion to 0 from NULL to prevent compiler warnings.
+
+       * cpu/cpu-sid.h: Remove #define for LOG_THIS; it
+       was causing the compiler to issue redefinition warnings.
+       * cpu/cpu-sid.cc: Add #define for LOG_THIS, to
+       prevent compiler warnings.
+       * cpu/init-sid.cc: Likewise.
+       * memory/memory-sid.cc: Likewise.
+
+2001-11-13  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/cpu-sid.cc: Added proper copyright notice.
+       * cpu/cpu-sid.h: Likewise.
+       * cpu/debugstuff-sid.cc: Likewise.
+       * cpu/exception-sid.cc: Likewise.
+       * cpu/fetchdecode-sid.cc: Likewise.
+       * cpu/init-sid.cc: Likewise.
+       * cpu/x86-memory-modes.cc: Likewise.
+       * cpu/x86.cc: Likewise.
+       * cpu/x86.h: Likewise.
+       * memory/memory-sid.cc: Likewise.
+       * memory/memory-sid.h: Likewise.
+       * cpu/debugstuff-sid.cc: Remove unneeded debug message.
+       * README: New file.
+
+2001-11-09  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/debugstuff-sid.cc (dbg_set_reg): Remove some checks that
+       bochs performed when writing to the eflags register.  They were
+       causing some gdb testsuite failures.
+       * memory/memory-sid.cc: Add exception handling to read_physical
+       and write_physical.
+
+2001-11-07  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/x86-memory-modes.cc: Change memory mode setup to use
+       sidcpuutil.h write_data_memory functions.
+       * cpu/x86-memory-modes.cc: Change default memory mode's gdt to
+       more closely resemble cygmon mode's.
+       * cpu/x86.cc: Remove write_memory and read_memory implementations.
+       * cpu/x86.h: Make sid_mem_c's read_physical and write_physical
+       friends of x86_cpu.
+       * cpu/x86.h: Remove write_memory and read_memory declarations.
+       * memory/memory-sid.cc: Rewrite write_physical and read_physical
+       implementations to use sidcpuutil.h's write_data_memory_* and
+       read_data_memory_* members.
+
+2001-10-15  Frank Ch. Eigler  <fche@redhat.com>
+
+       * configure.in (AC_CHECK_SIZEOF*): Give default sizes for
+       canadian-cross builds.
+       * configure: Regenerated.
+
+2001-10-12  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/x86.cc: Add blocking_on_syscall again.
+       * cpu/x86.h: Add blocking_on_syscall again.
+       * cpu/exception-sid.cc: Add trap to breakpoint comment.
+
+       * bochs.h: Include debug/debug.h.
+       * cpu/Makefile.am: Add debug.h to INCLUDES and added debugstuff-sid.cc
+       to libcpu_la_SOURCES.
+       * cpu/cpu-sid.cc: Add detail to error reporting.
+       * cpu/cpu-sid.h: Add dbg_get_eflags, dbg_get_reg, dbg_set_reg, INT3
+       removed verbose_p.
+       * cpu/exception-sid.cc: Intercept vector == 0x03 to call do_breakpoint.
+       * cpu/fetchdecode-sid.cc: Change BxOpcodeInfo to call sid version of INT3.
+       * cpu/soft_int-sid.cc: Include INT3 implementation.
+       * cpu/x86-memory-modes.cc: Change limit_scaled's to the proper value,
+       0xffffffff.
+       * cpu/x86.cc: Remove blocking_on_syscall, remove watchable_register "pc".
+       * cpu/x86.cc: Add call to create_gdb_register_attrs.
+       * cpu/x86.cc: Change do_syscall to use yield() rather than
+       blocking_on_syscall.
+       * cpu/x86.cc (step_insn): Catch cpu_exception, and add call to signal_trap
+       when enable_step_trap_p is set.
+       * cpu/x86.cc: Add implementations for do_breakpoint, flush_icache,
+       dgb_get_reg, dbg_set_reg, remove set_endian.
+       * cpu/x86.h: Add do_breakpoint, remove set_endian and blocking_on_syscall.
+       * cpu/x86.h: Change x86 component to a basic_bi_endian_cpu from a
+       basic_little_endian_cpu.
+
+2001-10-01  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * Makefile.am: Add conditional compiling of cpu/* fpu/* and 
+       memory/* files.
+       * components.cxx: Add info to generate stub when sid not
+       configured for x86 target.
+       * cpu/x86.h: Add verbose_p member.
+       * cpu/x86.cc: Add verbose_p support.
+
+2001-09-28  Frank Ch. Eigler  <fche@redhat.com>
+
+       * configure.in: Removed AC_OUTPUT calls for nonexistent subdirs.
+       * configure: Regenerated.
+
+2001-09-24  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * fpu/*: Add fpu support to bochs component.
+
+2001-09-23  Frank Ch. Eigler  <fche@redhat.com>
+
+       * configure.in (with_nogui): Hard-code --with-nogui.
+       * configure: Regenerated.
+
+2001-09-18  Frank Ch. Eigler  <fche@redhat.com>
+
+       * memory/misc_mem.cc (BX_MEM_C): Use sprintf, not snprintf, for
+       portability to Solaris.
+
+2001-09-18  Frank Ch. Eigler  <fche@redhat.com>
+
+       * cpu/cpu.cc (prefetch): Make itranslate_* call conditional on
+       BX_SUPPORT_PAGING.
+       * cpu/cpu.h ({i,d}translate_linear): Make declaration conditional.
+       * cpu/main-hack.cc (main): Comment out if BX_SUPPORT_SID.
+
+2001-09-13  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/*: Remove deprecated files: memory-base.h memory-bochs.cc
+       memory-bochs.h memory-sid.cc memory-sid.h misc_mem.cc.
+       * memory/*: Remove deprecated files: memory-base.h memory-bochs.cc
+       memory-bochs.h.
+       * cpu/x86-memory-modes.cc: Add support for cygmon protected
+       memory mode.
+       * cpu/x86.cc: Add proper handling of signal_trap return values
+       to do_syscall().
+       * cpu/x86.h: Add memory-mode member to x86_cpu.
+
+2001-08-30  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * cpu/*: Make changes to support syscalls.
+
+2001-08-20  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       Subclass BX_CPU_C to create sid_cpu_c class.
+
+       Make changes to fetch/decode code; bochs now runs test asm program.
diff --git a/sid/component/bochs/Makefile.am b/sid/component/bochs/Makefile.am
new file mode 100644 (file)
index 0000000..0ab3781
--- /dev/null
@@ -0,0 +1,26 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I ../../config
+
+pkglib_LTLIBRARIES = libx86.la
+
+if SIDTARGET_X86
+SUBDIRLIST = fpu cpu memory .
+SUBLIBLIST = fpu/libfpu.la cpu/libcpu.la memory/libmemory.la 
+else
+SUBDIRLIST =
+SUBLIBLIST =
+endif
+
+SUBDIRS = $(SUBDIRLIST)
+
+INCLUDES = -I$(top_builddir)/.. -I$(top_builddir)/../../include -I$(srcdir)/../../include -I$(srcdir)/cpu -I$(srcdir)/memory
+
+libx86_la_SOURCES = components.cxx
+libx86_la_LDFLAGS = -module -no-undefined
+libx86_la_LIBADD = $(SUBLIBLIST)
+libx86_la_DEPENDENCIES = $(SUBLIBLIST)
+
+AUTOHEADER = echo "Not running autoheader"
+
diff --git a/sid/component/bochs/Makefile.in b/sid/component/bochs/Makefile.in
new file mode 100644 (file)
index 0000000..5634741
--- /dev/null
@@ -0,0 +1,592 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I ../../config
+
+pkglib_LTLIBRARIES = libx86.la
+@SIDTARGET_X86_TRUE@SUBDIRLIST = @SIDTARGET_X86_TRUE@fpu cpu memory .
+@SIDTARGET_X86_FALSE@SUBDIRLIST = 
+@SIDTARGET_X86_TRUE@SUBLIBLIST = @SIDTARGET_X86_TRUE@fpu/libfpu.la cpu/libcpu.la memory/libmemory.la 
+@SIDTARGET_X86_FALSE@SUBLIBLIST = 
+
+SUBDIRS = $(SUBDIRLIST)
+
+INCLUDES = -I$(top_builddir)/.. -I$(top_builddir)/../../include -I$(srcdir)/../../include -I$(srcdir)/cpu -I$(srcdir)/memory
+
+libx86_la_SOURCES = components.cxx
+libx86_la_LDFLAGS = -module -no-undefined
+libx86_la_LIBADD = $(SUBLIBLIST)
+libx86_la_DEPENDENCIES = $(SUBLIBLIST)
+
+AUTOHEADER = echo "Not running autoheader"
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(pkglib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libx86_la_OBJECTS =  components.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+aclocal.m4 config.guess config.h.in config.sub configure configure.in \
+install-sh ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DIST_SUBDIRS =  fpu cpu memory .
+DEP_FILES =  .deps/components.P
+SOURCES = $(libx86_la_SOURCES)
+OBJECTS = $(libx86_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cxx .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in  \
+               ../../config/am_rpm_init.m4 ../../config/cgen-maint.m4 \
+               ../../config/docbuild.m4 ../../config/libstdc++.m4 \
+               ../../config/libtool.m4 ../../config/ltdl.m4 \
+               ../../config/sidtargets.m4
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-pkglibLTLIBRARIES:
+
+clean-pkglibLTLIBRARIES:
+       -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+
+distclean-pkglibLTLIBRARIES:
+
+maintainer-clean-pkglibLTLIBRARIES:
+
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+       @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+         else :; fi; \
+       done
+
+uninstall-pkglibLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+         $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libx86.la: $(libx86_la_OBJECTS) $(libx86_la_DEPENDENCIES)
+       $(CXXLINK) -rpath $(pkglibdir) $(libx86_la_LDFLAGS) $(libx86_la_OBJECTS) $(libx86_la_LIBADD) $(LIBS)
+.cxx.o:
+       $(CXXCOMPILE) -c $<
+.cxx.lo:
+       $(LTCXXCOMPILE) -c $<
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+         rev="$$subdir $$rev"; \
+         test "$$subdir" = "." && dot_seen=yes; \
+       done; \
+       test "$$dot_seen" = "no" && rev=". $$rev"; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+   if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+   fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+       for subdir in $(DIST_SUBDIRS); do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           chmod 777 $(distdir)/$$subdir; \
+           (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+             || exit 1; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-pkglibLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-pkglibLTLIBRARIES
+uninstall: uninstall-recursive
+all-am: Makefile $(LTLIBRARIES) config.h
+all-redirect: all-recursive-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+       $(mkinstalldirs)  $(DESTDIR)$(pkglibdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-pkglibLTLIBRARIES \
+               mostlyclean-compile mostlyclean-libtool \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am:  clean-hdr clean-pkglibLTLIBRARIES clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am:  distclean-hdr distclean-pkglibLTLIBRARIES \
+               distclean-compile distclean-libtool distclean-tags \
+               distclean-depend distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-recursive
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr \
+               maintainer-clean-pkglibLTLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-pkglibLTLIBRARIES distclean-pkglibLTLIBRARIES \
+clean-pkglibLTLIBRARIES maintainer-clean-pkglibLTLIBRARIES \
+uninstall-pkglibLTLIBRARIES install-pkglibLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sid/component/bochs/README b/sid/component/bochs/README
new file mode 100644 (file)
index 0000000..1292c16
--- /dev/null
@@ -0,0 +1,29 @@
+This is the sid x86 component.  It is based heavily on code from bochs
+1.2.1. I have tried to "wrap" the bochs code as much as possible so
+that new bochs releases can be easily incorporated. The design looks
+something like this:
+
++-----------------------------------------------------+
+|                                                     |
+|  x86_cpu object (see cpu/x86.h)                     |<---+
+|                                                     |<-+ |
+|     +---------------------------------------------+ |  | |
+|     |  sid_cpu_c object (see cpu/cpu-sid.h)       | |  | |
+|     |                                             | |  | |
+|     |    x86_cpu * ------------------------------------+ |
+|     |                                             | |    |
+|     +---------------------------------------------+ |    |
+|     +---------------------------------------------+ |    |
+|     |  sid_mem_c object (see memory/memory-sid.h) | |    |  
+|     |                                             | |    |
+|     |    x86_cpu * --------------------------------------+
+|     |                                             | |
+|     +---------------------------------------------+ |
++-----------------------------------------------------+
+
+The sid_cpu_c class inherits from bx_cpu_c which is the main bochs cpu
+class. Likewise, sid_mem_c inherits from bx_mem_c, the main bochs
+memory class. Anytime a bochs member function needed to be changed to
+work in the sid framework, I overrode the function in either sid_cpu_c
+or sid_mem_c.
+
diff --git a/sid/component/bochs/aclocal.m4 b/sid/component/bochs/aclocal.m4
new file mode 100644 (file)
index 0000000..f1e2a76
--- /dev/null
@@ -0,0 +1,711 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "[$]*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "[$]*" != "X $srcdir/configure conftestfile" \
+      && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
+
+# serial 41 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+AC_ARG_WITH(pic,
+  [  --with-pic              try to use only PIC/non-PIC objects [default=use both]],
+     pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+  # recent cygwin and mingw systems supply a stub DllMain which the user
+  # can override, but on older systems we have to supply one
+  AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+    [AC_TRY_LINK([DllMain (0, 0, 0);],
+      [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);],
+      [lt_cv_need_dllmain=yes],[lt_cv_need_dllmain=no])])
+
+  case $host in
+  *-*-cygwin*)
+    # cygwin systems need to pass --dll to the linker, and not link
+    # crt.o which will require a WinMain@16 definition.
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+  *-*-mingw*)
+    # old mingw systems require "-dll" to link a DLL, while more recent ones
+    # require "-mdll"
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mdll"
+    AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+      [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+    CFLAGS="$SAVE_CFLAGS" ;;
+  esac
+  ;;
+  ])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+dnl sidtargets.m4  -*- m4 -*-
+
+dnl Copyright (C) 1999, 2000, 2001 Red Hat.
+dnl This file is part of SID and is licensed under the GPL.
+dnl See the file COPYING.SID for conditions for redistribution.
+
+dnl Use CY_SIDTARGET_CHECK in configure.in to respond to the builder's
+dnl selection of --target/--enable-targets
+
+AC_DEFUN(CY_SIDTARGET_CHECK, [
+
+
+dnl Assume all targets if $host==$target or $target==NONE
+sid_host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host`
+sid_target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target`
+
+if test "$sid_host" = "$sid_target" -o "$target" = "NONE"
+then
+    AC_MSG_WARN(Assuming --enable-targets=all)
+    all_targets=""
+    sidtarget_default=1
+else 
+    all_targets="$target"
+    sidtarget_default=0
+fi
+
+
+AC_ARG_ENABLE(targets,
+[  --enable-targets=LIST   support given additional targets, or all],
+[
+  case "${enable_targets}" in
+    all)  sidtarget_default=1 ;;
+    no)   sidtarget_default=0 ;;
+    *)    all_targets="${all_targets} `echo ${enable_targets} | sed -e 's-,- -g'`" ;;
+  esac
+])
+
+dnl Enumerate known chip families
+sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
+sidtarget_mips=$sidtarget_default
+sidtarget_m32r=$sidtarget_default
+sidtarget_m68k=$sidtarget_default
+sidtarget_ppc=$sidtarget_default
+
+dnl Iterate over all listed targets
+for targ in $all_targets
+do
+   case "$targ" in
+      arm*)   sidtarget_arm=1 ;;
+      thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
+      mips*)  sidtarget_mips=1 ;;
+      m32r*)  sidtarget_m32r=1 ;;
+      m68k*)  sidtarget_m68k=1 ;;
+      powerpc*) sidtarget_ppc=1 ;;
+      ppc*)   sidtarget_ppc=1 ;;
+      *)      AC_MSG_WARN("Unknown target $targ") ;;
+   esac
+done
+
+dnl Ensure at least one of these variables is non-zero.
+case 1 in
+  ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
+  ${sidtarget_mips}) ;;
+  ${sidtarget_m32r}) ;;
+  ${sidtarget_m68k}) ;;
+  ${sidtarget_ppc}) ;;
+  *) AC_MSG_WARN([No selected sid targets: use --enable-targets or --target])
+       ;;
+esac
+
+dnl Report results SIDTARGET_family
+dnl nb: Use "x$sidtarget_family" in the tested expression to prevent
+dnl     syntax errors in configure when sidtarget_family is left unset.
+
+AC_MSG_CHECKING(ARM family support)
+AC_SUBST(sidtarget_arm)
+AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
+AC_MSG_RESULT($sidtarget_arm)
+
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
+AC_MSG_CHECKING(MIPS family support)
+AC_SUBST(sidtarget_mips)
+AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
+AC_MSG_RESULT($sidtarget_mips)
+
+AC_MSG_CHECKING(M32R family support)
+AC_SUBST(sidtarget_m32r)
+AM_CONDITIONAL(SIDTARGET_M32R,[test "x$sidtarget_m32r" = x1])
+AC_MSG_RESULT($sidtarget_m32r)
+
+AC_MSG_CHECKING(M68K family support)
+AC_SUBST(sidtarget_m68k)
+AM_CONDITIONAL(SIDTARGET_M68K,[test "x$sidtarget_m68k" = x1])
+AC_MSG_RESULT($sidtarget_m68k)
+
+AC_MSG_CHECKING(PPC family support)
+AC_SUBST(sidtarget_ppc)
+AM_CONDITIONAL(SIDTARGET_PPC,[test "x$sidtarget_ppc" = x1])
+AC_MSG_RESULT($sidtarget_ppc)
+
+])
+
diff --git a/sid/component/bochs/bochs.h b/sid/component/bochs/bochs.h
new file mode 100644 (file)
index 0000000..50a775d
--- /dev/null
@@ -0,0 +1,688 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+//
+// bochs.h is the master header file for all C++ code.  It includes all 
+// the system header files needed by bochs, and also includes all the bochs
+// C++ header files.  Because bochs.h and the files that it includes has 
+// structure and class definitions, it cannot be called from C code.
+// 
+
+#ifndef BX_BOCHS_H
+#  define BX_BOCHS_H 1
+
+extern "C" {
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef WIN32
+#  include <unistd.h>
+#else
+#  include <io.h>
+#endif
+#include <time.h>
+#ifdef macintosh
+#  include <types.h>
+#  include <stat.h>
+#  include <utime.h>
+#else
+#  ifndef WIN32
+#    include <sys/time.h>
+#  endif
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#endif
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+#ifdef macintosh
+#  include "macutils.h"
+#  define SuperDrive "[fd:]"
+#endif
+}
+
+// Hacks for win32: always return regular file.
+#ifdef WIN32
+#ifndef __MINGW32__
+#  define S_ISREG(st_mode) 1
+#  define S_ISCHR(st_mode) 0
+
+// VCPP includes also are missing these
+#  define off_t long
+#  define ssize_t int
+
+// win32 has snprintf though with different name.
+#define snprintf _snprintf
+#endif
+
+#endif
+
+#define BX_SUPPORT_SID 1
+
+#if BX_SUPPORT_SID
+#  include "config.h"      /* generated by configure script from config.h.in */
+#  include "debug/debug.h"
+#  include "bxversion.h"
+#else
+#  include "config.h"      /* generated by configure script from config.h.in */
+#  include "osdep.h"       /* platform dependent includes and defines */ 
+#  include "debug/debug.h"
+#  include "bxversion.h"
+#endif
+
+
+#if BX_SUPPORT_SID
+class sid_mem_c;
+#define BX_MEM_DECL sid_mem_c
+#else
+#define BX_MEM_DECL BX_MEM_C
+#endif // BX_SUPPORT_SID
+
+//
+// some macros to interface the CPU and memory to external environment
+// so that these functions can be redirected to the debugger when
+// needed.
+//
+
+#if ((BX_DEBUGGER == 1) && (BX_NUM_SIMULATORS >= 2))
+// =-=-=-=-=-=-=- Redirected to cosimulation debugger -=-=-=-=-=-=-=
+#define BX_VGA_MEM_READ(addr)       bx_dbg_ucmem_read(addr)
+#define BX_VGA_MEM_WRITE(addr, val) bx_dbg_ucmem_write(addr, val)
+#if BX_SUPPORT_A20
+#  define A20ADDR(x)               ( (x) & bx_pc_system.a20_mask )
+#else
+#  define A20ADDR(x)                (x)
+#endif
+#define BX_INP(addr, len)           bx_dbg_inp(addr, len)
+#define BX_OUTP(addr, val, len)     bx_dbg_outp(addr, val, len)
+#define BX_HRQ                      (bx_pc_system.HRQ)
+#define BX_RAISE_HLDA()             bx_dbg_raise_HLDA()
+#define BX_TICK1()
+#define BX_INTR                     bx_pc_system.INTR
+#define BX_SET_INTR(b)              bx_dbg_set_INTR(b)
+#if BX_SIM_ID == 0
+#  define BX_CPU_C                  bx_cpu0_c
+#  define BX_CPU                    bx_cpu0
+#  define BX_MEM_C                  bx_mem0_c
+#  define BX_MEM                    bx_mem0
+#else
+#  define BX_CPU_C                  bx_cpu1_c
+#  define BX_CPU                    bx_cpu1
+#  define BX_MEM_C                  bx_mem1_c
+#  define BX_MEM                    bx_mem1
+#endif
+#define BX_SET_ENABLE_A20(enabled)  bx_dbg_async_pin_request(BX_DBG_ASYNC_PENDING_A20, \
+                                      enabled)
+#define BX_GET_ENABLE_A20()         bx_pc_system.get_enable_a20()
+#error FIXME: cosim mode not fixed yet
+
+#else
+
+// =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#if BX_SUPPORT_SID
+#define BX_VGA_MEM_READ(addr) 0
+#define BX_VGA_MEM_WRITE(addr, val)
+#else
+#define BX_VGA_MEM_READ(addr) (bx_devices.vga->mem_read(addr))
+#define BX_VGA_MEM_WRITE(addr, val) bx_devices.vga->mem_write(addr, val)
+#endif
+#if BX_SUPPORT_A20
+#  define A20ADDR(x)               ( (x) & bx_pc_system.a20_mask )
+#else
+#  define A20ADDR(x)               (x)
+#endif
+//
+// some pc_systems functions just redirect to the IO devices so optimize
+// by eliminating call here
+//
+// #define BX_INP(addr, len)        bx_pc_system.inp(addr, len)
+// #define BX_OUTP(addr, val, len)  bx_pc_system.outp(addr, val, len)
+#define BX_INP(addr, len)           bx_devices.inp(addr, len)
+#define BX_OUTP(addr, val, len)     bx_devices.outp(addr, val, len)
+#define BX_HRQ                      (bx_pc_system.HRQ)
+#define BX_RAISE_HLDA()             bx_pc_system.raise_HLDA()
+#if BX_SUPPORT_SID
+#define BX_TICK1()
+#else
+#define BX_TICK1()                  bx_pc_system.tick1()
+#endif // BX_SUPPORT_SID
+#define BX_TICKN(n)                 bx_pc_system.tickn(n)
+#define BX_INTR                     bx_pc_system.INTR
+#define BX_SET_INTR(b)              bx_pc_system.set_INTR(b)
+#define BX_CPU_C                    bx_cpu_c
+#define BX_MEM_C                    bx_mem_c
+#if BX_SMP_PROCESSORS==1
+#define BX_CPU(x)                   (&bx_cpu)
+#define BX_MEM(x)                   (&bx_mem)
+#else
+#define BX_CPU(x)                   (bx_cpu_array[x])
+#define BX_MEM(x)                   (bx_mem_array[x])
+#endif
+
+#define BX_SET_ENABLE_A20(enabled)  bx_pc_system.set_enable_a20(enabled)
+#define BX_GET_ENABLE_A20()         bx_pc_system.get_enable_a20()
+
+#endif
+
+// you can't use static member functions on the CPU, if there are going
+// to be 2 cpus.  Check this early on.
+#if (BX_SMP_PROCESSORS>1)
+#  if (BX_USE_CPU_SMF!=0)
+#    error For SMP simulation, BX_USE_CPU_SMF must be 0.
+#  endif
+#endif
+
+
+// #define BX_IAC()                 bx_pc_system.IAC()
+#define BX_IAC()                    bx_devices.pic->IAC()
+//#define BX_IAC()                    bx_dbg_IAC()
+
+//
+// Ways for the the external environment to report back information
+// to the debugger.
+//
+
+#if BX_DEBUGGER
+#  define BX_DBG_ASYNC_INTR bx_guard.async.irq
+#  define BX_DBG_ASYNC_DMA  bx_guard.async.dma
+#if (BX_NUM_SIMULATORS > 1)
+// for multiple simulators, we always need this info, since we're
+// going to replay it.
+#  define BX_DBG_DMA_REPORT(addr, len, what, val) \
+        bx_dbg_dma_report(addr, len, what, val)
+#  define BX_DBG_IAC_REPORT(vector, irq) \
+        bx_dbg_iac_report(vector, irq)
+#  define BX_DBG_A20_REPORT(val) \
+        bx_dbg_a20_report(val)
+#  define BX_DBG_IO_REPORT(addr, size, op, val) \
+        bx_dbg_io_report(addr, size, op, val)
+#  define BX_DBG_UCMEM_REPORT(addr, size, op, val)
+#else
+// for a single simulator debug environment, we can optimize a little
+// by conditionally calling, as per requested.
+
+#  define BX_DBG_DMA_REPORT(addr, len, what, val) \
+        if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val)
+#  define BX_DBG_IAC_REPORT(vector, irq) \
+        if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq)
+#  define BX_DBG_A20_REPORT(val) \
+        if (bx_guard.report.a20) bx_dbg_a20_report(val)
+#  define BX_DBG_IO_REPORT(addr, size, op, val) \
+        if (bx_guard.report.io) bx_dbg_io_report(addr, size, op, val)
+#  define BX_DBG_UCMEM_REPORT(addr, size, op, val) \
+        if (bx_guard.report.ucmem) bx_dbg_ucmem_report(addr, size, op, val)
+#endif  // #if (BX_NUM_SIMULATORS > 1)
+
+#else  // #if BX_DEBUGGER
+// debugger not compiled in, use empty stubs
+#  define BX_DBG_ASYNC_INTR 1
+#  define BX_DBG_ASYNC_DMA  1
+#  define BX_DBG_DMA_REPORT(addr, len, what, val)
+#  define BX_DBG_IAC_REPORT(vector, irq)
+#  define BX_DBG_A20_REPORT(val)
+#  define BX_DBG_IO_REPORT(addr, size, op, val)
+#  define BX_DBG_UCMEM_REPORT(addr, size, op, val)
+#endif  // #if BX_DEBUGGER
+
+extern Bit8u DTPageDirty[];
+#if BX_DYNAMIC_TRANSLATION
+#  define BX_DYN_DIRTY_PAGE(page) DTPageDirty[page] = 1;
+#else
+#  define BX_DYN_DIRTY_PAGE(page)
+#endif
+
+#define MAGIC_LOGNUM 0x12345678
+
+// Log Level defines
+#define LOGLEV_DEBUG 0
+#define LOGLEV_INFO  1
+#define LOGLEV_ERROR 2
+#define LOGLEV_PANIC 3
+#define MAX_LOGLEV   4
+
+typedef class logfunctions {
+       char *prefix;
+       int type;
+// values of onoff: 0=ignore, 1=report, 2=fatal
+#define ACT_IGNORE 0
+#define ACT_REPORT 1
+#define ACT_FATAL  2
+       int onoff[MAX_LOGLEV];
+       class iofunctions *logio;
+public:
+       logfunctions(void);
+       logfunctions(class iofunctions *);
+       ~logfunctions(void);
+
+       void info(char *fmt, ...);
+       void error(char *fmt, ...);
+       void panic(char *fmt, ...);
+       void ldebug(char *fmt, ...);
+       void fatal (char *prefix, char *fmt, va_list ap);
+       void setprefix(char *);
+       void settype(int);
+       void setio(class iofunctions *);
+       void setonoff(int loglev, int value) { onoff[loglev] = value; }
+} logfunc_t;
+
+class iofunctions {
+       int showtick,magic;
+       FILE *logfd;
+       class logfunctions *log;
+       void init(void);
+       void flush(void);
+       char *getlevel(int i) {
+               static char *loglevel[] = {
+                       "DEBUG",
+                       "INFO",
+                       "ERROR",
+                       "PANIC",
+               };
+               return loglevel[i];
+       }
+
+       char *getclass(int i) {
+               char *logclass[] = {
+                 "IO  ",
+                 "FD  ",
+                 "GEN ",
+                 "CMOS",
+                 "CD  ",
+                 "DMA ",
+                 "ETH ",
+                 "G2H ",
+                 "HD  ",
+                 "KBD ",
+                 "NE2K",
+                 "PAR ",
+                 "PCI ",
+                 "PIC ",
+                 "PIT ",
+                 "SB16",
+                 "SER ",
+                 "VGA ",
+                 "ST  ",
+                 "DEV ",
+                 "MEM ",
+                 "DIS ",
+                 "GUI ",
+                 "IOAP",
+                 "APIC",
+                 "CPU0",
+                 "CPU1",
+                 "CPU2",
+                 "CPU3",
+                 "CPU4",
+                 "CPU5",
+                 "CPU6",
+                 "CPU7",
+                 "CPU8",
+                 "CPU9",
+                 "CPUa",
+                 "CPUb",
+                 "CPUc",
+                 "CPUd",
+                 "CPUe",
+                 "CPUf",
+               };
+               return logclass[i];
+       }
+
+// Log Class defines
+#define    IOLOG           0
+#define    FDLOG           1
+#define    GENLOG          2
+#define    CMOSLOG         3
+#define    CDLOG           4
+#define    DMALOG          5
+#define    ETHLOG          6
+#define    G2HLOG          7
+#define    HDLOG           8
+#define    KBDLOG          9
+#define    NE2KLOG         10
+#define    PARLOG          11
+#define    PCILOG          12
+#define    PICLOG          13
+#define    PITLOG          14
+#define    SB16LOG         15
+#define    SERLOG          16
+#define    VGALOG          17
+#define    STLOG           18   // state_file.cc
+#define    DEVLOG          19
+#define    MEMLOG          20
+#define    DISLOG          21
+#define    GUILOG          22
+#define    IOAPICLOG       23
+#define    APICLOG         24
+#define    CPU0LOG         25
+#define    CPU1LOG         26
+#define    CPU2LOG         27
+#define    CPU3LOG         28
+#define    CPU4LOG         29
+#define    CPU5LOG         30
+#define    CPU6LOG         31
+#define    CPU7LOG         32
+#define    CPU8LOG         33
+#define    CPU9LOG         34
+#define    CPU10LOG         35
+#define    CPU11LOG         36
+#define    CPU12LOG         37
+#define    CPU13LOG         38
+#define    CPU14LOG         39
+#define    CPU15LOG         40
+
+
+public:
+       iofunctions(void);
+       iofunctions(FILE *);
+       iofunctions(int);
+       iofunctions(char *);
+       ~iofunctions(void);
+
+       void out(int facility, int level, char *pre, char *fmt, va_list ap);
+
+       void init_log(char *fn);
+       void init_log(int fd);
+       void init_log(FILE *fs);
+       int get_n_logfns () { return n_logfn; }
+       logfunc_t *get_logfn (int index) { return logfn_list[index]; }
+       void add_logfn (logfunc_t *fn);
+       void set_log_action (int loglevel, int action);
+protected:
+       int n_logfn;
+#define MAX_LOGFNS 64
+       logfunc_t *logfn_list[MAX_LOGFNS];
+       char *logfn;
+};
+
+typedef class iofunctions iofunc_t;
+
+
+#define SAFE_GET_IOFUNC() \
+  ((io==NULL)? (io=new iofunc_t("/dev/stderr")) : io)
+#define SAFE_GET_GENLOG() \
+  ((genlog==NULL)? (genlog=new logfunc_t(SAFE_GET_IOFUNC())) : genlog)
+/* #define NO_LOGGING */
+#ifndef NO_LOGGING
+
+#define BX_INFO(x)  (LOG_THIS info) x
+#define BX_DEBUG(x) (LOG_THIS ldebug) x
+#define BX_ERROR(x) (LOG_THIS error) x
+#define BX_PANIC(x) (LOG_THIS panic) x
+
+#else
+
+#define EMPTY do { } while(0)
+
+#define BX_INFO(x)  EMPTY
+#define BX_DEBUG(x) EMPTY
+#define BX_ERROR(x) EMPTY
+#define BX_PANIC(x) (LOG_THIS panic) x
+
+#endif
+
+extern iofunc_t *io;
+extern logfunc_t *genlog;
+
+#if BX_SUPPORT_SID
+#else
+#include "state_file.h"
+#endif
+
+#ifndef UNUSED
+#  define UNUSED(x) ((void)x)
+#endif
+
+#define uint8   Bit8u
+#define uint16  Bit16u
+#define uint32  Bit32u
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+#if BX_SUPPORT_SID
+#include "cpu/cpu-sid.h"
+#else
+#  include "cpu/cpu.h"
+#endif
+#endif
+
+#if BX_DISASM
+#  include "disasm/disasm.h"
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+#  include "dynamic/dynamic.h"
+#endif
+
+
+typedef struct {
+  Boolean floppy;
+  Boolean keyboard;
+  Boolean video;
+  Boolean disk;
+  Boolean pit;
+  Boolean pic;
+  Boolean bios;
+  Boolean cmos;
+  Boolean a20;
+  Boolean interrupts;
+  Boolean exceptions;
+  Boolean unsupported;
+  Boolean temp;
+  Boolean reset;
+  Boolean debugger;
+  Boolean mouse;
+  Boolean io;
+  Boolean xms;
+  Boolean v8086;
+  Boolean paging;
+  Boolean creg;
+  Boolean dreg;
+  Boolean dma;
+  Boolean unsupported_io;
+  Boolean serial;
+  Boolean cdrom;
+#ifdef MAGIC_BREAKPOINT
+  Boolean magic_break_enabled;
+#endif /* MAGIC_BREAKPOINT */
+#if BX_SUPPORT_APIC
+  Boolean apic;
+  Boolean ioapic;
+#endif
+#if BX_DEBUG_LINUX
+  Boolean linux_syscall;
+#endif
+  void* record_io;
+  } bx_debug_t;
+
+#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%s\n", #x, __FILE__, __LINE__));} while (0)
+void bx_signal_handler (int signum);
+void bx_atexit(void);
+#if BX_DEBUGGER
+extern bx_debug_t bx_dbg;
+#endif
+
+
+#define BX_FLOPPY_NONE   10 // floppy not present
+#define BX_FLOPPY_1_2    11 // 1.2M  5.25"
+#define BX_FLOPPY_1_44   12 // 1.44M 3.5"
+#define BX_FLOPPY_2_88   13 // 2.88M 3.5"
+#define BX_FLOPPY_720K   14 // 720K  3.5"
+
+
+#define BX_READ    10
+#define BX_WRITE   11
+#define BX_RW      12
+
+
+#if BX_SUPPORT_SID
+#include "memory/memory-sid.h"
+#else
+#include "memory/memory.h"
+#endif
+
+enum PCS_OP { PCS_CLEAR, PCS_SET, PCS_TOGGLE };
+
+#if BX_SUPPORT_SID
+#else
+#include "pc_system.h"
+
+#include "gui/gui.h"
+extern bx_gui_c   bx_gui;
+#include "iodev/iodev.h"
+#endif // BX_SUPPORT_SID
+
+
+
+
+
+
+
+/* --- EXTERNS --- */
+
+#if BX_SUPPORT_SID==0
+#if ( BX_PROVIDE_DEVICE_MODELS==1 )
+extern bx_devices_c   bx_devices;
+#endif
+#endif // BX_SUPPORT_SID
+
+#define BX_EJECTED   10
+#define BX_INSERTED  11
+
+
+#define BX_RESET_SOFTWARE 10
+#define BX_RESET_HARDWARE 11
+
+
+typedef struct {
+  char path[512];
+  unsigned type;
+  unsigned initial_status;
+  } bx_floppy_options;
+
+typedef struct {
+  Boolean present;
+  char path[512];
+  unsigned int cylinders;
+  unsigned int heads;
+  unsigned int spt;
+  } bx_disk_options;
+
+struct bx_cdrom_options
+{
+  Boolean present;
+  char dev[512];
+  Boolean inserted;
+};
+
+typedef struct {
+  char *path;
+  unsigned long address;
+  } bx_rom_options;
+
+typedef struct {
+  char *path;
+  } bx_vgarom_options;
+
+typedef struct {
+  size_t megs;
+  } bx_mem_options;
+
+typedef struct {
+  char      *path;
+  Boolean   cmosImage;
+       unsigned int time0;
+  } bx_cmos_options;
+
+typedef struct {
+  int       valid;
+  unsigned  ioaddr;
+  unsigned  irq;
+  unsigned char macaddr[6];
+  char      *ethmod;
+  char      *ethdev;
+  } bx_ne2k_options;
+
+typedef struct {
+// These options are used for a special hack to load a
+// 32bit OS directly into memory, so it can be run without
+// any of the 16bit real mode or BIOS assistance.  This
+// is for the development of freemware, so we don't have
+// to implement real mode up front.
+#define Load32bitOSLinux       1
+#define Load32bitOSNullKernel  2 // being developed for freemware
+  unsigned whichOS;
+  char    *path;
+  char    *iolog;
+  char    *initrd;
+  } bx_load32bitOSImage_t;
+
+
+typedef struct {
+  char *midifile, *wavefile, *logfile;
+  unsigned int midimode, wavemode, loglevel;
+  Bit32u dmatimer;
+  } bx_sb16_options;
+
+typedef struct {
+  bx_floppy_options floppya;
+  bx_floppy_options floppyb;
+  bx_disk_options   diskc;
+  bx_disk_options   diskd;
+  bx_cdrom_options  cdromd; 
+  bx_rom_options    rom;
+  bx_vgarom_options vgarom;
+  bx_mem_options    memory;
+  bx_sb16_options   sb16;
+  char              bootdrive[2];
+  unsigned long     vga_update_interval;
+  unsigned long     keyboard_serial_delay;
+  unsigned long     floppy_command_delay;
+  unsigned long     ips;
+  Boolean           mouse_enabled;
+  Boolean           private_colormap;
+  Boolean           i440FXSupport;
+  bx_cmos_options   cmos;
+  bx_ne2k_options   ne2k;
+  Boolean           newHardDriveSupport;
+  bx_load32bitOSImage_t load32bitOSImage;
+         // one array item for each log level, indexed by LOGLEV_*.
+        // values: 0=ignore event, 1=report event in log, 2=fatal
+  unsigned char log_actions[MAX_LOGLEV];  
+  } bx_options_t;
+
+extern bx_options_t bx_options;
+
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+#else
+// #  include "external_interface.h"
+#endif
+
+#define BX_USE_PS2_MOUSE 1
+
+int bx_bochs_init(int argc, char *argv[]);
+
+#include "instrument.h"
+
+#endif  /* BX_BOCHS_H */
diff --git a/sid/component/bochs/bxversion.h b/sid/component/bochs/bxversion.h
new file mode 100644 (file)
index 0000000..18c3798
--- /dev/null
@@ -0,0 +1,3 @@
+// This file is generated by "make bxversion.h"
+#define VER_STRING "1.2.1"
+#define REL_STRING "June 12, 2001"
diff --git a/sid/component/bochs/components.cxx b/sid/component/bochs/components.cxx
new file mode 100644 (file)
index 0000000..8fcb41d
--- /dev/null
@@ -0,0 +1,83 @@
+// components.cxx - definitions for this component library. -*- C++ -*-
+
+// Copyright (C) 1999, 2000 Red Hat.
+// This file is part of SID and is licensed under the GPL.
+// See the file COPYING.SID for conditions for redistribution.
+
+#include "tconfig.h"
+#include "config.h"
+
+#include <sidcomp.h>
+#include <sidso.h>
+
+#include <vector>
+#include <string>
+
+#include "x86.h"
+
+using std::vector;
+using std::string;
+
+using sid::component;
+using sid::component_library;
+using sid::COMPONENT_LIBRARY_MAGIC;
+
+
+
+// ----------------------------------------------------------------------------
+
+
+static
+vector<string>
+compX86ListTypes()
+{
+  vector<string> types;
+
+
+#if SIDTARGET_X86
+  types.push_back("hw-cpu-x86");
+#endif
+
+  return types;
+}
+
+
+static
+component*
+compX86Create(const string& typeName)
+{
+#if SIDTARGET_X86
+    try {
+        
+        if(typeName == "hw-cpu-x86")
+        {
+            return new x86_cpu();
+        }
+    }
+    catch (...) { }
+#endif
+    return 0;
+}
+
+
+static
+void
+compX86Delete(component* c)
+{
+#if SIDTARGET_X86
+    delete dynamic_cast<sidutil::basic_cpu*>(c);
+#endif
+}
+
+
+
+// static object
+extern const component_library x86_component_library;
+
+const component_library x86_component_library DLLEXPORT = 
+{
+  COMPONENT_LIBRARY_MAGIC,
+  & compX86ListTypes, 
+  & compX86Create,
+  & compX86Delete
+};
diff --git a/sid/component/bochs/config.guess b/sid/component/bochs/config.guess
new file mode 100644 (file)
index 0000000..0ce538b
--- /dev/null
@@ -0,0 +1,1183 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+#   Free Software Foundation, Inc.
+#
+# This file 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+  if test x"$HOST_CC" != x; then
+    CC_FOR_BUILD="$HOST_CC"
+  else
+    if test x"$CC" != x; then
+      CC_FOR_BUILD="$CC"
+    else
+      CC_FOR_BUILD=cc
+    fi
+  fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # Netbsd (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       # Determine the machine/vendor (is the vendor relevant).
+       case "${UNAME_MACHINE}" in
+           amiga) machine=m68k-cbm ;;
+           arm32) machine=arm-unknown ;;
+           atari*) machine=m68k-atari ;;
+           sun3*) machine=m68k-sun ;;
+           mac68k) machine=m68k-apple ;;
+           macppc) machine=powerpc-apple ;;
+           hp3[0-9][05]) machine=m68k-hp ;;
+           ibmrt|romp-ibm) machine=romp-ibm ;;
+           *) machine=${UNAME_MACHINE}-unknown ;;
+       esac
+       # The Operating System including object format.
+       if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+               | grep __ELF__ >/dev/null
+       then
+           # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+           # Return netbsd for either.  FIX?
+           os=netbsd
+       else
+           os=netbsdelf
+       fi
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       rm -f $dummy.c $dummy
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_help_string=`cd /; ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         *ia64)
+               echo "${UNAME_MACHINE}-unknown-linux"
+               exit 0
+               ;;
+         i?86linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0
+               ;;
+         elf_i?86)
+               echo "${UNAME_MACHINE}-pc-linux"
+               exit 0
+               ;;
+         i?86coff)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0
+               ;;
+         sparclinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         armlinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         elf32arm*)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
+               exit 0
+               ;;
+         armelf_linux*)
+               echo "${UNAME_MACHINE}-unknown-linux-gnu"
+               exit 0
+               ;;
+         m68klinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         elf32ppc | elf32ppclinux)
+               # Determine Lib Version
+               cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#if defined(__GLIBC__)
+  printf("%s %s\n", __libc_version, __libc_release);
+#else
+  printf("unkown\n");
+#endif
+  return 0;
+}
+EOF
+               LIBC=""
+               $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./$dummy | grep 1\.99 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi
+               rm -f $dummy.c $dummy
+               echo powerpc-unknown-linux-gnu${LIBC}
+               exit 0
+               ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               cat <<EOF >$dummy.s
+                       .data
+               \$Lformat:
+                       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+                       .text
+                       .globl main
+                       .align 4
+                       .ent main
+               main:
+                       .frame \$30,16,\$26,0
+                       ldgp \$29,0(\$27)
+                       .prologue 1
+                       .long 0x47e03d80 # implver \$0
+                       lda \$2,-1
+                       .long 0x47e20c21 # amask \$2,\$1
+                       lda \$16,\$Lformat
+                       mov \$0,\$17
+                       not \$1,\$18
+                       jsr \$26,printf
+                       ldgp \$29,0(\$26)
+                       mov 0,\$16
+                       jsr \$26,exit
+                       .end main
+EOF
+               LIBC=""
+               $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+                       esac
+
+                       objdump --private-headers $dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi
+               rm -f $dummy.s $dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >$dummy.c <<EOF
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+         rm -f $dummy.c $dummy
+       elif test "${UNAME_MACHINE}" = "s390"; then
+         echo s390-ibm-linux && exit 0
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+         rm -f $dummy.c $dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i?86:*:5:7*)
+        # Fixed at (any) Pentium or better
+        UNAME_MACHINE=i586
+        if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+           echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
+       else
+           echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i?86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       if test "${UNAME_MACHINE}" = "x86pc"; then
+               UNAME_MACHINE=pc
+       fi
+       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-W:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/sid/component/bochs/config.h.in b/sid/component/bochs/config.h.in
new file mode 100644 (file)
index 0000000..d1bc0a2
--- /dev/null
@@ -0,0 +1,534 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+//
+// config.h.in is distributed in the source TAR file.  When you run
+// the configure script, it generates config.h with some changes
+// according to your build environment.  For example, in config.h.in,
+// SIZEOF_UNSIGNED_CHAR is set to 0.  When configure produces config.h
+// it will change "0" to the detected value for your system.
+// 
+// config.h contains ONLY preprocessor #defines and a few typedefs.
+// It must be included by both C and C++ files, so it must not
+// contain anything language dependent such as a class declaration.
+//
+
+#ifdef _BX_CONFIG_H_
+#else
+#define _BX_CONFIG_H_ 1
+
+///////////////////////////////////////////////////////////////////
+// USER CONFIGURABLE OPTIONS : EDIT ONLY OPTIONS IN THIS SECTION //
+///////////////////////////////////////////////////////////////////
+
+// I have tested the following combinations:
+//  * processors=1, bootstrap=0, ioapic_id=1   (uniprocessor system)
+//  * processors=2, bootstrap=0, ioapic_id=2
+//  * processors=4, bootstrap=2, ioapic_id=4
+#define BX_SMP_PROCESSORS 1
+#define BX_BOOTSTRAP_PROCESSOR 0
+// choose IOAPIC id to be equal to the number of processors.  This leaves
+// one space for each processor to have an ID, starting with 0.
+#define BX_IOAPIC_DEFAULT_ID (BX_SMP_PROCESSORS)
+
+#define BX_ADDRESS_SPACES 1
+// controls how many instances of BX_MEM_C are created.  For
+// SMP, use several processors with one shared memory space.
+// For cosimulation, you could use two processors and two address
+// spaces.
+
+#define BX_SUPPORT_APIC 0
+// include in APIC models, required for a multiprocessor system.
+
+#if (BX_SMP_PROCESSORS>1 && !BX_SUPPORT_APIC)
+#error For multiprocessor simulation, BX_SUPPORT_APIC is required.
+#endif
+
+#define BX_DEBUG_LINUX 0
+// if simulating Linux, this provides a few more debugging options
+// such as tracing all system calls.
+
+#define HAVE_LIBREADLINE 0
+#define HAVE_READLINE_HISTORY_H 0
+// adds support for the GNU readline library in the debugger command 
+// prompt.
+
+// I rebuilt the code which provides timers to IO devices.
+// Setting this to 1 will introduce a little code which
+// will panic out if cases which shouldn't happen occur.
+// Set this to 0 for optimal performance.
+#define BX_TIMER_DEBUG 1
+
+// Settable A20 line.  For efficiency, you can disable
+// having a settable A20 line, eliminating conditional
+// code for every physical memory access.  You'll have
+// to tell your software not to mess with the A20 line,
+// and accept it as always being on if you change this.
+//   1 = use settable A20 line. (normal)
+//   0 = A20 is like the rest of the address lines
+
+#define BX_SUPPORT_A20 0 
+
+// Processor Instructions Per Second
+// To find out what value to use for the 'ips' directive
+// in your '.bochsrc' file, set BX_SHOW_IPS to 1, and
+// run the software in bochs you plan to use most.  Bochs
+// will print out periodic IPS ratings.  This will change
+// based on the processor mode at the time, and various
+// other factors.  You'll get a reasonable estimate though.
+// When you're done, reset BX_SHOW_IPS to 0, do a
+// 'make all-clean', then 'make' again.
+
+#define BX_SHOW_IPS         0
+
+
+#if (BX_SHOW_IPS) && defined(__MINGW32__)
+#define        SIGALRM         14
+#endif
+
+// Paging Options:
+// ---------------
+// Support Paging mechanism.
+//   0 = don't support paging at all (DOS & Minix don't require it)
+//   1 = support paging.  (Most other OS's require paging)
+// Use Translation Lookaside Buffer (TLB) for caching
+// paging translations.  This will make paging mode
+// more efficient.  If you're OS doesn't use paging,
+// then you won't need either.
+//   1 = Use a TLB for effiency
+//   0 = don't use a TLB, walk the page tables for every access
+// BX_TLB_SIZE: Number of entries in TLB
+// BX_TLB_INDEX_OF(lpf): This macro is passed the linear page frame
+//   (top 20 bits of the linear address.  It must map these bits to
+//   one of the TLB cache slots, given the size of BX_TLB_SIZE.
+//   There will be a many-to-one mapping to each TLB cache slot.
+//   When there are collisions, the old entry is overwritten with
+//   one for the newest access.
+
+#define BX_SUPPORT_PAGING    0 
+#define BX_USE_TLB 0 
+
+#define BX_TLB_SIZE 1024
+#define BX_TLB_INDEX_OF(lpf) (((lpf) & 0x003ff000) >> 12)
+
+
+// Compile in support for DMA & FLOPPY IO.  You'll need this
+// if you plan to use the floppy drive emulation.  But if
+// you're environment doesn't require it, you can change
+// it to 0.
+
+#define BX_DMA_FLOPPY_IO 0
+
+
+// Default number of Megs of memory to emulate.  The
+// 'megs:' directive in the '.bochsrc' file overrides this,
+// allowing per-run settings.
+
+#define BX_DEFAULT_MEM_MEGS 4
+
+
+//
+// x86 hardware tasking.  There is some tasking support now.
+// I'm trying to get Linux to boot.  The default for this
+// is now 1, but if you don't need x86 tasking (DOS, Win'95),
+// then set this to 0.
+//
+
+#define BX_SUPPORT_TASKING    0
+
+
+// CPU level emulation.  Default level is set in
+// the configure script.  BX_CPU_LEVEL defines the CPU level
+// to emulate.  BX_CPU_LEVEL_HACKED is a hack to define the
+// level of some integer instructions, so they can be tested
+// before the rest of the emulation is up to that level.
+
+#define BX_CPU_LEVEL 0
+#define BX_CPU_LEVEL_HACKED 0
+
+
+// Virtual 8086 mode emulation.
+//   1 = compile in support for v8086 mode.
+//   0 = don't compile in support for v8086 mode.
+
+#define BX_SUPPORT_V8086_MODE 1
+
+// Support shadowing of ROM from C0000 to FFFFF.
+// This allows that region to be written to.
+#define BX_SHADOW_RAM 0
+
+// Number of CMOS registers
+#define BX_NUM_CMOS_REGS 64
+//#define BX_NUM_CMOS_REGS 128
+
+// Use Static Member Funtions to eliminate 'this' pointer passing
+// If you want the efficiency of 'C', you can make all the
+// members of the C++ CPU class to be static.
+// This defaults to 1 since it should improve performance, but when
+// SMP mode is enabled, it will be turned off by configure.
+
+#define BX_USE_CPU_SMF 0
+
+// Use static member functions in IO DEVice emulation modules.
+// For efficiency, use C like functions for IO handling,
+// and declare a device instance at compile time,
+// instead of using 'new' and storing the pointer.  This
+// eliminates some overhead, especially for high-use IO
+// devices like the disk drive.
+//   1 = Use static member efficiency (normal)
+//   0 = Use nonstatic member functions (use only if you need
+//       multiple instances of a device class
+
+#define BX_USE_HD_SMF   1  // Hard drive
+#define BX_USE_CMOS_SMF 1  // CMOS
+#define BX_USE_DMA_SMF  1  // DMA
+#define BX_USE_FD_SMF   1  // Floppy
+#define BX_USE_KEY_SMF  1  // Keyboard
+#define BX_USE_PAR_SMF  1  // Parallel
+#define BX_USE_PIC_SMF  1  // PIC
+#define BX_USE_PIT_SMF  1  // PIT
+#define BX_USE_SER_SMF  1  // Serial
+#define BX_USE_UM_SMF   1  // Unmapped
+#define BX_USE_VGA_SMF  1  // VGA
+#define BX_USE_SB16_SMF 1  // Sound (SB 16)
+#define BX_USE_DEV_SMF  1  // System Devices (port92)
+#define BX_USE_PCI_SMF  1  // PCI
+#define BX_USE_NE2K_SMF 1  // NE2K
+
+#define BX_SUPPORT_SB16 0
+
+#if BX_SUPPORT_SB16
+// Use virtual methods for the sound output functions
+#define BX_USE_SOUND_VIRTUAL  1
+// Determines which sound output class is to be used.
+// Currently the following are available:
+//    bx_sound_linux_c      Output for Linux, to /dev/dsp and /dev/midi00
+//    bx_sound_windows_c    Output for Windows midi and wave mappers
+//    bx_sound_output_c     Dummy functions, no output
+#define BX_SOUND_OUTPUT_C  bx_sound_output_c
+#endif
+
+#define BX_USE_SPECIFIED_TIME0 0
+
+// This enables writing to port 0xe9 and the output
+// is sent to the console.  Reading from port 0xe9
+// will return 0xe9 to let you know this is available.
+// Leave this 0 unless you have a reason to use it.
+#define BX_PORT_E9_HACK 0
+
+// This option enables "split hard drive" support, which means
+// that a series of partial hard disk images can be treated
+// as a single large image.  If you set up the partition sizes and
+// file sizes correctly, this allows you to store each partition
+// in a separate file, which is very convenient if you want to operate
+// on a single partition (e.g. mount with loopback, create filesystem,
+// fsck, etc.).
+// [[Provide example of partitioning]]
+#define BX_SPLIT_HD_SUPPORT 0
+
+
+// =================================================================
+// BEGIN: OPTIONAL DEBUGGER SECTION
+//
+// These options are only used if you compile in support for the
+// native command line debugging environment.  Typically, the debugger
+// is not used, and this section can be ignored.
+// =================================================================
+
+#define BX_MAX_DIRTY_PAGE_TABLE_MEGS 64
+
+// Compile in support for virtual/linear/physical breakpoints.
+// Set to 1, only those you need.  Recommend using only linear
+// breakpoints, unless you need others.  Less supported means
+// slightly faster execution time.
+#define BX_DBG_SUPPORT_VIR_BPOINT 1
+#define BX_DBG_SUPPORT_LIN_BPOINT 1
+#define BX_DBG_SUPPORT_PHY_BPOINT 1
+
+// You need only define one initial breakpoint into each
+// cpu simulator (emulator) here.  Each simulator sets callbacks
+// and variables which the debugger uses from then on.
+#define BX_SIM1_INIT bx_dbg_init_cpu_mem_env0
+#ifndef BX_SIM2_INIT
+#define BX_SIM2_INIT bx_dbg_init_cpu_mem_env1
+#endif
+//#define BX_SIM2_INIT sim2_init
+
+// max number of virtual/linear/physical breakpoints handled
+#define BX_DBG_MAX_VIR_BPOINTS 10
+#define BX_DBG_MAX_LIN_BPOINTS 10
+#define BX_DBG_MAX_PHY_BPOINTS 10
+
+// max file pathname size for debugger commands
+#define BX_MAX_PATH     256
+// max nesting level for debug scripts including other scripts
+#define BX_INFILE_DEPTH  10
+// use this command to include (nest) debug scripts
+#define BX_INCLUDE_CMD   "source"
+
+// Use either 32 or 64 bit instruction counter for
+// debugger purposes.  Uncomment one of these.
+//#define BX_DBG_ICOUNT_SIZE   32
+#define BX_DBG_ICOUNT_SIZE   64
+
+// Make a call to command line debugger extensions.  If set to 1,
+// a call is made.  An external routine has a chance to process
+// the command.  If it does, than the debugger ignores the command.
+#define BX_DBG_EXTENSIONS 0
+
+// =================================================================
+// END: OPTIONAL DEBUGGER SECTION
+// =================================================================
+
+
+//////////////////////////////////////////////////////////////////////
+// END OF USER CONFIGURABLE OPTIONS : DON'T EDIT ANYTHING BELOW !!! //
+// THIS IS GENERATED BY THE ./configure SCRIPT                      //
+//////////////////////////////////////////////////////////////////////
+
+
+#define BX_WITH_X11 0
+#define BX_WITH_BEOS 0
+#define BX_WITH_WIN32 0
+#define BX_WITH_MACOS 0
+#define BX_WITH_NOGUI 0
+#define BX_WITH_TERM 0
+#define BX_WITH_RFB 0
+
+
+#define WORDS_BIGENDIAN 0
+
+#define SIZEOF_UNSIGNED_CHAR      0
+#define SIZEOF_UNSIGNED_SHORT     0
+#define SIZEOF_UNSIGNED_INT       0
+#define SIZEOF_UNSIGNED_LONG      0
+#define SIZEOF_UNSIGNED_LONG_LONG 0
+#define SIZEOF_INT_P              0
+
+#define BX_64BIT_CONSTANTS_USE_LL 1
+#if BX_64BIT_CONSTANTS_USE_LL
+// doesn't work on Microsoft Visual C++, maybe others
+#define BX_CONST64(x)  (x##LL)
+#else
+#define BX_CONST64(x)  (x)
+#endif
+
+#if BX_WITH_WIN32
+  typedef unsigned char      Bit8u;
+  typedef   signed char      Bit8s;
+  typedef unsigned short     Bit16u;
+  typedef   signed short     Bit16s;
+  typedef unsigned int       Bit32u;
+  typedef   signed int       Bit32s;
+#ifdef __MINGW32__
+  typedef unsigned long long Bit64u;
+  typedef   signed long long Bit64s;
+  typedef             Bit32s ssize_t;
+#else
+  typedef unsigned __int64   Bit64u;
+  typedef   signed __int64   Bit64s;
+#endif
+#elif BX_WITH_MACOS
+  typedef unsigned char      Bit8u;
+  typedef   signed char      Bit8s;
+  typedef unsigned short     Bit16u;
+  typedef   signed short     Bit16s;
+  typedef unsigned int       Bit32u;
+  typedef   signed int       Bit32s;
+  typedef unsigned long long Bit64u;
+  typedef   signed long long Bit64s;
+#else  // #if BX_WITH_WIN32
+
+// Unix like platforms
+
+#if SIZEOF_UNSIGNED_CHAR != 1
+#  error "sizeof (unsigned char) != 1"
+#else
+  typedef unsigned char Bit8u;
+  typedef   signed char Bit8s;
+#endif
+
+#if SIZEOF_UNSIGNED_SHORT != 2
+#  error "sizeof (unsigned short) != 2"
+#else
+  typedef unsigned short Bit16u;
+  typedef   signed short Bit16s;
+#endif
+
+#if SIZEOF_UNSIGNED_INT == 4
+  typedef unsigned int Bit32u;
+  typedef   signed int Bit32s;
+#elif SIZEOF_UNSIGNED_LONG == 4
+  typedef unsigned long Bit32u;
+  typedef   signed long Bit32s;
+#else
+#  error "can't find sizeof(type) of 4 bytes!"
+#endif
+
+#if SIZEOF_UNSIGNED_LONG == 8
+  typedef unsigned long Bit64u;
+  typedef   signed long Bit64s;
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+  typedef unsigned long long Bit64u;
+  typedef   signed long long Bit64s;
+#else
+#  error "can't find data type of 8 bytes"
+#endif
+
+#endif // BX_WITH_WIN32
+
+// create an unsigned integer type that is the same size as a pointer.
+// You can typecast a pointer to a bx_pr_equiv_t without losing any 
+// bits (and without getting the compiler excited).  This is used in
+// the FPU emulation code, where pointers and integers are often 
+// used interchangeably.
+#if SIZEOF_INT_P == 4
+  typedef Bit32u bx_ptr_equiv_t;
+#elif SIZEOF_INT_P == 8
+  typedef Bit64u bx_ptr_equiv_t;
+#else
+#  error "could not define bx_ptr_equiv_t to size of int*"
+#endif
+
+#if BX_WITH_MACOS == 0
+typedef unsigned int Boolean;
+#endif
+
+#if BX_WITH_MACOS
+#  define bx_ptr_t char *
+#else
+#  define bx_ptr_t void *
+#endif
+
+#if BX_WITH_WIN32
+#  define BX_LITTLE_ENDIAN
+#elif BX_WITH_MACOS
+#  define BX_BIG_ENDIAN
+#else
+#if WORDS_BIGENDIAN
+#  define BX_BIG_ENDIAN
+#else
+#  define BX_LITTLE_ENDIAN
+#endif
+#endif // BX_WITH_WIN32
+
+// for now only term.cc requires a GUI sighandler.
+#define BX_GUI_SIGHANDLER (BX_WITH_TERM)
+
+#define HAVE_SIGACTION 1
+
+// configure will change the definition of "inline" to the value
+// that the C compiler allows.  It tests the following keywords to
+// see if any is permitted: inline, __inline__, __inline.  If none
+// is permitted, it defines inline to be empty.
+#define inline inline
+
+// inline functions in headers that are compiled with C compiler
+// (e.g. fpu code) are declared with BX_C_INLINE macro.  Note that
+// the word "inline" itself may now be redefined by the above #define.
+// Many compilers are known to work with "static inline".  If the 
+// compiler can put the function inline, it does so and never creates
+// a symbol for the function.  If optimization is off, or inline is
+// defined to be empty, the static keyword causes the function to create
+// a symbol that's visible only to that .c file.  Each .c file that 
+// includes the header will produde another local version of the 
+// BX_C_INLINE function (not ideal).  However without "static" you can
+// duplicate symbol problems which are even worse.
+#define BX_C_INLINE static inline
+
+// Use BX_CPP_INLINE for all C++ inline functions.  Note that the
+// word "inline" itself may now be redefined by the above #define.
+#define BX_CPP_INLINE inline
+
+#define BX_DEBUGGER 0
+#define BX_DISASM   0
+
+#define BX_PROVIDE_CPU_MEMORY    1
+#define BX_PROVIDE_DEVICE_MODELS 0
+#define BX_PROVIDE_BIOS_HOOKS    0
+
+#define BX_EMULATE_HGA_DUMPS 0
+
+#define BX_SUPPORT_VGA        0
+
+#define BX_PROVIDE_MAIN       0
+
+#define BX_INSTRUMENTATION    0
+
+#define BX_USE_LOADER    0
+
+// for debugger, CPU simulator handle ID
+//   0 is the default, for using only one CPU simulator
+//   1 is for the 2nd CPU simulator
+#define BX_SIM_ID    0
+#define BX_NUM_SIMULATORS 1
+
+// limited i440FX PCI support
+#define BX_PCI_SUPPORT 0
+
+// dynamic translation (future: not supported yet)
+#define BX_DYNAMIC_TRANSLATION 0
+#define BX_DYNAMIC_CPU_I386    0
+#define BX_DYNAMIC_CPU_SPARC   0
+
+#define BX_SUPPORT_FPU 0
+
+#define BX_HAVE_SELECT 0
+#define BX_HAVE_SNPRINTF 0
+#define BX_HAVE_STRTOULL 0
+#define BX_HAVE_STRTOUQ 0
+#define BX_HAVE_STRDUP 0
+
+// set if your compiler does not permit an empty struct
+#define BX_NO_EMPTY_STRUCTS 0
+
+// set if your compiler does not understand __attribute__ after a struct
+#define BX_NO_ATTRIBUTES 0
+#if BX_NO_ATTRIBUTES
+#define GCC_ATTRIBUTE(x) /* attribute not supported */
+#else
+#define GCC_ATTRIBUTE __attribute__
+#endif
+
+// set if your compiler does not allow label at the end of a {} block
+#define BX_NO_BLANK_LABELS 0
+
+// set if you don't have <hash_map.h>, used in debug/dbg_main.c
+#define BX_HAVE_HASH_MAP 0
+
+// Support x86 hardware debugger registers and facilites.
+// These are the debug facilites offered by the x86 architecture,
+// not the optional built-in debugger.
+#define BX_X86_DEBUGGER 0
+
+#define BX_SUPPORT_CDROM 0
+
+#if BX_SUPPORT_CDROM
+   // This is the C++ class name to use if we are supporting
+   // low-level CDROM.
+#  define LOWLEVEL_CDROM cdrom_interface
+#endif
+
+// NE2K network emulation
+#define BX_NE2K_SUPPORT 0
+
+#endif  // _BX_CONFIG_H
diff --git a/sid/component/bochs/config.sub b/sid/component/bochs/config.sub
new file mode 100644 (file)
index 0000000..c8e7785
--- /dev/null
@@ -0,0 +1,1268 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+#   Free Software Foundation, Inc.
+#
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+               | 580 | i960 | h8300 \
+               | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
+               | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+               | hppa64 \
+               | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+               | alphaev6[78] \
+               | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+               | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+               | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+               | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+               | mips64vr5000 | miprs64vr5000el | mcore \
+               | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+               | thumb | d10v | fr30 | avr)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[34567]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       # FIXME: clean up the formatting here.
+       vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+             | xmp-* | ymp-* \
+             | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
+             | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+             | hppa2.0n-* | hppa64-* \
+             | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+             | alphaev6[78]-* \
+             | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+             | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-* \
+             | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+             | mipstx39-* | mipstx39el-* | mcore-* \
+             | f301-* | armv*-* | s390-* | sv1-* | t3e-* \
+             | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+             | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
+             | bs2000-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[34567]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[34567]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[34567]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[34567]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       i386-go32 | go32)
+               basic_machine=i386-unknown
+               os=-go32
+               ;;
+       i386-mingw32 | mingw32)
+               basic_machine=i386-unknown
+               os=-mingw32
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-unknown
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc | sparcv9)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i[34567]86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -*MiNT)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -*MiNT)
+                               vendor=atari
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
diff --git a/sid/component/bochs/configure b/sid/component/bochs/configure
new file mode 100755 (executable)
index 0000000..bb7309d
--- /dev/null
@@ -0,0 +1,6160 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static[=PKGS]  build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-fast-install[=PKGS]  optimize for fast installation [default=yes]"
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --disable-libtool-lock  avoid locking (might break parallel builds)"
+ac_help="$ac_help
+  --with-pic              try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+  --with-x                use the X Window System"
+ac_help="$ac_help
+  --enable-processors                select number of processors (1,2,4)"
+ac_help="$ac_help
+  --enable-cpu-level                select cpu level (3,4,5,6)"
+ac_help="$ac_help
+  --enable-dynamic                  enable dynamic translation support"
+ac_help="$ac_help
+  --enable-apic                   enable APIC support"
+ac_help="$ac_help
+  --enable-split-hd                   allows split hard disk image"
+ac_help="$ac_help
+  --enable-ne2000                   enable limited ne2000 support"
+ac_help="$ac_help
+  --enable-pci                      enable limited i440FX PCI support"
+ac_help="$ac_help
+  --enable-port-e9-hack             writes to port e9 go to console"
+ac_help="$ac_help
+  --enable-cpp                      use .cpp as C++ suffix"
+ac_help="$ac_help
+  --enable-debugger                 compile in support for Bochs internal debugger"
+ac_help="$ac_help
+  --enable-disasm                   compile in support for disassembler"
+ac_help="$ac_help
+ --enable-readline                     use readline library with debugger"
+ac_help="$ac_help
+  --enable-loader                   support calling external loader from debugger"
+ac_help="$ac_help
+  --enable-instrumentation          compile in support for instrumentation"
+ac_help="$ac_help
+  --enable-simid=0 or 1             CPU simulator ID if using more than one"
+ac_help="$ac_help
+  --enable-num-sim=1 or 2           number of CPU simulators"
+ac_help="$ac_help
+  --enable-time0=n                  start at n instead of using time()"
+ac_help="$ac_help
+  --enable-vga                      use VGA emulation"
+ac_help="$ac_help
+  --enable-fpu                      compile in FPU emulation"
+ac_help="$ac_help
+  --enable-x86-debugger             x86 debugger support"
+ac_help="$ac_help
+  --enable-cdrom                    CDROM support"
+ac_help="$ac_help
+  --enable-sb16                     Sound Blaster 16 Support"
+ac_help="$ac_help
+  --enable-hga-dumps=Nmicroseconds  copy memory to HGA video buffer every N useconds"
+ac_help="$ac_help
+  --with-x11                        use X11 GUI"
+ac_help="$ac_help
+  --with-beos                       use BeOS GUI"
+ac_help="$ac_help
+  --with-win32                      use Win32 GUI"
+ac_help="$ac_help
+  --with-win32-vcpp                 use Win32 GUI/Visual C++ environment"
+ac_help="$ac_help
+  --with-macos                      use Macintosh/CodeWarrior environment"
+ac_help="$ac_help
+  --with-nogui                      no native GUI, just use blank stubs"
+ac_help="$ac_help
+  --with-term                       textmode terminal environment"
+ac_help="$ac_help
+  --with-rfb                        use RFB protocol, works with VNC viewer"
+ac_help="$ac_help
+  --enable-targets=LIST   support given additional targets, or all"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --site-file=FILE        use FILE as the site file
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -site-file | --site-file | --site-fil | --site-fi | --site-f)
+    ac_prev=sitefile ;;
+  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+    sitefile="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=components.cxx
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+  if test -z "$CONFIG_SITE"; then
+    if test "x$prefix" != xNONE; then
+      CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+    else
+      CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+    fi
+  fi
+else
+  CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in ../../config $srcdir/../../config; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in ../../config $srcdir/../../config" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:652: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:705: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "$*" != "X $srcdir/configure conftestfile" \
+      && test "$*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+   fi
+
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:762: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=sidcomp
+
+VERSION=0.1
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:808: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:821: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:834: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:847: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:860: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:874: checking whether to enable maintainer-specific portions of Makefiles" >&5
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+  
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+  MAINT=$MAINTAINER_MODE_TRUE
+  
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:897: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 902 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:930: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 935 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_mingw32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:961: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1067: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1088: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1108: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1138: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1189: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1221: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1232 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1263: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1268: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1296: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1339: checking for ld used by GCC" >&5
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1369: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1372: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1408: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1424: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1461: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1491: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="${ac_tool_prefix}ar"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1523: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1555: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  RANLIB=":"
+fi
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+  :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 1622 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1623: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1644: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1649 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1764: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1794: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1845: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1877: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1888 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1919: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1924: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1952: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1988: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2020: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2031 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:2036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2062: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:2067: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:2095: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:2127: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2156: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2185: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 2200 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 2217 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2223: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 2234 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:2269: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+  :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+  cd conftestdir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat > Imakefile <<'EOF'
+acfindx:
+       @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+        test -f $ac_im_libdir/libX11.$ac_extension; then
+        ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case "$ac_im_incroot" in
+       /usr/include) ;;
+       *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+    esac
+    case "$ac_im_usrlibdir" in
+       /usr/lib | /lib) ;;
+       *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+  # Guess where to find include files, by looking for this one X11 .h file.
+  test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+  # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 2331 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2336: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+  for ac_dir in               \
+    /usr/X11/include          \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11          \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11/include    \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11    \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    ; \
+  do
+    if test -r "$ac_dir/$x_direct_test_include"; then
+      ac_x_includes=$ac_dir
+      break
+    fi
+  done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+  # Check for the libraries.
+
+  test -z "$x_direct_test_library" && x_direct_test_library=Xt
+  test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2405 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:2412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+    /usr/X11/lib          \
+    /usr/X11R6/lib        \
+    /usr/X11R5/lib        \
+    /usr/X11R4/lib        \
+                          \
+    /usr/lib/X11          \
+    /usr/lib/X11R6        \
+    /usr/lib/X11R5        \
+    /usr/lib/X11R4        \
+                          \
+    /usr/local/X11/lib    \
+    /usr/local/X11R6/lib  \
+    /usr/local/X11R5/lib  \
+    /usr/local/X11R4/lib  \
+                          \
+    /usr/local/lib/X11    \
+    /usr/local/lib/X11R6  \
+    /usr/local/lib/X11R5  \
+    /usr/local/lib/X11R4  \
+                          \
+    /usr/X386/lib         \
+    /usr/x386/lib         \
+    /usr/XFree86/lib/X11  \
+                          \
+    /usr/lib              \
+    /usr/local/lib        \
+    /usr/unsupported/lib  \
+    /usr/athena/lib       \
+    /usr/local/x11r5/lib  \
+    /usr/lpp/Xamples/lib  \
+    /lib/usr/lib/X11     \
+                          \
+    /usr/openwin/lib      \
+    /usr/openwin/share/lib \
+    ; \
+do
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+               ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$ac_t""$have_x" 1>&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+               ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+  cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case "`(uname -sr) 2>/dev/null`" in
+    "SunOS 5"*)
+      echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:2518: checking whether -R must be followed by a space" >&5
+      ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+      cat > conftest.$ac_ext <<EOF
+#line 2521 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_nospace=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_nospace=no
+fi
+rm -f conftest*
+      if test $ac_R_nospace = yes; then
+       echo "$ac_t""no" 1>&6
+       X_LIBS="$X_LIBS -R$x_libraries"
+      else
+       LIBS="$ac_xsave_LIBS -R $x_libraries"
+       cat > conftest.$ac_ext <<EOF
+#line 2544 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_space=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_space=no
+fi
+rm -f conftest*
+       if test $ac_R_space = yes; then
+         echo "$ac_t""yes" 1>&6
+         X_LIBS="$X_LIBS -R $x_libraries"
+       else
+         echo "$ac_t""neither works" 1>&6
+       fi
+      fi
+      LIBS="$ac_xsave_LIBS"
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And karl@cs.umb.edu says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:2583: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2591 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:2624: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2632 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:2643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to dickey@clark.net.
+    echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:2672: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2677 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:2721: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2729 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:2740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says simon@lia.di.epfl.ch: it contains
+    # gethostby* variants that don't use the nameserver (or something).
+    # -lsocket must be given before -lnsl if both are needed.
+    # We assume that if connect needs -lnsl, so does gethostbyname.
+    echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:2770: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2775 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_connect=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_connect = no; then
+      echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:2819: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2827 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:2838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+    echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:2862: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2867 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_remove=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_remove = no; then
+      echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:2911: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lposix  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2919 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:2930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:2954: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2959 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_shmat = no; then
+      echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:3003: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lipc  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3011 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:3022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS="$LDFLAGS"
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+  echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:3055: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3063 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:3074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3100: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 3107 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 3122 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3133: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3153 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:3166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3190: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 3197 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking size of unsigned char""... $ac_c" 1>&6
+echo "configure:3230: checking size of unsigned char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_unsigned_char=1
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3238 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned char));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_char=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char
+EOF
+
+
+echo $ac_n "checking size of unsigned short""... $ac_c" 1>&6
+echo "configure:3269: checking size of unsigned short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_unsigned_short=2
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3277 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+EOF
+
+
+echo $ac_n "checking size of unsigned int""... $ac_c" 1>&6
+echo "configure:3308: checking size of unsigned int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_unsigned_int=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3316 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+EOF
+
+
+echo $ac_n "checking size of unsigned long""... $ac_c" 1>&6
+echo "configure:3347: checking size of unsigned long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_unsigned_long=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3355 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+EOF
+
+
+echo $ac_n "checking size of unsigned long long""... $ac_c" 1>&6
+echo "configure:3386: checking size of unsigned long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_unsigned_long_long=8
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3394 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned long long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_long_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+EOF
+
+
+echo $ac_n "checking size of int *""... $ac_c" 1>&6
+echo "configure:3425: checking size of int *" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int_p'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_int_p=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3433 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int *));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int_p=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int_p=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int_p" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT_P $ac_cv_sizeof_int_p
+EOF
+
+
+for ac_func in select
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3466: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3471 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_SELECT 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in snprintf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3524: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3529 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_SNPRINTF 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strtoull
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3582: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3587 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRTOULL 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strtouq
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3640: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3645 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRTOUQ 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strdup
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3698: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3703 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRDUP 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking if compiler allows empty structs""... $ac_c" 1>&6
+echo "configure:3755: checking if compiler allows empty structs" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3757 "configure"
+#include "confdefs.h"
+
+int main() {
+typedef struct { } junk;
+; return 0; }
+EOF
+if { (eval echo configure:3764: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+      cat >> confdefs.h <<\EOF
+#define BX_NO_EMPTY_STRUCTS 1
+EOF
+
+      echo "$ac_t""no" 1>&6
+    
+fi
+rm -f conftest*
+
+echo $ac_n "checking if compiler allows __attribute__""... $ac_c" 1>&6
+echo "configure:3782: checking if compiler allows __attribute__" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3784 "configure"
+#include "confdefs.h"
+
+int main() {
+typedef struct { } __attribute__ ((packed)) junk;
+; return 0; }
+EOF
+if { (eval echo configure:3791: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+      echo "$ac_t""no" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_NO_ATTRIBUTES 1
+EOF
+
+    
+fi
+rm -f conftest*
+
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking for hash_map.h""... $ac_c" 1>&6
+echo "configure:3817: checking for hash_map.h" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3819 "configure"
+#include "confdefs.h"
+#include <hash_map.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3826: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  
+     echo "$ac_t""yes" 1>&6
+     cat >> confdefs.h <<\EOF
+#define BX_HAVE_HASH_MAP 1
+EOF
+
+   
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+
+echo $ac_n "checking for number of processors""... $ac_c" 1>&6
+echo "configure:3851: checking for number of processors" >&5
+# Check whether --enable-processors or --disable-processors was given.
+if test "${enable_processors+set}" = set; then
+  enableval="$enable_processors"
+  case "$enableval" in
+     1)
+       echo "$ac_t""1" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 1
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 1
+EOF
+
+       ;;
+     2)
+       echo "$ac_t""2" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 2
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 2
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+       ;;
+     4)
+       echo "$ac_t""4" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 4
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 2
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 4
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+       ;;
+     *)
+       echo " "
+       echo "WARNING: processors != 1,2,4 can work, but you need to modify rombios.c manually"
+       echo "$ac_t""$enable_val" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS $enable_val
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID $enable_val
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+       ;;
+   esac
+   bx_procs="$enableval"
+  
+else
+  
+     echo "$ac_t""1" 1>&6
+     cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 1
+EOF
+
+     cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+     cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 1
+EOF
+
+     bx_procs=1
+  
+  
+fi
+
+
+echo $ac_n "checking if compiler allows blank labels""... $ac_c" 1>&6
+echo "configure:3955: checking if compiler allows blank labels" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3957 "configure"
+#include "confdefs.h"
+
+int main() {
+ { label1: } 
+; return 0; }
+EOF
+if { (eval echo configure:3964: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+      echo "$ac_t""no" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_NO_BLANK_LABELS 1
+EOF
+
+    
+fi
+rm -f conftest*
+
+echo $ac_n "checking if compiler allows LL for 64-bit constants""... $ac_c" 1>&6
+echo "configure:3982: checking if compiler allows LL for 64-bit constants" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3984 "configure"
+#include "confdefs.h"
+
+int main() {
+ { 42LL; } 
+; return 0; }
+EOF
+if { (eval echo configure:3991: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+      echo "$ac_t""no" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_64BIT_CONSTANTS_USE_LL 0
+EOF
+
+    
+fi
+rm -f conftest*
+
+echo $ac_n "checking for cpu level""... $ac_c" 1>&6
+echo "configure:4009: checking for cpu level" >&5
+# Check whether --enable-cpu-level or --disable-cpu-level was given.
+if test "${enable_cpu_level+set}" = set; then
+  enableval="$enable_cpu_level"
+  case "$enableval" in
+     3)
+       echo "$ac_t""3" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 3
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 3
+EOF
+
+       ;;
+     4)
+       echo "$ac_t""4" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 4
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 4
+EOF
+
+       ;;
+     5)
+       echo "$ac_t""5" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 5
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 5
+EOF
+
+       ;;
+     6)
+       echo "$ac_t""6" 1>&6
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 6
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 6
+EOF
+
+       ;;
+     *)
+       echo " "
+       echo "ERROR: you must supply a valid CPU level to --enable-cpu-level"
+       exit 1
+       ;;
+   esac
+   bx_cpu_level=$enableval
+   if test "$bx_procs" -gt 1 -a "$enableval" -lt 6; then
+     echo "ERROR: with >1 processor, use --enable-cpu-level=6"
+     exit 1
+   fi
+  
+else
+  
+    # for multiprocessors, cpu level must be 6
+    if test "$bx_procs" -gt 1; then
+      echo "$ac_t""6" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 6
+EOF
+
+      cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 6
+EOF
+
+      bx_cpu_level=6
+    else
+      echo "$ac_t""5" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 5
+EOF
+
+      cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 5
+EOF
+
+      bx_cpu_level=5
+    fi
+  
+  
+fi
+
+
+
+echo $ac_n "checking for dynamic translation support""... $ac_c" 1>&6
+echo "configure:4103: checking for dynamic translation support" >&5
+# Check whether --enable-dynamic or --disable-dynamic was given.
+if test "${enable_dynamic+set}" = set; then
+  enableval="$enable_dynamic"
+  if test "$enableval" = no; then
+     echo "$ac_t""no" 1>&6
+     cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 0
+EOF
+
+     DYNAMIC_VAR=''
+     AS_DYNAMIC_OBJS=''
+     AS_DYNAMIC_INCS=''
+   else
+     if test "$enableval" = yes; then
+       echo " "
+       echo \!\!\!Error\!\!\!
+       echo "You must specify a CPU type to dynamic-translation option"
+       echo \!\!\!Error\!\!\!
+       exit 1
+     fi
+     case "$enableval" in
+       i386)
+         cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_CPU_I386 1
+EOF
+
+         AS_DYNAMIC_OBJS='$(X86_OBJS)'
+         AS_DYNAMIC_INCS='$(X86_H)'
+         ;;
+       sparc)
+         cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_CPU_SPARC 1
+EOF
+
+         AS_DYNAMIC_OBJS='$(SPARC_OBJS).o'
+         AS_DYNAMIC_INCS='$(SPARC_H)'
+         ;;
+       *)
+         echo " "
+         echo \!\!\!Error\!\!\!
+         echo "Sorry, dynamic translation is not yet available on your platform"
+         echo \!\!\!Error\!\!\!
+         AS_DYNAMIC_OBJS=''
+         AS_DYNAMIC_INCS=''
+         exit 1 ;;
+     esac
+     echo "$ac_t""yes" 1>&6
+     cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 1
+EOF
+
+     DYNAMIC_VAR='$(DYNAMIC_LIB)'
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 0
+EOF
+
+    DYNAMIC_VAR=''
+    AS_DYNAMIC_OBJS=''
+    AS_DYNAMIC_INCS=''
+    
+  
+fi
+
+
+
+
+
+echo $ac_n "checking for APIC support""... $ac_c" 1>&6
+echo "configure:4176: checking for APIC support" >&5
+# Check whether --enable-apic or --disable-apic was given.
+if test "${enable_apic+set}" = set; then
+  enableval="$enable_apic"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 1
+EOF
+
+    IOAPIC_OBJS='ioapic.o'
+    APIC_OBJS='apic.o'
+   else
+    echo "$ac_t""no" 1>&6
+    if test "$bx_procs" -gt 1; then
+      echo "Number of processors = $bx_procs"
+      echo "ERROR: With processors > 1 you must use --enable-apic"
+      exit 1
+    fi
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 0
+EOF
+
+    IOAPIC_OBJS=''
+    APIC_OBJS=''
+   fi
+   
+else
+  
+    if test "$bx_procs" -gt 1 -o "$bx_cpu_level" -gt 5; then
+      # enable APIC by default, if processors>1 or if cpulevel>5
+      echo "$ac_t""yes" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 1
+EOF
+
+      IOAPIC_OBJS='ioapic.o'
+      APIC_OBJS='apic.o'
+    else
+      echo "$ac_t""no" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 0
+EOF
+
+      IOAPIC_OBJS=''
+      APIC_OBJS=''
+     fi
+   
+  
+fi
+
+
+
+
+echo $ac_n "checking for split hard disk image support""... $ac_c" 1>&6
+echo "configure:4231: checking for split hard disk image support" >&5
+# Check whether --enable-split-hd or --disable-split-hd was given.
+if test "${enable_split_hd+set}" = set; then
+  enableval="$enable_split_hd"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 1
+EOF
+
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 0
+EOF
+
+   fi
+else
+  
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 1
+EOF
+
+    
+  
+fi
+
+
+
+echo $ac_n "checking for NE2000 support""... $ac_c" 1>&6
+echo "configure:4262: checking for NE2000 support" >&5
+# Check whether --enable-ne2000 or --disable-ne2000 was given.
+if test "${enable_ne2000+set}" = set; then
+  enableval="$enable_ne2000"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 1
+EOF
+
+    NE2K_OBJS='ne2k.o eth.o eth_null.o'
+    ac_safe=`echo "net/bpf.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for net/bpf.h""... $ac_c" 1>&6
+echo "configure:4275: checking for net/bpf.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4280 "configure"
+#include "confdefs.h"
+#include <net/bpf.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  NE2K_OBJS="$NE2K_OBJS eth_fbsd.o"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 0
+EOF
+
+    NE2K_OBJS=''
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 0
+EOF
+
+    NE2K_OBJS=''
+    
+  
+fi
+
+
+
+
+echo $ac_n "checking for i440FX PCI support""... $ac_c" 1>&6
+echo "configure:4330: checking for i440FX PCI support" >&5
+# Check whether --enable-pci or --disable-pci was given.
+if test "${enable_pci+set}" = set; then
+  enableval="$enable_pci"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 1
+EOF
+
+    PCI_OBJ='pci.o'
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 0
+EOF
+
+    PCI_OBJ=''
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 0
+EOF
+
+    PCI_OBJ=''
+    
+  
+fi
+
+
+
+
+echo $ac_n "checking for port e9 hack""... $ac_c" 1>&6
+echo "configure:4365: checking for port e9 hack" >&5
+# Check whether --enable-port-e9-hack or --disable-port-e9-hack was given.
+if test "${enable_port_e9_hack+set}" = set; then
+  enableval="$enable_port_e9_hack"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 1
+EOF
+
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 0
+EOF
+
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 0
+EOF
+
+    
+  
+fi
+
+
+
+echo $ac_n "checking for use of .cpp as suffix""... $ac_c" 1>&6
+echo "configure:4396: checking for use of .cpp as suffix" >&5
+# Check whether --enable-cpp or --disable-cpp was given.
+if test "${enable_cpp+set}" = set; then
+  enableval="$enable_cpp"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    SUFFIX_LINE='.SUFFIXES: .cpp'
+    CPP_SUFFIX='cpp'
+   else
+    echo "$ac_t""no" 1>&6
+    SUFFIX_LINE='.SUFFIXES: .cc'
+    CPP_SUFFIX='cc'
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    SUFFIX_LINE='.SUFFIXES: .cc'
+    CPP_SUFFIX='cc'
+    
+  
+fi
+
+
+
+
+if test "$enable_cpp" = yes; then
+  echo "moving .cc source files to .cpp"
+  sourcefiles=`find . -name "*.cc" -print`
+  if test "$sourcefiles" != ""; then
+    for ccname in $sourcefiles
+    do
+      cppname=`echo $ccname | sed -e "s/\.cc$/.cpp/"`
+      echo "mv $ccname $cppname"
+      mv   $ccname $cppname
+    done
+  else
+    echo "no more .cc source files to rename"
+  fi
+fi
+
+
+echo $ac_n "checking for Bochs internal debugger support""... $ac_c" 1>&6
+echo "configure:4438: checking for Bochs internal debugger support" >&5
+# Check whether --enable-debugger or --disable-debugger was given.
+if test "${enable_debugger+set}" = set; then
+  enableval="$enable_debugger"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 1
+EOF
+
+    DEBUGGER_VAR='$(DEBUGGER_LIB)'
+    bx_debugger=1
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 0
+EOF
+
+    DEBUGGER_VAR=''
+    bx_debugger=0
+   fi
+   
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 0
+EOF
+
+    DEBUGGER_VAR=''
+    bx_debugger=0
+    
+  
+fi
+
+
+
+echo $ac_n "checking for disassembler support""... $ac_c" 1>&6
+echo "configure:4476: checking for disassembler support" >&5
+# Check whether --enable-disasm or --disable-disasm was given.
+if test "${enable_disasm+set}" = set; then
+  enableval="$enable_disasm"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_DISASM 1
+EOF
+
+    DISASM_VAR='$(DISASM_LIB)'
+   else
+    echo "$ac_t""no" 1>&6
+    if test "$bx_debugger" = 1; then
+      echo "ERROR: debugger is enabled, so --enable-disasm is required"
+      exit 1
+    fi
+    cat >> confdefs.h <<\EOF
+#define BX_DISASM 0
+EOF
+
+    DISASM_VAR=''
+   fi
+else
+  
+    if test "$bx_debugger" = 1; then
+      echo "$ac_t""yes" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_DISASM 1
+EOF
+
+      DISASM_VAR='$(DISASM_LIB)'
+    else
+      echo "$ac_t""no" 1>&6
+      cat >> confdefs.h <<\EOF
+#define BX_DISASM 0
+EOF
+
+      DISASM_VAR=''
+    fi
+    
+  
+fi
+
+
+
+echo $ac_n "checking whether to use readline""... $ac_c" 1>&6
+echo "configure:4523: checking whether to use readline" >&5
+# Check whether --enable-readline or --disable-readline was given.
+if test "${enable_readline+set}" = set; then
+  enableval="$enable_readline"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+     want_readline=yes
+   else
+     echo "$ac_t""no" 1>&6
+     want_readline=no
+   fi
+else
+   # default is yes
+    echo "$ac_t""yes" 1>&6
+    want_readline=yes 
+fi
+
+
+
+if test "$want_readline" = yes; then
+  echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
+echo "configure:4545: checking for readline in -lreadline" >&5
+ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lreadline  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4553 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char readline();
+
+int main() {
+readline()
+; return 0; }
+EOF
+if { (eval echo configure:4564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  
+      if test "$bx_debugger" = 1; then
+       # only add readline library if debugger is on
+       cat >> confdefs.h <<\EOF
+#define HAVE_LIBREADLINE 1
+EOF
+
+       READLINE_LIB='-lreadline'
+      fi
+    
+  
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+  
+
+ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for readline/history.h""... $ac_c" 1>&6
+echo "configure:4599: checking for readline/history.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4604 "configure"
+#include "confdefs.h"
+#include <readline/history.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4609: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_READLINE_HISTORY_H 1
+EOF
+
+  
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for loader support""... $ac_c" 1>&6
+echo "configure:4637: checking for loader support" >&5
+# Check whether --enable-loader or --disable-loader was given.
+if test "${enable_loader+set}" = set; then
+  enableval="$enable_loader"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 1
+EOF
+
+    BX_LOADER_OBJS='bx_loader.o loader.o'
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 0
+EOF
+
+    BX_LOADER_OBJS=''
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 0
+EOF
+
+    BX_LOADER_OBJS=''
+    
+  
+fi
+
+
+
+
+
+INSTRUMENT_DIR='instrument/stubs'
+
+echo $ac_n "checking for instrumentation support""... $ac_c" 1>&6
+echo "configure:4675: checking for instrumentation support" >&5
+# Check whether --enable-instrumentation or --disable-instrumentation was given.
+if test "${enable_instrumentation+set}" = set; then
+  enableval="$enable_instrumentation"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 1
+EOF
+
+    INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+   elif test "$enableval" = no; then
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 0
+EOF
+
+    INSTRUMENT_VAR=''
+   else
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 1
+EOF
+
+    INSTRUMENT_DIR=$enableval
+    INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 0
+EOF
+
+    INSTRUMENT_VAR=''
+    
+  
+fi
+
+
+
+
+# Check whether --enable-simid or --disable-simid was given.
+if test "${enable_simid+set}" = set; then
+  enableval="$enable_simid"
+  if test "$enableval" = yes; then
+    cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+   elif test "$enableval" = no; then
+    cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+   else
+    cat >> confdefs.h <<EOF
+#define BX_SIM_ID $enableval
+EOF
+
+   fi
+else
+  
+    cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+    
+  
+fi
+
+
+# Check whether --enable-num-sim or --disable-num-sim was given.
+if test "${enable_num_sim+set}" = set; then
+  enableval="$enable_num_sim"
+  if test "$enableval" = yes; then
+    cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+   elif test "$enableval" = no; then
+    cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+   else
+    cat >> confdefs.h <<EOF
+#define BX_NUM_SIMULATORS $enableval
+EOF
+
+   fi
+else
+  
+    cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+    
+  
+fi
+
+
+# Check whether --enable-time0 or --disable-time0 was given.
+if test "${enable_time0+set}" = set; then
+  enableval="$enable_time0"
+  if test "$enableval" = yes; then
+    cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 917385580
+EOF
+
+   elif test "$enableval" = no; then
+    cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 0
+EOF
+
+   else
+    cat >> confdefs.h <<EOF
+#define BX_USE_SPECIFIED_TIME0 $enableval
+EOF
+
+   fi
+else
+  
+    cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 0
+EOF
+
+    
+  
+fi
+
+
+
+
+echo $ac_n "checking for VGA emulation""... $ac_c" 1>&6
+echo "configure:4810: checking for VGA emulation" >&5
+# Check whether --enable-vga or --disable-vga was given.
+if test "${enable_vga+set}" = set; then
+  enableval="$enable_vga"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 1
+EOF
+
+    VIDEO_OBJS='$(VIDEO_OBJS_VGA)'
+   else
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 0
+EOF
+
+    VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 0
+EOF
+
+    VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+    
+  
+fi
+
+
+
+echo $ac_n "checking for FPU emulation""... $ac_c" 1>&6
+echo "configure:4844: checking for FPU emulation" >&5
+FPU_VAR=''
+FPU_GLUE_OBJ=''
+# Check whether --enable-fpu or --disable-fpu was given.
+if test "${enable_fpu+set}" = set; then
+  enableval="$enable_fpu"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 1
+EOF
+
+    FPU_VAR='$(FPU_LIB)'
+    FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+   elif test "$enableval" = no; then
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 0
+EOF
+
+   else
+    echo " "
+    echo "ERROR: --enable-fpu does not accept a path"
+    exit 1
+   fi
+   
+else
+  
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 1
+EOF
+
+    FPU_VAR='$(FPU_LIB)'
+    FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+    
+  
+fi
+
+
+
+
+
+
+echo $ac_n "checking for x86 debugger support""... $ac_c" 1>&6
+echo "configure:4889: checking for x86 debugger support" >&5
+# Check whether --enable-x86-debugger or --disable-x86-debugger was given.
+if test "${enable_x86_debugger+set}" = set; then
+  enableval="$enable_x86_debugger"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 1
+EOF
+
+   elif test "$enableval" = no; then
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 0
+EOF
+
+   else
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 1
+EOF
+
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 0
+EOF
+
+    
+  
+fi
+
+
+echo $ac_n "checking for CDROM support""... $ac_c" 1>&6
+echo "configure:4925: checking for CDROM support" >&5
+# Check whether --enable-cdrom or --disable-cdrom was given.
+if test "${enable_cdrom+set}" = set; then
+  enableval="$enable_cdrom"
+  if test "$enableval" = yes; then
+    echo "$ac_t""yes" 1>&6
+    CDROM_OBJS='cdrom.o'
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 1
+EOF
+
+   elif test "$enableval" = no; then
+    echo "$ac_t""no" 1>&6
+    CDROM_OBJS=''
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 0
+EOF
+
+   else
+    echo "$ac_t""yes" 1>&6
+    CDROM_OBJS='cdrom.o'
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 1
+EOF
+
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    CDROM_OBJS=''
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 0
+EOF
+
+    
+  
+fi
+
+
+
+
+echo $ac_n "checking for Sound Blaster 16 support""... $ac_c" 1>&6
+echo "configure:4967: checking for Sound Blaster 16 support" >&5
+# Check whether --enable-sb16 or --disable-sb16 was given.
+if test "${enable_sb16+set}" = set; then
+  enableval="$enable_sb16"
+  if test "$enableval" = no; then
+     echo "$ac_t""no" 1>&6
+     SB16_OBJS=''
+     cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 0
+EOF
+
+   else
+     case "$enableval" in
+       dummy)
+         SB16_OBJS='$(SB16_DUMMY_OBJS)'
+         cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_output_c
+EOF
+
+         echo "$ac_t""dummy" 1>&6
+         ;;
+       linux)
+         SB16_OBJS='$(SB16_LINUX_OBJS)'
+         cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_linux_c
+EOF
+
+         echo "$ac_t""linux" 1>&6
+         ;;
+       win)
+         SB16_OBJS='$(SB16_WIN_OBJS)'
+         cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_windows_c
+EOF
+
+         echo "$ac_t""win" 1>&6
+         ;;
+       *)
+         echo " "
+         echo \!\!\!Error\!\!\!
+         echo "You must pass one of dummy, linux, win to --enable-sb16"
+         exit 1 ;;
+     esac
+     cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 1
+EOF
+
+   fi
+else
+  
+    echo "$ac_t""no" 1>&6
+    SB16_OBJS=''
+    cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 0
+EOF
+
+    
+  
+fi
+
+
+
+
+# Check whether --enable-hga-dumps or --disable-hga-dumps was given.
+if test "${enable_hga_dumps+set}" = set; then
+  enableval="$enable_hga_dumps"
+  cat >> confdefs.h <<EOF
+#define BX_EMULATE_HGA_DUMPS $enableval
+EOF
+
+fi
+
+
+PRIMARY_TARGET='bochs'
+
+cat >> confdefs.h <<\EOF
+#define BX_PROVIDE_DEVICE_MODELS 0
+EOF
+
+IODEV_LIB_VAR='iodev/libiodev.a'
+cat >> confdefs.h <<\EOF
+#define BX_PROVIDE_CPU_MEMORY 1
+EOF
+
+NONINLINE_VAR='$(NONINLINE_OBJS)'
+
+
+
+
+
+
+
+# Check whether --with-x11 or --without-x11 was given.
+if test "${with_x11+set}" = set; then
+  withval="$with_x11"
+  :
+fi
+
+
+# Check whether --with-beos or --without-beos was given.
+if test "${with_beos+set}" = set; then
+  withval="$with_beos"
+  :
+fi
+
+
+# Check whether --with-win32 or --without-win32 was given.
+if test "${with_win32+set}" = set; then
+  withval="$with_win32"
+  :
+fi
+
+
+# Check whether --with-win32-vcpp or --without-win32-vcpp was given.
+if test "${with_win32_vcpp+set}" = set; then
+  withval="$with_win32_vcpp"
+  :
+fi
+
+
+# Check whether --with-macos or --without-macos was given.
+if test "${with_macos+set}" = set; then
+  withval="$with_macos"
+  :
+fi
+
+
+# Check whether --with-nogui or --without-nogui was given.
+if test "${with_nogui+set}" = set; then
+  withval="$with_nogui"
+  :
+fi
+
+
+# Check whether --with-term or --without-term was given.
+if test "${with_term+set}" = set; then
+  withval="$with_term"
+  :
+fi
+
+
+# Check whether --with-rfb or --without-rfb was given.
+if test "${with_rfb+set}" = set; then
+  withval="$with_rfb"
+  :
+fi
+
+
+echo $ac_n "checking for gui library to use""... $ac_c" 1>&6
+echo "configure:5116: checking for gui library to use" >&5
+
+with_nogui=yes
+
+if (test "$with_x11" != yes) && \
+   (test "$with_beos" != yes) && \
+   (test "$with_win32" != yes) && \
+   (test "$with_nogui" != yes) && \
+   (test "$with_win32_vcpp" != yes) && \
+   (test "$with_term" != yes) && \
+   (test "$with_rfb" != yes) && \
+   (test "$with_macos" != yes); then
+  with_x11=yes
+fi
+
+DASH="-"
+SLASH="/"
+CXXFP=""
+CFP=""
+OFP="-o "
+MAKELIB="ar rv \$@"
+RMCOMMAND="rm -f "
+LINK="\$(CXX) -o \$@ \$(CXXFLAGS)"
+EXE=""
+COMMAND_SEPARATOR="&& \\"
+CD_UP_ONE="echo done"
+CD_UP_TWO="echo done"
+
+if test "$with_x11" = yes; then
+  echo "$ac_t""X windows" 1>&6
+  if test "$no_x" = yes; then
+    echo ERROR: X windows gui was selected, but X windows libraries were not found.
+    exit 1
+  fi
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_X11 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_X11)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_X)'
+elif test "$with_win32" = yes; then
+  echo "$ac_t""win32" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_WIN32 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_WIN32)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32)'
+elif test "$with_beos" = yes; then
+  echo "$ac_t""beos" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_BEOS 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_BEOS)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_BEOS)'
+elif test "$with_rfb" = yes; then
+  echo "$ac_t""rfb" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_RFB 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_RFB)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_RFB)'
+elif test "$with_win32_vcpp" = yes; then
+  echo "$ac_t""win32-vcpp" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_WIN32 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_WIN32)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32_VCPP)'
+
+  CC="cl"
+  CXX="$CC"
+  #C_OPT="/Zi"   # for debugging
+  C_OPT="/O2"   # optimize for speed
+  CFLAGS="/nologo /G6 /MT /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS $C_OPT"
+  CXXFLAGS="$CFLAGS"
+  DASH="/"
+  SLASH="\\"
+  CXXFP="/Tp"
+  CFP="/Tc"
+  OFP="/Fo"
+  MAKELIB="lib.exe /nologo /subsystem:console /machine:I386 /verbose /out:\$@"
+  RMCOMMAND="-del"
+  RANLIB="echo"
+  #L_OPT="/debug"    # for debugging
+  L_OPT=""           # no debug info
+  LINK="link $L_OPT /nologo /subsystem:console /incremental:no /machine:I386 /out:\$@ BINMODE.OBJ"
+  EXE=".exe"
+  PRIMARY_TARGET="bochs.exe"
+  COMMAND_SEPARATOR=""
+  CD_UP_ONE="cd .."
+  CD_UP_TWO="cd ..\.."
+  cat >> confdefs.h <<\EOF
+#define BX_64BIT_CONSTANTS_USE_LL 0
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define inline __inline
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define BX_NO_EMPTY_STRUCTS 1
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define BX_NO_ATTRIBUTES 1
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define BX_HAVE_HASH_MAP 0
+EOF
+
+elif test "$with_macos" = yes; then
+  echo "$ac_t""macos" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_MACOS 1
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRDUP 0
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_MACOS)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_MACOS)'
+elif test "$with_term" = yes; then
+  echo "$ac_t""term" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_TERM 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_TERM)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_TERM)'
+  use_curses=yes
+else
+  echo "$ac_t""none" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BX_WITH_NOGUI 1
+EOF
+
+  GUI_OBJS='$(GUI_OBJS_NOGUI)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_NOGUI)'
+fi
+
+if test "$use_curses" = yes; then
+  echo $ac_n "checking for mvaddch in -lcurses""... $ac_c" 1>&6
+echo "configure:5264: checking for mvaddch in -lcurses" >&5
+ac_lib_var=`echo curses'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lcurses  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5272 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  GUI_LINK_OPTS_TERM='-lcurses'
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  echo $ac_n "checking for mvaddch in -lncurses""... $ac_c" 1>&6
+echo "configure:5304: checking for mvaddch in -lncurses" >&5
+ac_lib_var=`echo ncurses'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lncurses  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5312 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  GUI_LINK_OPTS_TERM='-lncurses'
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  echo $ac_n "checking for mvaddch in -ltermlib""... $ac_c" 1>&6
+echo "configure:5344: checking for mvaddch in -ltermlib" >&5
+ac_lib_var=`echo termlib'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ltermlib  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5352 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  GUI_LINK_OPTS_TERM='-ltermlib'
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test "$GUI_LINK_OPTS_TERM" = ""; then
+    echo Curses library not found: tried curses, ncurses, and termlib.
+    exit 1
+  fi
+fi
+
+if test "$with_rfb" = yes; then
+  # first see if compiler takes "-pthread" argument
+  echo $ac_n "checking for -pthread arg to compiler""... $ac_c" 1>&6
+echo "configure:5392: checking for -pthread arg to compiler" >&5
+  CFLAGS_SAVE="$CFLAGS"
+  CFLAGS="$CFLAGS -pthread"
+  cat > conftest.$ac_ext <<EOF
+#line 5396 "configure"
+#include "confdefs.h"
+ #include <pthread.h> 
+int main() {
+ pthread_create(0,0,0,0); 
+; return 0; }
+EOF
+if { (eval echo configure:5403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+   
+      # it compiles with -pthread
+      echo "$ac_t""yes" 1>&6 
+      CXXFLAGS="$CXXFLAGS -pthread"
+    
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+      echo "$ac_t""no" 1>&6
+      # now try with -lpthread
+      CFLAGS="$CFLAGS_SAVE"
+      echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:5419: checking for pthread_create in -lpthread" >&5
+ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lpthread  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5427 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char pthread_create();
+
+int main() {
+pthread_create()
+; return 0; }
+EOF
+if { (eval echo configure:5438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  
+         # it compiles with -lpthread
+         RFB_LIBS='-lpthread'
+       
+else
+  echo "$ac_t""no" 1>&6
+
+           echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
+       
+fi
+
+    
+fi
+rm -f conftest*
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Extract the first word of "gzip", so it can be a program name with args.
+set dummy gzip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5490: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GZIP" in
+  /*)
+  ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+  ;;
+  ?:/*)                         
+  ac_cv_path_GZIP="$GZIP" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GZIP="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+GZIP="$ac_cv_path_GZIP"
+if test -n "$GZIP"; then
+  echo "$ac_t""$GZIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "tar", so it can be a program name with args.
+set dummy tar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5525: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_TAR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$TAR" in
+  /*)
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+  ;;
+  ?:/*)                         
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_TAR="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+TAR="$ac_cv_path_TAR"
+if test -n "$TAR"; then
+  echo "$ac_t""$TAR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+
+sid_host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host`
+sid_target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target`
+
+if test "$sid_host" = "$sid_target" -o "$target" = "NONE"
+then
+    echo "configure: warning: Assuming --enable-targets=all" 1>&2
+    all_targets=""
+    sidtarget_default=1
+else 
+    all_targets="$target"
+    sidtarget_default=0
+fi
+
+
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+  enableval="$enable_targets"
+  
+  case "${enable_targets}" in
+    all)  sidtarget_default=1 ;;
+    no)   sidtarget_default=0 ;;
+    *)    all_targets="${all_targets} `echo ${enable_targets} | sed -e 's-,- -g'`" ;;
+  esac
+
+fi
+
+
+sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
+sidtarget_mips=$sidtarget_default
+sidtarget_m32r=$sidtarget_default
+sidtarget_m68k=$sidtarget_default
+sidtarget_ppc=$sidtarget_default
+
+for targ in $all_targets
+do
+   case "$targ" in
+      arm*)   sidtarget_arm=1 ;;
+      thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
+      mips*)  sidtarget_mips=1 ;;
+      m32r*)  sidtarget_m32r=1 ;;
+      m68k*)  sidtarget_m68k=1 ;;
+      powerpc*) sidtarget_ppc=1 ;;
+      ppc*)   sidtarget_ppc=1 ;;
+      *)      echo "configure: warning: "Unknown target $targ"" 1>&2 ;;
+   esac
+done
+
+case 1 in
+  ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
+  ${sidtarget_mips}) ;;
+  ${sidtarget_m32r}) ;;
+  ${sidtarget_m68k}) ;;
+  ${sidtarget_ppc}) ;;
+  *) echo "configure: warning: No selected sid targets: use --enable-targets or --target" 1>&2
+       ;;
+esac
+
+
+echo $ac_n "checking ARM family support""... $ac_c" 1>&6
+echo "configure:5623: checking ARM family support" >&5
+
+
+
+if test "x$sidtarget_arm" = x1; then
+  SIDTARGET_ARM_TRUE=
+  SIDTARGET_ARM_FALSE='#'
+else
+  SIDTARGET_ARM_TRUE='#'
+  SIDTARGET_ARM_FALSE=
+fi
+echo "$ac_t""$sidtarget_arm" 1>&6
+
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:5637: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
+echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
+echo "configure:5651: checking MIPS family support" >&5
+
+
+
+if test "x$sidtarget_mips" = x1; then
+  SIDTARGET_MIPS_TRUE=
+  SIDTARGET_MIPS_FALSE='#'
+else
+  SIDTARGET_MIPS_TRUE='#'
+  SIDTARGET_MIPS_FALSE=
+fi
+echo "$ac_t""$sidtarget_mips" 1>&6
+
+echo $ac_n "checking M32R family support""... $ac_c" 1>&6
+echo "configure:5665: checking M32R family support" >&5
+
+
+
+if test "x$sidtarget_m32r" = x1; then
+  SIDTARGET_M32R_TRUE=
+  SIDTARGET_M32R_FALSE='#'
+else
+  SIDTARGET_M32R_TRUE='#'
+  SIDTARGET_M32R_FALSE=
+fi
+echo "$ac_t""$sidtarget_m32r" 1>&6
+
+echo $ac_n "checking M68K family support""... $ac_c" 1>&6
+echo "configure:5679: checking M68K family support" >&5
+
+
+
+if test "x$sidtarget_m68k" = x1; then
+  SIDTARGET_M68K_TRUE=
+  SIDTARGET_M68K_FALSE='#'
+else
+  SIDTARGET_M68K_TRUE='#'
+  SIDTARGET_M68K_FALSE=
+fi
+echo "$ac_t""$sidtarget_m68k" 1>&6
+
+echo $ac_n "checking PPC family support""... $ac_c" 1>&6
+echo "configure:5693: checking PPC family support" >&5
+
+
+
+if test "x$sidtarget_ppc" = x1; then
+  SIDTARGET_PPC_TRUE=
+  SIDTARGET_PPC_FALSE='#'
+else
+  SIDTARGET_PPC_TRUE='#'
+  SIDTARGET_PPC_FALSE=
+fi
+echo "$ac_t""$sidtarget_ppc" 1>&6
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile cpu/Makefile memory/Makefile fpu/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CXX@%$CXX%g
+s%@CPP@%$CPP%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@DYNAMIC_VAR@%$DYNAMIC_VAR%g
+s%@AS_DYNAMIC_OBJS@%$AS_DYNAMIC_OBJS%g
+s%@AS_DYNAMIC_INCS@%$AS_DYNAMIC_INCS%g
+s%@IOAPIC_OBJS@%$IOAPIC_OBJS%g
+s%@APIC_OBJS@%$APIC_OBJS%g
+s%@BX_SPLIT_HD_SUPPORT@%$BX_SPLIT_HD_SUPPORT%g
+s%@NE2K_OBJS@%$NE2K_OBJS%g
+s%@PCI_OBJ@%$PCI_OBJ%g
+s%@SUFFIX_LINE@%$SUFFIX_LINE%g
+s%@CPP_SUFFIX@%$CPP_SUFFIX%g
+s%@DEBUGGER_VAR@%$DEBUGGER_VAR%g
+s%@DISASM_VAR@%$DISASM_VAR%g
+s%@READLINE_LIB@%$READLINE_LIB%g
+s%@BX_LOADER_OBJS@%$BX_LOADER_OBJS%g
+s%@INSTRUMENT_DIR@%$INSTRUMENT_DIR%g
+s%@INSTRUMENT_VAR@%$INSTRUMENT_VAR%g
+s%@VIDEO_OBJS@%$VIDEO_OBJS%g
+s%@FPU_VAR@%$FPU_VAR%g
+s%@FPU_GLUE_OBJ@%$FPU_GLUE_OBJ%g
+s%@CDROM_OBJS@%$CDROM_OBJS%g
+s%@SB16_OBJS@%$SB16_OBJS%g
+s%@IODEV_LIB_VAR@%$IODEV_LIB_VAR%g
+s%@NONINLINE_VAR@%$NONINLINE_VAR%g
+s%@INLINE_VAR@%$INLINE_VAR%g
+s%@EXTERNAL_DEPENDENCY@%$EXTERNAL_DEPENDENCY%g
+s%@RFB_LIBS@%$RFB_LIBS%g
+s%@GUI_OBJS@%$GUI_OBJS%g
+s%@GUI_LINK_OPTS@%$GUI_LINK_OPTS%g
+s%@GUI_LINK_OPTS_TERM@%$GUI_LINK_OPTS_TERM%g
+s%@DASH@%$DASH%g
+s%@SLASH@%$SLASH%g
+s%@CXXFP@%$CXXFP%g
+s%@CFP@%$CFP%g
+s%@OFP@%$OFP%g
+s%@MAKELIB@%$MAKELIB%g
+s%@RMCOMMAND@%$RMCOMMAND%g
+s%@LINK@%$LINK%g
+s%@EXE@%$EXE%g
+s%@PRIMARY_TARGET@%$PRIMARY_TARGET%g
+s%@COMMAND_SEPARATOR@%$COMMAND_SEPARATOR%g
+s%@CD_UP_ONE@%$CD_UP_ONE%g
+s%@CD_UP_TWO@%$CD_UP_TWO%g
+s%@GZIP@%$GZIP%g
+s%@TAR@%$TAR%g
+s%@sidtarget_arm@%$sidtarget_arm%g
+s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
+s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
+s%@sidtarget_mips@%$sidtarget_mips%g
+s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
+s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
+s%@sidtarget_m32r@%$sidtarget_m32r%g
+s%@SIDTARGET_M32R_TRUE@%$SIDTARGET_M32R_TRUE%g
+s%@SIDTARGET_M32R_FALSE@%$SIDTARGET_M32R_FALSE%g
+s%@sidtarget_m68k@%$sidtarget_m68k%g
+s%@SIDTARGET_M68K_TRUE@%$SIDTARGET_M68K_TRUE%g
+s%@SIDTARGET_M68K_FALSE@%$SIDTARGET_M68K_FALSE%g
+s%@sidtarget_ppc@%$sidtarget_ppc%g
+s%@SIDTARGET_PPC_TRUE@%$SIDTARGET_PPC_TRUE%g
+s%@SIDTARGET_PPC_FALSE@%$SIDTARGET_PPC_FALSE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile cpu/Makefile memory/Makefile fpu/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/sid/component/bochs/configure.in b/sid/component/bochs/configure.in
new file mode 100644 (file)
index 0000000..09216c6
--- /dev/null
@@ -0,0 +1,928 @@
+dnl // Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.4)
+AC_INIT(components.cxx)
+AC_CONFIG_AUX_DIR(../../config)
+AM_CONFIG_HEADER(config.h)
+
+AM_INIT_AUTOMAKE(sidcomp,0.1)
+AM_MAINTAINER_MODE
+AC_EXEEXT
+AM_PROG_LIBTOOL
+
+changequote(<<, >>)
+changequote([, ])
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_PATH_XTRA
+
+AC_C_BIGENDIAN
+AC_C_INLINE
+AC_CHECK_SIZEOF(unsigned char, 1)
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned long, 4)
+AC_CHECK_SIZEOF(unsigned long long, 8)
+AC_CHECK_SIZEOF(int *, 4)
+AC_CHECK_FUNCS(select, AC_DEFINE(BX_HAVE_SELECT))
+AC_CHECK_FUNCS(snprintf, AC_DEFINE(BX_HAVE_SNPRINTF))
+AC_CHECK_FUNCS(strtoull, AC_DEFINE(BX_HAVE_STRTOULL))
+AC_CHECK_FUNCS(strtouq, AC_DEFINE(BX_HAVE_STRTOUQ))
+AC_CHECK_FUNCS(strdup, AC_DEFINE(BX_HAVE_STRDUP))
+
+AC_MSG_CHECKING(if compiler allows empty structs)
+AC_TRY_COMPILE([], [typedef struct { } junk;], 
+    AC_MSG_RESULT(yes),
+    [
+      AC_DEFINE(BX_NO_EMPTY_STRUCTS)
+      AC_MSG_RESULT(no)
+    ])
+
+AC_MSG_CHECKING(if compiler allows __attribute__)
+AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], 
+    AC_MSG_RESULT(yes),
+    [
+      AC_MSG_RESULT(no)
+      AC_DEFINE(BX_NO_ATTRIBUTES)
+    ])
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_MSG_CHECKING(for hash_map.h)
+AC_TRY_COMPILE([#include <hash_map.h>], [],
+   [
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(BX_HAVE_HASH_MAP)
+   ], AC_MSG_RESULT(no))
+AC_LANG_RESTORE
+
+AC_MSG_CHECKING(for number of processors)
+AC_ARG_ENABLE(processors,
+  [  --enable-processors                select number of processors (1,2,4)],
+  [case "$enableval" in
+     1)
+       AC_MSG_RESULT(1)
+       AC_DEFINE(BX_SMP_PROCESSORS, 1)
+       AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+       AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 1)
+       ;;
+     2)
+       AC_MSG_RESULT(2)
+       AC_DEFINE(BX_SMP_PROCESSORS, 2)
+       AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+       AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 2)
+       AC_DEFINE(BX_USE_CPU_SMF, 0)
+       ;;
+     4)
+       AC_MSG_RESULT(4)
+       AC_DEFINE(BX_SMP_PROCESSORS, 4)
+       AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 2)
+       AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 4)
+       AC_DEFINE(BX_USE_CPU_SMF, 0)
+       ;;
+     *)
+       echo " "
+       echo "WARNING: processors != [1,2,4] can work, but you need to modify rombios.c manually"
+       AC_MSG_RESULT($enable_val)
+       AC_DEFINE(BX_SMP_PROCESSORS, $enable_val)
+       AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+       AC_DEFINE(BX_IOAPIC_DEFAULT_ID, $enable_val)
+       AC_DEFINE(BX_USE_CPU_SMF, 0)
+       ;;
+   esac
+   bx_procs="$enableval"
+  ],
+  [
+     AC_MSG_RESULT(1)
+     AC_DEFINE(BX_SMP_PROCESSORS, 1)
+     AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+     AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 1)
+     bx_procs=1
+  ]
+  )
+
+AC_MSG_CHECKING(if compiler allows blank labels)
+AC_TRY_COMPILE([], [ { label1: } ],
+    AC_MSG_RESULT(yes),
+    [
+      AC_MSG_RESULT(no)
+      AC_DEFINE(BX_NO_BLANK_LABELS)
+    ])
+
+AC_MSG_CHECKING(if compiler allows LL for 64-bit constants)
+AC_TRY_COMPILE([], [ { 42LL; } ],
+    AC_MSG_RESULT(yes),
+    [
+      AC_MSG_RESULT(no)
+      AC_DEFINE(BX_64BIT_CONSTANTS_USE_LL, 0)
+    ])
+
+AC_MSG_CHECKING(for cpu level)
+AC_ARG_ENABLE(cpu-level,
+  [  --enable-cpu-level                select cpu level (3,4,5,6)],
+  [case "$enableval" in
+     3)
+       AC_MSG_RESULT(3)
+       AC_DEFINE(BX_CPU_LEVEL, 3)
+       AC_DEFINE(BX_CPU_LEVEL_HACKED, 3)
+       ;;
+     4)
+       AC_MSG_RESULT(4)
+       AC_DEFINE(BX_CPU_LEVEL, 4)
+       AC_DEFINE(BX_CPU_LEVEL_HACKED, 4)
+       ;;
+     5)
+       AC_MSG_RESULT(5)
+       AC_DEFINE(BX_CPU_LEVEL, 5)
+       AC_DEFINE(BX_CPU_LEVEL_HACKED, 5)
+       ;;
+     6)
+       AC_MSG_RESULT(6)
+       AC_DEFINE(BX_CPU_LEVEL, 6)
+       AC_DEFINE(BX_CPU_LEVEL_HACKED, 6)
+       ;;
+     *)
+       echo " "
+       echo "ERROR: you must supply a valid CPU level to --enable-cpu-level"
+       exit 1
+       ;;
+   esac
+   bx_cpu_level=$enableval
+   if test "$bx_procs" -gt 1 -a "$enableval" -lt 6; then
+     echo "ERROR: with >1 processor, use --enable-cpu-level=6"
+     exit 1
+   fi
+  ],
+  [
+    # for multiprocessors, cpu level must be 6
+    if test "$bx_procs" -gt 1; then
+      AC_MSG_RESULT(6)
+      AC_DEFINE(BX_CPU_LEVEL, 6)
+      AC_DEFINE(BX_CPU_LEVEL_HACKED, 6)
+      bx_cpu_level=6
+    else
+      AC_MSG_RESULT(5)
+      AC_DEFINE(BX_CPU_LEVEL, 5)
+      AC_DEFINE(BX_CPU_LEVEL_HACKED, 5)
+      bx_cpu_level=5
+    fi
+  ]
+  )
+
+
+AC_MSG_CHECKING(for dynamic translation support)
+AC_ARG_ENABLE(dynamic,
+  [  --enable-dynamic                  enable dynamic translation support],
+  [if test "$enableval" = no; then
+     AC_MSG_RESULT(no)
+     AC_DEFINE(BX_DYNAMIC_TRANSLATION, 0)
+     DYNAMIC_VAR=''
+     AS_DYNAMIC_OBJS=''
+     AS_DYNAMIC_INCS=''
+   else
+     if test "$enableval" = yes; then
+       echo " "
+       echo \!\!\!Error\!\!\!
+       echo "You must specify a CPU type to dynamic-translation option"
+       echo \!\!\!Error\!\!\!
+       exit 1
+     fi
+     case "$enableval" in
+       i386)
+         AC_DEFINE(BX_DYNAMIC_CPU_I386, 1)
+         AS_DYNAMIC_OBJS='$(X86_OBJS)'
+         AS_DYNAMIC_INCS='$(X86_H)'
+         ;;
+       sparc)
+         AC_DEFINE(BX_DYNAMIC_CPU_SPARC, 1)
+         AS_DYNAMIC_OBJS='$(SPARC_OBJS).o'
+         AS_DYNAMIC_INCS='$(SPARC_H)'
+         ;;
+       *)
+         echo " "
+         echo \!\!\!Error\!\!\!
+         echo "Sorry, dynamic translation is not yet available on your platform"
+         echo \!\!\!Error\!\!\!
+         AS_DYNAMIC_OBJS=''
+         AS_DYNAMIC_INCS=''
+         exit 1 ;;
+     esac
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(BX_DYNAMIC_TRANSLATION, 1)
+     DYNAMIC_VAR='$(DYNAMIC_LIB)'
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_DYNAMIC_TRANSLATION, 0)
+    DYNAMIC_VAR=''
+    AS_DYNAMIC_OBJS=''
+    AS_DYNAMIC_INCS=''
+    ]
+  )
+AC_SUBST(DYNAMIC_VAR)
+AC_SUBST(AS_DYNAMIC_OBJS)
+AC_SUBST(AS_DYNAMIC_INCS)
+
+AC_MSG_CHECKING(for APIC support)
+AC_ARG_ENABLE(apic,
+  [  --enable-apic                   enable APIC support],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SUPPORT_APIC, 1)
+    IOAPIC_OBJS='ioapic.o'
+    APIC_OBJS='apic.o'
+   else
+    AC_MSG_RESULT(no)
+    if test "$bx_procs" -gt 1; then
+      echo "Number of processors = $bx_procs"
+      echo "ERROR: With processors > 1 you must use --enable-apic"
+      exit 1
+    fi
+    AC_DEFINE(BX_SUPPORT_APIC, 0)
+    IOAPIC_OBJS=''
+    APIC_OBJS=''
+   fi
+   ],
+  [
+    if test "$bx_procs" -gt 1 -o "$bx_cpu_level" -gt 5; then
+      # enable APIC by default, if processors>1 or if cpulevel>5
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(BX_SUPPORT_APIC, 1)
+      IOAPIC_OBJS='ioapic.o'
+      APIC_OBJS='apic.o'
+    else
+      AC_MSG_RESULT(no)
+      AC_DEFINE(BX_SUPPORT_APIC, 0)
+      IOAPIC_OBJS=''
+      APIC_OBJS=''
+     fi
+   ]
+  )
+AC_SUBST(IOAPIC_OBJS)
+AC_SUBST(APIC_OBJS)
+
+AC_MSG_CHECKING(for split hard disk image support)
+AC_ARG_ENABLE(split-hd,
+  [  --enable-split-hd                   allows split hard disk image],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SPLIT_HD_SUPPORT, 1)
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_SPLIT_HD_SUPPORT, 0)
+   fi],
+  [
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SPLIT_HD_SUPPORT, 1)
+    ]
+  )
+AC_SUBST(BX_SPLIT_HD_SUPPORT)
+
+AC_MSG_CHECKING(for NE2000 support)
+AC_ARG_ENABLE(ne2000,
+  [  --enable-ne2000                   enable limited ne2000 support],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_NE2K_SUPPORT, 1)
+    NE2K_OBJS='ne2k.o eth.o eth_null.o'
+    AC_CHECK_HEADER(net/bpf.h, NE2K_OBJS="$NE2K_OBJS eth_fbsd.o")
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_NE2K_SUPPORT, 0)
+    NE2K_OBJS=''
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_NE2K_SUPPORT, 0)
+    NE2K_OBJS=''
+    ]
+  )
+AC_SUBST(NE2K_OBJS)
+
+
+AC_MSG_CHECKING(for i440FX PCI support)
+AC_ARG_ENABLE(pci,
+  [  --enable-pci                      enable limited i440FX PCI support],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_PCI_SUPPORT, 1)
+    PCI_OBJ='pci.o'
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_PCI_SUPPORT, 0)
+    PCI_OBJ=''
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_PCI_SUPPORT, 0)
+    PCI_OBJ=''
+    ]
+  )
+AC_SUBST(PCI_OBJ)
+
+
+AC_MSG_CHECKING(for port e9 hack)
+AC_ARG_ENABLE(port-e9-hack,
+  [  --enable-port-e9-hack             writes to port e9 go to console],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_PORT_E9_HACK, 1)
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_PORT_E9_HACK, 0)
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_PORT_E9_HACK, 0)
+    ]
+  )
+
+
+AC_MSG_CHECKING(for use of .cpp as suffix)
+AC_ARG_ENABLE(cpp,
+  [  --enable-cpp                      use .cpp as C++ suffix],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    SUFFIX_LINE='.SUFFIXES: .cpp'
+    CPP_SUFFIX='cpp'
+   else
+    AC_MSG_RESULT(no)
+    SUFFIX_LINE='.SUFFIXES: .cc'
+    CPP_SUFFIX='cc'
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    SUFFIX_LINE='.SUFFIXES: .cc'
+    CPP_SUFFIX='cc'
+    ]
+  )
+AC_SUBST(SUFFIX_LINE)
+AC_SUBST(CPP_SUFFIX)
+
+if test "$enable_cpp" = yes; then
+  echo "moving .cc source files to .cpp"
+  sourcefiles=`find . -name "*.cc" -print`
+  if test "$sourcefiles" != ""; then
+    for ccname in $sourcefiles
+    do
+      cppname=`echo $ccname | sed -e "s/\.cc$/.cpp/"`
+      echo "mv $ccname $cppname"
+      mv   $ccname $cppname
+    done
+  else
+    echo "no more .cc source files to rename"
+  fi
+fi
+
+
+AC_MSG_CHECKING(for Bochs internal debugger support)
+AC_ARG_ENABLE(debugger,
+  [  --enable-debugger                 compile in support for Bochs internal debugger],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_DEBUGGER, 1)
+    DEBUGGER_VAR='$(DEBUGGER_LIB)'
+    bx_debugger=1
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_DEBUGGER, 0)
+    DEBUGGER_VAR=''
+    bx_debugger=0
+   fi
+   ],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_DEBUGGER, 0)
+    DEBUGGER_VAR=''
+    bx_debugger=0
+    ]
+  )
+AC_SUBST(DEBUGGER_VAR)
+
+AC_MSG_CHECKING(for disassembler support)
+AC_ARG_ENABLE(disasm,
+  [  --enable-disasm                   compile in support for disassembler],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_DISASM, 1)
+    DISASM_VAR='$(DISASM_LIB)'
+   else
+    AC_MSG_RESULT(no)
+    if test "$bx_debugger" = 1; then
+      echo "ERROR: debugger is enabled, so --enable-disasm is required"
+      exit 1
+    fi
+    AC_DEFINE(BX_DISASM, 0)
+    DISASM_VAR=''
+   fi],
+  [
+    if test "$bx_debugger" = 1; then
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(BX_DISASM, 1)
+      DISASM_VAR='$(DISASM_LIB)'
+    else
+      AC_MSG_RESULT(no)
+      AC_DEFINE(BX_DISASM, 0)
+      DISASM_VAR=''
+    fi
+    ]
+  )
+AC_SUBST(DISASM_VAR)
+
+AC_MSG_CHECKING(whether to use readline)
+AC_ARG_ENABLE(readline,
+  [ --enable-readline                     use readline library with debugger],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+     want_readline=yes
+   else
+     AC_MSG_RESULT(no)
+     want_readline=no
+   fi],
+  [ # default is yes
+    AC_MSG_RESULT(yes)
+    want_readline=yes ]
+ )
+
+
+if test "$want_readline" = yes; then
+  AC_CHECK_LIB(readline, 
+    readline,
+    [
+      if test "$bx_debugger" = 1; then
+       # only add readline library if debugger is on
+       AC_DEFINE(HAVE_LIBREADLINE, 1)
+       READLINE_LIB='-lreadline'
+      fi
+    ]
+  )
+fi
+  AC_SUBST(READLINE_LIB)
+
+AC_CHECK_HEADER(readline/history.h,
+  AC_DEFINE(HAVE_READLINE_HISTORY_H)
+  )
+
+
+AC_MSG_CHECKING(for loader support)
+AC_ARG_ENABLE(loader,
+  [  --enable-loader                   support calling external loader from debugger],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_USE_LOADER, 1)
+    BX_LOADER_OBJS='bx_loader.o loader.o'
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_USE_LOADER, 0)
+    BX_LOADER_OBJS=''
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_USE_LOADER, 0)
+    BX_LOADER_OBJS=''
+    ]
+  )
+AC_SUBST(BX_LOADER_OBJS)
+
+
+
+INSTRUMENT_DIR='instrument/stubs'
+
+AC_MSG_CHECKING(for instrumentation support)
+AC_ARG_ENABLE(instrumentation,
+  [  --enable-instrumentation          compile in support for instrumentation],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_INSTRUMENTATION, 1)
+    INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+   elif test "$enableval" = no; then
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_INSTRUMENTATION, 0)
+    INSTRUMENT_VAR=''
+   else
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_INSTRUMENTATION, 1)
+    INSTRUMENT_DIR=$enableval
+    INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_INSTRUMENTATION, 0)
+    INSTRUMENT_VAR=''
+    ]
+  )
+AC_SUBST(INSTRUMENT_DIR)
+AC_SUBST(INSTRUMENT_VAR)
+
+AC_ARG_ENABLE(simid,
+  [  --enable-simid=0 or 1             CPU simulator ID if using more than one],
+  [if test "$enableval" = yes; then
+    AC_DEFINE(BX_SIM_ID, 0)
+   elif test "$enableval" = no; then
+    AC_DEFINE(BX_SIM_ID, 0)
+   else
+    AC_DEFINE_UNQUOTED(BX_SIM_ID, $enableval)
+   fi],
+  [
+    AC_DEFINE(BX_SIM_ID, 0)
+    ]
+  )
+
+AC_ARG_ENABLE(num-sim,
+  [  --enable-num-sim=1 or 2           number of CPU simulators],
+  [if test "$enableval" = yes; then
+    AC_DEFINE(BX_NUM_SIMULATORS, 1)
+   elif test "$enableval" = no; then
+    AC_DEFINE(BX_NUM_SIMULATORS, 1)
+   else
+    AC_DEFINE_UNQUOTED(BX_NUM_SIMULATORS, $enableval)
+   fi],
+  [
+    AC_DEFINE(BX_NUM_SIMULATORS, 1)
+    ]
+  )
+
+AC_ARG_ENABLE(time0,
+  [  --enable-time0=n                  start at n instead of using time()],
+  [if test "$enableval" = yes; then
+    AC_DEFINE(BX_USE_SPECIFIED_TIME0, 917385580)
+   elif test "$enableval" = no; then
+    AC_DEFINE(BX_USE_SPECIFIED_TIME0, 0)
+   else
+    AC_DEFINE_UNQUOTED(BX_USE_SPECIFIED_TIME0, $enableval)
+   fi],
+  [
+    AC_DEFINE(BX_USE_SPECIFIED_TIME0, 0)
+    ]
+  )
+
+
+
+AC_MSG_CHECKING(for VGA emulation)
+AC_ARG_ENABLE(vga,
+  [  --enable-vga                      use VGA emulation],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SUPPORT_VGA, 1)
+    VIDEO_OBJS='$(VIDEO_OBJS_VGA)'
+   else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_SUPPORT_VGA, 0)
+    VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_SUPPORT_VGA, 0)
+    VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+    ]
+  )
+AC_SUBST(VIDEO_OBJS)
+
+AC_MSG_CHECKING(for FPU emulation)
+FPU_VAR=''
+FPU_GLUE_OBJ=''
+AC_ARG_ENABLE(fpu,
+  [  --enable-fpu                      compile in FPU emulation],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SUPPORT_FPU, 1)
+    FPU_VAR='$(FPU_LIB)'
+    FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+   elif test "$enableval" = no; then
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_SUPPORT_FPU, 0)
+   else
+    echo " "
+    echo "ERROR: --enable-fpu does not accept a path"
+    exit 1
+   fi
+   ],
+  [
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_SUPPORT_FPU, 1)
+    FPU_VAR='$(FPU_LIB)'
+    FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+    ]
+  )
+AC_SUBST(FPU_VAR)
+AC_SUBST(FPU_GLUE_OBJ)
+
+
+
+AC_MSG_CHECKING(for x86 debugger support)
+AC_ARG_ENABLE(x86-debugger,
+  [  --enable-x86-debugger             x86 debugger support],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_X86_DEBUGGER, 1)
+   elif test "$enableval" = no; then
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_X86_DEBUGGER, 0)
+   else
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(BX_X86_DEBUGGER, 1)
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    AC_DEFINE(BX_X86_DEBUGGER, 0)
+    ]
+  )
+
+AC_MSG_CHECKING(for CDROM support)
+AC_ARG_ENABLE(cdrom,
+  [  --enable-cdrom                    CDROM support],
+  [if test "$enableval" = yes; then
+    AC_MSG_RESULT(yes)
+    CDROM_OBJS='cdrom.o'
+    AC_DEFINE(BX_SUPPORT_CDROM, 1)
+   elif test "$enableval" = no; then
+    AC_MSG_RESULT(no)
+    CDROM_OBJS=''
+    AC_DEFINE(BX_SUPPORT_CDROM, 0)
+   else
+    AC_MSG_RESULT(yes)
+    CDROM_OBJS='cdrom.o'
+    AC_DEFINE(BX_SUPPORT_CDROM, 1)
+   fi],
+  [
+    AC_MSG_RESULT(no)
+    CDROM_OBJS=''
+    AC_DEFINE(BX_SUPPORT_CDROM, 0)
+    ]
+  )
+AC_SUBST(CDROM_OBJS)
+
+
+AC_MSG_CHECKING(for Sound Blaster 16 support)
+AC_ARG_ENABLE(sb16,
+  [  --enable-sb16                     Sound Blaster 16 Support],
+  [if test "$enableval" = no; then
+     AC_MSG_RESULT(no)
+     SB16_OBJS=''
+     AC_DEFINE(BX_SUPPORT_SB16, 0)
+   else
+     case "$enableval" in
+       dummy)
+         SB16_OBJS='$(SB16_DUMMY_OBJS)'
+         AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_output_c)
+         AC_MSG_RESULT(dummy)
+         ;;
+       linux)
+         SB16_OBJS='$(SB16_LINUX_OBJS)'
+         AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_linux_c)
+         AC_MSG_RESULT(linux)
+         ;;
+       win)
+         SB16_OBJS='$(SB16_WIN_OBJS)'
+         AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_windows_c)
+         AC_MSG_RESULT(win)
+         ;;
+       *)
+         echo " "
+         echo \!\!\!Error\!\!\!
+         echo "You must pass one of dummy, linux, win to --enable-sb16"
+         exit 1 ;;
+     esac
+     AC_DEFINE(BX_SUPPORT_SB16, 1)
+   fi],
+
+  [
+    AC_MSG_RESULT(no)
+    SB16_OBJS=''
+    AC_DEFINE(BX_SUPPORT_SB16, 0)
+    ]
+  )
+AC_SUBST(SB16_OBJS)
+
+
+AC_ARG_ENABLE(hga-dumps,
+  [  --enable-hga-dumps=Nmicroseconds  copy memory to HGA video buffer every N useconds],
+  AC_DEFINE_UNQUOTED(BX_EMULATE_HGA_DUMPS, $enableval),
+  )
+
+PRIMARY_TARGET='bochs'
+
+AC_DEFINE(BX_PROVIDE_DEVICE_MODELS, 0)
+IODEV_LIB_VAR='iodev/libiodev.a'
+AC_DEFINE(BX_PROVIDE_CPU_MEMORY, 1)
+NONINLINE_VAR='$(NONINLINE_OBJS)'
+
+AC_SUBST(IODEV_LIB_VAR)
+AC_SUBST(NONINLINE_VAR)
+AC_SUBST(INLINE_VAR)
+AC_SUBST(EXTERNAL_DEPENDENCY)
+
+
+AC_ARG_WITH(x11,
+  [  --with-x11                        use X11 GUI],
+  )
+
+AC_ARG_WITH(beos,
+  [  --with-beos                       use BeOS GUI],
+  )
+
+AC_ARG_WITH(win32,
+  [  --with-win32                      use Win32 GUI],
+  )
+
+AC_ARG_WITH(win32-vcpp,
+  [  --with-win32-vcpp                 use Win32 GUI/Visual C++ environment],
+  )
+
+AC_ARG_WITH(macos,
+  [  --with-macos                      use Macintosh/CodeWarrior environment],
+  )
+
+AC_ARG_WITH(nogui,
+  [  --with-nogui                      no native GUI, just use blank stubs],
+  )
+
+AC_ARG_WITH(term,
+  [  --with-term                       textmode terminal environment],
+  )
+
+AC_ARG_WITH(rfb,
+  [  --with-rfb                        use RFB protocol, works with VNC viewer],
+  )
+
+AC_MSG_CHECKING(for gui library to use)
+
+dnl Disable GUIs for SID use
+with_nogui=yes
+
+dnl // make sure X Windows is default if no other chosen
+if (test "$with_x11" != yes) && \
+   (test "$with_beos" != yes) && \
+   (test "$with_win32" != yes) && \
+   (test "$with_nogui" != yes) && \
+   (test "$with_win32_vcpp" != yes) && \
+   (test "$with_term" != yes) && \
+   (test "$with_rfb" != yes) && \
+   (test "$with_macos" != yes); then
+  with_x11=yes
+fi
+
+dnl // DASH is option prefix for your platform
+dnl // SLASH is directory for your platform
+dnl // CXXFP is C++ File Prefix; the flag that tells the compiler
+dnl //   this is a C++ source file
+dnl // CFP is C File Prefix; the flag that tells the compiler
+dnl //   this is a C source file
+dnl // OFP is Object File Prefix; the flag that tells the compiler
+dnl //   generate an object file with this name
+DASH="-"
+SLASH="/"
+CXXFP=""
+CFP=""
+OFP="-o "
+MAKELIB="ar rv \$@"
+RMCOMMAND="rm -f "
+LINK="\$(CXX) -o \$@ \$(CXXFLAGS)"
+EXE=""
+COMMAND_SEPARATOR="&& \\"
+CD_UP_ONE="echo done"
+CD_UP_TWO="echo done"
+
+if test "$with_x11" = yes; then
+  AC_MSG_RESULT(X windows)
+  if test "$no_x" = yes; then
+    echo ERROR: X windows gui was selected, but X windows libraries were not found.
+    exit 1
+  fi
+  AC_DEFINE(BX_WITH_X11, 1)
+  GUI_OBJS='$(GUI_OBJS_X11)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_X)'
+elif test "$with_win32" = yes; then
+  AC_MSG_RESULT(win32)
+  AC_DEFINE(BX_WITH_WIN32, 1)
+  GUI_OBJS='$(GUI_OBJS_WIN32)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32)'
+elif test "$with_beos" = yes; then
+  AC_MSG_RESULT(beos)
+  AC_DEFINE(BX_WITH_BEOS, 1)
+  GUI_OBJS='$(GUI_OBJS_BEOS)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_BEOS)'
+elif test "$with_rfb" = yes; then
+  AC_MSG_RESULT(rfb)
+  AC_DEFINE(BX_WITH_RFB, 1)
+  GUI_OBJS='$(GUI_OBJS_RFB)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_RFB)'
+elif test "$with_win32_vcpp" = yes; then
+  AC_MSG_RESULT(win32-vcpp)
+  AC_DEFINE(BX_WITH_WIN32, 1)
+  GUI_OBJS='$(GUI_OBJS_WIN32)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32_VCPP)'
+
+  CC="cl"
+  CXX="$CC"
+  #C_OPT="/Zi"   # for debugging
+  C_OPT="/O2"   # optimize for speed
+  CFLAGS="/nologo /G6 /MT /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS $C_OPT"
+  CXXFLAGS="$CFLAGS"
+  DASH="/"
+  SLASH="\\"
+  CXXFP="/Tp"
+  CFP="/Tc"
+  OFP="/Fo"
+  MAKELIB="lib.exe /nologo /subsystem:console /machine:I386 /verbose /out:\$@"
+  RMCOMMAND="-del"
+  RANLIB="echo"
+  #L_OPT="/debug"    # for debugging
+  L_OPT=""           # no debug info
+  LINK="link $L_OPT /nologo /subsystem:console /incremental:no /machine:I386 /out:\$@ BINMODE.OBJ"
+  EXE=".exe"
+  PRIMARY_TARGET="bochs.exe"
+  COMMAND_SEPARATOR=""
+  CD_UP_ONE="cd .."
+  CD_UP_TWO="cd ..\.."
+  AC_DEFINE(BX_64BIT_CONSTANTS_USE_LL, 0)
+  AC_DEFINE(inline, __inline)
+  AC_DEFINE(BX_NO_EMPTY_STRUCTS, 1)
+  AC_DEFINE(BX_NO_ATTRIBUTES, 1)
+  AC_DEFINE(BX_HAVE_HASH_MAP, 0)
+elif test "$with_macos" = yes; then
+  AC_MSG_RESULT(macos)
+  AC_DEFINE(BX_WITH_MACOS, 1)
+  AC_DEFINE(BX_HAVE_STRDUP, 0)
+  GUI_OBJS='$(GUI_OBJS_MACOS)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_MACOS)'
+elif test "$with_term" = yes; then
+  AC_MSG_RESULT(term)
+  AC_DEFINE(BX_WITH_TERM, 1)
+  GUI_OBJS='$(GUI_OBJS_TERM)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_TERM)'
+  use_curses=yes
+else
+  AC_MSG_RESULT(none)
+  AC_DEFINE(BX_WITH_NOGUI, 1)
+  GUI_OBJS='$(GUI_OBJS_NOGUI)'
+  GUI_LINK_OPTS='$(GUI_LINK_OPTS_NOGUI)'
+fi
+
+if test "$use_curses" = yes; then
+  AC_CHECK_LIB(curses, mvaddch, GUI_LINK_OPTS_TERM='-lcurses')
+  AC_CHECK_LIB(ncurses, mvaddch, GUI_LINK_OPTS_TERM='-lncurses')
+  AC_CHECK_LIB(termlib, mvaddch, GUI_LINK_OPTS_TERM='-ltermlib')
+  if test "$GUI_LINK_OPTS_TERM" = ""; then
+    echo Curses library not found: tried curses, ncurses, and termlib.
+    exit 1
+  fi
+fi
+
+if test "$with_rfb" = yes; then
+  # first see if compiler takes "-pthread" argument
+  AC_MSG_CHECKING(for -pthread arg to compiler)
+  CFLAGS_SAVE="$CFLAGS"
+  CFLAGS="$CFLAGS -pthread"
+  AC_TRY_LINK([ #include <pthread.h> ],
+    [ pthread_create(0,0,0,0); ], 
+    [ 
+      # it compiles with -pthread
+      AC_MSG_RESULT(yes) 
+      CXXFLAGS="$CXXFLAGS -pthread"
+    ],
+    [
+      AC_MSG_RESULT(no)
+      # now try with -lpthread
+      CFLAGS="$CFLAGS_SAVE"
+      AC_CHECK_LIB(pthread, 
+       pthread_create,
+       [
+         # it compiles with -lpthread
+         RFB_LIBS='-lpthread'
+       ],
+       [
+           echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
+       ])
+    ])
+fi
+
+AC_SUBST(RFB_LIBS)
+AC_SUBST(GUI_OBJS)
+AC_SUBST(GUI_LINK_OPTS)
+AC_SUBST(GUI_LINK_OPTS_TERM)
+AC_SUBST(DASH)
+AC_SUBST(SLASH)
+AC_SUBST(CXXFP)
+AC_SUBST(CFP)
+AC_SUBST(OFP)
+AC_SUBST(MAKELIB)
+AC_SUBST(RMCOMMAND)
+AC_SUBST(LINK)
+AC_SUBST(EXE)
+AC_SUBST(PRIMARY_TARGET)
+AC_SUBST(COMMAND_SEPARATOR)
+AC_SUBST(CD_UP_ONE)
+AC_SUBST(CD_UP_TWO)
+
+AC_PATH_PROG(GZIP, gzip)
+AC_PATH_PROG(TAR, tar)
+
+dnl Perform --target/--enable-targets processing.
+CY_SIDTARGET_CHECK
+
+AC_OUTPUT(Makefile cpu/Makefile memory/Makefile fpu/Makefile)
diff --git a/sid/component/bochs/cpu/Makefile.am b/sid/component/bochs/cpu/Makefile.am
new file mode 100644 (file)
index 0000000..cf73d0a
--- /dev/null
@@ -0,0 +1,12 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+##         sid/include in build tree       bochs/cpu   component/bochs sid/include in src tree     bochs/memory
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../memory -I$(srcdir)/../debug
+
+noinst_LTLIBRARIES = libcpu.la
+
+libcpu_la_SOURCES =  exception-sid.cc cpu.cc cpu.h cpu-sid.h cpu-sid.cc init-sid.cc state_file.h main-hack.cc x86.cc access.cc ctrl_xfer8.cc flag_ctrl.cc mult32.cc shift16.cc ctrl_xfer_pro.cc flag_ctrl_pro.cc mult8.cc shift32.cc arith16.cc data_xfer16.cc init.cc paging.cc shift8.cc arith32.cc data_xfer32.cc io.cc proc_ctrl.cc soft_int.cc soft_int-sid.cc arith8.cc data_xfer8.cc io_pro.cc protect_ctrl.cc stack16.cc bcd.cc debugstuff.cc debugstuff-sid.cc lazy_flags.cc protect_ctrl_pro.cc stack32.cc bit.cc decode16.cc logical16.cc resolve16.cc stack_pro.cc decode32.cc logical32.cc resolve32.cc string.cc ctrl_xfer16.cc exception.cc logical8.cc segment_ctrl.cc tasking.cc ctrl_xfer32.cc ctrl_xfer32-sid.cc fetchdecode.cc fetchdecode-sid.cc mult16.cc segment_ctrl_pro.cc vm8086.cc lazy_flags.h x86.h x86-memory-modes.cc
+
+libcpu_la_LDFLAGS = -no-undefined
diff --git a/sid/component/bochs/cpu/Makefile.in b/sid/component/bochs/cpu/Makefile.in
new file mode 100644 (file)
index 0000000..2c5807f
--- /dev/null
@@ -0,0 +1,438 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../memory -I$(srcdir)/../debug
+
+noinst_LTLIBRARIES = libcpu.la
+
+libcpu_la_SOURCES = exception-sid.cc cpu.cc cpu.h cpu-sid.h cpu-sid.cc init-sid.cc state_file.h main-hack.cc x86.cc access.cc ctrl_xfer8.cc flag_ctrl.cc mult32.cc shift16.cc ctrl_xfer_pro.cc flag_ctrl_pro.cc mult8.cc shift32.cc arith16.cc data_xfer16.cc init.cc paging.cc shift8.cc arith32.cc data_xfer32.cc io.cc proc_ctrl.cc soft_int.cc soft_int-sid.cc arith8.cc data_xfer8.cc io_pro.cc protect_ctrl.cc stack16.cc bcd.cc debugstuff.cc debugstuff-sid.cc lazy_flags.cc protect_ctrl_pro.cc stack32.cc bit.cc decode16.cc logical16.cc resolve16.cc stack_pro.cc decode32.cc logical32.cc resolve32.cc string.cc ctrl_xfer16.cc exception.cc logical8.cc segment_ctrl.cc tasking.cc ctrl_xfer32.cc ctrl_xfer32-sid.cc fetchdecode.cc fetchdecode-sid.cc mult16.cc segment_ctrl_pro.cc vm8086.cc lazy_flags.h x86.h x86-memory-modes.cc
+
+libcpu_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libcpu_la_LIBADD = 
+libcpu_la_OBJECTS =  exception-sid.lo cpu.lo cpu-sid.lo init-sid.lo \
+main-hack.lo x86.lo access.lo ctrl_xfer8.lo flag_ctrl.lo mult32.lo \
+shift16.lo ctrl_xfer_pro.lo flag_ctrl_pro.lo mult8.lo shift32.lo \
+arith16.lo data_xfer16.lo init.lo paging.lo shift8.lo arith32.lo \
+data_xfer32.lo io.lo proc_ctrl.lo soft_int.lo soft_int-sid.lo arith8.lo \
+data_xfer8.lo io_pro.lo protect_ctrl.lo stack16.lo bcd.lo debugstuff.lo \
+debugstuff-sid.lo lazy_flags.lo protect_ctrl_pro.lo stack32.lo bit.lo \
+decode16.lo logical16.lo resolve16.lo stack_pro.lo decode32.lo \
+logical32.lo resolve32.lo string.lo ctrl_xfer16.lo exception.lo \
+logical8.lo segment_ctrl.lo tasking.lo ctrl_xfer32.lo \
+ctrl_xfer32-sid.lo fetchdecode.lo fetchdecode-sid.lo mult16.lo \
+segment_ctrl_pro.lo vm8086.lo x86-memory-modes.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES =  .deps/access.P .deps/arith16.P .deps/arith32.P \
+.deps/arith8.P .deps/bcd.P .deps/bit.P .deps/cpu-sid.P .deps/cpu.P \
+.deps/ctrl_xfer16.P .deps/ctrl_xfer32-sid.P .deps/ctrl_xfer32.P \
+.deps/ctrl_xfer8.P .deps/ctrl_xfer_pro.P .deps/data_xfer16.P \
+.deps/data_xfer32.P .deps/data_xfer8.P .deps/debugstuff-sid.P \
+.deps/debugstuff.P .deps/decode16.P .deps/decode32.P \
+.deps/exception-sid.P .deps/exception.P .deps/fetchdecode-sid.P \
+.deps/fetchdecode.P .deps/flag_ctrl.P .deps/flag_ctrl_pro.P \
+.deps/init-sid.P .deps/init.P .deps/io.P .deps/io_pro.P \
+.deps/lazy_flags.P .deps/logical16.P .deps/logical32.P .deps/logical8.P \
+.deps/main-hack.P .deps/mult16.P .deps/mult32.P .deps/mult8.P \
+.deps/paging.P .deps/proc_ctrl.P .deps/protect_ctrl.P \
+.deps/protect_ctrl_pro.P .deps/resolve16.P .deps/resolve32.P \
+.deps/segment_ctrl.P .deps/segment_ctrl_pro.P .deps/shift16.P \
+.deps/shift32.P .deps/shift8.P .deps/soft_int-sid.P .deps/soft_int.P \
+.deps/stack16.P .deps/stack32.P .deps/stack_pro.P .deps/string.P \
+.deps/tasking.P .deps/vm8086.P .deps/x86-memory-modes.P .deps/x86.P
+SOURCES = $(libcpu_la_SOURCES)
+OBJECTS = $(libcpu_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign cpu/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libcpu.la: $(libcpu_la_OBJECTS) $(libcpu_la_DEPENDENCIES)
+       $(CXXLINK)  $(libcpu_la_LDFLAGS) $(libcpu_la_OBJECTS) $(libcpu_la_LIBADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = cpu
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign cpu/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstLTLIBRARIES clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstLTLIBRARIES distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstLTLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sid/component/bochs/cpu/access.cc b/sid/component/bochs/cpu/access.cc
new file mode 100644 (file)
index 0000000..067c1c8
--- /dev/null
@@ -0,0 +1,493 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+
+
+  void
+BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
+                               unsigned length)
+{
+  Bit32u upper_limit;
+
+
+  if ( protected_mode() ) {
+    if ( seg->cache.valid==0 ) {
+      BX_INFO(("seg = %s\n", BX_CPU_THIS_PTR strseg(seg)));
+      BX_INFO(("seg->selector.value = %04x\n", (unsigned) seg->selector.value));
+      BX_INFO(("write_virtual_checks: valid bit = 0\n"));
+         BX_INFO(("CS: %04x\n", (unsigned) BX_CPU_THIS_PTR sregs[1].selector.value));
+         BX_INFO(("IP: %04x\n", (unsigned) BX_CPU_THIS_PTR prev_eip));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+
+    if (seg->cache.p == 0) { /* not present */
+         BX_INFO(("write_virtual_checks(): segment not present\n"));
+      exception(int_number(seg), 0, 0);
+      return;
+      }
+
+    switch ( seg->cache.type ) {
+      case 0: case 1:   // read only
+      case 4: case 5:   // read only, expand down
+      case 8: case 9:   // execute only
+      case 10: case 11: // execute/read
+      case 12: case 13: // execute only, conforming
+      case 14: case 15: // execute/read-only, conforming
+               BX_INFO(("write_virtual_checks(): no write access to seg\n"));
+        exception(int_number(seg), 0, 0);
+        return;
+
+      case 2: case 3: /* read/write */
+        if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+                 BX_INFO(("write_virtual_checks(): write beyond limit, r/w\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+
+      case 6: case 7: /* read write, expand down */
+        if (seg->cache.u.segment.d_b)
+          upper_limit = 0xffffffff;
+        else
+          upper_limit = 0x0000ffff;
+        if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+             (offset > upper_limit) ||
+             ((upper_limit - offset) < (length - 1)) ) {
+                 BX_INFO(("write_virtual_checks(): write beyond limit, r/w ED\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+      }
+
+    return;
+    }
+
+  else { /* real mode */
+    if ( (offset + length - 1)  >  seg->cache.u.segment.limit_scaled) {
+      //BX_INFO(("write_virtual_checks() SEG EXCEPTION:  %x:%x + %x\n",
+      //  (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
+      if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
+      else exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+}
+
+  void
+BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
+                              unsigned length)
+{
+  Bit32u upper_limit;
+
+
+  if ( protected_mode() ) {
+    if ( seg->cache.valid==0 ) {
+      BX_CPU_THIS_PTR info("seg = %s\n", BX_CPU_THIS_PTR strseg(seg));
+      BX_CPU_THIS_PTR info("seg->selector.value = %04x\n", (unsigned) seg->selector.value);
+      //BX_CPU_THIS_PTR info("read_virtual_checks: valid bit = 0\n");
+      //BX_CPU_THIS_PTR info("CS: %04x\n", (unsigned)
+      //BX_CPU_THIS_PTR sregs[1].selector.value);
+      BX_INFO(("seg = %s\n", BX_CPU_THIS_PTR strseg(seg)));
+      BX_INFO(("seg->selector.value = %04x\n", (unsigned) seg->selector.value));
+      //BX_INFO(("read_virtual_checks: valid bit = 0\n"));
+      //BX_INFO(("CS: %04x\n", (unsigned)
+      //   BX_CPU_THIS_PTR sregs[1].selector.value));
+      //BX_INFO(("IP: %04x\n", (unsigned) BX_CPU_THIS_PTR prev_eip));
+      //debug(BX_CPU_THIS_PTR eip);
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+
+    if (seg->cache.p == 0) { /* not present */
+         BX_INFO(("read_virtual_checks(): segment not present\n"));
+      exception(int_number(seg), 0, 0);
+      return;
+      }
+
+    switch ( seg->cache.type ) {
+      case 0: case 1: /* read only */
+      case 10: case 11: /* execute/read */
+      case 14: case 15: /* execute/read-only, conforming */
+        if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+                 BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+
+      case 2: case 3: /* read/write */
+        if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+                 BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+
+      case 4: case 5: /* read only, expand down */
+        if (seg->cache.u.segment.d_b)
+          upper_limit = 0xffffffff;
+        else
+          upper_limit = 0x0000ffff;
+        if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+             (offset > upper_limit) ||
+             ((upper_limit - offset) < (length - 1)) ) {
+                 BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+
+      case 6: case 7: /* read write, expand down */
+        if (seg->cache.u.segment.d_b)
+          upper_limit = 0xffffffff;
+        else
+          upper_limit = 0x0000ffff;
+        if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+             (offset > upper_limit) ||
+             ((upper_limit - offset) < (length - 1)) ) {
+                 BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+          exception(int_number(seg), 0, 0);
+          return;
+          }
+        break;
+
+      case 8: case 9: /* execute only */
+      case 12: case 13: /* execute only, conforming */
+        /* can't read or write an execute-only segment */
+               BX_INFO(("read_virtual_checks(): execute only\n"));
+        exception(int_number(seg), 0, 0);
+        return;
+        break;
+      }
+    return;
+    }
+
+  else { /* real mode */
+    if ( (offset + length - 1)  >  seg->cache.u.segment.limit_scaled) {
+      //BX_CPU_THIS_PTR info("read_virtual_checks() SEG EXCEPTION:  %x:%x + %x\n",
+      //  (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length);
+      if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
+      else exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    return;
+    }
+}
+
+
+
+
+  char *
+BX_CPU_C::strseg(bx_segment_reg_t *seg)
+{
+  if (seg == &BX_CPU_THIS_PTR sregs[0]) return("ES");
+  else if (seg == & BX_CPU_THIS_PTR sregs[1]) return("CS");
+  else if (seg == & BX_CPU_THIS_PTR sregs[2]) return("SS");
+  else if (seg == &BX_CPU_THIS_PTR sregs[3]) return("DS");
+  else if (seg == &BX_CPU_THIS_PTR sregs[4]) return("FS");
+  else if (seg == &BX_CPU_THIS_PTR sregs[5]) return("GS");
+  else {
+    BX_INFO(("undefined segment passed to strseg()!\n"));
+    return("??");
+    }
+}
+
+
+
+
+  void
+BX_CPU_C::write_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 1);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 1, BX_WRITE);
+
+  // all checks OK
+  access_linear(laddr, 1, CPL==3, BX_WRITE, (void *) data);
+}
+
+  void
+BX_CPU_C::write_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 2);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 2, BX_WRITE);
+
+  // all checks OK
+  access_linear(laddr, 2, CPL==3, BX_WRITE, (void *) data);
+}
+
+  void
+BX_CPU_C::write_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 4);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 4, BX_WRITE);
+
+  // all checks OK
+  access_linear(laddr, 4, CPL==3, BX_WRITE, (void *) data);
+}
+
+  void
+BX_CPU_C::read_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  read_virtual_checks(seg, offset, 1);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 1, BX_READ);
+
+  // all checks OK
+  access_linear(laddr, 1, CPL==3, BX_READ, (void *) data);
+}
+
+
+  void
+BX_CPU_C::read_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  read_virtual_checks(seg, offset, 2);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 2, BX_READ);
+
+  // all checks OK
+  access_linear(laddr, 2, CPL==3, BX_READ, (void *) data);
+}
+
+
+  void
+BX_CPU_C::read_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  read_virtual_checks(seg, offset, 4);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 4, BX_READ);
+
+  // all checks OK
+  access_linear(laddr, 4, CPL==3, BX_READ, (void *) data);
+}
+
+//////////////////////////////////////////////////////////////
+// special Read-Modify-Write operations                     //
+// address translation info is kept across read/write calls //
+//////////////////////////////////////////////////////////////
+
+  void
+BX_CPU_C::read_RMW_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 1);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 1, BX_READ);
+
+  // all checks OK
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg)
+    access_linear(laddr, 1, CPL==3, BX_RW, (void *) data);
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+    BX_INSTR_LIN_READ(laddr, laddr, 1);
+    BX_INSTR_LIN_WRITE(laddr, laddr, 1);
+    BX_CPU_THIS_PTR mem->read_physical(this, laddr, 1, (void *) data);
+    }
+}
+
+
+  void
+BX_CPU_C::read_RMW_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 2);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 2, BX_READ);
+
+  // all checks OK
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg)
+    access_linear(laddr, 2, CPL==3, BX_RW, (void *) data);
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+    BX_INSTR_LIN_READ(laddr, laddr, 2);
+    BX_INSTR_LIN_WRITE(laddr, laddr, 2);
+    BX_CPU_THIS_PTR mem->read_physical(this, laddr, 2, data);
+    }
+}
+
+  void
+BX_CPU_C::read_RMW_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+  Bit32u laddr;
+  bx_segment_reg_t *seg;
+
+  seg = &BX_CPU_THIS_PTR sregs[s];
+  write_virtual_checks(seg, offset, 4);
+
+  laddr = seg->cache.u.segment.base + offset;
+  BX_INSTR_MEM_DATA(laddr, 4, BX_READ);
+
+  // all checks OK
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg)
+    access_linear(laddr, 4, CPL==3, BX_RW, (void *) data);
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+    BX_INSTR_LIN_READ(laddr, laddr, 4);
+    BX_INSTR_LIN_WRITE(laddr, laddr, 4);
+    BX_CPU_THIS_PTR mem->read_physical(this, laddr, 4, data);
+    }
+}
+
+  void
+BX_CPU_C::write_RMW_virtual_byte(Bit8u val8)
+{
+  BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 1, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    // BX_CPU_THIS_PTR address_xlation.pages must be 1
+    BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
+    }
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
+    }
+}
+
+  void
+BX_CPU_C::write_RMW_virtual_word(Bit16u val16)
+{
+  BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 2, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
+      }
+    else {
+#ifdef BX_LITTLE_ENDIAN
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
+                            &val16);
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
+                            ((Bit8u *) &val16) + 1);
+#else
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
+                            ((Bit8u *) &val16) + 1);
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
+                            &val16);
+#endif
+      }
+    }
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
+    }
+}
+
+  void
+BX_CPU_C::write_RMW_virtual_dword(Bit32u val32)
+{
+  BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 4, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
+      }
+    else {
+#ifdef BX_LITTLE_ENDIAN
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                            BX_CPU_THIS_PTR address_xlation.len1,
+                            &val32);
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                            BX_CPU_THIS_PTR address_xlation.len2,
+                            ((Bit8u *) &val32) + BX_CPU_THIS_PTR address_xlation.len1);
+#else
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                            BX_CPU_THIS_PTR address_xlation.len1,
+                            ((Bit8u *) &val32) + (4 - BX_CPU_THIS_PTR address_xlation.len1));
+      BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                            BX_CPU_THIS_PTR address_xlation.len2,
+                            &val32);
+#endif
+      }
+    }
+  else
+#endif
+    {
+    BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
+    }
+}
diff --git a/sid/component/bochs/cpu/apic.cc b/sid/component/bochs/cpu/apic.cc
new file mode 100644 (file)
index 0000000..8446078
--- /dev/null
@@ -0,0 +1,708 @@
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#include <assert.h>
+
+#define LOG_THIS this->
+
+bx_generic_apic_c *apic_index[APIC_MAX_ID];
+
+bx_generic_apic_c::bx_generic_apic_c () 
+{
+  id = APIC_UNKNOWN_ID;
+  setprefix("[APIC?]");
+  settype(APICLOG);
+  hwreset ();
+}
+
+bx_generic_apic_c::~bx_generic_apic_c () 
+{
+}
+
+// init is called during RESET and when an INIT message is delivered.
+void bx_generic_apic_c::init ()
+{
+}
+
+void bx_generic_apic_c::set_base (Bit32u newbase)
+{
+  BX_INFO(("relocate APIC id=%d to %8x\n", id, newbase));
+  base_addr = newbase;
+}
+
+void bx_generic_apic_c::set_id (Bit8u newid) {
+  // update apic_index
+  if (id != APIC_UNKNOWN_ID) {
+    BX_ASSERT (id < APIC_MAX_ID);
+    if (apic_index[id] != this)
+      BX_PANIC(("inconsistent APIC id table\n"));
+    apic_index[id] = NULL;
+  }
+  id = newid;
+  if (apic_index[id] != NULL)
+    BX_PANIC(("duplicate APIC id assigned\n"));
+  apic_index[id] = this;
+}
+
+char *
+bx_generic_apic_c::get_name () {
+  BX_PANIC(("get_name called on bx_generic_apic_c base class\n"));
+  return NULL;
+}
+
+Boolean
+bx_generic_apic_c::is_selected (Bit32u addr, Bit32u len)
+{
+  if ((addr & ~0xfff) == get_base ()) {
+    if ((addr & 0xf != 0) || (len != 4))
+      BX_INFO(("warning: misaligned or wrong-size APIC write\n"));
+    return true;
+  }
+  return false;
+}
+
+void
+bx_generic_apic_c::read (Bit32u addr, void *data, unsigned len)
+{
+  if ((addr & ~0xf) != ((addr+len-1) & ~0xf))
+    BX_PANIC(("APIC read spans 32-bit boundary\n"));
+  Bit32u value;
+  read_aligned (addr, &value, 4);
+  if ((addr&3) == 0) {
+    *((Bit32u *)data) = value;
+    return;
+  }
+  // handle partial word read, independent of endian-ness.
+  Bit8u bytes[4];
+  bytes[0] = value & 0xff;
+  bytes[1] = (value >> 8) & 0xff;
+  bytes[2] = (value >> 16) & 0xff;
+  bytes[3] = (value >> 24) & 0xff;
+  Bit8u *p1 = bytes+(addr&3);
+  Bit8u *p2 = (Bit8u *)data;
+  for (int i=0; i<len; i++) {
+    if (bx_dbg.apic)
+      BX_INFO(("apic: Copying byte %02x\n", (unsigned int) *p1));
+    *p2++ = *p1++;
+  }
+}
+
+void bx_generic_apic_c::read_aligned (Bit32u address, Bit32u *data, unsigned len)
+{
+  BX_PANIC(("read_aligned not implemented in base class bx_generic_apic_c\n"));
+}
+
+void bx_generic_apic_c::write(Bit32u address, Bit32u *value, unsigned len)
+{
+  BX_PANIC(("write not implemented in base class bx_generic_apic_c\n"));
+}
+
+void bx_generic_apic_c::startup_msg (Bit32u vector)
+{
+  BX_PANIC(("startup message sent to an I/O APIC\n"));
+}
+
+void bx_generic_apic_c::trigger_irq (unsigned num, unsigned from)
+{
+  BX_PANIC(("trigger_irq called on base class\n"));
+}
+
+void bx_generic_apic_c::untrigger_irq (unsigned num, unsigned from)
+{
+  BX_PANIC(("untrigger_irq called on base class\n"));
+}
+
+Boolean bx_generic_apic_c::match_logical_addr (Bit8u address) {
+  BX_PANIC(("match_logical_addr called on base class\n"));
+  return false;
+}
+
+bx_apic_type_t bx_generic_apic_c::get_type () {
+  BX_PANIC(("get_type called on base class"));
+  return APIC_TYPE_NONE;
+}
+
+Bit32u
+bx_generic_apic_c::get_delivery_bitmask (Bit8u dest, Bit8u dest_mode)
+{
+  int mask = 0;
+  if (dest_mode == 0) {
+    // physical 
+    if (dest < APIC_MAX_ID)
+      mask = 1<<dest;
+    else if (dest == 0xff) {
+      // physical destination 0xff means everybody. only local APICs can
+      // send this.
+      BX_ASSERT (get_type () == APIC_TYPE_LOCAL_APIC);
+      mask = 0xff; 
+    } else BX_PANIC(("bx_generic_apic_c::deliver: illegal physical destination %02x\n", dest));
+  } else {
+    // logical destination. call match_logical_addr for each APIC.
+    if (dest == 0) return 0;
+    for (int i=0; i<APIC_MAX_ID; i++) {
+      if (apic_index[i] && apic_index[i]->match_logical_addr(dest))
+       mask |= (1<<i);
+    }
+  }
+  if (bx_dbg.apic)
+    BX_INFO(("generic::get_delivery_bitmask returning 0x%04x\n", mask));
+  return mask;
+}
+
+Boolean
+bx_generic_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode)
+{
+  // return false if we can't deliver for any reason, so that the caller
+  // knows not to clear its IRR.
+  Bit32u deliver_bitmask = get_delivery_bitmask (dest, dest_mode);
+  // mask must include ONLY local APICs, or we will have problems.
+  if (!deliver_bitmask) {
+    if (bx_dbg.apic)
+                       BX_INFO(("deliver failed: no APICs in destination bitmask\n"));
+    return false;
+  }
+  switch (delivery_mode) {
+    case 0:  // fixed
+      break;
+    case 1:  // lowest priority of destinations
+      {
+       // find lowest priority of apics in the mask
+       int lowest_priority = 0x100, lowest_mask = -1;
+       for (int bit=0; bit<APIC_MAX_ID; bit++) {
+         if (deliver_bitmask & (1<<bit)) {
+           bx_local_apic_c *apic = (bx_local_apic_c *)apic_index[bit];
+           if (apic->get_ppr () < lowest_priority) {
+             lowest_priority = apic->get_ppr (); lowest_mask = 1<<bit;
+           }
+         }
+       }
+       deliver_bitmask = lowest_mask;
+       BX_ASSERT (deliver_bitmask >= 0);
+      }
+      break;
+    case 5:  // INIT
+      {
+       for (int bit=0; bit<APIC_MAX_ID; bit++) {
+         if (deliver_bitmask & (1<<bit)) 
+           apic_index[bit]->init ();
+       }
+      }
+      return true;
+    case 6:  // Start Up (local apic only)
+      BX_ASSERT (get_type () == APIC_TYPE_LOCAL_APIC);
+      for (int bit=0; bit<APIC_MAX_ID; bit++)
+       if (deliver_bitmask & (1<<bit))
+         apic_index[bit]->startup_msg (vector);
+      return true;
+    case 2:  // SMI
+    case 3:  // reserved
+    case 4:  // NMI
+    case 7:  // ExtINT (I/O apic only)
+    default:
+      BX_PANIC(("APIC delivery mode %d not implemented\n", delivery_mode));
+  }
+  // Fixed delivery mode
+  if (bx_dbg.apic)
+    BX_INFO(("delivering vector=0x%02x to bitmask=%04x\n", (int)vector, deliver_bitmask));
+  for (int bit=0; bit<APIC_MAX_ID; bit++) {
+    if (deliver_bitmask & (1<<bit)) {
+      if (apic_index[bit] == NULL)
+       BX_INFO(("IOAPIC: delivering int0x%x to nonexistent id=%d!\n", (unsigned)vector, bit));
+      else {
+        if (bx_dbg.apic)
+         BX_INFO(("IOAPIC: delivering int0x%x to apic#%d\n", (unsigned)vector, bit));
+       apic_index[bit]->trigger_irq (vector, id);
+      }
+    }
+  }
+  return true;
+}
+
+bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu)
+  : bx_generic_apic_c ()
+{
+  char buffer[16];
+  cpu = mycpu;
+  hwreset ();
+}
+
+void
+bx_local_apic_c::hwreset () 
+{
+  /* same as INIT but also sets arbitration ID and APIC ID */
+  init ();
+  /* since id is set explicitly by the function that creates the CPU
+     object, do not mess around with it */
+  // id = APIC_UNKNOWN_ID;
+  arb_id = id;
+}
+
+void
+bx_local_apic_c::init ()
+{
+  bx_generic_apic_c::init ();
+  BX_INFO(("local apic in %s initializing\n", 
+      (cpu && cpu->name) ? cpu->name : "?"));
+  // default address for a local APIC, can be moved
+  base_addr = 0xfee00000;
+  err_status = 0;
+  log_dest = 0;
+  dest_format = 0xff;
+  for (int bit=0; bit<BX_LOCAL_APIC_MAX_INTS; bit++) {
+    irr[bit] = isr[bit] = tmr[bit] = 0;
+  }
+  icr_high = icr_low = log_dest = task_priority = 0;
+  spurious_vec = 0xff;   // software disabled (bit 8)
+}
+
+BX_CPU_C 
+*bx_local_apic_c::get_cpu (Bit8u id)
+{
+  BX_ASSERT (id < APIC_MAX_ID);
+  return cpu;
+}
+
+bx_local_apic_c::~bx_local_apic_c(void)
+{
+  // nothing for now
+}
+
+void bx_local_apic_c::set_id (Bit8u newid) {
+  bx_generic_apic_c::set_id (newid);
+  sprintf (cpu->name, "CPU apicid=%02x", (Bit32u)id);
+  if (id >= 0 && id <= 15) {
+    char buffer[16];
+    sprintf (buffer, "[APIC%x]", id);
+    setprefix(buffer);
+    settype(CPU0LOG + id);
+    sprintf (buffer, "[CPU%x]", id);
+    cpu->setprefix (buffer);
+  } else {
+    BX_INFO (("naming convention for apics requires id=0-15 only"));
+  }
+  if(BX_CPU_LEVEL<2)
+    BX_INFO(( "8086\n" ));
+  else
+    BX_INFO(( "80%d86\n", BX_CPU_LEVEL ));
+}
+
+char *
+bx_local_apic_c::get_name()
+{
+  return cpu->name;
+}
+
+void bx_local_apic_c::set_divide_configuration (Bit32u value) {
+  BX_ASSERT (value == (value & 0x0b));
+  // move bit 3 down to bit 0.
+  value = ((value & 8) >> 1) | (value & 3);
+  BX_ASSERT (value >= 0 && value <= 7);
+  timer_divide_factor = (value==7)? 1 : (2 << value);
+  if (bx_dbg.apic)
+    BX_INFO(("%s: set timer divide factor to %d\n", cpu->name, timer_divide_factor));
+}
+
+void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len)
+{
+  assert (len == 4);
+  if (bx_dbg.apic)
+    BX_INFO(("%s: write %08x to APIC address %08x\n", cpu->name, *data, addr));
+  //assert (!(addr & 0xf));
+  addr &= 0xff0;
+  switch (addr) {
+    case 0x20: // local APIC id
+      id = ((*data)>>24) & 0xf;
+      break;
+    case 0x80: // task priority
+      task_priority = *data & 0xff;
+      break;
+    case 0xb0: // EOI
+      {
+       if (bx_dbg.apic)
+         BX_INFO(("%s: Wrote 0x%04x to EOI\n", cpu->name, *data));
+       int vec = highest_priority_int (isr);
+       if (vec < 0) {
+         BX_INFO(("EOI written without any bit in ISR\n"));
+       } else {
+         if (bx_dbg.apic)
+           BX_INFO(("%s: local apic received EOI, hopefully for vector 0x%02x\n", cpu->name, vec));
+         isr[vec] = 0; 
+         service_local_apic ();
+       }
+       if (bx_dbg.apic)
+         print_status ();
+      }
+      break;
+    case 0xd0: // logical destination
+      log_dest = (*data >> 24) & 0xff;
+      break;
+    case 0xe0: // destination format
+      dest_format = (*data >> 28) & 0xf;
+      break;
+    case 0xf0: // spurious interrupt vector
+      spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0);
+      break;
+    case 0x280: // error status reg
+      // Here's what the IA-devguide-3 says on p.7-45:
+      // The ESR is a read/write register and is reset after being written to
+      // by the processor. A write to the ESR must be done just prior to
+      // reading the ESR to allow the register to be updated.
+      // This doesn't seem clear.  If the write clears the register, then
+      // wouldn't you always read zero?  Otherwise, what does the write do?
+      err_status = 0;
+      break;
+    case 0x300: // interrupt command reg 0-31
+      {
+       icr_low = *data & ~(1<<12);  // force delivery status bit = 0 (idle)
+       int dest = (icr_high >> 24) & 0xff;
+       int trig_mode = (icr_low >> 15) & 1;
+       int level = (icr_low >> 14) & 1;
+       int dest_mode = (icr_low >> 11) & 1;
+       int delivery_mode = (icr_low >> 8) & 7;
+       int vector = (icr_low & 0xff);
+       //
+       // deliver will call get_delivery_bitmask to decide who to send to.
+       // This local_apic class redefines get_delivery_bitmask to 
+       // implement the destination shorthand field, which doesn't exist
+       // for all APICs.
+       Boolean accepted = 
+          deliver (dest, dest_mode, delivery_mode, vector, level, trig_mode);
+       if (!accepted)
+         err_status |= APIC_ERR_TX_ACCEPT_ERR;
+      }
+      break;
+    case 0x310: // interrupt command reg 31-63
+      icr_high = *data & 0xff000000;
+      break;
+    case 0x320: // LVT Timer Reg
+      lvt[APIC_LVT_TIMER] = *data & 0x310ff;
+      break;
+    case 0x330: // LVT Thermal Monitor
+      lvt[APIC_LVT_THERMAL] = *data & 0x117ff;
+      break;
+    case 0x340: // LVT Performance Counter
+      lvt[APIC_LVT_PERFORM] = *data & 0x117ff;
+      break;
+    case 0x350: // LVT LINT0 Reg
+      lvt[APIC_LVT_LINT0] = *data & 0x1f7ff;
+      break;
+    case 0x360: // LVT Lint1 Reg
+      lvt[APIC_LVT_LINT1] = *data & 0x1f7ff;
+      break;
+    case 0x370: // LVT Error Reg
+      lvt[APIC_LVT_ERROR] = *data & 0x117ff;
+      break;
+    case 0x380: // initial count for timer
+      timer_initial = *data;
+      // This should trigger the counter to start.  If already started,
+      // restart from the new start value.
+      timer_current = timer_initial;
+      timer_active = true;
+      timer_divide_counter = 0;
+      break;
+    case 0x3e0: // timer divide configuration
+      // only bits 3, 1, and 0 are writable
+      timer_divconf = *data & 0xb;
+      set_divide_configuration (timer_divconf);
+      break;
+    /* all read-only registers go here */
+    case 0x30: // local APIC version
+    case 0x90: // arbitration priority
+    case 0xa0: // processor priority
+    // ISRs not writable
+    case 0x100: case 0x110: case 0x120: case 0x130:
+    case 0x140: case 0x150: case 0x160: case 0x170:
+    // TMRs not writable
+    case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+    case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+    // IRRs not writable
+    case 0x200: case 0x210: case 0x220: case 0x230:
+    case 0x240: case 0x250: case 0x260: case 0x270:
+      // current count for timer
+    case 0x390:
+      // all read-only registers should fall into this line
+      BX_INFO(("warning: write to read-only APIC register 0x%02x\n", addr));
+      break;
+    default:
+      err_status |= APIC_ERR_ILLEGAL_ADDR;
+      // but for now I want to know about it in case I missed some.
+      BX_PANIC(("APIC register %08x not implemented\n", addr));
+  }
+}
+
+void bx_local_apic_c::startup_msg (Bit32u vector)
+{
+  if (cpu->debug_trap & 0x80000000) {
+    cpu->debug_trap &= ~0x80000000;
+    cpu->eip = 0;
+    cpu->load_seg_reg (&cpu->sregs[BX_SEG_REG_CS], vector*0x100);
+    BX_INFO(("%s started up at 0x%x by APIC\n", cpu->name, cpu->eip));
+  } else {
+    BX_INFO(("%s started up by APIC, but was not halted at the time\n", cpu->name));
+  }
+}
+
+void bx_local_apic_c::read_aligned (Bit32u addr, Bit32u *data, unsigned len)
+{
+  assert (len == 4);
+  *data = 0;  // default value for unimplemented registers
+  Bit32u addr2 = addr & 0xff0;
+  switch (addr2) {
+  case 0x20: // local APIC id
+    *data = (id) << 24; break;
+  case 0x30: // local APIC version
+    *data = 0x00170011; break;
+  case 0x80: // task priority
+    *data = task_priority & 0xff; break;
+  case 0x90: // arbitration priority
+    *data = get_apr (); break;
+  case 0xa0: // processor priority
+    *data = get_ppr (); break;
+  case 0xb0: // EOI
+    BX_PANIC(("EOI register not writable\n"));
+    break;
+  case 0xd0: // logical destination
+    *data = (log_dest & 0xff) << 24; break;
+  case 0xe0: // destination format
+    *data = ((dest_format & 0xf) << 24) | 0x0fffffff; break;
+  case 0xf0: // spurious interrupt vector
+    *data = spurious_vec; break;
+  // ISRs not writable
+  case 0x100: case 0x110: case 0x120: case 0x130:
+  case 0x140: case 0x150: case 0x160: case 0x170:
+  case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+  case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+  case 0x200: case 0x210: case 0x220: case 0x230:
+  case 0x240: case 0x250: case 0x260: case 0x270:
+    *data = 0;
+    BX_INFO(("reading ISR,TMR,IRR not implemented\n"));
+    break;
+  case 0x280: // error status reg
+    *data = err_status; break;
+  case 0x300: // interrupt command reg 0-31
+    *data = icr_low; break;
+  case 0x310: // interrupt command reg 31-63
+    *data = icr_high; break;
+  case 0x320: // LVT Timer Reg
+  case 0x330: // LVT Thermal Monitor
+  case 0x340: // LVT Performance Counter
+  case 0x350: // LVT LINT0 Reg
+  case 0x360: // LVT Lint1 Reg
+  case 0x370: // LVT Error Reg
+    {
+      int index = (addr2 - 0x320) >> 4;
+      *data = lvt[index];
+      break;
+    }
+  case 0x380: // initial count for timer
+    *data = timer_initial; break;
+  case 0x390: // current count for timer
+    *data = timer_current; break;
+  case 0x3e0: // timer divide configuration
+    *data = timer_divconf; break;
+  default:
+    BX_INFO(("APIC register %08x not implemented\n", addr));
+  }
+  if (bx_dbg.apic)
+    BX_INFO(("%s: read from APIC address %08x = %08x\n", cpu->name, addr, *data));
+}
+
+int 
+bx_local_apic_c::highest_priority_int (Bit8u *array)
+{
+  for (int i=0; i<BX_LOCAL_APIC_MAX_INTS; i++)
+    if (array[i]) return i;
+  return -1;
+}
+
+void bx_local_apic_c::service_local_apic ()
+{
+  if (bx_dbg.apic) {
+    BX_INFO(("service_local_apic()\n"));
+    print_status ();
+  }
+  if (cpu->INTR) return;  // INTR already up; do nothing
+  // find first interrupt in irr.
+  int first_irr = highest_priority_int (irr);
+  int first_isr = highest_priority_int (isr);
+  if (first_irr < 0) return;   // no interrupts, leave INTR=0
+  if (first_isr >= 0 && first_irr >= first_isr) {
+    if (bx_dbg.apic)
+      BX_INFO(("local apic (%s): not delivering int%02x because int%02x is in service\n", cpu->name, first_irr, first_isr));
+    return;
+  }
+  // interrupt has appeared in irr.  raise INTR.  When the CPU
+  // acknowledges, we will run highest_priority_int again and
+  // return it.
+  if (bx_dbg.apic)
+    BX_INFO(("service_local_apic(): setting INTR=1 for vector 0x%02x\n", first_irr));
+  cpu->set_INTR (1);
+  cpu->int_from_local_apic = 1;
+}
+
+void bx_local_apic_c::trigger_irq (unsigned vector, unsigned from)
+{
+  if (bx_dbg.apic)
+    BX_INFO(("Local apic on %s: trigger interrupt vector=0x%x\n", cpu->name, vector));
+  irr[vector] = 1;
+  service_local_apic ();
+}
+
+void bx_local_apic_c::untrigger_irq (unsigned vector, unsigned from)
+{
+  if (bx_dbg.apic)
+    BX_INFO(("Local apic on %s: untrigger interrupt vector=0x%x\n", cpu->name, vector));
+  // hardware says "no more".  clear the bit.  If the CPU hasn't yet
+  // acknowledged the interrupt, it will never be serviced.
+  BX_ASSERT (irr[vector] == 1);
+  irr[vector] = 0;
+  if (bx_dbg.apic) print_status ();
+}
+
+Bit8u
+bx_local_apic_c::acknowledge_int ()
+{
+  // CPU calls this when it is ready to service one interrupt
+  if (!cpu->INTR)
+    BX_PANIC(("%s: acknowledged an interrupt, but INTR=0\n", cpu->name));
+  BX_ASSERT (cpu->int_from_local_apic);
+  int vector = highest_priority_int (irr);
+  BX_ASSERT (irr[vector] == 1);
+  if (bx_dbg.apic)
+    BX_INFO(("%s: acknowledge_int returning vector 0x%x\n", cpu->name, vector));
+  // currently isr never gets cleared, so no point
+  //BX_ASSERT (isr[vector] == 0);
+  irr[vector] = 0;
+  isr[vector] = 1;
+  if (bx_dbg.apic) {
+    BX_INFO(("Status after setting isr:\n"));
+    print_status ();
+  }
+  cpu->INTR = 0;
+  cpu->int_from_local_apic = 0;
+  service_local_apic ();  // will set INTR again if another is ready
+  return vector;
+}
+
+void bx_local_apic_c::print_status () {
+  BX_INFO(("%s local apic: status is {:\n", cpu->name));
+  for (int vec=0; vec<BX_LOCAL_APIC_MAX_INTS; vec++) {
+    if (irr[vec] || isr[vec]) {
+      BX_INFO(("vec 0x%x: irr=%d, isr=%d\n", vec, (int)irr[vec], (int)isr[vec]));
+    }
+  }
+  BX_INFO(("}\n", cpu->name));
+}
+
+Boolean bx_local_apic_c::match_logical_addr (Bit8u address) 
+{
+  if (dest_format != 0xf) {
+    BX_PANIC(("bx_local_apic_c::match_logical_addr: cluster model addressing not implemented"));
+  }
+  // if all address bits are 1, send to all local APICs. SDG3:7-27.
+  if (address == 0xff) {
+    if (bx_dbg.apic) BX_INFO(("%s: MDA=0xff matches everybody\n", cpu->name));
+    return true;
+  }
+  Boolean match = ((address & log_dest) != 0);
+  if (bx_dbg.apic) {
+    BX_INFO(("%s: comparing MDA %02x to my LDR %02x -> %s\n", cpu->name,
+      address, log_dest, match? "Match" : "Not a match"));
+  }
+  return match;
+}
+
+Bit32u 
+bx_local_apic_c::get_delivery_bitmask (Bit8u dest, Bit8u dest_mode)
+{
+  int dest_shorthand = (icr_low >> 18) & 3;
+  Bit32u all_mask = (1<<APIC_MAX_ID) - 1;
+  Bit32u mask;
+  switch (dest_shorthand) {
+  case 0:  // no shorthand, use real destination value
+    return bx_generic_apic_c::get_delivery_bitmask (dest, dest_mode);
+  case 1:  // self
+    return (1<<id);
+  case 2:  // all including self
+    mask = all_mask;
+  case 3:  // all but self
+    mask = all_mask & ~(1<<id);
+  }
+  // prune nonexistents and I/O apics from list
+  for (int bit=0; bit<APIC_MAX_ID; bit++) {
+    if (!apic_index[bit] 
+       || (apic_index[bit]->get_type () != APIC_TYPE_LOCAL_APIC))
+      mask &= ~(1<<bit);
+  }
+  if (bx_dbg.apic)
+    BX_INFO(("local::get_delivery_bitmask returning 0x%04x\n", mask));
+  return mask;
+}
+
+Bit8u bx_local_apic_c::get_ppr ()
+{
+  if (bx_dbg.apic)
+               BX_INFO(("WARNING: Local APIC Processor Priority not implemented, returning 0\n"));
+  // should look at TPR, vector of highest priority isr, etc.
+  return 0;
+}
+
+
+Bit8u bx_local_apic_c::get_apr ()
+{
+  if (bx_dbg.apic)
+               BX_INFO(("WARNING: Local APIC Arbitration Priority not implemented, returning 0\n"));
+  // should look at TPR, vector of highest priority isr, etc.
+  return 0;
+}
+
+
+void
+bx_local_apic_c::periodic (Bit32u usec_delta)
+{
+  if (!timer_active) return;
+  if (bx_dbg.apic)
+    BX_INFO(("%s: bx_local_apic_c::periodic called with %d usec\n",
+      cpu->name, usec_delta));
+  // unless usec_delta is guaranteed to be a multiple of 128, I can't
+  // just divide usec_delta by the divide-down value.  Instead, it will
+  // have a similar effect to implement the divide-down by ignoring
+  // some fraction of calls to this function.  This can be improved if
+  // more granularity is important.
+  timer_divide_counter = (timer_divide_counter + 1) % timer_divide_factor;
+  if (timer_divide_counter != 0) return;
+  if (timer_current > usec_delta) {
+    timer_current -= usec_delta;
+    //BX_INFO(("%s: local apic timer is now 0x%08x\n", cpu->name, timer_current));
+    return;
+  }
+  // timer reached zero since the last call to periodic.
+  Bit32u timervec = lvt[APIC_LVT_TIMER];
+  if (timervec & 0x20000) {
+    // periodic mode.  Always trigger the interrupt when we reach zero.
+    trigger_irq (timervec & 0xff, id);
+    if (timer_initial == 0) {
+      usec_delta = 0;
+      timer_current = 0;
+    } else {
+      // timer_initial might be smaller than usec_delta.  I can't trigger
+      // multiple interrupts, so just try to get the timer_current right.
+      while (usec_delta > timer_initial)
+       usec_delta -= timer_initial;
+      timer_current = timer_current + timer_initial - usec_delta;
+      // sanity check. all these are unsigned so I can't check for
+      // negative timer_current.
+      BX_ASSERT ((timer_current + timer_initial) >= usec_delta);
+    }
+    if (bx_dbg.apic)
+      BX_INFO(("%s: local apic timer (periodic) triggered int, reset counter to 0x%08x\n", cpu->name, timer_current));
+  } else {
+    // one-shot mode
+    timer_current = 0;
+    if (timer_active) {
+      trigger_irq (timervec & 0xff, id);
+      timer_active = false;
+      if (bx_dbg.apic)
+        BX_INFO(("%s: local apic timer (one-shot) triggered int\n", cpu->name));
+    }
+  }
+}
diff --git a/sid/component/bochs/cpu/arith16.cc b/sid/component/bochs/cpu/arith16.cc
new file mode 100644 (file)
index 0000000..336a5af
--- /dev/null
@@ -0,0 +1,811 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::INC_RX(BxInstruction_t *i)
+{
+  Bit16u rx;
+
+  rx = ++ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+  SET_FLAGS_OSZAP_16(0, 0, rx, BX_INSTR_INC16);
+}
+
+  void
+BX_CPU_C::DEC_RX(BxInstruction_t *i)
+{
+  Bit16u rx;
+
+  rx = -- BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+  SET_FLAGS_OSZAP_16(0, 0, rx, BX_INSTR_DEC16);
+}
+
+
+  void
+BX_CPU_C::ADD_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, sum_16;
+
+
+    /* op2_16 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    sum_16 = op1_16 + op2_16;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, sum_16);
+      }
+    else {
+      write_virtual_word(i->seg, i->rm_addr, &sum_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+
+  void
+BX_CPU_C::ADD_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, sum_16;
+
+
+    /* op1_16 is a register, i->rm_addr is an index of a register */
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    sum_16 = op1_16 + op2_16;
+    /* now write sum back to destination */
+
+    BX_WRITE_16BIT_REG(i->nnn, sum_16);
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+
+  void
+BX_CPU_C::ADD_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, sum_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    sum_16 = op1_16 + op2_16;
+
+    /* now write sum back to destination */
+    AX = sum_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+  void
+BX_CPU_C::ADC_EwGw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op2_16, op1_16, sum_16;
+
+  temp_CF = get_CF();
+
+
+
+
+    /* op2_16 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    sum_16 = op1_16 + op2_16 + temp_CF;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, sum_16);
+      }
+    else {
+      write_RMW_virtual_word(sum_16);
+      }
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::ADC_GwEw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op1_16, op2_16, sum_16;
+
+  temp_CF = get_CF();
+
+
+    /* op1_16 is a register, i->rm_addr is an index of a register */
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    sum_16 = op1_16 + op2_16 + temp_CF;
+
+    /* now write sum back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, sum_16);
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+                             temp_CF);
+}
+
+
+  void
+BX_CPU_C::ADC_AXIw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op1_16, op2_16, sum_16;
+
+  temp_CF = get_CF();
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    sum_16 = op1_16 + op2_16 + temp_CF;
+
+    /* now write sum back to destination */
+    AX = sum_16;
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+                           temp_CF);
+}
+
+
+
+
+  void
+BX_CPU_C::SBB_EwGw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op2_16, op1_16, diff_16;
+
+
+  temp_CF = get_CF();
+
+
+    /* op2_16 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - (op2_16 + temp_CF);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, diff_16);
+      }
+    else {
+      write_RMW_virtual_word(diff_16);
+      }
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_GwEw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    Bit16u op1_16, op2_16, diff_16;
+
+
+    /* op1_16 is a register, i->rm_addr is an index of a register */
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    diff_16 = op1_16 - (op2_16 + temp_CF);
+
+    /* now write diff back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, diff_16);
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_AXIw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op1_16, op2_16, diff_16;
+
+  temp_CF = get_CF();
+
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    diff_16 = op1_16 - (op2_16 + temp_CF);
+
+    /* now write diff back to destination */
+    AX = diff_16;
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+                              temp_CF);
+}
+
+
+
+  void
+BX_CPU_C::SBB_EwIw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op2_16, op1_16, diff_16;
+
+  temp_CF = get_CF();
+
+
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - (op2_16 + temp_CF);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, diff_16);
+      }
+    else {
+      write_RMW_virtual_word(diff_16);
+      }
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SUB_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, diff_16;
+
+
+    /* op2_16 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, diff_16);
+      }
+    else {
+      write_RMW_virtual_word(diff_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+
+  void
+BX_CPU_C::SUB_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, diff_16;
+
+
+    /* op1_16 is a register, i->rm_addr is an index of a register */
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    /* now write diff back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, diff_16);
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+  void
+BX_CPU_C::SUB_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, diff_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    diff_16 = op1_16 - op2_16;
+
+
+    /* now write diff back to destination */
+    AX = diff_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+
+  void
+BX_CPU_C::CMP_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, diff_16;
+
+
+    /* op2_16 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+  void
+BX_CPU_C::CMP_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, diff_16;
+
+
+    /* op1_16 is a register, i->rm_addr is an index of a register */
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+  void
+BX_CPU_C::CMP_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, diff_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    diff_16 = op1_16 - op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+  void
+BX_CPU_C::CBW(BxInstruction_t *i)
+{
+  /* CBW: no flags are effected */
+
+  AX = (Bit8s) AL;
+}
+
+  void
+BX_CPU_C::CWD(BxInstruction_t *i)
+{
+  /* CWD: no flags are affected */
+
+    if (AX & 0x8000) {
+      DX = 0xFFFF;
+      }
+    else {
+      DX = 0x0000;
+      }
+}
+
+
+  void
+BX_CPU_C::XADD_EwGw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+    Bit16u op2_16, op1_16, sum_16;
+
+    /* XADD dst(r/m), src(r)
+     * temp <-- src + dst         | sum = op2 + op1
+     * src  <-- dst               | op2 = op1
+     * dst  <-- tmp               | op1 = sum
+     */
+
+    /* op2 is a register, i->rm_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    sum_16 = op1_16 + op2_16;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      // and write destination into source
+      // Note: if both op1 & op2 are registers, the last one written
+      //       should be the sum, as op1 & op2 may be the same register.
+      //       For example:  XADD AL, AL
+      BX_WRITE_16BIT_REG(i->nnn, op1_16);
+      BX_WRITE_16BIT_REG(i->rm, sum_16);
+      }
+    else {
+      write_RMW_virtual_word(sum_16);
+      /* and write destination into source */
+      BX_WRITE_16BIT_REG(i->nnn, op1_16);
+      }
+
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XADD16);
+#else
+  BX_PANIC(("XADD_EvGv: not supported on < 80486\n"));
+#endif
+}
+
+
+
+  void
+BX_CPU_C::ADD_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, sum_16;
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    sum_16 = op1_16 + op2_16;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, sum_16);
+      }
+    else {
+      write_RMW_virtual_word(sum_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+  void
+BX_CPU_C::ADC_EwIw(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+  Bit16u op2_16, op1_16, sum_16;
+
+  temp_CF = get_CF();
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    sum_16 = op1_16 + op2_16 + temp_CF;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, sum_16);
+      }
+    else {
+      write_RMW_virtual_word(sum_16);
+      }
+
+    SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SUB_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, diff_16;
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, diff_16);
+      }
+    else {
+      write_RMW_virtual_word(diff_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+  void
+BX_CPU_C::CMP_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, diff_16;
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = op1_16 - op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+
+  void
+BX_CPU_C::NEG_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16, diff_16;
+
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = 0 - op1_16;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, diff_16);
+      }
+    else {
+      write_RMW_virtual_word(diff_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, 0, diff_16, BX_INSTR_NEG16);
+}
+
+
+  void
+BX_CPU_C::INC_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    op1_16++;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+
+    SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_INC16);
+}
+
+
+  void
+BX_CPU_C::DEC_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    op1_16--;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+
+    SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_DEC16);
+}
+
+
+  void
+BX_CPU_C::CMPXCHG_EwGw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+    Bit16u op2_16, op1_16, diff_16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    diff_16 = AX - op1_16;
+
+    SET_FLAGS_OSZAPC_16(AX, op1_16, diff_16, BX_INSTR_CMP16);
+
+    if (diff_16 == 0) {  // if accumulator == dest
+      // ZF = 1
+      set_ZF(1);
+      // dest <-- src
+      op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+      if (i->mod == 0xc0) {
+        BX_WRITE_16BIT_REG(i->rm, op2_16);
+        }
+      else {
+        write_RMW_virtual_word(op2_16);
+        }
+      }
+    else {
+      // ZF = 0
+      set_ZF(0);
+      // accumulator <-- dest
+      AX = op1_16;
+      }
+
+#else
+  BX_PANIC(("CMPXCHG_EwGw:\n"));
+#endif
+}
diff --git a/sid/component/bochs/cpu/arith32.cc b/sid/component/bochs/cpu/arith32.cc
new file mode 100644 (file)
index 0000000..5212d48
--- /dev/null
@@ -0,0 +1,864 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::INC_ERX(BxInstruction_t *i)
+{
+  Bit32u erx;
+
+  erx = ++ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+  SET_FLAGS_OSZAP_32(0, 0, erx, BX_INSTR_INC32);
+}
+
+  void
+BX_CPU_C::DEC_ERX(BxInstruction_t *i)
+{
+  Bit32u erx;
+
+  erx = -- BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+  SET_FLAGS_OSZAP_32(0, 0, erx, BX_INSTR_DEC32);
+}
+
+
+
+
+  void
+BX_CPU_C::ADD_EdGd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, sum_32;
+
+    /* op2_32 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    sum_32 = op1_32 + op2_32;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, sum_32);
+      }
+    else {
+      write_RMW_virtual_dword(sum_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+
+  void
+BX_CPU_C::ADD_GdEd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, sum_32;
+
+    /* op1_32 is a register, i->rm_addr is an index of a register */
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    sum_32 = op1_32 + op2_32;
+
+    /* now write sum back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, sum_32);
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+
+  void
+BX_CPU_C::ADD_EAXId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, sum_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    sum_32 = op1_32 + op2_32;
+
+    /* now write sum back to destination */
+    EAX = sum_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+  void
+BX_CPU_C::ADC_EdGd(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, sum_32;
+
+    /* op2_32 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    sum_32 = op1_32 + op2_32 + temp_CF;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, sum_32);
+      }
+    else {
+      write_RMW_virtual_dword(sum_32);
+      }
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::ADC_GdEd(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, sum_32;
+
+    /* op1_32 is a register, i->rm_addr is an index of a register */
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    sum_32 = op1_32 + op2_32 + temp_CF;
+
+    /* now write sum back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, sum_32);
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+                             temp_CF);
+}
+
+
+  void
+BX_CPU_C::ADC_EAXId(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, sum_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    sum_32 = op1_32 + op2_32 + temp_CF;
+
+    /* now write sum back to destination */
+    EAX = sum_32;
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+                           temp_CF);
+}
+
+
+
+
+  void
+BX_CPU_C::SBB_EdGd(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    /* op2_32 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - (op2_32 + temp_CF);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, diff_32);
+      }
+    else {
+      write_RMW_virtual_dword(diff_32);
+      }
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_GdEd(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    /* op1_32 is a register, i->rm_addr is an index of a register */
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    diff_32 = op1_32 - (op2_32 + temp_CF);
+
+    /* now write diff back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, diff_32);
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_EAXId(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    diff_32 = op1_32 - (op2_32 + temp_CF);
+
+    /* now write diff back to destination */
+    EAX = diff_32;
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+                              temp_CF);
+}
+
+
+
+  void
+BX_CPU_C::SBB_EdId(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - (op2_32 + temp_CF);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, diff_32);
+      }
+    else {
+      write_RMW_virtual_dword(diff_32);
+      }
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SUB_EdGd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    /* op2_32 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, diff_32);
+      }
+    else {
+      write_RMW_virtual_dword(diff_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+
+  void
+BX_CPU_C::SUB_GdEd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    /* op1_32 is a register, i->rm_addr is an index of a register */
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    /* now write diff back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, diff_32);
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+  void
+BX_CPU_C::SUB_EAXId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    diff_32 = op1_32 - op2_32;
+
+    /* now write diff back to destination */
+    EAX = diff_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+
+  void
+BX_CPU_C::CMP_EdGd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    /* op2_32 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+  void
+BX_CPU_C::CMP_GdEd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    /* op1_32 is a register, i->rm_addr is an index of a register */
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+  void
+BX_CPU_C::CMP_EAXId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, diff_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    diff_32 = op1_32 - op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+  void
+BX_CPU_C::CWDE(BxInstruction_t *i)
+{
+  /* CBW: no flags are effected */
+
+    EAX = (Bit16s) AX;
+}
+
+  void
+BX_CPU_C::CDQ(BxInstruction_t *i)
+{
+  /* CWD: no flags are affected */
+
+    if (EAX & 0x80000000) {
+      EDX = 0xFFFFFFFF;
+      }
+    else {
+      EDX = 0x00000000;
+      }
+}
+
+// Some info on the opcodes at {0F,A6} and {0F,A7}
+// On 386 steps A0-B0:
+//   {OF,A6} = XBTS
+//   {OF,A7} = IBTS
+// On 486 steps A0-B0:
+//   {OF,A6} = CMPXCHG 8
+//   {OF,A7} = CMPXCHG 16|32
+//
+// On 486 >= B steps, and further processors, the
+// CMPXCHG instructions were moved to opcodes:
+//   {OF,B0} = CMPXCHG 8
+//   {OF,B1} = CMPXCHG 16|32
+
+  void
+BX_CPU_C::CMPXCHG_XBTS(BxInstruction_t *i)
+{
+  BX_INFO(("CMPXCHG_XBTS:\n"));
+  UndefinedOpcode(i);
+}
+
+  void
+BX_CPU_C::CMPXCHG_IBTS(BxInstruction_t *i)
+{
+  BX_INFO(("CMPXCHG_IBTS:\n"));
+  UndefinedOpcode(i);
+}
+
+
+  void
+BX_CPU_C::XADD_EdGd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+    Bit32u op2_32, op1_32, sum_32;
+
+    /* XADD dst(r/m), src(r)
+     * temp <-- src + dst         | sum = op2 + op1
+     * src  <-- dst               | op2 = op1
+     * dst  <-- tmp               | op1 = sum
+     */
+
+    /* op2 is a register, i->rm_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    sum_32 = op1_32 + op2_32;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      // and write destination into source
+      // Note: if both op1 & op2 are registers, the last one written
+      //       should be the sum, as op1 & op2 may be the same register.
+      //       For example:  XADD AL, AL
+      BX_WRITE_32BIT_REG(i->nnn, op1_32);
+      BX_WRITE_32BIT_REG(i->rm, sum_32);
+      }
+    else {
+      write_RMW_virtual_dword(sum_32);
+      /* and write destination into source */
+      BX_WRITE_32BIT_REG(i->nnn, op1_32);
+      }
+
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XADD32);
+#else
+  BX_PANIC(("XADD_EdGd: not supported on < 80486\n"));
+#endif
+}
+
+
+
+  void
+BX_CPU_C::ADD_EdId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, sum_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    sum_32 = op1_32 + op2_32;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, sum_32);
+      }
+    else {
+      write_RMW_virtual_dword(sum_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+  void
+BX_CPU_C::ADC_EdId(BxInstruction_t *i)
+{
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, sum_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    sum_32 = op1_32 + op2_32 + temp_CF;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, sum_32);
+      }
+    else {
+      write_RMW_virtual_dword(sum_32);
+      }
+
+    SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+                              temp_CF);
+}
+
+
+  void
+BX_CPU_C::SUB_EdId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, diff_32);
+      }
+    else {
+      write_RMW_virtual_dword(diff_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+  void
+BX_CPU_C::CMP_EdId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, diff_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = op1_32 - op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+
+
+  void
+BX_CPU_C::NEG_Ed(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, diff_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = 0 - op1_32;
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, diff_32);
+      }
+    else {
+      write_RMW_virtual_dword(diff_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, 0, diff_32, BX_INSTR_NEG32);
+}
+
+
+  void
+BX_CPU_C::INC_Ed(BxInstruction_t *i)
+{
+    Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    op1_32++;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+
+    SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_INC32);
+}
+
+
+  void
+BX_CPU_C::DEC_Ed(BxInstruction_t *i)
+{
+    Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    op1_32--;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+
+    SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_DEC32);
+}
+
+
+  void
+BX_CPU_C::CMPXCHG_EdGd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+    Bit32u op2_32, op1_32, diff_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    diff_32 = EAX - op1_32;
+
+    SET_FLAGS_OSZAPC_32(EAX, op1_32, diff_32, BX_INSTR_CMP32);
+
+    if (diff_32 == 0) {  // if accumulator == dest
+      // ZF = 1
+      set_ZF(1);
+      // dest <-- src
+      op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+      if (i->mod == 0xc0) {
+        BX_WRITE_32BIT_REG(i->rm, op2_32);
+        }
+      else {
+        write_RMW_virtual_dword(op2_32);
+        }
+      }
+    else {
+      // ZF = 0
+      set_ZF(0);
+      // accumulator <-- dest
+      EAX = op1_32;
+      }
+#else
+  BX_PANIC(("CMPXCHG_EdGd:\n"));
+#endif
+}
+
+  void
+BX_CPU_C::CMPXCHG8B(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 5) || (BX_CPU_LEVEL_HACKED >= 5)
+  if (i->mod != 0xc0) {
+    BX_INFO(("CMPXCHG8B: dest is reg: #UD\n"));
+    UndefinedOpcode(i);
+    }
+  BX_PANIC(("CMPXCHG8B: not implemented yet\n"));
+#else
+  BX_INFO(("CMPXCHG8B: not implemented yet\n"));
+  UndefinedOpcode(i);
+#endif
+}
diff --git a/sid/component/bochs/cpu/arith8.cc b/sid/component/bochs/cpu/arith8.cc
new file mode 100644 (file)
index 0000000..b7d3548
--- /dev/null
@@ -0,0 +1,763 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::ADD_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, sum;
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  sum = op1 + op2;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, sum);
+    }
+  else {
+    write_RMW_virtual_byte(sum);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+
+  void
+BX_CPU_C::ADD_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+
+
+  /* op1 is a register, i->rm_addr is an index of a register */
+  op1 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  sum = op1 + op2;
+
+  /* now write sum back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, sum);
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+  void
+BX_CPU_C::ADD_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+
+
+  op1 = AL;
+
+  op2 = i->Ib;
+
+  sum = op1 + op2;
+
+  /* now write sum back to destination, which is a register */
+  AL = sum;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+  void
+BX_CPU_C::ADC_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, sum;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  sum = op1 + op2 + temp_CF;
+
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, sum);
+    }
+  else {
+    write_RMW_virtual_byte(sum);
+    }
+
+  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8, temp_CF);
+}
+
+
+  void
+BX_CPU_C::ADC_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  /* op1 is a register, i->rm_addr is an index of a register */
+  op1 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  sum = op1 + op2 + temp_CF;
+
+  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+                           temp_CF);
+
+  /* now write sum back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, sum);
+}
+
+
+  void
+BX_CPU_C::ADC_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  op1 = AL;
+
+  op2 = i->Ib;
+
+  sum = op1 + op2 + temp_CF;
+
+  /* now write sum back to destination, which is a register */
+  AL = sum;
+
+  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+                           temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - (op2_8 + temp_CF);
+
+  /* now write diff back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, diff_8);
+    }
+  else {
+    write_RMW_virtual_byte(diff_8);
+    }
+
+  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+                           temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  /* op1 is a register, i->rm_addr is an index of a register */
+  op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+  diff_8 = op1_8 - (op2_8 + temp_CF);
+
+  /* now write diff back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, diff_8);
+
+  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+                           temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+
+  op1_8 = AL;
+
+  op2_8 = i->Ib;
+
+  diff_8 = op1_8 - (op2_8 + temp_CF);
+
+  /* now write diff back to destination, which is a register */
+  AL = diff_8;
+
+  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+                           temp_CF);
+}
+
+
+  void
+BX_CPU_C::SBB_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+  op2_8 = i->Ib;
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - (op2_8 + temp_CF);
+
+  /* now write diff back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, diff_8);
+    }
+  else {
+    write_RMW_virtual_byte(diff_8);
+    }
+
+  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+                           temp_CF);
+}
+
+
+
+  void
+BX_CPU_C::SUB_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  /* now write diff back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, diff_8);
+    }
+  else {
+    write_RMW_virtual_byte(diff_8);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+  void
+BX_CPU_C::SUB_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+
+
+  /* op1 is a register, i->rm_addr is an index of a register */
+  op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  /* now write diff back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, diff_8);
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+  void
+BX_CPU_C::SUB_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+
+  op1_8 = AL;
+
+  op2_8 = i->Ib;
+
+  diff_8 = op1_8 - op2_8;
+
+  /* now write diff back to destination, which is a register */
+  AL = diff_8;
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+
+  void
+BX_CPU_C::CMP_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+  void
+BX_CPU_C::CMP_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+
+  /* op1 is a register, i->rm_addr is an index of a register */
+  op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+
+  void
+BX_CPU_C::CMP_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+
+
+  op1_8 = AL;
+
+  op2_8 = i->Ib;
+
+  diff_8 = op1_8 - op2_8;
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+  void
+BX_CPU_C::XADD_EbGb(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit8u op2, op1, sum;
+
+  /* XADD dst(r/m8), src(r8)
+   * temp <-- src + dst         | sum = op2 + op1
+   * src  <-- dst               | op2 = op1
+   * dst  <-- tmp               | op1 = sum
+   */
+
+  /* op2 is a register, i->rm_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  sum = op1 + op2;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    // and write destination into source
+    // Note: if both op1 & op2 are registers, the last one written
+    //       should be the sum, as op1 & op2 may be the same register.
+    //       For example:  XADD AL, AL
+    BX_WRITE_8BIT_REG(i->nnn, op1);
+    BX_WRITE_8BIT_REG(i->rm, sum);
+    }
+  else {
+    write_RMW_virtual_byte(sum);
+    /* and write destination into source */
+    BX_WRITE_8BIT_REG(i->nnn, op1);
+    }
+
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_XADD8);
+#else
+  BX_PANIC(("XADD_EbGb: not supported on < 80486\n"));
+#endif
+}
+
+
+  void
+BX_CPU_C::ADD_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, sum;
+
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  sum = op1 + op2;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, sum);
+    }
+  else {
+    write_RMW_virtual_byte(sum);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+  void
+BX_CPU_C::ADC_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, sum;
+  Boolean temp_CF;
+
+  temp_CF = get_CF();
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  sum = op1 + op2 + temp_CF;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, sum);
+    }
+  else {
+    write_RMW_virtual_byte(sum);
+    }
+
+  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+                           temp_CF);
+}
+
+
+  void
+BX_CPU_C::SUB_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+
+
+  op2_8 = i->Ib;
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  /* now write diff back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, diff_8);
+    }
+  else {
+    write_RMW_virtual_byte(diff_8);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+  void
+BX_CPU_C::CMP_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2_8, op1_8, diff_8;
+
+  op2_8 = i->Ib;
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = op1_8 - op2_8;
+
+  SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+  void
+BX_CPU_C::NEG_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, diff_8;
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = 0 - op1_8;
+
+  /* now write diff back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, diff_8);
+    }
+  else {
+    write_RMW_virtual_byte(diff_8);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1_8, 0, diff_8, BX_INSTR_NEG8);
+}
+
+
+  void
+BX_CPU_C::INC_Eb(BxInstruction_t *i)
+{
+  Bit8u  op1;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+
+  op1++;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, op1);
+    }
+  else {
+    write_RMW_virtual_byte(op1);
+    }
+
+  SET_FLAGS_OSZAP_8(0, 0, op1, BX_INSTR_INC8);
+}
+
+
+  void
+BX_CPU_C::DEC_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8;
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  op1_8--;
+
+  /* now write sum back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, op1_8);
+    }
+  else {
+    write_RMW_virtual_byte(op1_8);
+    }
+
+  SET_FLAGS_OSZAP_8(0, 0, op1_8, BX_INSTR_DEC8);
+}
+
+
+  void
+BX_CPU_C::CMPXCHG_EbGb(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+  Bit8u op2_8, op1_8, diff_8;
+
+
+  /* op1_8 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  diff_8 = AL - op1_8;
+
+  SET_FLAGS_OSZAPC_8(AL, op1_8, diff_8, BX_INSTR_CMP8);
+
+  if (diff_8 == 0) {  // if accumulator == dest
+    // ZF = 1
+    set_ZF(1);
+    // dest <-- src
+    op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+    if (i->mod == 0xc0) {
+      BX_WRITE_8BIT_REG(i->rm, op2_8);
+      }
+    else {
+      write_RMW_virtual_byte(op2_8);
+      }
+    }
+  else {
+    // ZF = 0
+    set_ZF(0);
+    // accumulator <-- dest
+    AL = op1_8;
+    }
+
+#else
+  BX_PANIC(("CMPXCHG_EbGb:\n"));
+#endif
+}
diff --git a/sid/component/bochs/cpu/bcd.cc b/sid/component/bochs/cpu/bcd.cc
new file mode 100644 (file)
index 0000000..315e10a
--- /dev/null
@@ -0,0 +1,173 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::DAS(BxInstruction_t *)
+{
+  Bit8u tmpCF, tmpAL;
+
+  /* ??? */
+  /* the algorithm for DAS is fashioned after the pseudo code in the
+   * Pentium Processor Family Developer's Manual, volume 3.  It seems
+   * to have changed from earlier processor's manuals.  I'm not sure
+   * if this is a correction in the algorithm printed, or Intel has
+   * changed the handling of instruction.  It might not even be
+   * correct yet...
+   */
+
+  tmpCF = 0;
+  tmpAL = AL;
+
+  /* DAS effect the following flags: A,C,S,Z,P */
+
+  if (((tmpAL & 0x0F) > 0x09) || get_AF()) {
+    set_AF(1);
+    tmpCF = (AL < 0x06) || get_CF();
+    AL = AL - 0x06;
+    /*tmpCF = (AL < 0) || CF;*/
+    }
+  if ( (tmpAL > 0x99) || get_CF() ) {
+    AL = AL - 0x60;
+    tmpCF = 1;
+    }
+
+  set_CF(tmpCF);
+  set_SF(AL >> 7);
+  set_ZF(AL==0);
+  set_PF_base(AL);
+}
+
+  void
+BX_CPU_C::AAA(BxInstruction_t *)
+{
+  Bit8u ALcarry;
+
+  ALcarry = AL > 0xf9;
+
+  /* AAA effects the following flags: A,C */
+  if ( ((AL & 0x0f) > 9) || get_AF() ) {
+    AL = (AL + 6) & 0x0f;
+    AH = AH + 1 + ALcarry;
+    set_AF(1);
+    set_CF(1);
+    }
+  else {
+    set_AF(0);
+    set_CF(0);
+    AL = AL & 0x0f;
+    }
+}
+
+  void
+BX_CPU_C::AAS(BxInstruction_t *)
+{
+  Bit8u ALborrow;
+
+  /* AAS affects the following flags: A,C */
+
+  ALborrow = AL < 6;
+
+  if ( ((AL & 0x0F) > 0x09) || get_AF() ) {
+    AL = (AL - 6) & 0x0f;
+    AH = AH - 1 - ALborrow;
+    set_AF(1);
+    set_CF(1);
+    }
+  else {
+    set_CF(0);
+    set_AF(0);
+    AL = AL & 0x0f;
+    }
+}
+
+  void
+BX_CPU_C::AAM(BxInstruction_t *i)
+{
+  Bit8u al, imm8;
+
+  imm8 = i->Ib;
+
+  al = AL;
+  AH = al / imm8;
+  AL = al % imm8;
+
+  /* AAM affects the following flags: S,Z,P */
+  set_SF((AH & 0x80) > 0);
+  set_ZF(AX==0);
+  set_PF_base(AL); /* ??? */
+}
+
+  void
+BX_CPU_C::AAD(BxInstruction_t *i)
+{
+  Bit8u imm8;
+
+  imm8 = i->Ib;
+
+  AL = AH * imm8 + AL;
+  AH = 0;
+
+  /* AAD effects the following flags: S,Z,P */
+  set_SF(AL >= 0x80);
+  set_ZF(AL == 0);
+  set_PF_base(AL);
+}
+
+  void
+BX_CPU_C::DAA(BxInstruction_t *)
+{
+  Bit8u al;
+
+  al = AL;
+
+  // DAA affects the following flags: S,Z,A,P,C
+  // ???
+
+  if (((al & 0x0F) > 0x09) || get_AF()) {
+    al = al + 0x06;
+    set_AF(1);
+    }
+  else
+    set_AF(0);
+
+  if ((al > 0x9F) || get_CF()) {
+    al = al + 0x60;
+    set_CF(1);
+    }
+
+  AL = al;
+
+  set_SF(al >> 7);
+  set_ZF(al==0);
+  set_PF_base(al);
+}
diff --git a/sid/component/bochs/cpu/bit.cc b/sid/component/bochs/cpu/bit.cc
new file mode 100644 (file)
index 0000000..8bf5eb6
--- /dev/null
@@ -0,0 +1,1248 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+  void
+BX_CPU_C::SETO_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETO: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_OF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNO_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNO: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_OF()==0)
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETB_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETB: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_CF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNB_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNB: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_CF()==0)
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETZ_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETZ: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_ZF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNZ_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNZ: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_ZF()==0)
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETBE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETBE: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_CF() || get_ZF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNBE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNBE: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if ((get_CF()==0) && (get_ZF()==0))
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETS_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETS: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_SF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNS_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNL: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_SF()==0)
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETP_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETP: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_PF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNP_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNP: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_PF() == 0)
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETL_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETL: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_SF() != get_OF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNL_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNL: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_SF() == get_OF())
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETLE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETLE: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if (get_ZF() || (get_SF()!=get_OF()))
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::SETNLE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("SETNLE: not available on < 386\n"));
+#else
+  Bit8u result_8;
+
+
+  if ((get_ZF()==0) && (get_SF()==get_OF()))
+    result_8 = 1;
+  else
+    result_8 = 0;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &result_8);
+    }
+#endif
+}
+
+
+  void
+BX_CPU_C::BSF_GvEv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BSF_GvEv(): not supported on < 386\n"));
+#else
+
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32;
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    if (op2_32 == 0) {
+      set_ZF(1);
+      /* op1_32 undefined */
+      return;
+      }
+
+    op1_32 = 0;
+    while ( (op2_32 & 0x01) == 0 ) {
+      op1_32++;
+      op2_32 >>= 1;
+      }
+    set_ZF(0);
+
+    /* now write result back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, op1_32);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16;
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    if (op2_16 == 0) {
+      set_ZF(1);
+      /* op1_16 undefined */
+      return;
+      }
+
+    op1_16 = 0;
+    while ( (op2_16 & 0x01) == 0 ) {
+      op1_16++;
+      op2_16 >>= 1;
+      }
+    set_ZF(0);
+
+    /* now write result back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, op1_16);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BSR_GvEv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BSR_GvEv(): not supported on < 386\n"));
+#else
+
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32;
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    if (op2_32 == 0) {
+      set_ZF(1);
+      /* op1_32 undefined */
+      return;
+      }
+
+    op1_32 = 31;
+    while ( (op2_32 & 0x80000000) == 0 ) {
+      op1_32--;
+      op2_32 <<= 1;
+      }
+    set_ZF(0);
+
+    /* now write result back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, op1_32);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16;
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    if (op2_16 == 0) {
+      set_ZF(1);
+      /* op1_16 undefined */
+      return;
+      }
+
+    op1_16 = 15;
+    while ( (op2_16 & 0x8000) == 0 ) {
+      op1_16--;
+      op2_16 <<= 1;
+      }
+    set_ZF(0);
+
+    /* now write result back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, op1_16);
+    }
+#endif
+}
+
+
+  void
+BX_CPU_C::BSWAP_EAX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u eax, b0, b1, b2, b3;
+
+  eax = EAX;
+  b0  = eax & 0xff; eax >>= 8;
+  b1  = eax & 0xff; eax >>= 8;
+  b2  = eax & 0xff; eax >>= 8;
+  b3  = eax;
+
+  EAX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_EAX: not implemented CPU <= 3\n"));
+#endif
+}
+
+  void
+BX_CPU_C::BSWAP_ECX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u ecx, b0, b1, b2, b3;
+
+  ecx = ECX;
+  b0  = ecx & 0xff; ecx >>= 8;
+  b1  = ecx & 0xff; ecx >>= 8;
+  b2  = ecx & 0xff; ecx >>= 8;
+  b3  = ecx;
+
+  ECX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_ECX: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_EDX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u edx, b0, b1, b2, b3;
+
+  edx = EDX;
+  b0  = edx & 0xff; edx >>= 8;
+  b1  = edx & 0xff; edx >>= 8;
+  b2  = edx & 0xff; edx >>= 8;
+  b3  = edx;
+
+  EDX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_EDX: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_EBX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u ebx, b0, b1, b2, b3;
+
+  ebx = EBX;
+  b0  = ebx & 0xff; ebx >>= 8;
+  b1  = ebx & 0xff; ebx >>= 8;
+  b2  = ebx & 0xff; ebx >>= 8;
+  b3  = ebx;
+
+  EBX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_EBX: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_ESP(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u esp, b0, b1, b2, b3;
+
+  esp = ESP;
+  b0  = esp & 0xff; esp >>= 8;
+  b1  = esp & 0xff; esp >>= 8;
+  b2  = esp & 0xff; esp >>= 8;
+  b3  = esp;
+
+  ESP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_ESP: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_EBP(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u ebp, b0, b1, b2, b3;
+
+  ebp = EBP;
+  b0  = ebp & 0xff; ebp >>= 8;
+  b1  = ebp & 0xff; ebp >>= 8;
+  b2  = ebp & 0xff; ebp >>= 8;
+  b3  = ebp;
+
+  EBP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_EBP: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_ESI(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u esi, b0, b1, b2, b3;
+
+  esi = ESI;
+  b0  = esi & 0xff; esi >>= 8;
+  b1  = esi & 0xff; esi >>= 8;
+  b2  = esi & 0xff; esi >>= 8;
+  b3  = esi;
+
+  ESI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_ESI: not implemented CPU <= 3\n"));
+#endif
+}
+  void
+BX_CPU_C::BSWAP_EDI(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+  Bit32u edi, b0, b1, b2, b3;
+
+  edi = EDI;
+  b0  = edi & 0xff; edi >>= 8;
+  b1  = edi & 0xff; edi >>= 8;
+  b2  = edi & 0xff; edi >>= 8;
+  b3  = edi;
+
+  EDI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+  BX_PANIC(("BSWAP_EDI: not implemented CPU <= 3\n"));
+#endif
+}
+
+
+  void
+BX_CPU_C::BT_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BT_EvGv: not available on <386\n"));
+#else
+  Bit32u op1_addr;
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, index;
+    Bit32s displacement32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      op2_32 &= 0x1f;
+      set_CF((op1_32 >> op2_32) & 0x01);
+      return;
+      }
+
+    index = op2_32 & 0x1f;
+    displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+    op1_addr = i->rm_addr + 4 * displacement32;
+
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, op1_addr, &op1_32);
+
+    set_CF((op1_32 >> index) & 0x01);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16, index;
+    Bit32s displacement32;
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      op2_16 &= 0x0f;
+      set_CF((op1_16 >> op2_16) & 0x01);
+      return;
+      }
+
+    index = op2_16 & 0x0f;
+    displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+    op1_addr = i->rm_addr + 2 * displacement32;
+
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, op1_addr, &op1_16);
+
+    set_CF((op1_16 >> index) & 0x01);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTS_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTS_EvGv: not available on <386\n"));
+#else
+  Bit32u op1_addr;
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, bit_i, index;
+    Bit32s displacement32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      op2_32 &= 0x1f;
+      set_CF((op1_32 >> op2_32) & 0x01);
+      op1_32 |= (((Bit32u) 1) << op2_32);
+
+      /* now write diff back to destination */
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      return;
+      }
+
+    index = op2_32 & 0x1f;
+    displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+    op1_addr = i->rm_addr + 4 * displacement32;
+
+    /* pointer, segment address pair */
+    read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+
+    bit_i = (op1_32 >> index) & 0x01;
+    op1_32 |= (((Bit32u) 1) << index);
+
+    write_RMW_virtual_dword(op1_32);
+
+    set_CF(bit_i);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16, bit_i, index;
+    Bit32s displacement32;
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      op2_16 &= 0x0f;
+      set_CF((op1_16 >> op2_16) & 0x01);
+      op1_16 |= (((Bit16u) 1) << op2_16);
+
+      /* now write diff back to destination */
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      return;
+      }
+
+    index = op2_16 & 0x0f;
+    displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+    op1_addr = i->rm_addr + 2 * displacement32;
+
+    /* pointer, segment address pair */
+    read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+
+    bit_i = (op1_16 >> index) & 0x01;
+    op1_16 |= (((Bit16u) 1) << index);
+
+    write_RMW_virtual_word(op1_16);
+
+    set_CF(bit_i);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTR_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTR_EvGv: not available on <386\n"));
+#else
+  Bit32u op1_addr;
+
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, index, temp_cf;
+    Bit32s displacement32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      op2_32 &= 0x1f;
+      set_CF((op1_32 >> op2_32) & 0x01);
+      op1_32 &= ~(((Bit32u) 1) << op2_32);
+
+      /* now write diff back to destination */
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      return;
+      }
+
+    index = op2_32 & 0x1f;
+    displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+    op1_addr = i->rm_addr + 4 * displacement32;
+
+    /* pointer, segment address pair */
+    read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+
+    temp_cf = (op1_32 >> index) & 0x01;
+    op1_32 &= ~(((Bit32u) 1) << index);
+
+    /* now write back to destination */
+    write_RMW_virtual_dword(op1_32);
+
+    set_CF(temp_cf);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16, index, temp_cf;
+    Bit32s displacement32;
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      op2_16 &= 0x0f;
+      set_CF((op1_16 >> op2_16) & 0x01);
+      op1_16 &= ~(((Bit16u) 1) << op2_16);
+
+      /* now write diff back to destination */
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      return;
+      }
+
+    index = op2_16 & 0x0f;
+    displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+    op1_addr = i->rm_addr + 2 * displacement32;
+
+    /* pointer, segment address pair */
+    read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+
+    temp_cf = (op1_16 >> index) & 0x01;
+    op1_16 &= ~(((Bit16u) 1) << index);
+
+    /* now write back to destination */
+    write_RMW_virtual_word(op1_16);
+
+    set_CF(temp_cf);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTC_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTC_EvGv: not available on <386\n"));
+#else
+  Bit32u op1_addr;
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, index_32, temp_CF;
+    Bit32s displacement32;
+
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+    index_32 = op2_32 & 0x1f;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      op1_addr = 0; // keep compiler happy
+      }
+    else {
+      displacement32 = ((Bit32s) (op2_32 & 0xffffffe0)) / 32;
+      op1_addr = i->rm_addr + 4 * displacement32;
+      read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+      }
+
+    temp_CF = (op1_32 >> index_32) & 0x01;
+    op1_32 &= ~(((Bit32u) 1) << index_32);  /* clear out bit */
+    op1_32 |= (((Bit32u) !temp_CF) << index_32); /* set to complement */
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+    set_CF(temp_CF);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, op2_16, index_16, temp_CF;
+    Bit16s displacement16;
+
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+    index_16 = op2_16 & 0x0f;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      op1_addr = 0; // keep compiler happy
+      }
+    else {
+      displacement16 = ((Bit16s) (op2_16 & 0xfff0)) / 16;
+      op1_addr = i->rm_addr + 2 * displacement16;
+      read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+      }
+
+    temp_CF = (op1_16 >> index_16) & 0x01;
+    op1_16 &= ~(((Bit16u) 1) << index_16);  /* clear out bit */
+    op1_16 |= (((Bit16u) !temp_CF) << index_16); /* set to complement */
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+    set_CF(temp_CF);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BT_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BT_EvIb: not available on <386\n"));
+#else
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32;
+    Bit8u  op2_8;
+
+    op2_8 = i->Ib;
+    op2_8 %= 32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    set_CF((op1_32 >> op2_8) & 0x01);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16;
+    Bit8u  op2_8;
+
+
+    op2_8 = i->Ib;
+    op2_8 %= 16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    set_CF((op1_16 >> op2_8) & 0x01);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTS_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTS_EvIb: not available on <386\n"));
+#else
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, temp_CF;
+    Bit8u  op2_8;
+
+    op2_8 = i->Ib;
+    op2_8 %= 32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    temp_CF = (op1_32 >> op2_8) & 0x01;
+    op1_32 |= (((Bit32u) 1) << op2_8);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+    set_CF(temp_CF);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, temp_CF;
+    Bit8u  op2_8;
+
+
+    op2_8 = i->Ib;
+    op2_8 %= 16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    temp_CF = (op1_16 >> op2_8) & 0x01;
+    op1_16 |= (((Bit16u) 1) << op2_8);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+    set_CF(temp_CF);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTC_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTC_EvIb: not available on <386\n"));
+#else
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, temp_CF;
+    Bit8u  op2_8;
+
+    op2_8 = i->Ib;
+    op2_8 %= 32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    temp_CF = (op1_32 >> op2_8) & 0x01;
+
+    op1_32 &= ~(((Bit32u) 1) << op2_8);  /* clear out bit */
+    op1_32 |= (((Bit32u) !temp_CF) << op2_8); /* set to complement */
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+    set_CF(temp_CF);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, temp_CF;
+    Bit8u  op2_8;
+
+
+    op2_8 = i->Ib;
+    op2_8 %= 16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    temp_CF = (op1_16 >> op2_8) & 0x01;
+    op1_16 &= ~(((Bit16u) 1) << op2_8);  /* clear out bit */
+    op1_16 |= (((Bit16u) !temp_CF) << op2_8); /* set to complement */
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+    set_CF(temp_CF);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::BTR_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("BTR_EvIb: not available on <386\n"));
+#else
+
+  if (i->os_32) { /* 32 bit operand size mode */
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, temp_CF;
+    Bit8u  op2_8;
+
+    op2_8 = i->Ib;
+    op2_8 %= 32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    temp_CF = (op1_32 >> op2_8) & 0x01;
+    op1_32 &= ~(((Bit32u) 1) << op2_8);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op1_32);
+      }
+    else {
+      write_RMW_virtual_dword(op1_32);
+      }
+    set_CF(temp_CF);
+    }
+  else { /* 16 bit operand size mode */
+    Bit16u op1_16, temp_CF;
+    Bit8u  op2_8;
+
+
+    op2_8 = i->Ib;
+    op2_8 %= 16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    temp_CF = (op1_16 >> op2_8) & 0x01;
+    op1_16 &= ~(((Bit16u) 1) << op2_8);
+
+    /* now write diff back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op1_16);
+      }
+    else {
+      write_RMW_virtual_word(op1_16);
+      }
+    set_CF(temp_CF);
+    }
+#endif
+}
diff --git a/sid/component/bochs/cpu/cpu-sid.cc b/sid/component/bochs/cpu/cpu-sid.cc
new file mode 100644 (file)
index 0000000..f8b1b21
--- /dev/null
@@ -0,0 +1,582 @@
+//  cpu-sid.cc - override some important bx_cpu_c member functions. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+static Bit8u *sid_prefetch_data = NULL;
+
+void
+sid_cpu_c::cpu_loop(Bit32s max_instr_count)
+{
+  unsigned ret;
+  BxInstruction_t i;
+  unsigned maxisize;
+  Bit8u *fetch_ptr;
+  Boolean is_32;
+
+  static int num_loops = 0;
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR break_point = 0;
+#ifdef MAGIC_BREAKPOINT
+  BX_CPU_THIS_PTR magic_break = 0;
+#endif // MAGIC_BREAKPOINT
+  BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+#endif // BX_DEBUGGER
+
+  (void) setjmp( BX_CPU_THIS_PTR jmp_buf_env );
+
+  BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
+  BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
+
+#if X86_CPU_DEBUG
+    printf("At top of main loop, EIP = %p, ESP = %p\n", EIP, ESP);
+#endif
+    
+main_cpu_loop:  
+
+  // ???
+  BX_CPU_THIS_PTR EXT = 0;
+  BX_CPU_THIS_PTR errorno = 0;
+
+  // First check on events which occurred for previous instructions
+  // (traps) and ones which are asynchronous to the CPU
+  // (hardware interrupts).
+  if (BX_CPU_THIS_PTR async_event)
+    goto handle_async_event;
+
+async_events_processed:
+
+  // Now we can handle things which are synchronous to instruction
+  // execution.
+  if (BX_CPU_THIS_PTR eflags.rf) {
+    BX_CPU_THIS_PTR eflags.rf = 0;
+    }
+#if BX_X86_DEBUGGER
+  else {
+    // only bother comparing if any breakpoints enabled
+    if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+      Bit32u iaddr =
+        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base +
+        BX_CPU_THIS_PTR prev_eip;
+      Bit32u dr6_bits;
+      if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
+                                       BX_HWDebugInstruction)) ) {
+        // Add to the list of debug events thus far.
+        BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+        BX_CPU_THIS_PTR async_event = 1;
+        // If debug events are not inhibited on this boundary,
+        // fire off a debug fault.  Otherwise handle it on the next
+        // boundary. (becomes a trap)
+        if ( !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+          // Commit debug events to DR6
+          BX_CPU_THIS_PTR dr6 = BX_CPU_THIS_PTR debug_trap;
+          exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+          }
+        }
+      }
+    }
+#endif
+
+  // We have ignored processing of external interrupts and
+  // debug events on this boundary.  Reset the mask so they
+  // will be processed on the next boundary.
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+#if BX_DEBUGGER
+  {
+  Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+  if ( dbg_is_begin_instr_bpoint(
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+         debug_eip,
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+    return;
+    }
+  }
+#endif  // #if BX_DEBUGGER
+
+
+  is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+
+  if (BX_CPU_THIS_PTR bytesleft == 0) {
+      prefetch();
+    }
+  fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+  maxisize = 16;
+  if (BX_CPU_THIS_PTR bytesleft < 16)
+    maxisize = BX_CPU_THIS_PTR bytesleft;
+
+  ret = FetchDecode(fetch_ptr, &i, maxisize, is_32);
+
+#if X86_CPU_DEBUG
+  printf("FetchDecode returned: %d\n", ret);
+  printf("Current opcode: %p, with length: %d, EIP = %p\n", i.b1, i.ilen, this->eip);
+#endif
+  
+  if (ret) {
+    if (i.ResolveModrm) {
+      // call method on sid_cpu_c object
+      BX_CPU_CALL_METHOD_FROM_SID(i.ResolveModrm, (&i));
+      }
+    BX_CPU_THIS_PTR fetch_ptr += i.ilen;
+    BX_CPU_THIS_PTR bytesleft -= i.ilen;
+fetch_decode_OK:
+
+    if (i.rep_used && (i.attr & BxRepeatable)) {
+repeat_loop:
+      if (i.attr & BxRepeatableZF) {
+        if (i.as_32) {
+          if (ECX != 0) {
+            BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+            ECX -= 1;
+            }
+          if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
+          if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
+          if (ECX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        else {
+          if (CX != 0) {
+            BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+            CX -= 1;
+            }
+          if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
+          if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
+          if (CX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        }
+      else { // normal repeat, no concern for ZF
+        if (i.as_32) {
+          if (ECX != 0) {
+            BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+            ECX -= 1;
+            }
+          if (ECX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        else { // 16bit addrsize
+          if (CX != 0) {
+            BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+            CX -= 1;
+            }
+          if (CX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        }
+      // shouldn't get here from above
+repeat_not_done:
+#ifdef REGISTER_IADDR
+      REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
+#endif
+
+#if BX_DEBUGGER == 0
+      if (BX_CPU_THIS_PTR async_event) {
+        invalidate_prefetch_q();
+        goto debugger_check;
+      }
+      goto repeat_loop;
+#else  /* if BX_DEBUGGER == 1 */
+      invalidate_prefetch_q();
+      goto debugger_check;
+#endif
+
+
+repeat_done:
+      BX_CPU_THIS_PTR eip += i.ilen;
+    }
+    else {
+      // non repeating instruction
+      BX_CPU_THIS_PTR eip += i.ilen;
+      BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+    }
+
+    BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
+    BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
+#ifdef REGISTER_IADDR
+    REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
+#endif
+
+debugger_check:
+
+    // The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+    // instructions and then return so that the other processors have a chance
+    // to run.  Every time sid pulses the step pin, cpu_loop executes once
+    CHECK_MAX_INSTRUCTIONS(max_instr_count);
+
+#if BX_DEBUGGER
+    // BW vm mode switch support is in dbg_is_begin_instr_bpoint
+    // note instr generating exceptions never reach this point.
+
+    // (mch) Read/write, time break point support
+    if (BX_CPU_THIS_PTR break_point) {
+         switch (BX_CPU_THIS_PTR break_point) {
+               case BREAK_POINT_TIME:
+                     BX_CPU_THIS_PTR info("[%lld] Caught time breakpoint\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_TIME_BREAK_POINT;
+                     return;
+               case BREAK_POINT_READ:
+                     BX_CPU_THIS_PTR info("[%lld] Caught read watch point\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_READ_WATCH_POINT;
+                     return;
+               case BREAK_POINT_WRITE:
+                     BX_CPU_THIS_PTR info("[%lld] Caught write watch point\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_WRITE_WATCH_POINT;
+                     return;
+               default:
+                     BX_PANIC(("Weird break point condition"));
+         }
+    }
+#ifdef MAGIC_BREAKPOINT
+    // (mch) Magic break point support
+    if (BX_CPU_THIS_PTR magic_break) {
+         if (bx_dbg.magic_break_enabled) {
+               BX_CPU_THIS_PTR info("Stopped on MAGIC BREAKPOINT\n");
+               BX_CPU_THIS_PTR stop_reason = STOP_MAGIC_BREAK_POINT;
+               return;
+         } else {
+               BX_CPU_THIS_PTR magic_break = 0;
+               BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+               BX_CPU_THIS_PTR info("Ignoring MAGIC BREAKPOINT\n");
+         }
+    }
+#endif
+    if (BX_CPU_THIS_PTR trace) {
+         BX_CPU_THIS_PTR stop_reason = STOP_TRACE;
+         return;
+    }
+#endif
+
+#if BX_DEBUGGER
+    {
+    Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+    if ( dbg_is_end_instr_bpoint(
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+           debug_eip,
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+      return;
+      }
+    }
+#endif  // #if BX_DEBUGGER
+    goto main_cpu_loop;
+  }
+  else {
+    unsigned remain, j;
+    static Bit8u FetchBuffer[16];
+    Bit8u *temp_ptr;
+
+    // read all leftover bytes in current page
+    for (j=0; j<BX_CPU_THIS_PTR bytesleft; j++) {
+      FetchBuffer[j] = *fetch_ptr++;
+      }
+
+    // get remaining bytes for prefetch in next page
+    // prefetch() needs eip current
+    BX_CPU_THIS_PTR eip += BX_CPU_THIS_PTR bytesleft;
+    remain = BX_CPU_THIS_PTR bytesleft;
+    prefetch();
+
+    if (BX_CPU_THIS_PTR bytesleft < 16) {
+      // make sure (bytesleft - remain) below doesn't go negative
+      BX_PANIC(("fetch_decode: bytesleft==0 after prefetch\n"));
+      }
+    temp_ptr = fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+    // read leftover bytes in next page
+    for (; j<16; j++) {
+      FetchBuffer[j] = *temp_ptr++;
+      }
+
+    ret = FetchDecode(FetchBuffer, &i, 16, is_32);
+
+#if X86_CPU_DEBUG
+      printf("Just returned from prefetch...\n");
+      printf("FetchDecode returned: %d\n", ret);
+      printf("Current opcode: %p, with length: %d, EIP = %p, prev_eip = %p\n", i.b1, i.ilen, this->eip, this->prev_eip);
+#endif
+
+    if (ret==0)
+      BX_PANIC(("fetchdecode: cross boundary: ret==0\n"));
+    if (i.ResolveModrm) {
+      BX_CPU_CALL_METHOD_FROM_SID(i.ResolveModrm, (&i));
+      }
+    remain = i.ilen - remain;
+
+    // note: eip has already been advanced to beginning of page
+    BX_CPU_THIS_PTR fetch_ptr = fetch_ptr + remain;
+    BX_CPU_THIS_PTR bytesleft -= remain;
+    //BX_CPU_THIS_PTR eip += remain;
+    BX_CPU_THIS_PTR eip = BX_CPU_THIS_PTR prev_eip;
+    goto fetch_decode_OK;
+  }
+
+
+
+  //
+  // This area is where we process special conditions and events.
+  //
+
+handle_async_event:
+
+  if (BX_CPU_THIS_PTR debug_trap & 0x80000000) {
+    // I made up the bitmask above to mean HALT state.
+#if BX_SMP_PROCESSORS==1
+#else      /* BX_SMP_PROCESSORS != 1 */
+    // for multiprocessor simulation, even if this CPU is halted we still
+    // must give the others a chance to simulate.  If an interrupt has 
+    // arrived, then clear the HALT condition; otherwise just return from
+    // the CPU loop with stop_reason STOP_CPU_HALTED.
+    if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+      // interrupt ends the HALT condition
+      BX_CPU_THIS_PTR debug_trap = 0; // clear traps for after resume
+      BX_CPU_THIS_PTR inhibit_mask = 0; // clear inhibits for after resume
+      //bx_printf ("halt condition has been cleared in %s\n", name);
+    } else {
+      // HALT condition remains, return so other CPUs have a chance
+#if BX_DEBUGGER
+      BX_CPU_THIS_PTR stop_reason = STOP_CPU_HALTED;
+#endif
+      return;
+    }
+#endif
+  }
+
+
+  // Priority 1: Hardware Reset and Machine Checks
+  //   RESET
+  //   Machine Check
+  // (bochs doesn't support these)
+
+  // Priority 2: Trap on Task Switch
+  //   T flag in TSS is set
+  if (BX_CPU_THIS_PTR debug_trap & 0x00008000) {
+    BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
+    exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+    }
+
+  // Priority 3: External Hardware Interventions
+  //   FLUSH
+  //   STOPCLK
+  //   SMI
+  //   INIT
+  // (bochs doesn't support these)
+
+  // Priority 4: Traps on Previous Instruction
+  //   Breakpoints
+  //   Debug Trap Exceptions (TF flag set or data/IO breakpoint)
+  if ( BX_CPU_THIS_PTR debug_trap &&
+       !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+    // A trap may be inhibited on this boundary due to an instruction
+    // which loaded SS.  If so we clear the inhibit_mask below
+    // and don't execute this code until the next boundary.
+    // Commit debug events to DR6
+    BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
+    exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+    }
+
+  // Priority 5: External Interrupts
+  //   NMI Interrupts
+  //   Maskable Hardware Interrupts
+  if (BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_INTERRUPTS) {
+    // Processing external interrupts is inhibited on this
+    // boundary because of certain instructions like STI.
+    // inhibit_mask is cleared below, in which case we will have
+    // an opportunity to check interrupts on the next instruction
+    // boundary.
+    }
+  else if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ && BX_DBG_ASYNC_INTR) {
+    Bit8u vector;
+
+    // NOTE: similar code in ::take_irq()
+#if BX_SUPPORT_APIC
+    if (BX_CPU_THIS_PTR int_from_local_apic)
+      vector = BX_CPU_THIS_PTR local_apic.acknowledge_int ();
+    else
+      vector = BX_IAC(); // may set INTR with next interrupt
+#else
+#if 0 // FIXME: this will eventually be included
+    // if no local APIC, always acknowledge the PIC.
+    vector = BX_IAC(); // may set INTR with next interrupt
+#endif
+#endif
+    //if (bx_dbg.interrupts) BX_INFO(("decode: interrupt %u\n",
+    //                                   (unsigned) vector));
+    BX_CPU_THIS_PTR errorno = 0;
+    BX_CPU_THIS_PTR EXT   = 1; /* external event */
+    interrupt(vector, 0, 0, 0);
+    BX_INSTR_HWINTERRUPT(vector, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+    }
+#if 0 // FIXME: this will eventually be included
+  else if (BX_HRQ && BX_DBG_ASYNC_DMA) {
+    // NOTE: similar code in ::take_dma()
+    // assert Hold Acknowledge (HLDA) and go into a bus hold state
+    BX_RAISE_HLDA();
+    }
+#endif
+  // Priority 6: Faults from fetching next instruction
+  //   Code breakpoint fault
+  //   Code segment limit violation (priority 7 on 486/Pentium)
+  //   Code page fault (priority 7 on 486/Pentium)
+  // (handled in main decode loop)
+
+  // Priority 7: Faults from decoding next instruction
+  //   Instruction length > 15 bytes
+  //   Illegal opcode
+  //   Coprocessor not available
+  // (handled in main decode loop etc)
+
+  // Priority 8: Faults on executing an instruction
+  //   Floating point execution
+  //   Overflow
+  //   Bound error
+  //   Invalid TSS
+  //   Segment not present
+  //   Stack fault
+  //   General protection
+  //   Data page fault
+  //   Alignment check
+  // (handled by rest of the code)
+
+
+  if (BX_CPU_THIS_PTR eflags.tf) {
+    // TF is set before execution of next instruction.  Schedule
+    // a debug trap (#DB) after execution.  After completion of
+    // next instruction, the code above will invoke the trap.
+    BX_CPU_THIS_PTR debug_trap |= 0x00004000; // BS flag in DR6
+    }
+#if 0 // FIXME: this will eventually be included
+  if ( !(BX_CPU_THIS_PTR INTR ||
+         BX_CPU_THIS_PTR debug_trap ||
+         BX_HRQ ||
+         BX_CPU_THIS_PTR eflags.tf) )
+    BX_CPU_THIS_PTR async_event = 0;
+  goto async_events_processed;
+#endif
+}
+
+// boundaries of consideration:
+//
+//  * physical memory boundary: 1024k (1Megabyte) (increments of...)
+//  * A20 boundary:             1024k (1Megabyte)
+//  * page boundary:            4k
+//  * ROM boundary:             2k (dont care since we are only reading)
+//  * segment boundary:         any
+
+
+
+  void
+sid_cpu_c::prefetch(void)
+{
+  // cs:eIP
+  // prefetch QSIZE byte quantity aligned on corresponding boundary
+  Bit32u new_linear_addr;
+  Bit32u new_phy_addr;
+  Bit32u temp_eip, temp_limit;
+
+  temp_eip   = BX_CPU_THIS_PTR eip;
+  temp_limit = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled;
+
+  new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + temp_eip;
+  BX_CPU_THIS_PTR prev_linear_page = new_linear_addr & 0xfffff000;
+  if (temp_eip > temp_limit) {
+    BX_PANIC(("prefetch: EIP > CS.limit\n"));
+    }
+
+#if BX_SUPPORT_PAGING
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    // aligned block guaranteed to be all in one page, same A20 address
+    new_phy_addr = itranslate_linear(new_linear_addr, CPL==3);
+    new_phy_addr = A20ADDR(new_phy_addr);
+    }
+  else {
+#endif // BX_SUPPORT_PAGING
+    new_phy_addr = A20ADDR(new_linear_addr);
+#if BX_SUPPORT_PAGING
+    }
+#endif // BX_SUPPORT_PAGING
+
+  // max physical address as confined by page boundary
+  BX_CPU_THIS_PTR prev_phy_page = new_phy_addr & 0xfffff000;
+  BX_CPU_THIS_PTR max_phy_addr = BX_CPU_THIS_PTR prev_phy_page | 0x00000fff;
+
+  // check if segment boundary comes into play
+  //if ((temp_limit - temp_eip) < 4096) {
+  //  }
+
+  BX_CPU_THIS_PTR bytesleft = 16;
+  
+  if(!sid_prefetch_data)
+      sid_prefetch_data = new Bit8u[16];
+
+#if X86_CPU_DEBUG
+    printf("Prefetching 16 new bytes from %p...\n", new_phy_addr);
+#endif
+    
+  BX_CPU_THIS_PTR mem->read_physical(this, new_phy_addr, 16, (void *)sid_prefetch_data);
+
+  BX_CPU_THIS_PTR fetch_ptr = sid_prefetch_data;
+}
+
+
+  // If control has transfered locally, it is possible the prefetch Q is
+  // still valid.  This would happen for repeat instructions, and small
+  // branches.
+  void
+sid_cpu_c::revalidate_prefetch_q(void)
+{
+  Bit32u new_linear_addr, new_linear_page, new_linear_offset;
+  Bit32u new_phy_addr;
+
+  new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + BX_CPU_THIS_PTR eip;
+
+  new_linear_page = new_linear_addr & 0xfffff000;
+  if (new_linear_page == BX_CPU_THIS_PTR prev_linear_page) {
+    // same linear address, old linear->physical translation valid
+    new_linear_offset = new_linear_addr & 0x00000fff;
+    new_phy_addr = BX_CPU_THIS_PTR prev_phy_page | new_linear_offset;
+
+    BX_CPU_THIS_PTR bytesleft = 16;
+  
+    if(!sid_prefetch_data)
+        sid_prefetch_data = new Bit8u[16];
+
+#if X86_CPU_DEBUG
+      printf("Revalidating prefetch: Prefetching 16 new bytes from %p...\n", new_phy_addr);
+#endif
+      
+    BX_CPU_THIS_PTR mem->read_physical(this, new_phy_addr, 16, (void *)sid_prefetch_data);
+    
+    BX_CPU_THIS_PTR fetch_ptr = sid_prefetch_data;
+  }
+  else {
+    BX_CPU_THIS_PTR bytesleft = 0; // invalidate prefetch Q
+    }
+}
diff --git a/sid/component/bochs/cpu/cpu-sid.h b/sid/component/bochs/cpu/cpu-sid.h
new file mode 100644 (file)
index 0000000..3edf6ae
--- /dev/null
@@ -0,0 +1,68 @@
+//  cpu-sid.h - declaration of the sid_cpu_c class. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#ifndef __CPU_SID_H__
+#define __CPU_SID_H__
+
+// The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+// instructions and then return so that the other processors have a chance to
+// run.  This is used only when simulating multiple processors.
+// 
+// If maximum instructions have been executed, return.  A count less
+// than zero means run forever.
+#define CHECK_MAX_INSTRUCTIONS(count) \
+  if (count >= 0) {                   \
+    count--; if (count == 0) return;  \
+  }
+
+#define NEED_CPU_REG_SHORTCUTS 1
+
+#include "cpu.h"
+
+class x86_cpu;
+
+class sid_cpu_c : public BX_CPU_C {
+  public:
+    x86_cpu *sid_cpu;
+    
+    void init (sid_mem_c *addrspace);
+    void interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+                   Bit16u error_code);
+    void set_INTR(Boolean value);
+    void cpu_loop(Bit32s max_instr_count);
+    void prefetch(void);
+    void revalidate_prefetch_q(void);
+
+    Bit32u dbg_get_eflags(void);
+    Bit32u dbg_get_reg(unsigned reg);
+    Boolean dbg_set_reg(unsigned reg, Bit32u val);
+    void JCC_Jd(BxInstruction_t *i);
+    void INT3(BxInstruction_t *i);
+    void INT_Ib(BxInstruction_t *i);
+    unsigned FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+                         unsigned remain, Boolean is_32);
+};
+
+typedef void (sid_cpu_c::*SidExecutePtr_t)(BxInstruction_t *);
+
+#  define BX_CPU_CALL_METHOD_FROM_SID(func, args) \
+    (this->*((SidExecutePtr_t) (func))) args
+
+extern sid_cpu_c bx_cpu;
+
+#endif // __CPU_SID_H__
diff --git a/sid/component/bochs/cpu/cpu.cc b/sid/component/bochs/cpu/cpu.cc
new file mode 100644 (file)
index 0000000..753d49c
--- /dev/null
@@ -0,0 +1,819 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+//unsigned counter[2] = { 0, 0 };
+
+
+
+#if BX_SIM_ID == 0   // only need to define once
+// This array defines a look-up table for the even parity-ness
+// of an 8bit quantity, for optimal assignment of the parity bit
+// in the EFLAGS register
+const Boolean bx_parity_lookup[256] = {
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
+  };
+#endif
+
+
+#if BX_SMP_PROCESSORS==1
+#if BX_SUPPORT_SID
+sid_cpu_c bx_cpu;
+sid_mem_c bx_mem;
+#else
+// single processor simulation, so there's one of everything
+BX_CPU_C    bx_cpu;
+BX_MEM_C    bx_mem;
+#endif // BX_SUPPORT_SID
+#else
+// multiprocessor simulation, we need an array of cpus and memories
+BX_CPU_C    *bx_cpu_array[BX_SMP_PROCESSORS];
+BX_MEM_C    *bx_mem_array[BX_ADDRESS_SPACES];
+#endif
+
+
+
+// notes:
+//
+// check limit of CS?
+
+#ifdef REGISTER_IADDR
+extern void REGISTER_IADDR(Bit32u addr);
+#endif
+
+// The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+// instructions and then return so that the other processors have a chance to
+// run.  This is used only when simulating multiple processors.
+// 
+// If maximum instructions have been executed, return.  A count less
+// than zero means run forever.
+#define CHECK_MAX_INSTRUCTIONS(count) \
+  if (count >= 0) {                   \
+    count--; if (count == 0) return;  \
+  }
+
+#if BX_SMP_PROCESSORS==1
+#  define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1()
+#else
+#  define BX_TICK1_IF_SINGLE_PROCESSOR()
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION == 0
+  void
+BX_CPU_C::cpu_loop(Bit32s max_instr_count)
+{
+  unsigned ret;
+  BxInstruction_t i;
+  unsigned maxisize;
+  Bit8u *fetch_ptr;
+  Boolean is_32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR break_point = 0;
+#ifdef MAGIC_BREAKPOINT
+  BX_CPU_THIS_PTR magic_break = 0;
+#endif
+  BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+#endif
+
+  (void) setjmp( BX_CPU_THIS_PTR jmp_buf_env );
+
+  BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
+  BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
+
+main_cpu_loop:
+
+  // ???
+  BX_CPU_THIS_PTR EXT = 0;
+  BX_CPU_THIS_PTR errorno = 0;
+
+  // First check on events which occurred for previous instructions
+  // (traps) and ones which are asynchronous to the CPU
+  // (hardware interrupts).
+  if (BX_CPU_THIS_PTR async_event)
+    goto handle_async_event;
+
+async_events_processed:
+
+  // Now we can handle things which are synchronous to instruction
+  // execution.
+  if (BX_CPU_THIS_PTR eflags.rf) {
+    BX_CPU_THIS_PTR eflags.rf = 0;
+    }
+#if BX_X86_DEBUGGER
+  else {
+    // only bother comparing if any breakpoints enabled
+    if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+      Bit32u iaddr =
+        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base +
+        BX_CPU_THIS_PTR prev_eip;
+      Bit32u dr6_bits;
+      if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
+                                       BX_HWDebugInstruction)) ) {
+        // Add to the list of debug events thus far.
+        BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+        BX_CPU_THIS_PTR async_event = 1;
+        // If debug events are not inhibited on this boundary,
+        // fire off a debug fault.  Otherwise handle it on the next
+        // boundary. (becomes a trap)
+        if ( !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+          // Commit debug events to DR6
+          BX_CPU_THIS_PTR dr6 = BX_CPU_THIS_PTR debug_trap;
+          exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+          }
+        }
+      }
+    }
+#endif
+
+  // We have ignored processing of external interrupts and
+  // debug events on this boundary.  Reset the mask so they
+  // will be processed on the next boundary.
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+#if BX_DEBUGGER
+  {
+  Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+  if ( dbg_is_begin_instr_bpoint(
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+         debug_eip,
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+         BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+    return;
+    }
+  }
+#endif  // #if BX_DEBUGGER
+
+
+  is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+
+  if (BX_CPU_THIS_PTR bytesleft == 0) {
+    prefetch();
+    }
+  fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+  maxisize = 16;
+  if (BX_CPU_THIS_PTR bytesleft < 16)
+    maxisize = BX_CPU_THIS_PTR bytesleft;
+  ret = FetchDecode(fetch_ptr, &i, maxisize, is_32);
+
+  if (ret) {
+    if (i.ResolveModrm) {
+      // call method on BX_CPU_C object
+      BX_CPU_CALL_METHOD(i.ResolveModrm, (&i));
+      }
+    BX_CPU_THIS_PTR fetch_ptr += i.ilen;
+    BX_CPU_THIS_PTR bytesleft -= i.ilen;
+fetch_decode_OK:
+
+    if (i.rep_used && (i.attr & BxRepeatable)) {
+repeat_loop:
+      if (i.attr & BxRepeatableZF) {
+        if (i.as_32) {
+          if (ECX != 0) {
+            BX_CPU_CALL_METHOD(i.execute, (&i));
+            ECX -= 1;
+            }
+          if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
+          if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
+          if (ECX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        else {
+          if (CX != 0) {
+            BX_CPU_CALL_METHOD(i.execute, (&i));
+            CX -= 1;
+            }
+          if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
+          if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
+          if (CX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        }
+      else { // normal repeat, no concern for ZF
+        if (i.as_32) {
+          if (ECX != 0) {
+            BX_CPU_CALL_METHOD(i.execute, (&i));
+            ECX -= 1;
+            }
+          if (ECX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        else { // 16bit addrsize
+          if (CX != 0) {
+            BX_CPU_CALL_METHOD(i.execute, (&i));
+            CX -= 1;
+            }
+          if (CX == 0) goto repeat_done;
+          goto repeat_not_done;
+          }
+        }
+      // shouldn't get here from above
+repeat_not_done:
+#ifdef REGISTER_IADDR
+      REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
+#endif
+      BX_TICK1_IF_SINGLE_PROCESSOR();
+
+#if BX_DEBUGGER == 0
+      if (BX_CPU_THIS_PTR async_event) {
+        invalidate_prefetch_q();
+        goto debugger_check;
+      }
+      goto repeat_loop;
+#else  /* if BX_DEBUGGER == 1 */
+      invalidate_prefetch_q();
+      goto debugger_check;
+#endif
+
+
+repeat_done:
+      BX_CPU_THIS_PTR eip += i.ilen;
+      }
+    else {
+      // non repeating instruction
+      BX_CPU_THIS_PTR eip += i.ilen;
+      BX_CPU_CALL_METHOD(i.execute, (&i));
+      }
+
+    BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
+    BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
+#ifdef REGISTER_IADDR
+    REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
+#endif
+    BX_TICK1_IF_SINGLE_PROCESSOR();
+
+debugger_check:
+
+#if (BX_SMP_PROCESSORS>1 && BX_DEBUGGER==0)
+    // The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+    // instructions and then return so that the other processors have a chance
+    // to run.  This is used only when simulating multiple processors.  If only
+    // one processor, don't waste any cycles on it!  Also, it is not needed
+    // with the debugger because its guard mechanism provides the same
+    // functionality.
+    CHECK_MAX_INSTRUCTIONS(max_instr_count);
+#endif
+
+#if BX_DEBUGGER
+    // BW vm mode switch support is in dbg_is_begin_instr_bpoint
+    // note instr generating exceptions never reach this point.
+
+    // (mch) Read/write, time break point support
+    if (BX_CPU_THIS_PTR break_point) {
+         switch (BX_CPU_THIS_PTR break_point) {
+               case BREAK_POINT_TIME:
+                     BX_CPU_THIS_PTR info("[%lld] Caught time breakpoint\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_TIME_BREAK_POINT;
+                     return;
+               case BREAK_POINT_READ:
+                     BX_CPU_THIS_PTR info("[%lld] Caught read watch point\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_READ_WATCH_POINT;
+                     return;
+               case BREAK_POINT_WRITE:
+                     BX_CPU_THIS_PTR info("[%lld] Caught write watch point\n", bx_pc_system.time_ticks());
+                     BX_CPU_THIS_PTR stop_reason = STOP_WRITE_WATCH_POINT;
+                     return;
+               default:
+                     BX_PANIC(("Weird break point condition"));
+         }
+    }
+#ifdef MAGIC_BREAKPOINT
+    // (mch) Magic break point support
+    if (BX_CPU_THIS_PTR magic_break) {
+         if (bx_dbg.magic_break_enabled) {
+               BX_CPU_THIS_PTR info("Stopped on MAGIC BREAKPOINT\n");
+               BX_CPU_THIS_PTR stop_reason = STOP_MAGIC_BREAK_POINT;
+               return;
+         } else {
+               BX_CPU_THIS_PTR magic_break = 0;
+               BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+               BX_CPU_THIS_PTR info("Ignoring MAGIC BREAKPOINT\n");
+         }
+    }
+#endif
+    if (BX_CPU_THIS_PTR trace) {
+         BX_CPU_THIS_PTR stop_reason = STOP_TRACE;
+         return;
+    }
+#endif
+
+#if BX_DEBUGGER
+    {
+    Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+    if ( dbg_is_end_instr_bpoint(
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+           debug_eip,
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+           BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+      return;
+      }
+    }
+#endif  // #if BX_DEBUGGER
+    goto main_cpu_loop;
+    }
+  else {
+    unsigned remain, j;
+static Bit8u FetchBuffer[16];
+    Bit8u *temp_ptr;
+
+    // read all leftover bytes in current page
+    for (j=0; j<BX_CPU_THIS_PTR bytesleft; j++) {
+      FetchBuffer[j] = *fetch_ptr++;
+      }
+
+    // get remaining bytes for prefetch in next page
+    // prefetch() needs eip current
+    BX_CPU_THIS_PTR eip += BX_CPU_THIS_PTR bytesleft;
+    remain = BX_CPU_THIS_PTR bytesleft;
+    prefetch();
+
+    if (BX_CPU_THIS_PTR bytesleft < 16) {
+      // make sure (bytesleft - remain) below doesn't go negative
+      BX_PANIC(("fetch_decode: bytesleft==0 after prefetch\n"));
+      }
+    temp_ptr = fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+    // read leftover bytes in next page
+    for (; j<16; j++) {
+      FetchBuffer[j] = *temp_ptr++;
+      }
+    ret = FetchDecode(FetchBuffer, &i, 16, is_32);
+    if (ret==0)
+      BX_PANIC(("fetchdecode: cross boundary: ret==0\n"));
+    if (i.ResolveModrm) {
+      BX_CPU_CALL_METHOD(i.ResolveModrm, (&i));
+      }
+    remain = i.ilen - remain;
+
+    // note: eip has already been advanced to beginning of page
+    BX_CPU_THIS_PTR fetch_ptr = fetch_ptr + remain;
+    BX_CPU_THIS_PTR bytesleft -= remain;
+    //BX_CPU_THIS_PTR eip += remain;
+    BX_CPU_THIS_PTR eip = BX_CPU_THIS_PTR prev_eip;
+    goto fetch_decode_OK;
+    }
+
+
+
+  //
+  // This area is where we process special conditions and events.
+  //
+
+handle_async_event:
+
+  if (BX_CPU_THIS_PTR debug_trap & 0x80000000) {
+    // I made up the bitmask above to mean HALT state.
+#if BX_SMP_PROCESSORS==1
+    // for one processor, pass the time as quickly as possible until
+    // an interrupt wakes up the CPU.
+    while (1) {
+      if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+        break;
+        }
+      BX_TICK1();
+    }
+#else      /* BX_SMP_PROCESSORS != 1 */
+    // for multiprocessor simulation, even if this CPU is halted we still
+    // must give the others a chance to simulate.  If an interrupt has 
+    // arrived, then clear the HALT condition; otherwise just return from
+    // the CPU loop with stop_reason STOP_CPU_HALTED.
+    if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+      // interrupt ends the HALT condition
+      BX_CPU_THIS_PTR debug_trap = 0; // clear traps for after resume
+      BX_CPU_THIS_PTR inhibit_mask = 0; // clear inhibits for after resume
+      //bx_printf ("halt condition has been cleared in %s\n", name);
+    } else {
+      // HALT condition remains, return so other CPUs have a chance
+#if BX_DEBUGGER
+      BX_CPU_THIS_PTR stop_reason = STOP_CPU_HALTED;
+#endif
+      return;
+    }
+#endif
+  }
+
+
+  // Priority 1: Hardware Reset and Machine Checks
+  //   RESET
+  //   Machine Check
+  // (bochs doesn't support these)
+
+  // Priority 2: Trap on Task Switch
+  //   T flag in TSS is set
+  if (BX_CPU_THIS_PTR debug_trap & 0x00008000) {
+    BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
+    exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+    }
+
+  // Priority 3: External Hardware Interventions
+  //   FLUSH
+  //   STOPCLK
+  //   SMI
+  //   INIT
+  // (bochs doesn't support these)
+
+  // Priority 4: Traps on Previous Instruction
+  //   Breakpoints
+  //   Debug Trap Exceptions (TF flag set or data/IO breakpoint)
+  if ( BX_CPU_THIS_PTR debug_trap &&
+       !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+    // A trap may be inhibited on this boundary due to an instruction
+    // which loaded SS.  If so we clear the inhibit_mask below
+    // and don't execute this code until the next boundary.
+    // Commit debug events to DR6
+    BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
+    exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
+    }
+
+  // Priority 5: External Interrupts
+  //   NMI Interrupts
+  //   Maskable Hardware Interrupts
+  if (BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_INTERRUPTS) {
+    // Processing external interrupts is inhibited on this
+    // boundary because of certain instructions like STI.
+    // inhibit_mask is cleared below, in which case we will have
+    // an opportunity to check interrupts on the next instruction
+    // boundary.
+    }
+  else if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ && BX_DBG_ASYNC_INTR) {
+    Bit8u vector;
+
+    // NOTE: similar code in ::take_irq()
+#if BX_SUPPORT_APIC
+    if (BX_CPU_THIS_PTR int_from_local_apic)
+      vector = BX_CPU_THIS_PTR local_apic.acknowledge_int ();
+    else
+      vector = BX_IAC(); // may set INTR with next interrupt
+#else
+#if 0 // FIXME: look into this later
+    // if no local APIC, always acknowledge the PIC.
+    vector = BX_IAC(); // may set INTR with next interrupt
+#endif
+#endif
+    //if (bx_dbg.interrupts) BX_INFO(("decode: interrupt %u\n",
+    //                                   (unsigned) vector));
+    BX_CPU_THIS_PTR errorno = 0;
+    BX_CPU_THIS_PTR EXT   = 1; /* external event */
+    interrupt(vector, 0, 0, 0);
+    BX_INSTR_HWINTERRUPT(vector, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+    }
+#if 0 // FIXME: look into this later
+  else if (BX_HRQ && BX_DBG_ASYNC_DMA) {
+    // NOTE: similar code in ::take_dma()
+    // assert Hold Acknowledge (HLDA) and go into a bus hold state
+    BX_RAISE_HLDA();
+    }
+#endif
+  // Priority 6: Faults from fetching next instruction
+  //   Code breakpoint fault
+  //   Code segment limit violation (priority 7 on 486/Pentium)
+  //   Code page fault (priority 7 on 486/Pentium)
+  // (handled in main decode loop)
+
+  // Priority 7: Faults from decoding next instruction
+  //   Instruction length > 15 bytes
+  //   Illegal opcode
+  //   Coprocessor not available
+  // (handled in main decode loop etc)
+
+  // Priority 8: Faults on executing an instruction
+  //   Floating point execution
+  //   Overflow
+  //   Bound error
+  //   Invalid TSS
+  //   Segment not present
+  //   Stack fault
+  //   General protection
+  //   Data page fault
+  //   Alignment check
+  // (handled by rest of the code)
+
+
+  if (BX_CPU_THIS_PTR eflags.tf) {
+    // TF is set before execution of next instruction.  Schedule
+    // a debug trap (#DB) after execution.  After completion of
+    // next instruction, the code above will invoke the trap.
+    BX_CPU_THIS_PTR debug_trap |= 0x00004000; // BS flag in DR6
+    }
+#if 0 // FIXME: look into this later
+  if ( !(BX_CPU_THIS_PTR INTR ||
+         BX_CPU_THIS_PTR debug_trap ||
+         BX_HRQ ||
+         BX_CPU_THIS_PTR eflags.tf) )
+    BX_CPU_THIS_PTR async_event = 0;
+#endif
+  goto async_events_processed;
+}
+#endif  // #if BX_DYNAMIC_TRANSLATION == 0
+
+
+
+
+// boundaries of consideration:
+//
+//  * physical memory boundary: 1024k (1Megabyte) (increments of...)
+//  * A20 boundary:             1024k (1Megabyte)
+//  * page boundary:            4k
+//  * ROM boundary:             2k (dont care since we are only reading)
+//  * segment boundary:         any
+
+
+
+  void
+BX_CPU_C::prefetch(void)
+{
+  // cs:eIP
+  // prefetch QSIZE byte quantity aligned on corresponding boundary
+  Bit32u new_linear_addr;
+  Bit32u new_phy_addr;
+  Bit32u temp_eip, temp_limit;
+
+  temp_eip   = BX_CPU_THIS_PTR eip;
+  temp_limit = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled;
+
+  new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + temp_eip;
+  BX_CPU_THIS_PTR prev_linear_page = new_linear_addr & 0xfffff000;
+  if (temp_eip > temp_limit) {
+    BX_PANIC(("prefetch: EIP > CS.limit\n"));
+    }
+
+#if BX_SUPPORT_PAGING
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    // aligned block guaranteed to be all in one page, same A20 address
+    new_phy_addr = itranslate_linear(new_linear_addr, CPL==3);
+    new_phy_addr = A20ADDR(new_phy_addr);
+    }
+  else {
+#endif // BX_SUPPORT_PAGING
+    new_phy_addr = A20ADDR(new_linear_addr);
+#if BX_SUPPORT_PAGING
+    }
+#endif // BX_SUPPORT_PAGING
+
+  if ( new_phy_addr >= BX_CPU_THIS_PTR mem->len ) {
+    // don't take this out if dynamic translation enabled,
+    // otherwise you must make a check to see if bytesleft is 0 after
+    // a call to prefetch() in the dynamic code.
+    BX_PANIC(("prefetch: running in bogus memory\n"));
+    }
+
+  // max physical address as confined by page boundary
+  BX_CPU_THIS_PTR prev_phy_page = new_phy_addr & 0xfffff000;
+  BX_CPU_THIS_PTR max_phy_addr = BX_CPU_THIS_PTR prev_phy_page | 0x00000fff;
+
+  // check if segment boundary comes into play
+  //if ((temp_limit - temp_eip) < 4096) {
+  //  }
+
+  BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
+  BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
+}
+
+
+  // If control has transfered locally, it is possible the prefetch Q is
+  // still valid.  This would happen for repeat instructions, and small
+  // branches.
+  void
+BX_CPU_C::revalidate_prefetch_q(void)
+{
+  Bit32u new_linear_addr, new_linear_page, new_linear_offset;
+  Bit32u new_phy_addr;
+
+  new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + BX_CPU_THIS_PTR eip;
+
+  new_linear_page = new_linear_addr & 0xfffff000;
+  if (new_linear_page == BX_CPU_THIS_PTR prev_linear_page) {
+    // same linear address, old linear->physical translation valid
+    new_linear_offset = new_linear_addr & 0x00000fff;
+    new_phy_addr = BX_CPU_THIS_PTR prev_phy_page | new_linear_offset;
+    BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
+    BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
+    }
+  else {
+    BX_CPU_THIS_PTR bytesleft = 0; // invalidate prefetch Q
+    }
+}
+
+  void
+BX_CPU_C::invalidate_prefetch_q(void)
+{
+  BX_CPU_THIS_PTR bytesleft = 0;
+}
+
+
+
+
+#if BX_DEBUGGER
+extern unsigned int dbg_show_mask;
+
+  Boolean
+BX_CPU_C::dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+                                    Bit32u is_32)
+{
+  BX_CPU_THIS_PTR guard_found.cs  = cs;
+  BX_CPU_THIS_PTR guard_found.eip = eip;
+  BX_CPU_THIS_PTR guard_found.laddr = laddr;
+  BX_CPU_THIS_PTR guard_found.is_32bit_code = is_32;
+
+  // BW mode switch breakpoint
+  // instruction which generate exceptions never reach the end of the
+  // loop due to a long jump. Thats why we check at start of instr.
+  // Downside is that we show the instruction about to be executed
+  // (not the one generating the mode switch).
+  if (BX_CPU_THIS_PTR mode_break && 
+      (BX_CPU_THIS_PTR debug_vm != BX_CPU_THIS_PTR eflags.vm)) {
+    BX_CPU_THIS_PTR info("Caught vm mode switch breakpoint\n");
+    BX_CPU_THIS_PTR debug_vm = BX_CPU_THIS_PTR eflags.vm;
+    BX_CPU_THIS_PTR stop_reason = STOP_MODE_BREAK_POINT;
+    return 1;
+  }
+
+  if( (BX_CPU_THIS_PTR show_flag) & (dbg_show_mask)) {
+    int rv;
+    if((rv = bx_dbg_symbolic_output()))
+      return rv;
+  }
+
+  // see if debugger is looking for iaddr breakpoint of any type
+  if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_ALL) {
+#if BX_DBG_SUPPORT_VIR_BPOINT
+    if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_VIR) {
+      if (BX_CPU_THIS_PTR guard_found.icount!=0) {
+        for (unsigned i=0; i<bx_guard.iaddr.num_virtual; i++) {
+          if ( (bx_guard.iaddr.vir[i].cs  == cs) &&
+               (bx_guard.iaddr.vir[i].eip == eip) ) {
+            BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_VIR;
+            BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+            return(1); // on a breakpoint
+            }
+          }
+        }
+      }
+#endif
+#if BX_DBG_SUPPORT_LIN_BPOINT
+    if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_LIN) {
+      if (BX_CPU_THIS_PTR guard_found.icount!=0) {
+        for (unsigned i=0; i<bx_guard.iaddr.num_linear; i++) {
+          if ( bx_guard.iaddr.lin[i].addr == BX_CPU_THIS_PTR guard_found.laddr ) {
+            BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_LIN;
+            BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+            return(1); // on a breakpoint
+            }
+          }
+        }
+      }
+#endif
+#if BX_DBG_SUPPORT_PHY_BPOINT
+    if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_PHY) {
+      Bit32u phy;
+      Boolean valid;
+      dbg_xlate_linear2phy(BX_CPU_THIS_PTR guard_found.laddr,
+                              &phy, &valid);
+      if ( (BX_CPU_THIS_PTR guard_found.icount!=0) && valid ) {
+        for (unsigned i=0; i<bx_guard.iaddr.num_physical; i++) {
+          if ( bx_guard.iaddr.phy[i].addr == phy ) {
+            BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_PHY;
+            BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+            return(1); // on a breakpoint
+            }
+          }
+        }
+      }
+#endif
+    }
+  return(0); // not on a breakpoint
+}
+
+
+  Boolean
+BX_CPU_C::dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+                                  Bit32u is_32)
+{
+  BX_CPU_THIS_PTR guard_found.icount++;
+
+  // see if debugger requesting icount guard
+  if (bx_guard.guard_for & BX_DBG_GUARD_ICOUNT) {
+    if (BX_CPU_THIS_PTR guard_found.icount >= bx_guard.icount) {
+      BX_CPU_THIS_PTR guard_found.cs  = cs;
+      BX_CPU_THIS_PTR guard_found.eip = eip;
+      BX_CPU_THIS_PTR guard_found.laddr = laddr;
+      BX_CPU_THIS_PTR guard_found.is_32bit_code = is_32;
+      BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_ICOUNT;
+      return(1);
+      }
+    }
+
+  // convenient point to see if user typed Ctrl-C
+  if (bx_guard.interrupt_requested &&
+      (bx_guard.guard_for & BX_DBG_GUARD_CTRL_C)) {
+    BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_CTRL_C;
+    return(1);
+    }
+
+#if (BX_NUM_SIMULATORS >= 2)
+  // if async event pending, acknowlege them
+  if (bx_guard.async_changes_pending.which) {
+    if (bx_guard.async_changes_pending.which & BX_DBG_ASYNC_PENDING_A20)
+      bx_dbg_async_pin_ack(BX_DBG_ASYNC_PENDING_A20,
+                           bx_guard.async_changes_pending.a20);
+    if (bx_guard.async_changes_pending.which) {
+      BX_PANIC(("decode: async pending unrecognized.\n"));
+      }
+    }
+#endif
+  return(0); // no breakpoint
+}
+
+
+  void
+BX_CPU_C::dbg_take_irq(void)
+{
+  unsigned vector;
+
+  // NOTE: similar code in ::cpu_loop()
+
+  if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+    if ( setjmp(BX_CPU_THIS_PTR jmp_buf_env) == 0 ) {
+      // normal return from setjmp setup
+      vector = BX_IAC(); // may set INTR with next interrupt
+      BX_CPU_THIS_PTR errorno = 0;
+      BX_CPU_THIS_PTR EXT   = 1; // external event
+      BX_CPU_THIS_PTR async_event = 1; // set in case INTR is triggered
+      interrupt(vector, 0, 0, 0);
+      }
+    }
+}
+
+  void
+BX_CPU_C::dbg_force_interrupt(unsigned vector)
+{
+  // Used to force slave simulator to take an interrupt, without
+  // regard to IF
+
+  if ( setjmp(BX_CPU_THIS_PTR jmp_buf_env) == 0 ) {
+    // normal return from setjmp setup
+    BX_CPU_THIS_PTR errorno = 0;
+    BX_CPU_THIS_PTR EXT   = 1; // external event
+    BX_CPU_THIS_PTR async_event = 1; // probably don't need this
+    interrupt(vector, 0, 0, 0);
+    }
+}
+
+  void
+BX_CPU_C::dbg_take_dma(void)
+{
+  // NOTE: similar code in ::cpu_loop()
+  if ( BX_HRQ ) {
+    BX_CPU_THIS_PTR async_event = 1; // set in case INTR is triggered
+    BX_RAISE_HLDA();
+    }
+}
+#endif  // #if BX_DEBUGGER
+
diff --git a/sid/component/bochs/cpu/cpu.h b/sid/component/bochs/cpu/cpu.h
new file mode 100644 (file)
index 0000000..006e326
--- /dev/null
@@ -0,0 +1,1807 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#ifndef BX_CPU_H
+#  define BX_CPU_H 1
+
+#include <setjmp.h>
+
+#include "cpu/lazy_flags.h"
+
+
+#define BX_SREG_ES    0
+#define BX_SREG_CS    1
+#define BX_SREG_SS    2
+#define BX_SREG_DS    3
+#define BX_SREG_FS    4
+#define BX_SREG_GS    5
+
+// segment register encoding
+#define BX_SEG_REG_ES    0
+#define BX_SEG_REG_CS    1
+#define BX_SEG_REG_SS    2
+#define BX_SEG_REG_DS    3
+#define BX_SEG_REG_FS    4
+#define BX_SEG_REG_GS    5
+#define BX_SEG_REG_NULL  8
+#define BX_NULL_SEG_REG(seg) ((seg) & BX_SEG_REG_NULL)
+
+
+#ifdef BX_LITTLE_ENDIAN
+#define BX_REG8L_OFFSET 0
+#define BX_REG8H_OFFSET 1
+#define BX_REG16_OFFSET 0
+#else // BX_BIG_ENDIAN
+#define BX_REG8L_OFFSET 3
+#define BX_REG8H_OFFSET 2
+#define BX_REG16_OFFSET 2
+#endif // ifdef BX_LITTLE_ENDIAN
+
+#define BX_8BIT_REG_AL  0
+#define BX_8BIT_REG_CL  1
+#define BX_8BIT_REG_DL  2
+#define BX_8BIT_REG_BL  3
+#define BX_8BIT_REG_AH  4
+#define BX_8BIT_REG_CH  5
+#define BX_8BIT_REG_DH  6
+#define BX_8BIT_REG_BH  7
+
+#define BX_16BIT_REG_AX 0
+#define BX_16BIT_REG_CX 1
+#define BX_16BIT_REG_DX 2
+#define BX_16BIT_REG_BX 3
+#define BX_16BIT_REG_SP 4
+#define BX_16BIT_REG_BP 5
+#define BX_16BIT_REG_SI 6
+#define BX_16BIT_REG_DI 7
+
+#define BX_32BIT_REG_EAX 0
+#define BX_32BIT_REG_ECX 1
+#define BX_32BIT_REG_EDX 2
+#define BX_32BIT_REG_EBX 3
+#define BX_32BIT_REG_ESP 4
+#define BX_32BIT_REG_EBP 5
+#define BX_32BIT_REG_ESI 6
+#define BX_32BIT_REG_EDI 7
+
+
+#if defined(NEED_CPU_REG_SHORTCUTS)
+
+/* WARNING: 
+   Only BX_CPU_C member functions can use these shortcuts safely!
+   Functions that use the shortcuts outside of BX_CPU_C might work 
+   when BX_USE_CPU_SMF=1 but will fail when BX_USE_CPU_SMF=0
+   (for example in SMP mode).
+*/
+
+// access to 8 bit general registers
+#define AL (BX_CPU_THIS_PTR gen_reg[0].word.byte.rl)
+#define CL (BX_CPU_THIS_PTR gen_reg[1].word.byte.rl)
+#define DL (BX_CPU_THIS_PTR gen_reg[2].word.byte.rl)
+#define BL (BX_CPU_THIS_PTR gen_reg[3].word.byte.rl)
+#define AH (BX_CPU_THIS_PTR gen_reg[0].word.byte.rh)
+#define CH (BX_CPU_THIS_PTR gen_reg[1].word.byte.rh)
+#define DH (BX_CPU_THIS_PTR gen_reg[2].word.byte.rh)
+#define BH (BX_CPU_THIS_PTR gen_reg[3].word.byte.rh)
+
+
+// access to 16 bit general registers
+#define AX (BX_CPU_THIS_PTR gen_reg[0].word.rx)
+#define CX (BX_CPU_THIS_PTR gen_reg[1].word.rx)
+#define DX (BX_CPU_THIS_PTR gen_reg[2].word.rx)
+#define BX (BX_CPU_THIS_PTR gen_reg[3].word.rx)
+#define SP (BX_CPU_THIS_PTR gen_reg[4].word.rx)
+#define BP (BX_CPU_THIS_PTR gen_reg[5].word.rx)
+#define SI (BX_CPU_THIS_PTR gen_reg[6].word.rx)
+#define DI (BX_CPU_THIS_PTR gen_reg[7].word.rx)
+
+// access to 16 bit instruction pointer
+#define IP (* (Bit16u *) (((Bit8u *) &BX_CPU_THIS_PTR eip) + BX_REG16_OFFSET))
+
+
+// accesss to 32 bit general registers
+#define EAX BX_CPU_THIS_PTR gen_reg[0].erx
+#define ECX BX_CPU_THIS_PTR gen_reg[1].erx
+#define EDX BX_CPU_THIS_PTR gen_reg[2].erx
+#define EBX BX_CPU_THIS_PTR gen_reg[3].erx
+#define ESP BX_CPU_THIS_PTR gen_reg[4].erx
+#define EBP BX_CPU_THIS_PTR gen_reg[5].erx
+#define ESI BX_CPU_THIS_PTR gen_reg[6].erx
+#define EDI BX_CPU_THIS_PTR gen_reg[7].erx
+
+// access to 32 bit instruction pointer
+#define EIP BX_CPU_THIS_PTR eip
+
+
+#define BX_READ_8BIT_REG(index)  (((index) < 4) ? \
+  (BX_CPU_THIS_PTR gen_reg[index].word.byte.rl) : \
+  (BX_CPU_THIS_PTR gen_reg[(index)-4].word.byte.rh))
+#define BX_READ_16BIT_REG(index) (BX_CPU_THIS_PTR gen_reg[index].word.rx)
+#define BX_READ_32BIT_REG(index) (BX_CPU_THIS_PTR gen_reg[index].erx)
+
+#define BX_READ_16BIT_BASE_REG(var, index) {\
+  var = *BX_CPU_THIS_PTR _16bit_base_reg[index];\
+  }
+
+#define BX_READ_16BIT_INDEX_REG(var, index) {\
+  var = *BX_CPU_THIS_PTR _16bit_index_reg[index];\
+  }
+
+#define BX_WRITE_8BIT_REG(index, val) {\
+  if ((index) < 4) \
+    BX_CPU_THIS_PTR gen_reg[index].word.byte.rl = val; \
+  else \
+    BX_CPU_THIS_PTR gen_reg[(index)-4].word.byte.rh = val; \
+  }
+#define BX_WRITE_16BIT_REG(index, val) {\
+  BX_CPU_THIS_PTR gen_reg[index].word.rx = val; \
+  }
+#define BX_WRITE_32BIT_REG(index, val) {\
+  BX_CPU_THIS_PTR gen_reg[index].erx = val; \
+  }
+
+
+
+
+#define TF BX_CPU_THIS_PTR eflags.tf
+#define IF BX_CPU_THIS_PTR eflags.if_
+#define DF BX_CPU_THIS_PTR eflags.df
+
+#define IOPL BX_CPU_THIS_PTR eflags.iopl
+#ifndef CPL
+#define CPL  (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl)
+#endif
+
+
+#endif  // defined(NEED_CPU_REG_SHORTCUTS)
+
+#define BX_DE_EXCEPTION   0 // Divide Error (fault)
+#define BX_DB_EXCEPTION   1 // Debug (fault/trap)
+#define BX_BP_EXCEPTION   3 // Breakpoint (trap)
+#define BX_OF_EXCEPTION   4 // Overflow (trap)
+#define BX_BR_EXCEPTION   5 // BOUND (fault)
+#define BX_UD_EXCEPTION   6
+#define BX_NM_EXCEPTION   7
+#define BX_DF_EXCEPTION   8
+#define BX_TS_EXCEPTION  10
+#define BX_NP_EXCEPTION  11
+#define BX_SS_EXCEPTION  12
+#define BX_GP_EXCEPTION  13
+#define BX_PF_EXCEPTION  14
+#define BX_MF_EXCEPTION  16
+#define BX_AC_EXCEPTION  17
+
+
+
+
+
+typedef struct {
+  /* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
+   * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
+   *  0| 0| 0| 0| 0| 0| 0| 0| 0| 0|ID|VP|VF|AC|VM|RF
+   *
+   * 15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0
+   * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
+   *  0|NT| IOPL|OF|DF|IF|TF|SF|ZF| 0|AF| 0|PF| 1|CF
+   */
+
+  // In order to get access to these fields from the Dynamic Translation
+  // code, using only 8bit offsets, I needed to move these fields
+  // together.
+  Bit32u  cf;
+  Bit32u  af;
+  Bit32u  zf;
+  Bit32u  sf;
+  Bit32u  of;
+
+  Boolean bit1;
+  Bit8u   pf_byte;  /* PF derived from last result byte when needed */
+  Boolean bit3;
+  Boolean bit5;
+  Boolean tf;
+  Boolean if_;
+  Boolean df;
+#if BX_CPU_LEVEL >= 2
+  Bit8u   iopl;
+  Boolean nt;
+#endif
+  Boolean bit15;
+#if BX_CPU_LEVEL >= 3
+  Boolean rf;
+  Boolean vm;
+#endif
+#if BX_CPU_LEVEL >= 4
+  Boolean ac;  // alignment check
+  // Boolean vif; // Virtual Interrupt Flag
+  // Boolean vip; // Virtual Interrupt Pending
+  Boolean id;  // late model 486 and beyond had CPUID
+#endif
+  } bx_flags_reg_t;
+
+
+#if BX_CPU_LEVEL >= 2
+typedef struct {
+  Bit32u  val32; // 32bit value of register
+
+  // bitfields broken out for efficient access
+#if BX_CPU_LEVEL >= 3
+  Boolean pg; // paging
+#endif
+
+// CR0 notes:
+//   Each x86 level has its own quirks regarding how it handles
+//   reserved bits.  I used DOS DEBUG.EXE in real mode on the
+//   following processors, tried to clear bits 1..30, then tried
+//   to set bits 1..30, to see how these bits are handled.
+//   I found the following:
+//
+//   Processor    try to clear bits 1..30    try to set bits 1..30
+//   386          7FFFFFF0                   7FFFFFFE
+//   486DX2       00000010                   6005003E
+//   Pentium      00000010                   7FFFFFFE
+//   Pentium-II   00000010                   6005003E
+//
+// My assumptions:
+//   All processors: bit 4 is hardwired to 1 (not true on all clones)
+//   386: bits 5..30 of CR0 are also hardwired to 1
+//   Pentium: reserved bits retain value set using mov cr0, reg32
+//   486DX2/Pentium-II: reserved bits are hardwired to 0
+
+#if BX_CPU_LEVEL >= 4
+  Boolean cd; // cache disable
+  Boolean nw; // no write-through
+  Boolean am; // alignment mask
+  Boolean wp; // write-protect
+  Boolean ne; // numerics exception
+#endif
+
+  Boolean ts; // task switched
+  Boolean em; // emulate math coprocessor
+  Boolean mp; // monitor coprocessor
+  Boolean pe; // protected mode enable
+  } bx_cr0_t;
+#endif
+
+
+typedef struct { /* bx_selector_t */
+  Bit16u value;   /* the 16bit value of the selector */
+#if BX_CPU_LEVEL >= 2
+    /* the following fields are extracted from the value field in protected
+       mode only.  They're used for sake of efficiency */
+  Bit16u index;   /* 13bit index extracted from value in protected mode */
+  Bit8u  ti;      /* table indicator bit extracted from value */
+  Bit8u  rpl;     /* RPL extracted from value */
+#endif
+  } bx_selector_t;
+
+
+
+typedef struct {
+  Boolean valid;         /* 0 = invalid, 1 = valid */
+  Boolean p;             /* present */
+  Bit8u   dpl;           /* descriptor privilege level 0..3 */
+  Boolean segment;       /* 0 = system/gate, 1 = data/code segment */
+  Bit8u   type;          /* For system & gate descriptors, only
+                          *  0 = invalid descriptor (reserved)
+                          *  1 = 286 available Task State Segment (TSS)
+                          *  2 = LDT descriptor
+                          *  3 = 286 busy Task State Segment (TSS)
+                          *  4 = 286 call gate
+                          *  5 = task gate
+                          *  6 = 286 interrupt gate
+                          *  7 = 286 trap gate
+                          *  8 = (reserved)
+                          *  9 = 386 available TSS
+                          * 10 = (reserved)
+                          * 11 = 386 busy TSS
+                          * 12 = 386 call gate
+                          * 13 = (reserved)
+                          * 14 = 386 interrupt gate
+                          * 15 = 386 trap gate */
+  union {
+  struct {
+    Boolean executable;    /* 1=code, 0=data or stack segment */
+    Boolean c_ed;          /* for code: 1=conforming,
+                              for data/stack: 1=expand down */
+    Boolean r_w;           /* for code: readable?, for data/stack: writeable? */
+    Boolean a;             /* accessed? */
+    Bit32u  base;          /* base address: 286=24bits, 386=32bits */
+    Bit32u  limit;         /* limit: 286=16bits, 386=20bits */
+    Bit32u  limit_scaled;  /* for efficiency, this contrived field is set to
+                            * limit for byte granular, and
+                            * (limit << 12) | 0xfff for page granular seg's
+                            */
+#if BX_CPU_LEVEL >= 3
+    Boolean g;             /* granularity: 0=byte, 1=4K (page) */
+    Boolean d_b;           /* default size: 0=16bit, 1=32bit */
+    Boolean avl;           /* available for use by system */
+#endif
+    } segment;
+  struct {
+    Bit8u   word_count;    /* 5bits (0..31) #words to copy from caller's stack
+                            * to called procedure's stack.  (call gates only)*/
+    Bit16u  dest_selector;
+    Bit16u  dest_offset;
+    } gate286;
+  struct {                 // type 5: Task Gate Descriptor
+    Bit16u  tss_selector;  // TSS segment selector
+    } taskgate;
+#if BX_CPU_LEVEL >= 3
+  struct {
+    Bit8u   dword_count;   /* 5bits (0..31) #dwords to copy from caller's stack
+                            * to called procedure's stack.  (call gates only)*/
+    Bit16u  dest_selector;
+    Bit32u  dest_offset;
+    } gate386;
+#endif
+  struct {
+    Bit32u  base;          /* 24 bit 286 TSS base  */
+    Bit16u  limit;         /* 16 bit 286 TSS limit */
+    } tss286;
+#if BX_CPU_LEVEL >= 3
+  struct {
+    Bit32u  base;          /* 32 bit 386 TSS base  */
+    Bit32u  limit;         /* 20 bit 386 TSS limit */
+    Bit32u  limit_scaled;  // Same notes as for 'segment' field
+    Boolean g;             /* granularity: 0=byte, 1=4K (page) */
+    Boolean avl;           /* available for use by system */
+    } tss386;
+#endif
+  struct {
+    Bit32u  base;  /* 286=24 386+ =32 bit LDT base */
+    Bit16u  limit; /* 286+ =16 bit LDT limit */
+    } ldt;
+    } u;
+
+  } bx_descriptor_t;
+
+typedef struct {
+  bx_selector_t          selector;
+  bx_descriptor_t  cache;
+  } bx_segment_reg_t;
+
+typedef void * (*BxVoidFPtr_t)(void);
+class BX_CPU_C;
+#if BX_SUPPORT_SID
+class sid_cpu_c;
+#endif
+
+typedef struct BxInstruction_tag {
+  // prefix stuff here...
+  unsigned attr; // attribute from fetchdecode
+  unsigned b1; // opcode1 byte
+  unsigned rep_used;
+  unsigned modrm; // mod-nnn-r/m byte
+    unsigned mod;
+    unsigned nnn;
+    unsigned rm;
+  Bit16u displ16u; // for 16-bit modrm forms
+  Bit32u displ32u; // for 32-bit modrm forms
+  unsigned seg;
+  unsigned sib; // scale-index-base (2nd modrm byte)
+    unsigned scale;
+    unsigned index;
+    unsigned base;
+  Bit32u   addr_displacement; // address displacement
+  Bit32u   rm_addr;
+  Bit32u   Id;
+  Bit16u   Iw;
+  Bit8u    Ib;
+  Bit8u    Ib2; // for ENTER_IwIb
+  Bit16u   Iw2; // for JMP_Ap
+  unsigned ilen; // instruction length
+  unsigned os_32, as_32; // OperandSize/AddressSize is 32bit
+  unsigned flags_in, flags_out; // flags needed, flags modified
+
+#if BX_USE_CPU_SMF
+  void (*ResolveModrm)(BxInstruction_tag *);
+  void (*execute)(BxInstruction_tag *);
+#else
+  void (BX_CPU_C::*ResolveModrm)(BxInstruction_tag *);
+  void (BX_CPU_C::*execute)(BxInstruction_tag *);
+#if BX_SUPPORT_SID
+  void (sid_cpu_c::*execute_sid)(BxInstruction_tag *);
+#endif
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+  BxVoidFPtr_t DTResolveModrm;
+#endif
+#if BX_DYNAMIC_TRANSLATION
+  unsigned DTAttr;
+  Bit8u *   (*DTFPtr)(Bit8u *, BxInstruction_tag *);
+  unsigned DTMemRegsUsed;
+#endif
+  } BxInstruction_t;
+
+#if BX_USE_CPU_SMF
+typedef void (*BxExecutePtr_t)(BxInstruction_t *);
+#else
+typedef void (BX_CPU_C::*BxExecutePtr_t)(BxInstruction_t *);
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION
+typedef Bit8u * (*BxDTASResolveModrm_t)(Bit8u *, BxInstruction_t *,
+  unsigned, unsigned);
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION
+// Arrays of function pointers which handle a specific
+// mod-rm address format
+extern BxDTASResolveModrm_t  BxDTResolve32Mod0[];
+extern BxDTASResolveModrm_t  BxDTResolve32Mod1or2[];
+extern BxDTASResolveModrm_t  BxDTResolve32Mod0Base[];
+extern BxDTASResolveModrm_t  BxDTResolve32Mod1or2Base[];
+extern BxDTASResolveModrm_t  BxDTResolve16Mod1or2[];
+extern BxDTASResolveModrm_t  BxDTResolve16Mod0[];
+#endif
+
+
+#if BX_CPU_LEVEL < 2
+  /* no GDTR or IDTR register in an 8086 */
+#else
+typedef struct {
+  Bit32u                 base;      /* base address: 24bits=286,32bits=386 */
+  Bit16u                 limit;     /* limit, 16bits */
+  } bx_global_segment_reg_t;
+#endif
+
+
+
+
+#if BX_USE_TLB
+  typedef struct {
+    Bit32u lpf; // linear page frame
+    Bit32u ppf; // physical page frame
+    Bit32u pte_addr; // Page Table Address for updating A & D bits
+    Bit32u combined_access;
+    } bx_TLB_entry;
+#endif  // #if BX_USE_TLB
+
+
+
+#ifdef BX_BIG_ENDIAN
+typedef struct {
+  union {
+    Bit32u erx;
+    struct {
+      Bit16u word_filler;
+      union {
+        Bit16u rx;
+        struct {
+          Bit8u rh;
+          Bit8u rl;
+          } byte;
+        };
+      } word;
+    };
+  } bx_gen_reg_t;
+#else
+typedef struct {
+  union {
+    Bit32u erx;
+    struct {
+      union {
+        Bit16u rx;
+        struct {
+          Bit8u rl;
+          Bit8u rh;
+          } byte;
+        };
+      Bit16u word_filler;
+      } word;
+    };
+  } bx_gen_reg_t;
+#endif
+
+
+typedef enum {
+  APIC_TYPE_NONE,
+  APIC_TYPE_IOAPIC,
+  APIC_TYPE_LOCAL_APIC
+} bx_apic_type_t;
+
+#if BX_SUPPORT_APIC
+class bx_generic_apic_c : public logfunctions {
+protected:
+  Bit32u base_addr;
+  Bit8u id;
+#define APIC_UNKNOWN_ID 0xff
+#define APIC_VERSION_ID 0x00170011  // same version as 82093 IOAPIC
+public:
+  bx_generic_apic_c ();
+  virtual ~bx_generic_apic_c ();
+  virtual void init ();
+  virtual void hwreset () { }
+  Bit32u get_base (void) { return base_addr; }
+  void set_base (Bit32u newbase);
+  void set_id (Bit8u newid);
+  Bit8u get_id () { return id; }
+  virtual char *get_name();
+  Boolean is_selected (Bit32u addr, Bit32u len);
+  void read (Bit32u addr, void *data, unsigned len);
+  virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
+  virtual void write(Bit32u address, Bit32u *value, unsigned len);
+  virtual void startup_msg (Bit32u vector);
+  // on local APIC, trigger means deliver to the CPU.
+  // on I/O APIC, trigger means direct to another APIC according to table.
+  virtual void trigger_irq (unsigned num, unsigned from);
+  virtual void untrigger_irq (unsigned num, unsigned from);
+  virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode);
+  Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode);
+  virtual Boolean match_logical_addr (Bit8u address);
+  virtual bx_apic_type_t get_type ();
+};
+
+class bx_local_apic_c : public bx_generic_apic_c {
+#define BX_LOCAL_APIC_MAX_INTS 256
+  // TMR=trigger mode register.  Cleared for edge-triggered interrupts
+  // and set for level-triggered interrupts.  If set, local APIC must send
+  // EOI message to all other APICs.  EOI's are not implemented.
+  Bit8u tmr[BX_LOCAL_APIC_MAX_INTS];
+  // IRR=interrupt request register.  When an interrupt is triggered by
+  // the I/O APIC or another processor, it sets a bit in irr.  The bit is
+  // cleared when the interrupt is acknowledged by the processor.
+  Bit8u irr[BX_LOCAL_APIC_MAX_INTS];
+  // ISR=in-service register.  When an IRR bit is cleared, the corresponding
+  // bit in ISR is set.  The ISR bit is cleared when 
+  Bit8u isr[BX_LOCAL_APIC_MAX_INTS];
+  Bit32u arb_id, arb_priority, task_priority, log_dest, dest_format, spurious_vec;
+  Bit32u lvt[6];
+#define APIC_LVT_TIMER   0
+#define APIC_LVT_THERMAL 1
+#define APIC_LVT_PERFORM 2
+#define APIC_LVT_LINT0   3
+#define APIC_LVT_LINT1   4
+#define APIC_LVT_ERROR   5
+  Bit32u timer_initial, timer_current, timer_divconf;
+  Boolean timer_active;  // internal state, not accessible from bus
+  Bit32u timer_divide_counter, timer_divide_factor;
+  Bit32u apic_base_msr;
+  Bit32u icr_high, icr_low;
+  Bit32u err_status;
+#define APIC_ERR_ILLEGAL_ADDR    0x80
+#define APIC_ERR_RX_ILLEGAL_VEC  0x40
+#define APIC_ERR_TX_ILLEGAL_VEC  0x20
+#define APIC_ERR_RX_ACCEPT_ERR   0x08
+#define APIC_ERR_TX_ACCEPT_ERR   0x04
+#define APIC_ERR_RX_CHECKSUM     0x02
+#define APIC_ERR_TX_CHECKSUM     0x01
+public:
+  bx_local_apic_c(BX_CPU_C *mycpu);
+  virtual ~bx_local_apic_c(void);
+  BX_CPU_C *cpu;
+  virtual void hwreset ();
+  virtual void init ();
+  BX_CPU_C *get_cpu (Bit8u id);
+  void set_id (Bit8u newid);   // redefine to set cpu->name
+  virtual char *get_name();
+  virtual void write (Bit32u addr, Bit32u *data, unsigned len);
+  virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
+  virtual void startup_msg (Bit32u vector);
+  // on local APIC, trigger means raise the CPU's INTR line.  For now
+  // I also have to raise pc_system.INTR but that should be replaced
+  // with the cpu-specific INTR signals.
+  virtual void trigger_irq (unsigned num, unsigned from);
+  virtual void untrigger_irq (unsigned num, unsigned from);
+  Bit8u acknowledge_int ();  // only the local CPU should call this
+  int highest_priority_int (Bit8u *array);
+  void service_local_apic ();
+  void print_status ();
+  virtual Boolean match_logical_addr (Bit8u address);
+  virtual Boolean is_local_apic () { return true; }
+  virtual bx_apic_type_t get_type () { return APIC_TYPE_LOCAL_APIC; }
+  virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode);
+  Bit8u get_ppr ();
+  Bit8u get_apr ();
+  void periodic (Bit32u usec_delta);
+  void set_divide_configuration (Bit32u value);
+  };
+
+#define APIC_MAX_ID 16
+extern bx_generic_apic_c *apic_index[APIC_MAX_ID];
+#endif // if BX_SUPPORT_APIC
+
+
+#if BX_USE_CPU_SMF == 0
+// normal member functions.  This can ONLY be used within BX_CPU_C classes.
+// Anyone on the outside should use the BX_CPU macro (defined in bochs.h) 
+// instead.
+#  define BX_CPU_THIS_PTR  this->
+#  define BX_SMF
+#  define BX_CPU_C_PREFIX  BX_CPU_C::
+// with normal member functions, calling a member fn pointer looks like
+// object->*(fnptr)(arg, ...);
+// Since this is different from when SMF=1, encapsulate it in a macro.
+#  define BX_CPU_CALL_METHOD(func, args) \
+    (this->*((BxExecutePtr_t) (func))) args
+#else
+// static member functions.  With SMF, there is only one CPU by definition.
+#  define BX_CPU_THIS_PTR  BX_CPU(0)->
+#  define BX_SMF           static
+#  define BX_CPU_C_PREFIX
+#  define BX_CPU_CALL_METHOD(func, args) \
+    ((BxExecutePtr_t) (func)) args
+#endif
+
+typedef void (*BxDTShim_t)(void);
+
+#if BX_SUPPORT_SID
+class sid_mem_c;
+#else
+class BX_MEM_C;
+#endif
+
+class BX_CPU_C : public logfunctions {
+
+public: // for now...
+
+  char name[64];
+
+  // General register set
+  // eax: accumulator
+  // ebx: base
+  // ecx: count
+  // edx: data
+  // ebp: base pointer
+  // esi: source index
+  // edi: destination index
+  // esp: stack pointer
+  bx_gen_reg_t  gen_reg[8];
+
+  Bit32u eip;    // instruction pointer
+#if BX_CPU_LEVEL > 0
+  // so that we can back up when handling faults, exceptions, etc.
+  // we need to store the value of the instruction pointer, before
+  // each fetch/execute cycle.
+  Bit32u prev_eip;
+#endif
+  // A few pointer to functions for use by the dynamic translation
+  // code.  Keep them close to the gen_reg declaration, so I can
+  // use an 8bit offset to access them.
+
+#if BX_DYNAMIC_TRANSLATION
+  BxDTShim_t DTWrite8vShim;
+  BxDTShim_t DTWrite16vShim;
+  BxDTShim_t DTWrite32vShim;
+  BxDTShim_t DTRead8vShim;
+  BxDTShim_t DTRead16vShim;
+  BxDTShim_t DTRead32vShim;
+  BxDTShim_t DTReadRMW8vShim;
+  BxDTShim_t DTReadRMW16vShim;
+  BxDTShim_t DTReadRMW32vShim;
+  BxDTShim_t DTWriteRMW8vShim;
+  BxDTShim_t DTWriteRMW16vShim;
+  BxDTShim_t DTWriteRMW32vShim;
+  BxDTShim_t DTSetFlagsOSZAPCPtr;
+  BxDTShim_t DTIndBrHandler;
+  BxDTShim_t DTDirBrHandler;
+#endif
+
+  // status and control flags register set
+  Bit32u   lf_flags_status;
+  Boolean  lf_pf;
+  bx_flags_reg_t eflags;
+
+  bx_lf_flags_entry oszapc;
+  bx_lf_flags_entry oszap;
+
+  Bit32u prev_esp;
+
+#define BX_INHIBIT_INTERRUPTS 0x01
+#define BX_INHIBIT_DEBUG      0x02
+  // What events to inhibit at any given time.  Certain instructions
+  // inhibit interrupts, some debug exceptions and single-step traps.
+  unsigned inhibit_mask;
+
+  /* user segment register set */
+  bx_segment_reg_t  sregs[6];
+
+  /* system segment registers */
+#if BX_CPU_LEVEL >= 2
+  bx_global_segment_reg_t gdtr; /* global descriptor table register */
+  bx_global_segment_reg_t idtr; /* interrupt descriptor table register */
+#endif
+  bx_segment_reg_t        ldtr; /* interrupt descriptor table register */
+  bx_segment_reg_t        tr;   /* task register */
+
+
+  /* debug registers 0-7 (unimplemented) */
+#if BX_CPU_LEVEL >= 3
+  Bit32u dr0;
+  Bit32u dr1;
+  Bit32u dr2;
+  Bit32u dr3;
+  Bit32u dr6;
+  Bit32u dr7;
+#endif
+
+  /* TR3 - TR7 (Test Register 3-7), unimplemented */
+
+  /* Control registers */
+#if BX_CPU_LEVEL >= 2
+  bx_cr0_t  cr0;
+  Bit32u    cr1;
+  Bit32u    cr2;
+  Bit32u    cr3;
+#endif
+#if BX_CPU_LEVEL >= 4
+  Bit32u    cr4;
+#endif
+
+#if BX_SUPPORT_SID
+  sid_mem_c *mem;
+#else
+  // pointer to the address space that this processor uses.
+  BX_MEM_C *mem;
+#endif
+  
+  Boolean EXT; /* 1 if processing external interrupt or exception
+                * or if not related to current instruction,
+                * 0 if current CS:IP caused exception */
+  unsigned errorno;   /* signal exception during instruction emulation */
+
+  Bit32u   debug_trap; // holds DR6 value to be set as well
+  volatile Boolean async_event;
+  volatile Boolean INTR;
+
+  // for accessing registers by index number
+  Bit16u *_16bit_base_reg[8];
+  Bit16u *_16bit_index_reg[8];
+  Bit32u empty_register;
+
+  // for decoding instructions; accessing seg reg's by index
+  unsigned sreg_mod00_rm16[8];
+  unsigned sreg_mod01_rm16[8];
+  unsigned sreg_mod10_rm16[8];
+  unsigned sreg_mod01_rm32[8];
+  unsigned sreg_mod10_rm32[8];
+  unsigned sreg_mod0_base32[8];
+  unsigned sreg_mod1or2_base32[8];
+
+  // for exceptions
+  jmp_buf jmp_buf_env;
+  Bit8u curr_exception[2];
+
+  static const Boolean is_exception_OK[3][3];
+
+  bx_segment_reg_t save_cs;
+  bx_segment_reg_t save_ss;
+  Bit32u           save_eip;
+  Bit32u           save_esp;
+
+  // For prefetch'ing instructions
+  Bit32u bytesleft;
+  Bit8u *fetch_ptr;
+  Bit32u prev_linear_page;
+  Bit32u prev_phy_page;
+  Bit32u max_phy_addr;
+
+#if BX_DEBUGGER
+  Bit8u break_point;
+#ifdef MAGIC_BREAKPOINT
+  Bit8u magic_break;
+#endif
+  Bit8u stop_reason;
+  Bit8u trace;
+  Bit8u mode_break;            /* BW */
+  Boolean debug_vm;            /* BW contains current mode*/
+  Bit8u show_eip;              /* BW record eip at special instr f.ex eip */
+  Bit8u show_flag;             /* BW shows instr class executed */
+  bx_guard_found_t guard_found;
+#endif
+
+  // for paging
+#if BX_USE_TLB
+  struct {
+    bx_TLB_entry entry[BX_TLB_SIZE];
+    } TLB;
+#endif
+
+  struct {
+    Bit32u  paddress1;  // physical address after translation of 1st len1 bytes of data
+    Bit32u  paddress2;  // physical address after translation of 2nd len2 bytes of data
+    Bit32u  len1;       // number of bytes in page 1
+    Bit32u  len2;       // number of bytes in page 2
+    unsigned pages;     // number of pages access spans (1 or 2)
+    } address_xlation;
+
+  // for lazy flags processing
+  BX_SMF Boolean get_OF(void);
+  BX_SMF Boolean get_SF(void);
+  BX_SMF Boolean get_ZF(void);
+  BX_SMF Boolean get_AF(void);
+  BX_SMF Boolean get_PF(void);
+  BX_SMF Boolean get_CF(void);
+
+  // constructors & destructors...
+  BX_CPU_C();
+  ~BX_CPU_C(void);
+#if BX_SUPPORT_SID
+  void init (sid_mem_c *addrspace);
+#else
+  void init (BX_MEM_C *addrspace);
+#endif
+
+  // prototypes for CPU instructions...
+  BX_SMF void ADD_EbGb(BxInstruction_t *);
+  BX_SMF void ADD_EdGd(BxInstruction_t *);
+  BX_SMF void ADD_GbEb(BxInstruction_t *);
+  BX_SMF void ADD_GdEd(BxInstruction_t *);
+  BX_SMF void ADD_ALIb(BxInstruction_t *);
+  BX_SMF void ADD_EAXId(BxInstruction_t *);
+  BX_SMF void OR_EbGb(BxInstruction_t *);
+  BX_SMF void OR_EdGd(BxInstruction_t *);
+  BX_SMF void OR_EwGw(BxInstruction_t *);
+  BX_SMF void OR_GbEb(BxInstruction_t *);
+  BX_SMF void OR_GdEd(BxInstruction_t *);
+  BX_SMF void OR_GwEw(BxInstruction_t *);
+  BX_SMF void OR_ALIb(BxInstruction_t *);
+  BX_SMF void OR_EAXId(BxInstruction_t *);
+  BX_SMF void OR_AXIw(BxInstruction_t *);
+
+  BX_SMF void PUSH_CS(BxInstruction_t *);
+  BX_SMF void PUSH_DS(BxInstruction_t *);
+  BX_SMF void POP_DS(BxInstruction_t *);
+  BX_SMF void PUSH_ES(BxInstruction_t *);
+  BX_SMF void POP_ES(BxInstruction_t *);
+  BX_SMF void PUSH_FS(BxInstruction_t *);
+  BX_SMF void POP_FS(BxInstruction_t *);
+  BX_SMF void PUSH_GS(BxInstruction_t *);
+  BX_SMF void POP_GS(BxInstruction_t *);
+  BX_SMF void PUSH_SS(BxInstruction_t *);
+  BX_SMF void POP_SS(BxInstruction_t *);
+
+  BX_SMF void ADC_EbGb(BxInstruction_t *);
+  BX_SMF void ADC_EdGd(BxInstruction_t *);
+  BX_SMF void ADC_GbEb(BxInstruction_t *);
+  BX_SMF void ADC_GdEd(BxInstruction_t *);
+  BX_SMF void ADC_ALIb(BxInstruction_t *);
+  BX_SMF void ADC_EAXId(BxInstruction_t *);
+  BX_SMF void SBB_EbGb(BxInstruction_t *);
+  BX_SMF void SBB_EdGd(BxInstruction_t *);
+  BX_SMF void SBB_GbEb(BxInstruction_t *);
+  BX_SMF void SBB_GdEd(BxInstruction_t *);
+  BX_SMF void SBB_ALIb(BxInstruction_t *);
+  BX_SMF void SBB_EAXId(BxInstruction_t *);
+
+  BX_SMF void AND_EbGb(BxInstruction_t *);
+  BX_SMF void AND_EdGd(BxInstruction_t *);
+  BX_SMF void AND_EwGw(BxInstruction_t *);
+  BX_SMF void AND_GbEb(BxInstruction_t *);
+  BX_SMF void AND_GdEd(BxInstruction_t *);
+  BX_SMF void AND_GwEw(BxInstruction_t *);
+  BX_SMF void AND_ALIb(BxInstruction_t *);
+  BX_SMF void AND_EAXId(BxInstruction_t *);
+  BX_SMF void AND_AXIw(BxInstruction_t *);
+  BX_SMF void DAA(BxInstruction_t *);
+  BX_SMF void SUB_EbGb(BxInstruction_t *);
+  BX_SMF void SUB_EdGd(BxInstruction_t *);
+  BX_SMF void SUB_GbEb(BxInstruction_t *);
+  BX_SMF void SUB_GdEd(BxInstruction_t *);
+  BX_SMF void SUB_ALIb(BxInstruction_t *);
+  BX_SMF void SUB_EAXId(BxInstruction_t *);
+  BX_SMF void DAS(BxInstruction_t *);
+
+  BX_SMF void XOR_EbGb(BxInstruction_t *);
+  BX_SMF void XOR_EdGd(BxInstruction_t *);
+  BX_SMF void XOR_EwGw(BxInstruction_t *);
+  BX_SMF void XOR_GbEb(BxInstruction_t *);
+  BX_SMF void XOR_GdEd(BxInstruction_t *);
+  BX_SMF void XOR_GwEw(BxInstruction_t *);
+  BX_SMF void XOR_ALIb(BxInstruction_t *);
+  BX_SMF void XOR_EAXId(BxInstruction_t *);
+  BX_SMF void XOR_AXIw(BxInstruction_t *);
+  BX_SMF void AAA(BxInstruction_t *);
+  BX_SMF void CMP_EbGb(BxInstruction_t *);
+  BX_SMF void CMP_EdGd(BxInstruction_t *);
+  BX_SMF void CMP_GbEb(BxInstruction_t *);
+  BX_SMF void CMP_GdEd(BxInstruction_t *);
+  BX_SMF void CMP_ALIb(BxInstruction_t *);
+  BX_SMF void CMP_EAXId(BxInstruction_t *);
+  BX_SMF void AAS(BxInstruction_t *);
+
+  BX_SMF void PUSHAD32(BxInstruction_t *);
+  BX_SMF void PUSHAD16(BxInstruction_t *);
+  BX_SMF void POPAD32(BxInstruction_t *);
+  BX_SMF void POPAD16(BxInstruction_t *);
+  BX_SMF void BOUND_GvMa(BxInstruction_t *);
+  BX_SMF void ARPL_EwGw(BxInstruction_t *);
+  BX_SMF void PUSH_Id(BxInstruction_t *);
+  BX_SMF void PUSH_Iw(BxInstruction_t *);
+  BX_SMF void IMUL_GdEdId(BxInstruction_t *);
+  BX_SMF void INSB_YbDX(BxInstruction_t *);
+  BX_SMF void INSW_YvDX(BxInstruction_t *);
+  BX_SMF void OUTSB_DXXb(BxInstruction_t *);
+  BX_SMF void OUTSW_DXXv(BxInstruction_t *);
+
+  BX_SMF void TEST_EbGb(BxInstruction_t *);
+  BX_SMF void TEST_EdGd(BxInstruction_t *);
+  BX_SMF void TEST_EwGw(BxInstruction_t *);
+  BX_SMF void XCHG_EbGb(BxInstruction_t *);
+  BX_SMF void XCHG_EdGd(BxInstruction_t *);
+  BX_SMF void XCHG_EwGw(BxInstruction_t *);
+  BX_SMF void MOV_EbGb(BxInstruction_t *);
+  BX_SMF void MOV_EdGd(BxInstruction_t *);
+  BX_SMF void MOV_EwGw(BxInstruction_t *);
+  BX_SMF void MOV_GbEb(BxInstruction_t *);
+  BX_SMF void MOV_GdEd(BxInstruction_t *);
+  BX_SMF void MOV_GwEw(BxInstruction_t *);
+  BX_SMF void MOV_EwSw(BxInstruction_t *);
+  BX_SMF void LEA_GdM(BxInstruction_t *);
+  BX_SMF void LEA_GwM(BxInstruction_t *);
+  BX_SMF void MOV_SwEw(BxInstruction_t *);
+  BX_SMF void POP_Ev(BxInstruction_t *);
+
+  BX_SMF void CBW(BxInstruction_t *);
+  BX_SMF void CWD(BxInstruction_t *);
+  BX_SMF void CALL32_Ap(BxInstruction_t *);
+  BX_SMF void CALL16_Ap(BxInstruction_t *);
+  BX_SMF void FWAIT(BxInstruction_t *);
+  BX_SMF void PUSHF_Fv(BxInstruction_t *);
+  BX_SMF void POPF_Fv(BxInstruction_t *);
+  BX_SMF void SAHF(BxInstruction_t *);
+  BX_SMF void LAHF(BxInstruction_t *);
+
+  BX_SMF void MOV_ALOb(BxInstruction_t *);
+  BX_SMF void MOV_EAXOd(BxInstruction_t *);
+  BX_SMF void MOV_AXOw(BxInstruction_t *);
+  BX_SMF void MOV_ObAL(BxInstruction_t *);
+  BX_SMF void MOV_OdEAX(BxInstruction_t *);
+  BX_SMF void MOV_OwAX(BxInstruction_t *);
+  BX_SMF void MOVSB_XbYb(BxInstruction_t *);
+  BX_SMF void MOVSW_XvYv(BxInstruction_t *);
+  BX_SMF void CMPSB_XbYb(BxInstruction_t *);
+  BX_SMF void CMPSW_XvYv(BxInstruction_t *);
+  BX_SMF void TEST_ALIb(BxInstruction_t *);
+  BX_SMF void TEST_EAXId(BxInstruction_t *);
+  BX_SMF void TEST_AXIw(BxInstruction_t *);
+  BX_SMF void STOSB_YbAL(BxInstruction_t *);
+  BX_SMF void STOSW_YveAX(BxInstruction_t *);
+  BX_SMF void LODSB_ALXb(BxInstruction_t *);
+  BX_SMF void LODSW_eAXXv(BxInstruction_t *);
+  BX_SMF void SCASB_ALXb(BxInstruction_t *);
+  BX_SMF void SCASW_eAXXv(BxInstruction_t *);
+
+  BX_SMF void RETnear32(BxInstruction_t *);
+  BX_SMF void RETnear16(BxInstruction_t *);
+  BX_SMF void LES_GvMp(BxInstruction_t *);
+  BX_SMF void LDS_GvMp(BxInstruction_t *);
+  BX_SMF void MOV_EbIb(BxInstruction_t *);
+  BX_SMF void MOV_EdId(BxInstruction_t *);
+  BX_SMF void MOV_EwIw(BxInstruction_t *);
+  BX_SMF void ENTER_IwIb(BxInstruction_t *);
+  BX_SMF void LEAVE(BxInstruction_t *);
+  BX_SMF void RETfar32(BxInstruction_t *);
+  BX_SMF void RETfar16(BxInstruction_t *);
+
+  BX_SMF void INT1(BxInstruction_t *);
+  BX_SMF void INT3(BxInstruction_t *);
+  BX_SMF void INT_Ib(BxInstruction_t *);
+  BX_SMF void INTO(BxInstruction_t *);
+  BX_SMF void IRET32(BxInstruction_t *);
+  BX_SMF void IRET16(BxInstruction_t *);
+
+  BX_SMF void AAM(BxInstruction_t *);
+  BX_SMF void AAD(BxInstruction_t *);
+  BX_SMF void SALC(BxInstruction_t *);
+  BX_SMF void XLAT(BxInstruction_t *);
+
+  BX_SMF void LOOPNE_Jb(BxInstruction_t *);
+  BX_SMF void LOOPE_Jb(BxInstruction_t *);
+  BX_SMF void LOOP_Jb(BxInstruction_t *);
+  BX_SMF void JCXZ_Jb(BxInstruction_t *);
+  BX_SMF void IN_ALIb(BxInstruction_t *);
+  BX_SMF void IN_eAXIb(BxInstruction_t *);
+  BX_SMF void OUT_IbAL(BxInstruction_t *);
+  BX_SMF void OUT_IbeAX(BxInstruction_t *);
+  BX_SMF void CALL_Aw(BxInstruction_t *);
+  BX_SMF void CALL_Ad(BxInstruction_t *);
+  BX_SMF void JMP_Jd(BxInstruction_t *);
+  BX_SMF void JMP_Jw(BxInstruction_t *);
+  BX_SMF void JMP_Ap(BxInstruction_t *);
+  BX_SMF void IN_ALDX(BxInstruction_t *);
+  BX_SMF void IN_eAXDX(BxInstruction_t *);
+  BX_SMF void OUT_DXAL(BxInstruction_t *);
+  BX_SMF void OUT_DXeAX(BxInstruction_t *);
+
+  BX_SMF void HLT(BxInstruction_t *);
+  BX_SMF void CMC(BxInstruction_t *);
+  BX_SMF void CLC(BxInstruction_t *);
+  BX_SMF void STC(BxInstruction_t *);
+  BX_SMF void CLI(BxInstruction_t *);
+  BX_SMF void STI(BxInstruction_t *);
+  BX_SMF void CLD(BxInstruction_t *);
+  BX_SMF void STD(BxInstruction_t *);
+
+
+  BX_SMF void LAR_GvEw(BxInstruction_t *);
+  BX_SMF void LSL_GvEw(BxInstruction_t *);
+  BX_SMF void CLTS(BxInstruction_t *);
+  BX_SMF void INVD(BxInstruction_t *);
+  BX_SMF void WBINVD(BxInstruction_t *);
+
+  BX_SMF void MOV_CdRd(BxInstruction_t *);
+  BX_SMF void MOV_DdRd(BxInstruction_t *);
+  BX_SMF void MOV_RdCd(BxInstruction_t *);
+  BX_SMF void MOV_RdDd(BxInstruction_t *);
+  BX_SMF void MOV_TdRd(BxInstruction_t *);
+  BX_SMF void MOV_RdTd(BxInstruction_t *);
+
+  BX_SMF void JCC_Jd(BxInstruction_t *);
+  BX_SMF void JCC_Jw(BxInstruction_t *);
+
+  BX_SMF void SETO_Eb(BxInstruction_t *);
+  BX_SMF void SETNO_Eb(BxInstruction_t *);
+  BX_SMF void SETB_Eb(BxInstruction_t *);
+  BX_SMF void SETNB_Eb(BxInstruction_t *);
+  BX_SMF void SETZ_Eb(BxInstruction_t *);
+  BX_SMF void SETNZ_Eb(BxInstruction_t *);
+  BX_SMF void SETBE_Eb(BxInstruction_t *);
+  BX_SMF void SETNBE_Eb(BxInstruction_t *);
+  BX_SMF void SETS_Eb(BxInstruction_t *);
+  BX_SMF void SETNS_Eb(BxInstruction_t *);
+  BX_SMF void SETP_Eb(BxInstruction_t *);
+  BX_SMF void SETNP_Eb(BxInstruction_t *);
+  BX_SMF void SETL_Eb(BxInstruction_t *);
+  BX_SMF void SETNL_Eb(BxInstruction_t *);
+  BX_SMF void SETLE_Eb(BxInstruction_t *);
+  BX_SMF void SETNLE_Eb(BxInstruction_t *);
+
+  BX_SMF void CPUID(BxInstruction_t *);
+  BX_SMF void BT_EvGv(BxInstruction_t *);
+  BX_SMF void SHLD_EdGd(BxInstruction_t *);
+  BX_SMF void SHLD_EwGw(BxInstruction_t *);
+
+
+  BX_SMF void BTS_EvGv(BxInstruction_t *);
+
+  BX_SMF void SHRD_EwGw(BxInstruction_t *);
+  BX_SMF void SHRD_EdGd(BxInstruction_t *);
+
+  BX_SMF void IMUL_GdEd(BxInstruction_t *);
+
+  BX_SMF void LSS_GvMp(BxInstruction_t *);
+  BX_SMF void BTR_EvGv(BxInstruction_t *);
+  BX_SMF void LFS_GvMp(BxInstruction_t *);
+  BX_SMF void LGS_GvMp(BxInstruction_t *);
+  BX_SMF void MOVZX_GdEb(BxInstruction_t *);
+  BX_SMF void MOVZX_GwEb(BxInstruction_t *);
+  BX_SMF void MOVZX_GdEw(BxInstruction_t *);
+  BX_SMF void MOVZX_GwEw(BxInstruction_t *);
+  BX_SMF void BTC_EvGv(BxInstruction_t *);
+  BX_SMF void BSF_GvEv(BxInstruction_t *);
+  BX_SMF void BSR_GvEv(BxInstruction_t *);
+  BX_SMF void MOVSX_GdEb(BxInstruction_t *);
+  BX_SMF void MOVSX_GwEb(BxInstruction_t *);
+  BX_SMF void MOVSX_GdEw(BxInstruction_t *);
+  BX_SMF void MOVSX_GwEw(BxInstruction_t *);
+
+  BX_SMF void BSWAP_EAX(BxInstruction_t *);
+  BX_SMF void BSWAP_ECX(BxInstruction_t *);
+  BX_SMF void BSWAP_EDX(BxInstruction_t *);
+  BX_SMF void BSWAP_EBX(BxInstruction_t *);
+  BX_SMF void BSWAP_ESP(BxInstruction_t *);
+  BX_SMF void BSWAP_EBP(BxInstruction_t *);
+  BX_SMF void BSWAP_ESI(BxInstruction_t *);
+  BX_SMF void BSWAP_EDI(BxInstruction_t *);
+
+  BX_SMF void ADD_EbIb(BxInstruction_t *);
+  BX_SMF void ADC_EbIb(BxInstruction_t *);
+  BX_SMF void SBB_EbIb(BxInstruction_t *);
+  BX_SMF void SUB_EbIb(BxInstruction_t *);
+  BX_SMF void CMP_EbIb(BxInstruction_t *);
+
+  BX_SMF void XOR_EbIb(BxInstruction_t *);
+  BX_SMF void OR_EbIb(BxInstruction_t *);
+  BX_SMF void AND_EbIb(BxInstruction_t *);
+
+  BX_SMF void ADD_EdId(BxInstruction_t *);
+  BX_SMF void OR_EdId(BxInstruction_t *);
+  BX_SMF void OR_EwIw(BxInstruction_t *);
+  BX_SMF void ADC_EdId(BxInstruction_t *);
+  BX_SMF void SBB_EdId(BxInstruction_t *);
+  BX_SMF void AND_EdId(BxInstruction_t *);
+  BX_SMF void AND_EwIw(BxInstruction_t *);
+  BX_SMF void SUB_EdId(BxInstruction_t *);
+  BX_SMF void XOR_EdId(BxInstruction_t *);
+  BX_SMF void XOR_EwIw(BxInstruction_t *);
+  BX_SMF void CMP_EdId(BxInstruction_t *);
+
+  BX_SMF void ROL_Eb(BxInstruction_t *);
+  BX_SMF void ROR_Eb(BxInstruction_t *);
+  BX_SMF void RCL_Eb(BxInstruction_t *);
+  BX_SMF void RCR_Eb(BxInstruction_t *);
+  BX_SMF void SHL_Eb(BxInstruction_t *);
+  BX_SMF void SHR_Eb(BxInstruction_t *);
+  BX_SMF void SAR_Eb(BxInstruction_t *);
+
+  BX_SMF void ROL_Ed(BxInstruction_t *);
+  BX_SMF void ROL_Ew(BxInstruction_t *);
+  BX_SMF void ROR_Ed(BxInstruction_t *);
+  BX_SMF void ROR_Ew(BxInstruction_t *);
+  BX_SMF void RCL_Ed(BxInstruction_t *);
+  BX_SMF void RCL_Ew(BxInstruction_t *);
+  BX_SMF void RCR_Ed(BxInstruction_t *);
+  BX_SMF void RCR_Ew(BxInstruction_t *);
+  BX_SMF void SHL_Ed(BxInstruction_t *);
+  BX_SMF void SHL_Ew(BxInstruction_t *);
+  BX_SMF void SHR_Ed(BxInstruction_t *);
+  BX_SMF void SHR_Ew(BxInstruction_t *);
+  BX_SMF void SAR_Ed(BxInstruction_t *);
+  BX_SMF void SAR_Ew(BxInstruction_t *);
+
+  BX_SMF void TEST_EbIb(BxInstruction_t *);
+  BX_SMF void NOT_Eb(BxInstruction_t *);
+  BX_SMF void NEG_Eb(BxInstruction_t *);
+  BX_SMF void MUL_ALEb(BxInstruction_t *);
+  BX_SMF void IMUL_ALEb(BxInstruction_t *);
+  BX_SMF void DIV_ALEb(BxInstruction_t *);
+  BX_SMF void IDIV_ALEb(BxInstruction_t *);
+
+  BX_SMF void TEST_EdId(BxInstruction_t *);
+  BX_SMF void TEST_EwIw(BxInstruction_t *);
+  BX_SMF void NOT_Ed(BxInstruction_t *);
+  BX_SMF void NOT_Ew(BxInstruction_t *);
+  BX_SMF void NEG_Ed(BxInstruction_t *);
+  BX_SMF void MUL_EAXEd(BxInstruction_t *);
+  BX_SMF void IMUL_EAXEd(BxInstruction_t *);
+  BX_SMF void DIV_EAXEd(BxInstruction_t *);
+  BX_SMF void IDIV_EAXEd(BxInstruction_t *);
+
+  BX_SMF void INC_Eb(BxInstruction_t *);
+  BX_SMF void DEC_Eb(BxInstruction_t *);
+
+  BX_SMF void INC_Ed(BxInstruction_t *);
+  BX_SMF void DEC_Ed(BxInstruction_t *);
+  BX_SMF void CALL_Ed(BxInstruction_t *);
+  BX_SMF void CALL_Ew(BxInstruction_t *);
+  BX_SMF void CALL32_Ep(BxInstruction_t *);
+  BX_SMF void CALL16_Ep(BxInstruction_t *);
+  BX_SMF void JMP_Ed(BxInstruction_t *);
+  BX_SMF void JMP_Ew(BxInstruction_t *);
+  BX_SMF void JMP32_Ep(BxInstruction_t *);
+  BX_SMF void JMP16_Ep(BxInstruction_t *);
+  BX_SMF void PUSH_Ed(BxInstruction_t *);
+  BX_SMF void PUSH_Ew(BxInstruction_t *);
+
+  BX_SMF void SLDT_Ew(BxInstruction_t *);
+  BX_SMF void STR_Ew(BxInstruction_t *);
+  BX_SMF void LLDT_Ew(BxInstruction_t *);
+  BX_SMF void LTR_Ew(BxInstruction_t *);
+  BX_SMF void VERR_Ew(BxInstruction_t *);
+  BX_SMF void VERW_Ew(BxInstruction_t *);
+
+  BX_SMF void SGDT_Ms(BxInstruction_t *);
+  BX_SMF void SIDT_Ms(BxInstruction_t *);
+  BX_SMF void LGDT_Ms(BxInstruction_t *);
+  BX_SMF void LIDT_Ms(BxInstruction_t *);
+  BX_SMF void SMSW_Ew(BxInstruction_t *);
+  BX_SMF void LMSW_Ew(BxInstruction_t *);
+
+
+  BX_SMF void BT_EvIb(BxInstruction_t *);
+  BX_SMF void BTS_EvIb(BxInstruction_t *);
+  BX_SMF void BTR_EvIb(BxInstruction_t *);
+  BX_SMF void BTC_EvIb(BxInstruction_t *);
+
+  BX_SMF void ESC0(BxInstruction_t *);
+  BX_SMF void ESC1(BxInstruction_t *);
+  BX_SMF void ESC2(BxInstruction_t *);
+  BX_SMF void ESC3(BxInstruction_t *);
+  BX_SMF void ESC4(BxInstruction_t *);
+  BX_SMF void ESC5(BxInstruction_t *);
+  BX_SMF void ESC6(BxInstruction_t *);
+  BX_SMF void ESC7(BxInstruction_t *);
+
+  BX_SMF void fpu_execute(BxInstruction_t *i);
+  BX_SMF void fpu_init(void);
+
+  BX_SMF void CMPXCHG_XBTS(BxInstruction_t *);
+  BX_SMF void CMPXCHG_IBTS(BxInstruction_t *);
+  BX_SMF void CMPXCHG_EbGb(BxInstruction_t *);
+  BX_SMF void CMPXCHG_EdGd(BxInstruction_t *);
+  BX_SMF void CMPXCHG8B(BxInstruction_t *);
+  BX_SMF void XADD_EbGb(BxInstruction_t *);
+  BX_SMF void XADD_EdGd(BxInstruction_t *);
+  BX_SMF void RETnear32_Iw(BxInstruction_t *);
+  BX_SMF void RETnear16_Iw(BxInstruction_t *);
+  BX_SMF void RETfar32_Iw(BxInstruction_t *);
+  BX_SMF void RETfar16_Iw(BxInstruction_t *);
+
+  BX_SMF void LOADALL(BxInstruction_t *);
+  BX_SMF void CMOV_GdEd(BxInstruction_t *);
+  BX_SMF void CMOV_GwEw(BxInstruction_t *);
+
+  BX_SMF void ADD_EwGw(BxInstruction_t *);
+  BX_SMF void ADD_GwEw(BxInstruction_t *);
+  BX_SMF void ADD_AXIw(BxInstruction_t *);
+  BX_SMF void ADC_EwGw(BxInstruction_t *);
+  BX_SMF void ADC_GwEw(BxInstruction_t *);
+  BX_SMF void ADC_AXIw(BxInstruction_t *);
+  BX_SMF void SBB_EwGw(BxInstruction_t *);
+  BX_SMF void SBB_GwEw(BxInstruction_t *);
+  BX_SMF void SBB_AXIw(BxInstruction_t *);
+  BX_SMF void SBB_EwIw(BxInstruction_t *);
+  BX_SMF void SUB_EwGw(BxInstruction_t *);
+  BX_SMF void SUB_GwEw(BxInstruction_t *);
+  BX_SMF void SUB_AXIw(BxInstruction_t *);
+  BX_SMF void CMP_EwGw(BxInstruction_t *);
+  BX_SMF void CMP_GwEw(BxInstruction_t *);
+  BX_SMF void CMP_AXIw(BxInstruction_t *);
+  BX_SMF void CWDE(BxInstruction_t *);
+  BX_SMF void CDQ(BxInstruction_t *);
+  BX_SMF void XADD_EwGw(BxInstruction_t *);
+  BX_SMF void ADD_EwIw(BxInstruction_t *);
+  BX_SMF void ADC_EwIw(BxInstruction_t *);
+  BX_SMF void SUB_EwIw(BxInstruction_t *);
+  BX_SMF void CMP_EwIw(BxInstruction_t *);
+  BX_SMF void NEG_Ew(BxInstruction_t *);
+  BX_SMF void INC_Ew(BxInstruction_t *);
+  BX_SMF void DEC_Ew(BxInstruction_t *);
+  BX_SMF void CMPXCHG_EwGw(BxInstruction_t *);
+  BX_SMF void MUL_AXEw(BxInstruction_t *);
+  BX_SMF void IMUL_AXEw(BxInstruction_t *);
+  BX_SMF void DIV_AXEw(BxInstruction_t *);
+  BX_SMF void IDIV_AXEw(BxInstruction_t *);
+  BX_SMF void IMUL_GwEwIw(BxInstruction_t *);
+  BX_SMF void IMUL_GwEw(BxInstruction_t *);
+  BX_SMF void NOP(BxInstruction_t *);
+  BX_SMF void MOV_RLIb(BxInstruction_t *);
+  BX_SMF void MOV_RHIb(BxInstruction_t *);
+  BX_SMF void MOV_RXIw(BxInstruction_t *);
+  BX_SMF void MOV_ERXId(BxInstruction_t *);
+  BX_SMF void INC_RX(BxInstruction_t *);
+  BX_SMF void DEC_RX(BxInstruction_t *);
+  BX_SMF void INC_ERX(BxInstruction_t *);
+  BX_SMF void DEC_ERX(BxInstruction_t *);
+  BX_SMF void PUSH_RX(BxInstruction_t *);
+  BX_SMF void POP_RX(BxInstruction_t *);
+  BX_SMF void PUSH_ERX(BxInstruction_t *);
+  BX_SMF void POP_ERX(BxInstruction_t *);
+  BX_SMF void POP_Ew(BxInstruction_t *);
+  BX_SMF void POP_Ed(BxInstruction_t *);
+  BX_SMF void XCHG_RXAX(BxInstruction_t *);
+  BX_SMF void XCHG_ERXEAX(BxInstruction_t *);
+
+  // mch added
+  BX_SMF void INVLPG(BxInstruction_t *);
+  BX_SMF void wait_for_interrupt();
+  BX_SMF void RSM(BxInstruction_t *);
+
+  BX_SMF void WRMSR(BxInstruction_t *);
+  BX_SMF void RDTSC(BxInstruction_t *);
+  BX_SMF void RDMSR(BxInstruction_t *);
+  BX_SMF void SetCR0(Bit32u val_32);
+  BX_SMF void dynamic_translate(void);
+  BX_SMF void dynamic_init(void);
+  BX_SMF unsigned FetchDecode(Bit8u *, BxInstruction_t *, unsigned, Boolean);
+  BX_SMF void UndefinedOpcode(BxInstruction_t *);
+  BX_SMF void BxError(BxInstruction_t *i);
+  BX_SMF void BxResolveError(BxInstruction_t *i);
+
+  BX_SMF void Resolve16Mod0Rm0(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm1(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm2(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm3(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm4(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm5(BxInstruction_t *);
+  BX_SMF void Resolve16Mod0Rm7(BxInstruction_t *);
+
+  BX_SMF void Resolve16Mod1or2Rm0(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm1(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm2(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm3(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm4(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm5(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm6(BxInstruction_t *);
+  BX_SMF void Resolve16Mod1or2Rm7(BxInstruction_t *);
+
+  BX_SMF void Resolve32Mod0Rm0(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Rm1(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Rm2(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Rm3(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Rm6(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Rm7(BxInstruction_t *);
+
+  BX_SMF void Resolve32Mod1or2Rm0(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm1(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm2(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm3(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm5(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm6(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Rm7(BxInstruction_t *);
+
+  BX_SMF void Resolve32Mod0Base0(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base1(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base2(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base3(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base4(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base5(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base6(BxInstruction_t *);
+  BX_SMF void Resolve32Mod0Base7(BxInstruction_t *);
+
+  BX_SMF void Resolve32Mod1or2Base0(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base1(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base2(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base3(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base4(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base5(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base6(BxInstruction_t *);
+  BX_SMF void Resolve32Mod1or2Base7(BxInstruction_t *);
+
+
+  BX_SMF void REP(void (*)(void));
+  BX_SMF void REP_ZF(void (*)(void), unsigned rep_prefix);
+#if BX_DEBUGGER
+  BX_SMF void     dbg_take_irq(void);
+  BX_SMF void     dbg_force_interrupt(unsigned vector);
+  BX_SMF void     dbg_take_dma(void);
+  BX_SMF Boolean  dbg_get_cpu(bx_dbg_cpu_t *cpu);
+  BX_SMF Boolean  dbg_set_cpu(bx_dbg_cpu_t *cpu);
+  BX_SMF Boolean  dbg_set_reg(unsigned reg, Bit32u val);
+  BX_SMF Bit32u   dbg_get_reg(unsigned reg);
+  BX_SMF Boolean  dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no);
+  BX_SMF unsigned dbg_query_pending(void);
+  BX_SMF Bit32u   dbg_get_descriptor_l(bx_descriptor_t *);
+  BX_SMF Bit32u   dbg_get_descriptor_h(bx_descriptor_t *);
+  BX_SMF Bit32u   dbg_get_eflags(void);
+  BX_SMF Boolean  dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+                                            Bit32u is_32);
+  BX_SMF Boolean  dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip,
+                                          Bit32u laddr, Bit32u is_32);
+#endif
+#if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION
+  BX_SMF void     dbg_xlate_linear2phy(Bit32u linear, Bit32u *phy, Boolean *valid);
+#endif
+  BX_SMF void     atexit(void);
+
+  // now for some ancillary functions...
+  BX_SMF void cpu_loop(Bit32s max_instr_count);
+  BX_SMF void decode_exgx16(unsigned need_fetch);
+  BX_SMF void decode_exgx32(unsigned need_fetch);
+
+  BX_SMF void prefetch(void);
+  BX_SMF void revalidate_prefetch_q(void);
+  BX_SMF void invalidate_prefetch_q(void);
+
+  BX_SMF void write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
+  BX_SMF void read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
+  BX_SMF void write_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+  BX_SMF void write_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+  BX_SMF void write_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+  BX_SMF void read_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+  BX_SMF void read_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+  BX_SMF void read_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+
+  BX_SMF void read_RMW_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+  BX_SMF void read_RMW_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+  BX_SMF void read_RMW_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+  BX_SMF void write_RMW_virtual_byte(Bit8u val8);
+  BX_SMF void write_RMW_virtual_word(Bit16u val16);
+  BX_SMF void write_RMW_virtual_dword(Bit32u val32);
+
+  BX_SMF void access_linear(Bit32u address, unsigned length, unsigned pl,
+                     unsigned rw, void *data);
+#if BX_SUPPORT_PAGING
+  BX_SMF Bit32u itranslate_linear(Bit32u laddress, unsigned pl);
+  BX_SMF Bit32u dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw);
+#endif // BX_SUPPORT_PAGING
+  BX_SMF void TLB_flush(void);
+  BX_SMF void TLB_clear(void);
+  BX_SMF void TLB_init(void);
+  BX_SMF void set_INTR(Boolean value);
+  BX_SMF char *strseg(bx_segment_reg_t *seg);
+  BX_SMF void interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+                 Bit16u error_code);
+#if BX_CPU_LEVEL >= 2
+  BX_SMF void exception(unsigned vector, Bit16u error_code, Boolean is_INT);
+#endif
+  BX_SMF int  int_number(bx_segment_reg_t *seg);
+  BX_SMF void shutdown_cpu(void);
+  BX_SMF void enable_paging(void);
+  BX_SMF void disable_paging(void);
+  BX_SMF void CR3_change(Bit32u value32);
+  BX_SMF void reset(unsigned source);
+
+  BX_SMF void jump_protected(BxInstruction_t *, Bit16u cs, Bit32u disp32);
+  BX_SMF void call_protected(BxInstruction_t *, Bit16u cs, Bit32u disp32);
+  BX_SMF void return_protected(BxInstruction_t *, Bit16u pop_bytes);
+  BX_SMF void iret_protected(BxInstruction_t *);
+  BX_SMF void validate_seg_regs(void);
+  BX_SMF void stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
+                                     Bit32u flags32);
+  BX_SMF void stack_return_from_v86(BxInstruction_t *);
+  BX_SMF void init_v8086_mode(void);
+  BX_SMF void v8086_message(void);
+  BX_SMF void task_switch(bx_selector_t *selector,
+                     bx_descriptor_t *descriptor,
+                     unsigned source,
+                     Bit32u dword1, Bit32u dword2);
+  BX_SMF void get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp);
+  BX_SMF void write_flags(Bit16u flags, Boolean change_IOPL, Boolean change_IF);
+  BX_SMF void write_eflags(Bit32u eflags, Boolean change_IOPL, Boolean change_IF,
+                    Boolean change_VM, Boolean change_RF);
+  BX_SMF Bit16u read_flags(void);
+  BX_SMF Bit32u read_eflags(void);
+
+  BX_SMF Bit8u   inp8(Bit16u addr);
+  BX_SMF void    outp8(Bit16u addr, Bit8u value);
+  BX_SMF Bit16u  inp16(Bit16u addr);
+  BX_SMF void    outp16(Bit16u addr, Bit16u value);
+  BX_SMF Bit32u  inp32(Bit16u addr);
+  BX_SMF void    outp32(Bit16u addr, Bit32u value);
+  BX_SMF Boolean allow_io(Bit16u addr, unsigned len);
+  BX_SMF void    enter_protected_mode(void);
+  BX_SMF void    enter_real_mode(void);
+  BX_SMF void    parse_selector(Bit16u raw_selector, bx_selector_t *selector);
+  BX_SMF void    parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp);
+  BX_SMF void    load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor);
+  BX_SMF void    load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl);
+  BX_SMF void    load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl);
+  BX_SMF void    fetch_raw_descriptor(bx_selector_t *selector,
+                               Bit32u *dword1, Bit32u *dword2, Bit8u exception);
+  BX_SMF void    load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value);
+  BX_SMF Boolean fetch_raw_descriptor2(bx_selector_t *selector,
+                                Bit32u *dword1, Bit32u *dword2);
+  BX_SMF void    push_16(Bit16u value16);
+  BX_SMF void    push_32(Bit32u value32);
+  BX_SMF void    pop_16(Bit16u *value16_ptr);
+  BX_SMF void    pop_32(Bit32u *value32_ptr);
+  BX_SMF Boolean can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes);
+  BX_SMF Boolean can_pop(Bit32u bytes);
+  BX_SMF void    sanity_checks(void);
+
+  BX_SMF void    debug(Bit32u offset);
+
+#if BX_X86_DEBUGGER
+  // x86 hardware debug support
+  BX_SMF Bit32u  hwdebug_compare(Bit32u laddr, unsigned size,
+                                 unsigned opa, unsigned opb);
+#endif
+
+  BX_SMF BX_CPP_INLINE void set_CF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_AF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_ZF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_SF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_OF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_PF(Boolean val);
+  BX_SMF BX_CPP_INLINE void set_PF_base(Bit8u val);
+
+
+  BX_SMF BX_CPP_INLINE void set_AX(Bit16u ax);
+  BX_SMF BX_CPP_INLINE void set_BX(Bit16u bx);
+  BX_SMF BX_CPP_INLINE void set_CX(Bit16u cx);
+  BX_SMF BX_CPP_INLINE void set_DX(Bit16u dx);
+  BX_SMF BX_CPP_INLINE void set_AL(Bit8u  al);
+  BX_SMF BX_CPP_INLINE void set_AH(Bit8u  ah);
+  BX_SMF BX_CPP_INLINE void set_BL(Bit8u  bl);
+  BX_SMF BX_CPP_INLINE void set_BH(Bit8u  bh);
+  BX_SMF BX_CPP_INLINE void set_CL(Bit8u  cl);
+  BX_SMF BX_CPP_INLINE void set_CH(Bit8u  ch);
+  BX_SMF BX_CPP_INLINE void set_DL(Bit8u  dl);
+  BX_SMF BX_CPP_INLINE void set_DH(Bit8u  dh);
+
+  BX_SMF BX_CPP_INLINE Bit8u get_AL(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_AH(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_BL(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_BH(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_CL(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_CH(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_DL(void);
+  BX_SMF BX_CPP_INLINE Bit8u get_DH(void);
+
+  BX_SMF BX_CPP_INLINE Bit16u get_AX(void);
+  BX_SMF BX_CPP_INLINE Bit16u get_BX(void);
+  BX_SMF BX_CPP_INLINE Bit16u get_CX(void);
+  BX_SMF BX_CPP_INLINE Bit16u get_DX(void);
+
+#if BX_CPU_LEVEL >= 2
+  BX_SMF BX_CPP_INLINE Boolean real_mode(void);
+#endif
+#if BX_CPU_LEVEL >= 3
+  BX_SMF BX_CPP_INLINE Boolean protected_mode(void);
+  BX_SMF BX_CPP_INLINE Boolean v8086_mode(void);
+#endif
+#if BX_SUPPORT_APIC
+  bx_local_apic_c local_apic;
+  Boolean int_from_local_apic;
+#endif
+  };
+
+
+#if BX_X86_DEBUGGER
+#define BX_HWDebugInstruction   0x00
+#define BX_HWDebugMemW          0x01
+#define BX_HWDebugIO            0x02
+#define BX_HWDebugMemRW         0x03
+#endif
+
+#if BX_SUPPORT_SID
+#else
+#if BX_SMP_PROCESSORS==1
+// single processor simulation, so there's one of everything
+extern BX_CPU_C       bx_cpu;
+#else
+// multiprocessor simulation, we need an array of cpus and memories
+extern BX_CPU_C       *bx_cpu_array[BX_SMP_PROCESSORS];
+#endif
+#endif // BX_SUPPORT_SID
+
+#if defined(NEED_CPU_REG_SHORTCUTS)
+
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AX(Bit16u ax) { AX = ax; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BX(Bit16u bx) { BX = bx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CX(Bit16u cx) { CX = cx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DX(Bit16u dx) { DX = dx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AL(Bit8u  al) { AL = al; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AH(Bit8u  ah) { AH = ah; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BL(Bit8u  bl) { BL = bl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BH(Bit8u  bh) { BH = bh; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CL(Bit8u  cl) { CL = cl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CH(Bit8u  ch) { CH = ch; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DL(Bit8u  dl) { DL = dl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DH(Bit8u  dh) { DH = dh; };
+
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_AL(void) { return(AL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_AH(void) { return(AH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_BL(void) { return(BL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_BH(void) { return(BH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_CL(void) { return(CL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_CH(void) { return(CH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_DL(void) { return(DL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_DH(void) { return(DH); };
+
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_AX(void) { return(AX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_BX(void) { return(BX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_CX(void) { return(CX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_DX(void) { return(DX); };
+
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+  BX_CPP_INLINE Boolean BX_CPU_C::real_mode(void) { return( !BX_CPU_THIS_PTR cr0.pe ); };
+#endif
+
+#if BX_CPU_LEVEL == 2
+  BX_CPP_INLINE Boolean BX_CPU_C::protected_mode(void) { return( BX_CPU_THIS_PTR cr0.pe ); };
+#endif
+
+
+#if BX_CPU_LEVEL >= 3
+#  if BX_SUPPORT_V8086_MODE
+  BX_CPP_INLINE Boolean
+BX_CPU_C::v8086_mode(void) {
+  return(BX_CPU_THIS_PTR eflags.vm);
+  }
+
+  BX_CPP_INLINE Boolean
+BX_CPU_C::protected_mode(void) {
+  return(BX_CPU_THIS_PTR cr0.pe && !BX_CPU_THIS_PTR eflags.vm);
+  }
+#  else
+  BX_CPP_INLINE Boolean
+BX_CPU_C::v8086_mode(void) {
+  return(0);
+  }
+
+  BX_CPP_INLINE Boolean
+BX_CPU_C::protected_mode(void) {
+  return(BX_CPU_THIS_PTR cr0.pe);
+  }
+#  endif
+#endif
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_CF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0xfffff0;
+    BX_CPU_THIS_PTR eflags.cf = val;
+    }
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_AF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+    BX_CPU_THIS_PTR eflags.af = val;
+    }
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_ZF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+    BX_CPU_THIS_PTR eflags.zf = val;
+    }
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_SF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+    BX_CPU_THIS_PTR eflags.sf = val;
+    }
+
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_OF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+    BX_CPU_THIS_PTR eflags.of = val;
+    }
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_PF(Boolean val) {
+    BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+    BX_CPU_THIS_PTR lf_pf = val;
+    }
+
+    BX_CPP_INLINE void
+BX_CPU_C::set_PF_base(Bit8u val) {
+    BX_CPU_THIS_PTR eflags.pf_byte = val;
+    BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0xffff0f) | BX_LF_MASK_P;
+    }
+
+
+#define SET_FLAGS_OSZAPC_8(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszapc.op1_8 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_8 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_8 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+#define SET_FLAGS_OSZAPC_8_CF(op1, op2, result, ins, last_CF) { \
+    BX_CPU_THIS_PTR oszapc.op1_8 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_8 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_8 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+#define SET_FLAGS_OSZAPC_16(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszapc.op1_16 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_16 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_16 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+#define SET_FLAGS_OSZAPC_16_CF(op1, op2, result, ins, last_CF) { \
+    BX_CPU_THIS_PTR oszapc.op1_16 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_16 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_16 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+#define SET_FLAGS_OSZAPC_32(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszapc.op1_32 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_32 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_32 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+#define SET_FLAGS_OSZAPC_32_CF(op1, op2, result, ins, last_CF) { \
+    BX_CPU_THIS_PTR oszapc.op1_32 = op1; \
+    BX_CPU_THIS_PTR oszapc.op2_32 = op2; \
+    BX_CPU_THIS_PTR oszapc.result_32 = result; \
+    BX_CPU_THIS_PTR oszapc.instr = ins; \
+    BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+    BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+    }
+
+
+#define SET_FLAGS_OSZAP_8(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszap.op1_8 = op1; \
+    BX_CPU_THIS_PTR oszap.op2_8 = op2; \
+    BX_CPU_THIS_PTR oszap.result_8 = result; \
+    BX_CPU_THIS_PTR oszap.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+    }
+
+#define SET_FLAGS_OSZAP_16(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszap.op1_16 = op1; \
+    BX_CPU_THIS_PTR oszap.op2_16 = op2; \
+    BX_CPU_THIS_PTR oszap.result_16 = result; \
+    BX_CPU_THIS_PTR oszap.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+    }
+
+#define SET_FLAGS_OSZAP_32(op1, op2, result, ins) { \
+    BX_CPU_THIS_PTR oszap.op1_32 = op1; \
+    BX_CPU_THIS_PTR oszap.op2_32 = op2; \
+    BX_CPU_THIS_PTR oszap.result_32 = result; \
+    BX_CPU_THIS_PTR oszap.instr = ins; \
+    BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+    }
+
+#define SET_FLAGS_OxxxxC(new_of, new_cf) { \
+    BX_CPU_THIS_PTR eflags.of = (Boolean) new_of; \
+    BX_CPU_THIS_PTR eflags.cf = (Boolean) new_cf; \
+    BX_CPU_THIS_PTR lf_flags_status &= 0x0ffff0; \
+    /* ??? could also mark other bits undefined here */ \
+    }
+
+
+
+
+
+
+extern const Boolean bx_parity_lookup[256];
+
+#define BX_REPE_PREFIX  10
+#define BX_REPNE_PREFIX 11
+
+
+
+#define BX_TASK_FROM_JUMP         10
+#define BX_TASK_FROM_CALL_OR_INT  11
+#define BX_TASK_FROM_IRET         12
+
+
+//
+// For decoding...
+//
+
+// If the Immediate bit is set, the lowest 3 bits of the attribute
+// specify which kinds of immediate data a required by instruction.
+
+#define BxImmediate         0x000f // bits 3..0: any immediate
+#define BxImmediate_Ib      0x0001 // 8 bits regardless
+#define BxImmediate_Ib_SE   0x0002 // sign extend to OS size
+#define BxImmediate_Iv      0x0003 // 16 or 32 depending on OS size
+#define BxImmediate_Iw      0x0004 // 16 bits regardless
+#define BxImmediate_IvIw    0x0005 // call_Ap
+#define BxImmediate_IwIb    0x0006 // enter_IwIb
+#define BxImmediate_O       0x0007 // mov_ALOb, mov_ObAL, mov_eAXOv, mov_OveAX
+#define BxImmediate_BrOff8  0x0008 // Relative branch offset byte
+#define BxImmediate_BrOff16 0x0009 // Relative branch offset word
+#define BxImmediate_BrOff32 BxImmediate_Iv
+
+#define BxPrefix          0x0010 // bit  4
+#define BxAnother         0x0020 // bit  5
+#define BxRepeatable      0x0040 // bit  6
+#define BxRepeatableZF    0x0080 // bit  7
+#define BxGroupN          0x0100 // bits 8
+#define BxGroup1          BxGroupN
+#define BxGroup2          BxGroupN
+#define BxGroup3          BxGroupN
+#define BxGroup4          BxGroupN
+#define BxGroup5          BxGroupN
+#define BxGroup6          BxGroupN
+#define BxGroup7          BxGroupN
+#define BxGroup8          BxGroupN
+#define BxGroup9          BxGroupN
+#define BxGroupa          BxGroupN
+
+#if BX_DEBUGGER
+typedef enum _show_flags {
+      Flag_call = 0x1,
+      Flag_ret = 0x2,
+      Flag_int = 0x4,
+      Flag_iret = 0x8,
+      Flag_intsig = 0x10
+} show_flags_t;
+#endif
+
+#endif  // #ifndef BX_CPU_H
diff --git a/sid/component/bochs/cpu/ctrl_xfer16.cc b/sid/component/bochs/cpu/ctrl_xfer16.cc
new file mode 100644 (file)
index 0000000..201bf6f
--- /dev/null
@@ -0,0 +1,532 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+  void
+BX_CPU_C::RETnear16_Iw(BxInstruction_t *i)
+{
+  Bit16u imm16;
+  Bit32u temp_ESP;
+  Bit16u return_IP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+
+    if (protected_mode()) {
+      if ( !can_pop(2) ) {
+        BX_PANIC(("retnear_iw: can't pop IP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        2, CPL==3, BX_READ, &return_IP);
+
+      if ( return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("retnear_iw: IP > limit\n"));
+        }
+
+      if ( !can_pop(2 + imm16) ) {
+        BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+        /* #GP(0) -or #SS(0) ??? */
+        }
+
+      BX_CPU_THIS_PTR eip = return_IP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 2 + imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += 2 + imm16;
+      }
+    else {
+      pop_16(&return_IP);
+      BX_CPU_THIS_PTR eip = return_IP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += imm16;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETnear16(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit16u return_IP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    if (protected_mode()) {
+      if ( !can_pop(2) ) {
+        BX_PANIC(("retnear: can't pop IP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        2, CPL==3, BX_READ, &return_IP);
+
+      if ( return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("retnear: IP > limit\n"));
+        }
+
+      BX_CPU_THIS_PTR eip = return_IP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 2;
+      else
+        SP  += 2;
+      }
+    else {
+      pop_16(&return_IP);
+      BX_CPU_THIS_PTR eip = return_IP;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETfar16_Iw(BxInstruction_t *i)
+{
+  Bit16s imm16;
+  Bit16u ip, cs_raw;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR return_protected(i, imm16);
+    goto done;
+    }
+#endif
+
+
+    pop_16(&ip);
+    pop_16(&cs_raw);
+    BX_CPU_THIS_PTR eip = (Bit32u) ip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      ESP += imm16;
+    else
+      SP  += imm16;
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::RETfar16(BxInstruction_t *i)
+{
+  Bit16u ip, cs_raw;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if ( protected_mode() ) {
+    BX_CPU_THIS_PTR return_protected(i, 0);
+    goto done;
+    }
+#endif
+
+    pop_16(&ip);
+    pop_16(&cs_raw);
+    BX_CPU_THIS_PTR eip = (Bit32u) ip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+
+  void
+BX_CPU_C::CALL_Aw(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  invalidate_prefetch_q();
+
+  new_EIP = EIP + (Bit32s) i->Id;
+  new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+  if ( protected_mode() &&
+       (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+    BX_PANIC(("call_av: new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+#endif
+
+  /* push 16 bit EA of next instruction */
+  push_16(IP);
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL16_Ap(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit16u disp16;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  disp16 = i->Iw;
+  cs_raw = i->Iw2;
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR call_protected(i, cs_raw, disp16);
+    goto done;
+    }
+#endif
+  push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+  push_16((Bit16u) BX_CPU_THIS_PTR eip);
+  BX_CPU_THIS_PTR eip = (Bit32u) disp16;
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::CALL_Ew(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit16u op1_16;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+    invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("call_ev: IP out of CS limits!\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 2) ) {
+        BX_PANIC(("call_ev: can't push IP\n"));
+        }
+      }
+#endif
+
+    push_16(IP);
+
+    BX_CPU_THIS_PTR eip = op1_16;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL16_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit16u op1_16;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      BX_PANIC(("CALL_Ep: op1 is a register"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op1_16);
+    read_virtual_word(i->seg, i->rm_addr+2, &cs_raw);
+    invalidate_prefetch_q();
+
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16);
+      goto done;
+      }
+
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+    push_16(IP);
+
+    BX_CPU_THIS_PTR eip = op1_16;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+  void
+BX_CPU_C::JMP_Jw(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+
+
+  invalidate_prefetch_q();
+
+  new_EIP = EIP + (Bit32s) i->Id;
+  new_EIP &= 0x0000ffff;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+  void
+BX_CPU_C::JCC_Jw(BxInstruction_t *i)
+{
+  Boolean condition = 0;
+
+  switch (i->b1 & 0x0f) {
+    case 0x00: /* JO */ condition = get_OF(); break;
+    case 0x01: /* JNO */ condition = !get_OF(); break;
+    case 0x02: /* JB */ condition = get_CF(); break;
+    case 0x03: /* JNB */ condition = !get_CF(); break;
+    case 0x04: /* JZ */ condition = get_ZF(); break;
+    case 0x05: /* JNZ */ condition = !get_ZF(); break;
+    case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+    case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+    case 0x08: /* JS */ condition = get_SF(); break;
+    case 0x09: /* JNS */ condition = !get_SF(); break;
+    case 0x0A: /* JP */ condition = get_PF(); break;
+    case 0x0B: /* JNP */ condition = !get_PF(); break;
+    case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+    case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+    case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+      break;
+    case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+                            !get_ZF();
+      break;
+    }
+
+  if (condition) {
+    Bit32u new_EIP;
+
+    new_EIP = EIP + (Bit32s) i->Id;
+    new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+#endif
+    EIP = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+}
+
+
+
+  void
+BX_CPU_C::JMP_Ew(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+  Bit16u op1_16;
+
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    invalidate_prefetch_q();
+    new_EIP = op1_16;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+      BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+  /* Far indirect jump */
+
+  void
+BX_CPU_C::JMP16_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit16u op1_16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      /* far indirect must specify a memory address */
+      BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op1_16);
+    read_virtual_word(i->seg, i->rm_addr+2, &cs_raw);
+    invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_16);
+      goto done;
+      }
+#endif
+
+    BX_CPU_THIS_PTR eip = op1_16;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::IRET16(BxInstruction_t *i)
+{
+  Bit16u ip, cs_raw, flags;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_iret;
+  BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (v8086_mode()) {
+    // IOPL check in stack_return_from_v86()
+    stack_return_from_v86(i);
+    goto done;
+    }
+
+#if BX_CPU_LEVEL >= 2
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    iret_protected(i);
+    goto done;
+    }
+#endif
+
+
+  pop_16(&ip);
+  pop_16(&cs_raw);
+  pop_16(&flags);
+
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+  BX_CPU_THIS_PTR eip = (Bit32u) ip;
+  write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
diff --git a/sid/component/bochs/cpu/ctrl_xfer32-sid.cc b/sid/component/bochs/cpu/ctrl_xfer32-sid.cc
new file mode 100644 (file)
index 0000000..18d74b8
--- /dev/null
@@ -0,0 +1,559 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if 0
+  void
+BX_CPU_C::RETnear32_Iw(BxInstruction_t *i)
+{
+  Bit16u imm16;
+  Bit32u temp_ESP;
+  Bit32u return_EIP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+
+    if (protected_mode()) {
+      if ( !can_pop(4) ) {
+        BX_PANIC(("retnear_iw: can't pop EIP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &return_EIP);
+
+      if (protected_mode() &&
+          (return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+        BX_DEBUG(("retnear_iw: EIP > limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+
+      /* Pentium book says imm16 is number of words ??? */
+      if ( !can_pop(4 + imm16) ) {
+        BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+        /* #GP(0) -or #SS(0) ??? */
+        }
+
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 4 + imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += 4 + imm16;
+      }
+    else {
+      pop_32(&return_EIP);
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += imm16;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETnear32(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit32u return_EIP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    if (protected_mode()) {
+      if ( !can_pop(4) ) {
+        BX_PANIC(("retnear: can't pop EIP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &return_EIP);
+
+      if ( return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("retnear: EIP > limit\n"));
+        //exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 4;
+      else
+        SP  += 4;
+      }
+    else {
+      pop_32(&return_EIP);
+      BX_CPU_THIS_PTR eip = return_EIP;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETfar32_Iw(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw;
+  Bit16s imm16;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+  /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR return_protected(i, imm16);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw);
+    BX_CPU_THIS_PTR eip = eip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      ESP += imm16;
+    else
+      SP  += imm16;
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::RETfar32(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if ( protected_mode() ) {
+    BX_CPU_THIS_PTR return_protected(i, 0);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw); /* 32bit pop, MSW discarded */
+    BX_CPU_THIS_PTR eip = eip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+
+  void
+BX_CPU_C::CALL_Ad(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+  Bit32s disp32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  disp32 = i->Id;
+  invalidate_prefetch_q();
+
+  new_EIP = EIP + disp32;
+
+  if ( protected_mode() ) {
+    if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("call_av: offset outside of CS limits\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+
+  /* push 32 bit EA of next instruction */
+  push_32(BX_CPU_THIS_PTR eip);
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL32_Ap(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u disp32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  disp32 = i->Id;
+  cs_raw = i->Iw2;
+  invalidate_prefetch_q();
+
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32);
+    goto done;
+    }
+  push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+  push_32(BX_CPU_THIS_PTR eip);
+  BX_CPU_THIS_PTR eip = disp32;
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::CALL_Ed(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit32u op1_32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+    invalidate_prefetch_q();
+
+    if (protected_mode()) {
+      if (op1_32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_DEBUG(("call_ev: EIP out of CS limits! at %s:%d\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+        BX_PANIC(("call_ev: can't push EIP\n"));
+        }
+      }
+
+    push_32(BX_CPU_THIS_PTR eip);
+
+    BX_CPU_THIS_PTR eip = op1_32;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL32_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u op1_32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      BX_PANIC(("CALL_Ep: op1 is a register\n"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+    read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+    invalidate_prefetch_q();
+
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
+      goto done;
+      }
+
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+    push_32(BX_CPU_THIS_PTR eip);
+
+    BX_CPU_THIS_PTR eip = op1_32;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+  void
+BX_CPU_C::JMP_Jd(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+
+    invalidate_prefetch_q();
+
+    new_EIP = EIP + (Bit32s) i->Id;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+#endif
+
+  void
+sid_cpu_c::JCC_Jd(BxInstruction_t *i)
+{
+  Boolean condition = 0;
+
+  switch (i->b1 & 0x0f) {
+    case 0x00: /* JO */ condition = get_OF(); break;
+    case 0x01: /* JNO */ condition = !get_OF(); break;
+    case 0x02: /* JB */ condition = get_CF(); break;
+    case 0x03: /* JNB */ condition = !get_CF(); break;
+    case 0x04: /* JZ */ condition = get_ZF(); break;
+    case 0x05: /* JNZ */ condition = !get_ZF(); break;
+    case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+    case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+    case 0x08: /* JS */ condition = get_SF(); break;
+    case 0x09: /* JNS */ condition = !get_SF(); break;
+    case 0x0A: /* JP */ condition = get_PF(); break;
+    case 0x0B: /* JNP */ condition = !get_PF(); break;
+    case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+    case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+    case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+      break;
+    case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+                            !get_ZF();
+      break;
+    }
+
+  if (condition) {
+    Bit32u new_EIP;
+
+    new_EIP = EIP + (Bit32s) i->Id;
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+#endif
+    EIP = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+}
+#if 0
+  void
+BX_CPU_C::JMP_Ap(BxInstruction_t *i)
+{
+  Bit32u disp32;
+  Bit16u cs_raw;
+
+  invalidate_prefetch_q();
+
+  if (i->os_32) {
+    disp32 = i->Id;
+    }
+  else {
+    disp32 = i->Iw;
+    }
+  cs_raw = i->Iw2;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
+    goto done;
+    }
+#endif
+
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+  BX_CPU_THIS_PTR eip = disp32;
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+
+
+  void
+BX_CPU_C::JMP_Ed(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+  Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    invalidate_prefetch_q();
+    new_EIP = op1_32;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+      BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+  /* Far indirect jump */
+
+  void
+BX_CPU_C::JMP32_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      /* far indirect must specify a memory address */
+      BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+    read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+    invalidate_prefetch_q();
+
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
+      goto done;
+      }
+
+    BX_CPU_THIS_PTR eip = op1_32;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::IRET32(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw, eflags;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_iret;
+  BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (v8086_mode()) {
+    // IOPL check in stack_return_from_v86()
+    stack_return_from_v86(i);
+    goto done;
+    }
+
+#if BX_CPU_LEVEL >= 2
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    iret_protected(i);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw);
+    pop_32(&eflags);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+    BX_CPU_THIS_PTR eip = eip;
+    write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 1);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+#endif
diff --git a/sid/component/bochs/cpu/ctrl_xfer32.cc b/sid/component/bochs/cpu/ctrl_xfer32.cc
new file mode 100644 (file)
index 0000000..44ef61f
--- /dev/null
@@ -0,0 +1,557 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+  void
+BX_CPU_C::RETnear32_Iw(BxInstruction_t *i)
+{
+  Bit16u imm16;
+  Bit32u temp_ESP;
+  Bit32u return_EIP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+
+    if (protected_mode()) {
+      if ( !can_pop(4) ) {
+        BX_PANIC(("retnear_iw: can't pop EIP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &return_EIP);
+
+      if (protected_mode() &&
+          (return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+        BX_DEBUG(("retnear_iw: EIP > limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+
+      /* Pentium book says imm16 is number of words ??? */
+      if ( !can_pop(4 + imm16) ) {
+        BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+        /* #GP(0) -or #SS(0) ??? */
+        }
+
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 4 + imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += 4 + imm16;
+      }
+    else {
+      pop_32(&return_EIP);
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += imm16; /* ??? should it be 2*imm16 ? */
+      else
+        SP  += imm16;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETnear32(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit32u return_EIP;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    if (protected_mode()) {
+      if ( !can_pop(4) ) {
+        BX_PANIC(("retnear: can't pop EIP\n"));
+        /* ??? #SS(0) -or #GP(0) */
+        }
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &return_EIP);
+
+      if ( return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("retnear: EIP > limit\n"));
+        //exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      BX_CPU_THIS_PTR eip = return_EIP;
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+        ESP += 4;
+      else
+        SP  += 4;
+      }
+    else {
+      pop_32(&return_EIP);
+      BX_CPU_THIS_PTR eip = return_EIP;
+      }
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::RETfar32_Iw(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw;
+  Bit16s imm16;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+  /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+  imm16 = i->Iw;
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR return_protected(i, imm16);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw);
+    BX_CPU_THIS_PTR eip = eip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      ESP += imm16;
+    else
+      SP  += imm16;
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::RETfar32(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+  if ( protected_mode() ) {
+    BX_CPU_THIS_PTR return_protected(i, 0);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw); /* 32bit pop, MSW discarded */
+    BX_CPU_THIS_PTR eip = eip;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+
+  void
+BX_CPU_C::CALL_Ad(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+  Bit32s disp32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  disp32 = i->Id;
+  invalidate_prefetch_q();
+
+  new_EIP = EIP + disp32;
+
+  if ( protected_mode() ) {
+    if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("call_av: offset outside of CS limits\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+
+  /* push 32 bit EA of next instruction */
+  push_32(BX_CPU_THIS_PTR eip);
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL32_Ap(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u disp32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  disp32 = i->Id;
+  cs_raw = i->Iw2;
+  invalidate_prefetch_q();
+
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32);
+    goto done;
+    }
+  push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+  push_32(BX_CPU_THIS_PTR eip);
+  BX_CPU_THIS_PTR eip = disp32;
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::CALL_Ed(BxInstruction_t *i)
+{
+  Bit32u temp_ESP;
+  Bit32u op1_32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+    invalidate_prefetch_q();
+
+    if (protected_mode()) {
+      if (op1_32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_DEBUG(("call_ev: EIP out of CS limits! at %s:%d\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+        BX_PANIC(("call_ev: can't push EIP\n"));
+        }
+      }
+
+    push_32(BX_CPU_THIS_PTR eip);
+
+    BX_CPU_THIS_PTR eip = op1_32;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::CALL32_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u op1_32;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      BX_PANIC(("CALL_Ep: op1 is a register\n"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+    read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+    invalidate_prefetch_q();
+
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
+      goto done;
+      }
+
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+    push_32(BX_CPU_THIS_PTR eip);
+
+    BX_CPU_THIS_PTR eip = op1_32;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+  void
+BX_CPU_C::JMP_Jd(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+
+    invalidate_prefetch_q();
+
+    new_EIP = EIP + (Bit32s) i->Id;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+  void
+BX_CPU_C::JCC_Jd(BxInstruction_t *i)
+{
+  Boolean condition = 0;
+
+  switch (i->b1 & 0x0f) {
+    case 0x00: /* JO */ condition = get_OF(); break;
+    case 0x01: /* JNO */ condition = !get_OF(); break;
+    case 0x02: /* JB */ condition = get_CF(); break;
+    case 0x03: /* JNB */ condition = !get_CF(); break;
+    case 0x04: /* JZ */ condition = get_ZF(); break;
+    case 0x05: /* JNZ */ condition = !get_ZF(); break;
+    case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+    case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+    case 0x08: /* JS */ condition = get_SF(); break;
+    case 0x09: /* JNS */ condition = !get_SF(); break;
+    case 0x0A: /* JP */ condition = get_PF(); break;
+    case 0x0B: /* JNP */ condition = !get_PF(); break;
+    case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+    case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+    case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+      break;
+    case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+                            !get_ZF();
+      break;
+    }
+
+  if (condition) {
+    Bit32u new_EIP;
+
+    new_EIP = EIP + (Bit32s) i->Id;
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+#endif
+    EIP = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+}
+
+  void
+BX_CPU_C::JMP_Ap(BxInstruction_t *i)
+{
+  Bit32u disp32;
+  Bit16u cs_raw;
+
+  invalidate_prefetch_q();
+
+  if (i->os_32) {
+    disp32 = i->Id;
+    }
+  else {
+    disp32 = i->Iw;
+    }
+  cs_raw = i->Iw2;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
+    goto done;
+    }
+#endif
+
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+  BX_CPU_THIS_PTR eip = disp32;
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+
+
+
+  void
+BX_CPU_C::JMP_Ed(BxInstruction_t *i)
+{
+  Bit32u new_EIP;
+  Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    invalidate_prefetch_q();
+    new_EIP = op1_32;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+      BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+#endif
+
+  BX_CPU_THIS_PTR eip = new_EIP;
+
+  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+  /* Far indirect jump */
+
+  void
+BX_CPU_C::JMP32_Ep(BxInstruction_t *i)
+{
+  Bit16u cs_raw;
+  Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      /* far indirect must specify a memory address */
+      BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+      }
+
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+    read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+    invalidate_prefetch_q();
+
+    if ( protected_mode() ) {
+      BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
+      goto done;
+      }
+
+    BX_CPU_THIS_PTR eip = op1_32;
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
+
+  void
+BX_CPU_C::IRET32(BxInstruction_t *i)
+{
+  Bit32u eip, ecs_raw, eflags;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_iret;
+  BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+  invalidate_prefetch_q();
+
+  if (v8086_mode()) {
+    // IOPL check in stack_return_from_v86()
+    stack_return_from_v86(i);
+    goto done;
+    }
+
+#if BX_CPU_LEVEL >= 2
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    iret_protected(i);
+    goto done;
+    }
+#endif
+
+
+    pop_32(&eip);
+    pop_32(&ecs_raw);
+    pop_32(&eflags);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+    BX_CPU_THIS_PTR eip = eip;
+    write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 1);
+
+done:
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  return;
+}
diff --git a/sid/component/bochs/cpu/ctrl_xfer8.cc b/sid/component/bochs/cpu/ctrl_xfer8.cc
new file mode 100644 (file)
index 0000000..878db4c
--- /dev/null
@@ -0,0 +1,188 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::JCXZ_Jb(BxInstruction_t *i)
+{
+  Bit32u temp_ECX;
+
+  if (i->as_32)
+    temp_ECX = ECX;
+  else
+    temp_ECX = CX;
+
+  if ( temp_ECX == 0 ) {
+    Bit32u new_EIP;
+
+    new_EIP = EIP + (Bit32s) i->Id;
+    if (i->os_32==0)
+      new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+        BX_PANIC(("jcxz_jb: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+#endif
+    EIP = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+}
+
+
+
+  void
+BX_CPU_C::LOOPNE_Jb(BxInstruction_t *i)
+{
+  Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32)
+    count = ECX;
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    count = CX;
+
+  count--;
+  if ( (count!=0) && (get_ZF()==0) ) {
+
+    new_EIP = EIP + (Bit32s) i->Id;
+    if (i->os_32==0)
+      new_EIP &= 0x0000ffff;
+    if (protected_mode()) {
+      if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("loopne_jb: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+    BX_CPU_THIS_PTR eip = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+
+  if (i->as_32)
+    ECX--;
+  else
+    CX--;
+}
+
+  void
+BX_CPU_C::LOOPE_Jb(BxInstruction_t *i)
+{
+  Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32)
+    count = ECX;
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    count = CX;
+
+  count--;
+  if ( (count!=0) && get_ZF()) {
+
+    new_EIP = EIP + (Bit32s) i->Id;
+    if (i->os_32==0)
+      new_EIP &= 0x0000ffff;
+    if (protected_mode()) {
+      if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("loope_jb: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+    BX_CPU_THIS_PTR eip = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+
+  if (i->as_32)
+    ECX--;
+  else
+    CX--;
+}
+
+  void
+BX_CPU_C::LOOP_Jb(BxInstruction_t *i)
+{
+  Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32)
+    count = ECX;
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    count = CX;
+
+  count--;
+  if (count != 0) {
+
+    new_EIP = EIP + (Bit32s) i->Id;
+    if (i->os_32==0)
+      new_EIP &= 0x0000ffff;
+    if (protected_mode()) {
+      if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("loop_jb: offset outside of CS limits\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+    BX_CPU_THIS_PTR eip = new_EIP;
+    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+    revalidate_prefetch_q();
+    }
+#if BX_INSTRUMENTATION
+  else {
+    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+    }
+#endif
+
+  if (i->as_32)
+    ECX--;
+  else
+    CX--;
+}
diff --git a/sid/component/bochs/cpu/ctrl_xfer_pro.cc b/sid/component/bochs/cpu/ctrl_xfer_pro.cc
new file mode 100644 (file)
index 0000000..06bd17a
--- /dev/null
@@ -0,0 +1,1765 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::jump_protected(BxInstruction_t *i, Bit16u cs_raw, Bit32u disp32)
+{
+  bx_descriptor_t  descriptor;
+  bx_selector_t    selector;
+  Bit32u dword1, dword2;
+
+
+
+  /* destination selector is not null else #GP(0) */
+  if ((cs_raw & 0xfffc) == 0) {
+    BX_PANIC(("jump_protected: cs == 0\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  parse_selector(cs_raw, &selector);
+
+  /* destination selector index is whithin its descriptor table
+     limits else #GP(selector) */
+  fetch_raw_descriptor(&selector, &dword1, &dword2,
+    BX_GP_EXCEPTION);
+
+  /* examine AR byte of destination selector for legal values: */
+  parse_descriptor(dword1, dword2, &descriptor);
+
+  if ( descriptor.segment ) {
+    if ( descriptor.u.segment.executable==0 ) {
+      BX_INFO(("jump_protected: S=1: descriptor not executable\n"));
+      exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+      return;
+      }
+    // CASE: JUMP CONFORMING CODE SEGMENT:
+    if ( descriptor.u.segment.c_ed ) {
+      // descripor DPL must be <= CPL else #GP(selector)
+      if (descriptor.dpl > CPL) {
+        BX_INFO(("jump_protected: dpl > CPL\n"));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+
+      /* segment must be PRESENT else #NP(selector) */
+      if (descriptor.p == 0) {
+        BX_INFO(("jump_protected: p == 0\n"));
+        exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+
+      /* instruction pointer must be in code segment limit else #GP(0) */
+      if (disp32 > descriptor.u.segment.limit_scaled) {
+        BX_PANIC(("jump_protected: IP > limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        return;
+        }
+
+      /* Load CS:IP from destination pointer */
+      /* Load CS-cache with new segment descriptor */
+      /* CPL does not change for conforming code segment */
+      load_cs(&selector, &descriptor, CPL);
+      BX_CPU_THIS_PTR eip = disp32;
+      return;
+      }
+
+    // CASE: jump nonconforming code segment:
+    else {
+      /* RPL of destination selector must be <= CPL else #GP(selector) */
+      if (selector.rpl > CPL) {
+        BX_PANIC(("jump_protected: rpl > CPL\n"));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+
+      // descriptor DPL must = CPL else #GP(selector)
+      if (descriptor.dpl != CPL) {
+        BX_INFO(("jump_protected: dpl != CPL\n"));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+
+      /* segment must be PRESENT else #NP(selector) */
+      if (descriptor.p == 0) {
+        BX_INFO(("jump_protected: p == 0\n"));
+        exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+
+      /* IP must be in code segment limit else #GP(0) */
+      if (disp32 > descriptor.u.segment.limit_scaled) {
+        BX_PANIC(("jump_protected: IP > limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        return;
+        }
+
+      /* load CS:IP from destination pointer */
+      /* load CS-cache with new segment descriptor */
+      /* set RPL field of CS register to CPL */
+      load_cs(&selector, &descriptor, CPL);
+      BX_CPU_THIS_PTR eip = disp32;
+      return;
+      }
+    BX_PANIC(("jump_protected: segment=1\n"));
+    }
+
+  else {
+    Bit16u          raw_tss_selector;
+    bx_selector_t   tss_selector, gate_cs_selector;
+    bx_descriptor_t tss_descriptor, gate_cs_descriptor;
+    Bit16u gate_cs_raw;
+    Bit32u temp_eIP;
+
+
+    switch ( descriptor.type ) {
+      case  1: // 286 available TSS
+      case  9: // 386 available TSS
+        //if ( descriptor.type==1 )
+        //  BX_INFO(("jump to 286 TSS\n"));
+        //else
+        //  BX_INFO(("jump to 386 TSS\n"));
+
+        // TSS DPL must be >= CPL, else #GP(TSS selector)
+        if (descriptor.dpl < CPL) {
+          BX_PANIC(("jump_protected: TSS.dpl < CPL\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // TSS DPL must be >= TSS selector RPL, else #GP(TSS selector)
+        if (descriptor.dpl < selector.rpl) {
+          BX_PANIC(("jump_protected: TSS.dpl < selector.rpl\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // descriptor AR byte must specify available TSS,
+        //   else #GP(TSS selector) */
+        // this is taken care of by the 'default' case of switch statement */
+
+        // Task State Seg must be present, else #NP(TSS selector)
+        // checked in task_switch()
+
+        // SWITCH_TASKS _without_ nesting to TSS
+        task_switch(&selector, &descriptor,
+          BX_TASK_FROM_JUMP, dword1, dword2);
+
+        // IP must be in code seg limit, else #GP(0)
+        if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+          BX_INFO(("jump_protected: TSS.p == 0\n"));
+          exception(BX_GP_EXCEPTION, 0, 0);
+          return;
+          }
+        return;
+        break;
+
+      case  3: // Busy 286 TSS
+        BX_PANIC(("jump_protected: JUMP to busy 286 TSS unsupported.\n"));
+        return;
+        break;
+
+      case  4: // 286 call gate
+        //BX_INFO(("jump_protected: JUMP TO 286 CALL GATE:\n"));
+
+        // descriptor DPL must be >= CPL else #GP(gate selector)
+        if (descriptor.dpl < CPL) {
+          BX_INFO(("jump_protected: gate.dpl < CPL\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // descriptor DPL must be >= gate selector RPL else #GP(gate selector)
+        if (descriptor.dpl < selector.rpl) {
+          BX_INFO(("jump_protected: gate.dpl < selector.rpl\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // gate must be present else #NP(gate selector)
+        if (descriptor.p==0) {
+          BX_PANIC(("jump_protected: task gate.p == 0\n"));
+          exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // examine selector to code segment given in call gate descriptor
+        // selector must not be null, else #GP(0)
+        gate_cs_raw = descriptor.u.gate286.dest_selector;
+        if ( (gate_cs_raw & 0xfffc) == 0 ) {
+          BX_PANIC(("jump_protected: CS selector null\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+        parse_selector(gate_cs_raw, &gate_cs_selector);
+
+        // selector must be within its descriptor table limits else #GP(CS selector)
+        fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2,
+          BX_GP_EXCEPTION);
+        parse_descriptor(dword1, dword2, &gate_cs_descriptor);
+        // descriptor AR byte must indicate code segment else #GP(CS selector)
+        if ( (gate_cs_descriptor.valid==0) ||
+             (gate_cs_descriptor.segment==0) ||
+             (gate_cs_descriptor.u.segment.executable==0) ) {
+          BX_INFO(("jump_protected: AR byte: not code segment.\n"));
+          exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+          }
+
+        // if non-conforming, code segment descriptor DPL must = CPL else #GP(CS selector)
+        if (gate_cs_descriptor.u.segment.c_ed==0) {
+          if (gate_cs_descriptor.dpl != CPL) {
+            BX_INFO(("jump_protected: non-conform: code seg des DPL != CPL.\n"));
+            exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+            }
+          }
+        // if conforming, then code segment descriptor DPL must <= CPL else #GP(CS selector)
+        else {
+          if (gate_cs_descriptor.dpl > CPL) {
+            BX_INFO(("jump_protected: conform: code seg des DPL > CPL.\n"));
+            exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+            }
+          }
+
+        // code segment must be present else #NP(CS selector)
+        if (gate_cs_descriptor.p==0) {
+          BX_INFO(("jump_protected: code seg not present.\n"));
+          exception(BX_NP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+          }
+
+        // IP must be in code segment limit else #GP(0)
+        if ( descriptor.u.gate286.dest_offset >
+             gate_cs_descriptor.u.segment.limit_scaled ) {
+          BX_PANIC(("jump_protected: IP > limit\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+
+        // load CS:IP from call gate
+        // load CS cache with new code segment
+        // set rpl of CS to CPL
+        load_cs(&gate_cs_selector, &gate_cs_descriptor, CPL);
+        EIP = descriptor.u.gate286.dest_offset;
+        return;
+        break;
+
+
+      case  5: // task gate
+//BX_INFO(("jump_pro: task gate\n"));
+
+        // gate descriptor DPL must be >= CPL else #GP(gate selector)
+        if (descriptor.dpl < CPL) {
+          BX_PANIC(("jump_protected: gate.dpl < CPL\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // gate descriptor DPL must be >= gate selector RPL
+        //   else #GP(gate selector)
+        if (descriptor.dpl < selector.rpl) {
+          BX_PANIC(("jump_protected: gate.dpl < selector.rpl\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // task gate must be present else #NP(gate selector)
+        if (descriptor.p==0) {
+          BX_PANIC(("jump_protected: task gate.p == 0\n"));
+          exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // examine selector to TSS, given in Task Gate descriptor
+        // must specify global in the local/global bit else #GP(TSS selector)
+
+        raw_tss_selector = descriptor.u.taskgate.tss_selector;
+        parse_selector(raw_tss_selector, &tss_selector);
+        if (tss_selector.ti) {
+          BX_PANIC(("jump_protected: tss_selector.ti=1\n"));
+          exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          return;
+          }
+
+        // index must be within GDT limits else #GP(TSS selector)
+        fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+          BX_GP_EXCEPTION);
+
+        // descriptor AR byte must specify available TSS
+        //   else #GP(TSS selector)
+        parse_descriptor(dword1, dword2, &tss_descriptor);
+        if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+          BX_INFO(("jump_protected: TSS selector points to bad TSS\n"));
+          exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+        if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+          BX_INFO(("jump_protected: TSS selector points to bad TSS\n"));
+          exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+
+
+        // task state segment must be present, else #NP(tss selector)
+        if (tss_descriptor.p==0) {
+          BX_PANIC(("jump_protected: task descriptor.p == 0\n"));
+          exception(BX_NP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+
+        // SWITCH_TASKS _without_ nesting to TSS
+        task_switch(&tss_selector, &tss_descriptor,
+                    BX_TASK_FROM_JUMP, dword1, dword2);
+
+        // eIP must be within code segment limit, else #GP(0)
+        if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+          temp_eIP = EIP;
+        else
+          temp_eIP =  IP;
+        if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+          BX_PANIC(("jump_protected: eIP > cs.limit\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+
+        break;
+
+      case 11: // Busy 386 TSS
+        BX_PANIC(("jump_protected: JUMP to busy 386 TSS unsupported.\n"));
+        return;
+        break;
+
+      case 12: // 386 call gate
+        //BX_INFO(("jump_protected: JUMP TO 386 CALL GATE:\n"));
+
+        // descriptor DPL must be >= CPL else #GP(gate selector)
+        if (descriptor.dpl < CPL) {
+          BX_PANIC(("jump_protected: gate.dpl < CPL\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // descriptor DPL must be >= gate selector RPL else #GP(gate selector)
+        if (descriptor.dpl < selector.rpl) {
+          BX_PANIC(("jump_protected: gate.dpl < selector.rpl\n"));
+          exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // gate must be present else #NP(gate selector)
+        if (descriptor.p==0) {
+          BX_PANIC(("jump_protected: task gate.p == 0\n"));
+          exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // examine selector to code segment given in call gate descriptor
+        // selector must not be null, else #GP(0)
+        gate_cs_raw = descriptor.u.gate386.dest_selector;
+        if ( (gate_cs_raw & 0xfffc) == 0 ) {
+          BX_PANIC(("jump_protected: CS selector null\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+        parse_selector(gate_cs_raw, &gate_cs_selector);
+
+        // selector must be within its descriptor table limits else #GP(CS selector)
+        fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2,
+          BX_GP_EXCEPTION);
+        parse_descriptor(dword1, dword2, &gate_cs_descriptor);
+        // descriptor AR byte must indicate code segment else #GP(CS selector)
+        if ( (gate_cs_descriptor.valid==0) ||
+             (gate_cs_descriptor.segment==0) ||
+             (gate_cs_descriptor.u.segment.executable==0) ) {
+          BX_PANIC(("jump_protected: AR byte: not code segment.\n"));
+          exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+          }
+
+        // if non-conforming, code segment descriptor DPL must = CPL else #GP(CS selector)
+        if (gate_cs_descriptor.u.segment.c_ed==0) {
+          if (gate_cs_descriptor.dpl != CPL) {
+            BX_PANIC(("jump_protected: non-conform: code seg des DPL != CPL.\n"));
+            exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+            }
+          }
+        // if conforming, then code segment descriptor DPL must <= CPL else #GP(CS selector)
+        else {
+          if (gate_cs_descriptor.dpl > CPL) {
+            BX_PANIC(("jump_protected: conform: code seg des DPL > CPL.\n"));
+            exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+            }
+          }
+
+        // code segment must be present else #NP(CS selector)
+        if (gate_cs_descriptor.p==0) {
+          BX_PANIC(("jump_protected: code seg not present.\n"));
+          exception(BX_NP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+          }
+
+        // IP must be in code segment limit else #GP(0)
+        if ( descriptor.u.gate386.dest_offset >
+             gate_cs_descriptor.u.segment.limit_scaled ) {
+          BX_PANIC(("jump_protected: IP > limit\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+
+        // load CS:IP from call gate
+        // load CS cache with new code segment
+        // set rpl of CS to CPL
+        load_cs(&gate_cs_selector, &gate_cs_descriptor, CPL);
+        EIP = descriptor.u.gate386.dest_offset;
+        return;
+        break;
+
+      default:
+        BX_INFO(("jump_protected: gate type %u unsupported\n",
+          (unsigned) descriptor.type));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        break;
+      }
+    }
+    return;
+}
+#endif /* if BX_CPU_LEVEL >= 2 */
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::call_protected(BxInstruction_t *i, Bit16u cs_raw, Bit32u disp32)
+{
+  bx_selector_t cs_selector;
+  Bit32u dword1, dword2;
+  bx_descriptor_t cs_descriptor;
+
+  /* Opsize in effect for CALL is specified by the D bit for the
+   * segment containing dest & by any opsize prefix.
+   * For gate descriptor, deterermined by type of call gate:
+   * 4=16bit, 12=32bit
+   * count field: 16bit specifies #words, 32bit specifies #dwords
+   */
+
+  /* new cs selector must not be null, else #GP(0) */
+  if ( (cs_raw & 0xfffc) == 0 ) {
+    BX_PANIC(("call_protected: CS selector null\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+  parse_selector(cs_raw, &cs_selector);
+
+  // check new CS selector index within its descriptor limits,
+  // else #GP(new CS selector)
+  fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+    BX_GP_EXCEPTION);
+
+  parse_descriptor(dword1, dword2, &cs_descriptor);
+
+  // examine AR byte of selected descriptor for various legal values
+  if (cs_descriptor.valid==0) {
+    BX_PANIC(("call_protected: invalid CS descriptor\n"));
+    exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+    }
+
+  if (cs_descriptor.segment) { // normal segment
+    Bit32u temp_ESP;
+
+    if (cs_descriptor.u.segment.executable==0) {
+      BX_PANIC(("call_protected: non executable segment\n"));
+      exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+      return;
+      }
+
+    if (cs_descriptor.u.segment.c_ed) { // conforming code segment
+      // DPL must be <= CPL, else #GP(code seg selector)
+      if (cs_descriptor.dpl > CPL) {
+        BX_PANIC(("call_protected: cs.dpl > CPL\n"));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        return;
+        }
+      }
+    else { // non-conforming code segment
+      // RPL must be <= CPL, else #GP(code seg selector)
+      // DPL must be = CPL, else #GP(code seg selector)
+      if ( (cs_selector.rpl > CPL) ||
+           (cs_descriptor.dpl != CPL) ) {
+        BX_PANIC(("call_protected: cs.rpl > CPL\n"));
+        exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+        }
+      }
+
+    // segment must be present, else #NP(code seg selector)
+    if (cs_descriptor.p == 0) {
+      BX_INFO(("call_protected: cs.p = 0\n"));
+      exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+      }
+
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      temp_ESP = ESP;
+    else
+      temp_ESP = SP;
+
+    // stack must be big enough for return addr, else #SS(0)
+    if (i->os_32) {
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 8) ) {
+        BX_PANIC(("call_protected: stack doesn't have room for ret addr\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        }
+
+      // IP must be in code seg limit, else #GP(0)
+      if (disp32 > cs_descriptor.u.segment.limit_scaled) {
+        BX_PANIC(("call_protected: IP not in code seg limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+
+      // push return address onto stack (CS padded to 32bits)
+      push_32((Bit32u) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+      push_32(EIP);
+      }
+    else { // 16bit opsize
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+        BX_PANIC(("call_protected: stack doesn't have room for ret addr\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        }
+
+      // IP must be in code seg limit, else #GP(0)
+      if (disp32 > cs_descriptor.u.segment.limit_scaled) {
+        BX_PANIC(("call_protected: IP not in code seg limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+
+      push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+      push_16(IP);
+      }
+
+    // load code segment descriptor into CS cache
+    // load CS with new code segment selector
+    // set RPL of CS to CPL
+    // load eIP with new offset
+    load_cs(&cs_selector, &cs_descriptor, CPL);
+    BX_CPU_THIS_PTR eip = disp32;
+    if (cs_descriptor.u.segment.d_b==0)
+      BX_CPU_THIS_PTR eip &= 0x0000ffff;
+    return;
+    }
+  else { // gate & special segment
+    bx_descriptor_t  gate_descriptor;
+    bx_selector_t    gate_selector;
+    Bit32u new_EIP;
+    Bit16u dest_selector;
+    Bit16u          raw_tss_selector;
+    bx_selector_t   tss_selector;
+    bx_descriptor_t tss_descriptor;
+    Bit32u temp_eIP;
+
+    /* 1 level of indirection via gate, switch gate & cs */
+    gate_descriptor = cs_descriptor;
+    gate_selector   = cs_selector;
+
+    switch (gate_descriptor.type) {
+      case 1: // available 16bit TSS
+      case 9: // available 32bit TSS
+        //if (gate_descriptor.type==1)
+        //  BX_INFO(("call_protected: 16bit available TSS\n"));
+        //else
+        //  BX_INFO(("call_protected: 32bit available TSS\n"));
+
+        // TSS DPL must be >= CPL, else #TS(TSS selector)
+        if (gate_descriptor.dpl < CPL) {
+          BX_PANIC(("call_protected: TSS.dpl < CPL\n"));
+          exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // TSS DPL must be >= TSS selector RPL, else #TS(TSS selector)
+        if (gate_descriptor.dpl < gate_selector.rpl) {
+          BX_PANIC(("call_protected: TSS.dpl < selector.rpl\n"));
+          exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // descriptor AR byte must specify available TSS,
+        //   else #TS(TSS selector) */
+        // this is taken care of by the 'default' case of switch statement */
+
+        // Task State Seg must be present, else #NP(TSS selector)
+        // checked in task_switch()
+
+        // SWITCH_TASKS _without_ nesting to TSS
+        task_switch(&gate_selector, &gate_descriptor,
+          BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+        // IP must be in code seg limit, else #TS(0)
+        if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+          BX_INFO(("call_protected: TSS.p == 0\n"));
+          exception(BX_TS_EXCEPTION, 0, 0);
+          return;
+          }
+        return;
+        break;
+
+      case 5: // TASK GATE
+        //BX_INFO(("call_protected: task gate\n"));
+        // gate descriptor DPL must be >= CPL else #TS(gate selector)
+        if (gate_descriptor.dpl < CPL) {
+          BX_PANIC(("call_protected: gate.dpl < CPL\n"));
+          exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // gate descriptor DPL must be >= gate selector RPL
+        //   else #TS(gate selector)
+        if (gate_descriptor.dpl < gate_selector.rpl) {
+          BX_PANIC(("call_protected: gate.dpl < selector.rpl\n"));
+          exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // task gate must be present else #NP(gate selector)
+        if (gate_descriptor.p==0) {
+          BX_PANIC(("call_protected: task gate.p == 0\n"));
+          exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+          return;
+          }
+
+        // examine selector to TSS, given in Task Gate descriptor
+        // must specify global in the local/global bit else #TS(TSS selector)
+
+        raw_tss_selector = gate_descriptor.u.taskgate.tss_selector;
+        parse_selector(raw_tss_selector, &tss_selector);
+        if (tss_selector.ti) {
+          BX_PANIC(("call_protected: tss_selector.ti=1\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          return;
+          }
+
+        // index must be within GDT limits else #TS(TSS selector)
+        fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+          BX_TS_EXCEPTION);
+
+        // descriptor AR byte must specify available TSS
+        //   else #TS(TSS selector)
+        parse_descriptor(dword1, dword2, &tss_descriptor);
+        if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+          BX_PANIC(("call_protected: TSS selector points to bad TSS\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+        if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+          BX_PANIC(("call_protected: TSS selector points to bad TSS\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+
+
+        // task state segment must be present, else #NP(tss selector)
+        if (tss_descriptor.p==0) {
+          BX_PANIC(("call_protected: task descriptor.p == 0\n"));
+          exception(BX_NP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          }
+
+        // SWITCH_TASKS without nesting to TSS
+        task_switch(&tss_selector, &tss_descriptor,
+                    BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+        // eIP must be within code segment limit, else #TS(0)
+        if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+          temp_eIP = EIP;
+        else
+          temp_eIP =  IP;
+        if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+          BX_PANIC(("call_protected: eIP > cs.limit\n"));
+          exception(BX_TS_EXCEPTION, 0x0000, 0);
+          }
+
+        return;
+        break;
+
+      case  4: // 16bit CALL GATE
+      case 12: // 32bit CALL GATE
+//if (gate_descriptor.type==4)
+//  BX_INFO(("CALL: 16bit call gate\n"));
+//else
+//  BX_INFO(("CALL: 32bit call gate\n"));
+
+        // call gate DPL must be >= CPL, else #GP(call gate selector)
+        // call gate DPL must be >= RPL, else #GP(call gate selector)
+        if ( (gate_descriptor.dpl < CPL) ||
+             (gate_descriptor.dpl < gate_selector.rpl) ) {
+          BX_PANIC(("call_protected: DPL < CPL or RPL\n"));
+          exception(BX_GP_EXCEPTION, gate_selector.value & 0xfffc, 0);
+          }
+
+        // call gate must be present, else #NP(call gate selector)
+        if (gate_descriptor.p==0) {
+          BX_PANIC(("call_protected: not present\n"));
+          exception(BX_NP_EXCEPTION, gate_selector.value & 0xfffc, 0);
+          }
+
+        // examine code segment selector in call gate descriptor
+
+        if (gate_descriptor.type==4) {
+          dest_selector = gate_descriptor.u.gate286.dest_selector;
+          new_EIP = gate_descriptor.u.gate286.dest_offset;
+          }
+        else {
+          dest_selector = gate_descriptor.u.gate386.dest_selector;
+          new_EIP = gate_descriptor.u.gate386.dest_offset;
+          }
+
+        // selector must not be null else #GP(0)
+        if ( (dest_selector & 0xfffc) == 0 ) {
+          BX_PANIC(("call_protected: selector in gate null\n"));
+          exception(BX_GP_EXCEPTION, 0, 0);
+          }
+
+        parse_selector(dest_selector, &cs_selector);
+
+        // selector must be within its descriptor table limits,
+        //   else #GP(code segment selector)
+        fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+          BX_GP_EXCEPTION);
+        parse_descriptor(dword1, dword2, &cs_descriptor);
+
+        // AR byte of selected descriptor must indicate code segment,
+        //   else #GP(code segment selector)
+        // DPL of selected descriptor must be <= CPL,
+        // else #GP(code segment selector)
+        if (cs_descriptor.valid==0 ||
+            cs_descriptor.segment==0 ||
+            cs_descriptor.u.segment.executable==0 ||
+            cs_descriptor.dpl > CPL) {
+          BX_PANIC(("call_protected: selected desciptor not code\n"));
+          exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+          }
+
+        // CALL GATE TO MORE PRIVILEGE
+        // if non-conforming code segment and DPL < CPL then
+        // ??? use gate_descriptor.dpl or cs_descriptor.dpl ???
+        if ( (cs_descriptor.u.segment.c_ed==0)  &&
+             (cs_descriptor.dpl < CPL) ) {
+
+          Bit16u SS_for_cpl_x;
+          Bit32u ESP_for_cpl_x;
+          bx_selector_t   ss_selector;
+          bx_descriptor_t ss_descriptor;
+          unsigned room_needed;
+          Bit8u    param_count;
+          Bit16u   return_SS, return_CS;
+          Bit32u   return_ESP, return_EIP;
+          Bit32u   return_ss_base;
+          unsigned i;
+          Bit16u   parameter_word[32];
+          Bit32u   parameter_dword[32];
+          Bit32u   temp_ESP;
+
+//BX_INFO(("CALL: Call Gate: to more priviliged level\n"));
+
+          // get new SS selector for new privilege level from TSS
+          get_SS_ESP_from_TSS(cs_descriptor.dpl,
+                              &SS_for_cpl_x, &ESP_for_cpl_x);
+
+/* ??? use dpl or rpl ??? */
+
+          // check selector & descriptor for new SS:
+          // selector must not be null, else #TS(0)
+          if ( (SS_for_cpl_x & 0xfffc) == 0 ) {
+            BX_PANIC(("call_protected: new SS null\n"));
+            exception(BX_TS_EXCEPTION, 0, 0);
+            return;
+            }
+
+          // selector index must be within its descriptor table limits,
+          //   else #TS(SS selector)
+          parse_selector(SS_for_cpl_x, &ss_selector);
+          fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+            BX_TS_EXCEPTION);
+
+          parse_descriptor(dword1, dword2, &ss_descriptor);
+
+          // selector's RPL must equal DPL of code segment,
+          //   else #TS(SS selector)
+          if (ss_selector.rpl != cs_descriptor.dpl) {
+            BX_PANIC(("call_protected: SS selector.rpl != CS descr.dpl\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            return;
+            }
+
+          // stack segment DPL must equal DPL of code segment,
+          //   else #TS(SS selector)
+          if (ss_descriptor.dpl != cs_descriptor.dpl) {
+            BX_PANIC(("call_protected: SS descr.rpl != CS descr.dpl\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            return;
+            }
+
+          // descriptor must indicate writable data segment,
+          //   else #TS(SS selector)
+          if (ss_descriptor.valid==0 ||
+              ss_descriptor.segment==0  ||
+              ss_descriptor.u.segment.executable ||
+              ss_descriptor.u.segment.r_w==0) {
+            BX_INFO(("call_protected: ss descriptor not writable data seg\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            return;
+            }
+
+          // segment must be present, else #SS(SS selector)
+          if (ss_descriptor.p==0) {
+            BX_PANIC(("call_protected: ss descriptor not present.\n"));
+            exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            return;
+            }
+
+          if ( cs_descriptor.u.segment.d_b )
+            // new stack must have room for parameters plus 16 bytes
+            room_needed = 16;
+          else
+            // new stack must have room for parameters plus 8 bytes
+            room_needed =  8;
+
+          if (gate_descriptor.type==4) {
+            // get word count from call gate, mask to 5 bits
+            param_count = gate_descriptor.u.gate286.word_count & 0x1f;
+            room_needed += param_count*2;
+            }
+          else {
+            // get word count from call gate, mask to 5 bits
+            param_count = gate_descriptor.u.gate386.dword_count & 0x1f;
+            room_needed += param_count*4;
+            }
+
+          // new stack must have room for parameters plus return info
+          //   else #SS(SS selector)
+
+          if ( !can_push(&ss_descriptor, ESP_for_cpl_x, room_needed) ) {
+            BX_INFO(("call_protected: stack doesn't have room\n"));
+            exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            return;
+            }
+
+          // new eIP must be in code segment limit else #GP(0)
+          if ( new_EIP > cs_descriptor.u.segment.limit_scaled ) {
+            BX_PANIC(("call_protected: IP not within CS limits\n"));
+            exception(BX_GP_EXCEPTION, 0, 0);
+            return;
+            }
+
+
+          // save return SS:eSP to be pushed on new stack
+          return_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+          if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+            return_ESP = ESP;
+          else
+            return_ESP =  SP;
+          return_ss_base = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base;
+
+          // save return CS:eIP to be pushed on new stack
+          return_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+          if ( cs_descriptor.u.segment.d_b )
+            return_EIP = EIP;
+          else
+            return_EIP =  IP;
+
+
+          if (gate_descriptor.type==4) {
+            for (i=0; i<param_count; i++) {
+              access_linear(return_ss_base + return_ESP + i*2,
+                2, 0, BX_READ, &parameter_word[i]);
+              }
+            }
+          else {
+            for (i=0; i<param_count; i++) {
+              access_linear(return_ss_base + return_ESP + i*4,
+                4, 0, BX_READ, &parameter_dword[i]);
+              }
+            }
+
+          /* load new SS:SP value from TSS */
+          /* load SS descriptor */
+          load_ss(&ss_selector, &ss_descriptor, ss_descriptor.dpl);
+          if (ss_descriptor.u.segment.d_b)
+            ESP = ESP_for_cpl_x;
+          else
+            SP =  (Bit16u) ESP_for_cpl_x;
+
+          /* load new CS:IP value from gate */
+          /* load CS descriptor */
+          /* set CPL to stack segment DPL */
+          /* set RPL of CS to CPL */
+          load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl);
+          EIP = new_EIP;
+
+          // push pointer of old stack onto new stack
+          if (gate_descriptor.type==4) {
+            push_16(return_SS);
+            push_16((Bit16u) return_ESP);
+            }
+          else {
+            push_32(return_SS);
+            push_32(return_ESP);
+            }
+
+          /* get word count from call gate, mask to 5 bits */
+          /* copy parameters from old stack onto new stack */
+          if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+            temp_ESP = ESP;
+          else
+            temp_ESP =  SP;
+
+          if (gate_descriptor.type==4) {
+            for (i=param_count; i>0; i--) {
+              push_16(parameter_word[i-1]);
+              //access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + i*2,
+              //  2, 0, BX_WRITE, &parameter_word[i]);
+              }
+            }
+          else {
+            for (i=param_count; i>0; i--) {
+              push_32(parameter_dword[i-1]);
+              //access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + i*4,
+              //  4, 0, BX_WRITE, &parameter_dword[i]);
+              }
+            }
+
+          // push return address onto new stack
+          if (gate_descriptor.type==4) {
+            push_16(return_CS);
+            push_16((Bit16u) return_EIP);
+            }
+          else {
+            push_32(return_CS);
+            push_32(return_EIP);
+            }
+
+          return;
+          }
+
+        // CALL GATE TO SAME PRIVILEGE
+        else {
+          Bit32u temp_ESP;
+
+//BX_INFO(("CALL: Call Gate: to same priviliged level\n"));
+          if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+            temp_ESP = ESP;
+          else
+            temp_ESP = SP;
+
+          if (gate_descriptor.type==12) {
+          //if (i->os_32) {}
+            // stack must room for 8-byte return address (2 are padding)
+            //   else #SS(0)
+            if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 8) ) {
+              BX_PANIC(("call_protected: stack doesn't have room for 8 bytes\n"));
+              exception(BX_SS_EXCEPTION, 0, 0);
+              }
+            }
+          else {
+            // stack must room for 4-byte return address
+            //   else #SS(0)
+            if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+              BX_PANIC(("call_protected: stack doesn't have room for 4 bytes\n"));
+              exception(BX_SS_EXCEPTION, 0, 0);
+              }
+            }
+
+          // EIP must be within code segment limit, else #GP(0)
+          if ( new_EIP > cs_descriptor.u.segment.limit_scaled ) {
+            BX_PANIC(("call_protected: IP not within code segment limits\n"));
+            exception(BX_GP_EXCEPTION, 0, 0);
+            }
+
+          if (gate_descriptor.type==12) {
+            // push return address onto stack
+            push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+            push_32(EIP);
+            }
+          else {
+            // push return address onto stack
+            push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+            push_16(IP);
+            }
+
+          // load CS:EIP from gate
+          // load code segment descriptor into CS register
+          // set RPL of CS to CPL
+          load_cs(&cs_selector, &cs_descriptor, CPL);
+          EIP = new_EIP;
+
+          return;
+          }
+
+        BX_PANIC(("call_protected: call gate: should not get here\n"));
+        return;
+
+      default:
+        BX_PANIC(("call_protected: type = %d\n",
+          (unsigned) cs_descriptor.type));
+        return;
+      }
+    BX_PANIC(("call_protected: gate segment unfinished\n"));
+    }
+
+  BX_PANIC(("call_protected: shouldn't get here!\n"));
+  return;
+}
+#endif /* 286+ */
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::return_protected(BxInstruction_t *i, Bit16u pop_bytes)
+{
+  Bit16u raw_cs_selector, raw_ss_selector;
+  bx_selector_t cs_selector, ss_selector;
+  bx_descriptor_t cs_descriptor, ss_descriptor;
+  Bit32u stack_cs_offset, stack_param_offset;
+  Bit32u return_EIP, return_ESP, temp_ESP;
+  Bit32u dword1, dword2;
+  Bit16u return_IP;
+
+
+  /* + 6+N*2: SS      | +12+N*4:     SS */
+  /* + 4+N*2: SP      | + 8+N*4:    ESP */
+  /*          parm N  | +        parm N */
+  /*          parm 3  | +        parm 3 */
+  /*          parm 2  | +        parm 2 */
+  /*          parm 1  | + 8:     parm 1 */
+  /* + 2:     CS      | + 4:         CS */
+  /* + 0:     IP      | + 0:        EIP */
+
+#if BX_CPU_LEVEL >= 3
+  if ( i->os_32 ) {
+    /* operand size=32: third word on stack must be within stack limits,
+     *   else #SS(0); */
+    if (!can_pop(6)) {
+      BX_PANIC(("return_protected: 3rd word not in stack limits\n"));
+      /* #SS(0) */
+      return;
+      }
+    stack_cs_offset = 4;
+    stack_param_offset = 8;
+    }
+  else
+#endif
+    {
+    /* operand size=16: second word on stack must be within stack limits,
+     *   else #SS(0);
+     */
+    if ( !can_pop(4) ) {
+      BX_PANIC(("return_protected: 2nd word not in stack limits\n"));
+      /* #SS(0) */
+      return;
+      }
+    stack_cs_offset = 2;
+    stack_param_offset = 4;
+    }
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) temp_ESP = ESP;
+  else temp_ESP = SP;
+
+  // return selector RPL must be >= CPL, else #GP(return selector)
+  access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP +
+                       stack_cs_offset, 2, CPL==3, BX_READ, &raw_cs_selector);
+  parse_selector(raw_cs_selector, &cs_selector);
+  if ( cs_selector.rpl < CPL ) {
+    BX_INFO(("return_protected: CS.rpl < CPL\n"));
+    BX_INFO(("  CS.rpl=%u CPL=%u\n", (unsigned) cs_selector.rpl,
+      (unsigned) CPL));
+    exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+    return;
+    }
+
+  // if return selector RPL == CPL then
+  // RETURN TO SAME LEVEL
+  if ( cs_selector.rpl == CPL ) {
+    //BX_INFO(("return: to same level %04x:%08x\n",
+    //   BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+    //   BX_CPU_THIS_PTR prev_eip));
+    // return selector must be non-null, else #GP(0)
+    if ( (raw_cs_selector & 0xfffc) == 0 ) {
+      BX_PANIC(("return_protected: CS null\n"));
+      /* #GP(0) */
+      return;
+      }
+
+    // selector index must be within its descriptor table limits,
+    // else #GP(selector)
+    fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+      BX_GP_EXCEPTION);
+
+    // descriptor AR byte must indicate code segment, else #GP(selector)
+    parse_descriptor(dword1, dword2, &cs_descriptor);
+    if (cs_descriptor.valid==0 ||
+        cs_descriptor.segment==0 ||
+        cs_descriptor.u.segment.executable==0) {
+      BX_INFO(("return_protected: same: AR byte not code\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      }
+
+    // if non-conforming then code segment DPL must = CPL,
+    // else #GP(selector)
+    if ((cs_descriptor.u.segment.c_ed==0)  && (cs_descriptor.dpl!=CPL)) {
+      BX_PANIC(("return_protected: non-conforming, DPL!=CPL\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    // if conforming then code segment DPL must be <= CPL,
+    // else #GP(selector)
+    if (cs_descriptor.u.segment.c_ed  && (cs_descriptor.dpl>CPL)) {
+      BX_INFO(("return_protected: conforming, DPL>CPL\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      }
+
+    // code segment must be present, else #NP(selector)
+    if (cs_descriptor.p==0) {
+      BX_INFO(("return_protected: not present\n"));
+      exception(BX_NP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    // top word on stack must be within stack limits, else #SS(0)
+    if ( !can_pop(stack_param_offset + pop_bytes) ) {
+      BX_PANIC(("return_protected: top word not in stack limits\n"));
+      /* #SS(0) */
+      return;
+      }
+
+    // eIP must be in code segment limit, else #GP(0)
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &return_EIP);
+      }
+    else
+#endif
+      {
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        2, CPL==3, BX_READ, &return_IP);
+      return_EIP = return_IP;
+      }
+
+    if ( return_EIP > cs_descriptor.u.segment.limit_scaled ) {
+      BX_PANIC(("return_protected: return IP > CS.limit\n"));
+      /* #GP(0) */
+      return;
+      }
+
+    // load CS:eIP from stack
+    // load CS register with descriptor
+    // increment eSP
+    load_cs(&cs_selector, &cs_descriptor, CPL);
+    BX_CPU_THIS_PTR eip = return_EIP;
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      ESP += stack_param_offset + pop_bytes;
+    else
+      SP += stack_param_offset + pop_bytes;
+
+    return;
+    }
+
+  /* RETURN TO OUTER PRIVILEGE LEVEL */
+  else {
+    /* + 6+N*2: SS      | +12+N*4:     SS */
+    /* + 4+N*2: SP      | + 8+N*4:    ESP */
+    /*          parm N  | +        parm N */
+    /*          parm 3  | +        parm 3 */
+    /*          parm 2  | +        parm 2 */
+    /*          parm 1  | + 8:     parm 1 */
+    /* + 2:     CS      | + 4:         CS */
+    /* + 0:     IP      | + 0:        EIP */
+
+//BX_INFO(("return: to outer level %04x:%08x\n",
+//  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+//  BX_CPU_THIS_PTR prev_eip));
+
+    if (i->os_32) {
+      /* top 16+immediate bytes on stack must be within stack limits, else #SS(0) */
+      if ( !can_pop(16 + pop_bytes) ) {
+        BX_PANIC(("return_protected: 8 bytes not within stack limits\n"));
+        /* #SS(0) */
+        return;
+        }
+      }
+    else {
+      /* top 8+immediate bytes on stack must be within stack limits, else #SS(0) */
+      if ( !can_pop(8 + pop_bytes) ) {
+        BX_PANIC(("return_protected: 8 bytes not within stack limits\n"));
+        /* #SS(0) */
+        return;
+        }
+      }
+
+    /* examine return CS selector and associated descriptor */
+
+    /* selector must be non-null else #GP(0) */
+    if ( (raw_cs_selector & 0xfffc) == 0 ) {
+      BX_PANIC(("return_protected: CS selector null\n"));
+      /* #GP(0) */
+      return;
+      }
+
+    /* selector index must be within its descriptor table limits,
+     * else #GP(selector) */
+    fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+      BX_GP_EXCEPTION);
+    parse_descriptor(dword1, dword2, &cs_descriptor);
+
+    /* descriptor AR byte must indicate code segment else #GP(selector) */
+    if (cs_descriptor.valid==0 ||
+        cs_descriptor.segment==0  ||
+        cs_descriptor.u.segment.executable==0) {
+      BX_PANIC(("return_protected: AR byte not code\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    /* if non-conforming code then code seg DPL must equal return selector RPL
+     * else #GP(selector) */
+    if (cs_descriptor.u.segment.c_ed==0 &&
+        cs_descriptor.dpl!=cs_selector.rpl) {
+      BX_PANIC(("return_protected: non-conforming seg DPL != selector.rpl\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    /* if conforming then code segment DPL must be <= return selector RPL
+     * else #GP(selector) */
+    if (cs_descriptor.u.segment.c_ed &&
+        cs_descriptor.dpl>cs_selector.rpl) {
+      BX_PANIC(("return_protected: conforming seg DPL > selector.rpl\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    /* segment must be present else #NP(selector) */
+    if (cs_descriptor.p==0) {
+      BX_PANIC(("return_protected: segment not present\n"));
+      /* #NP(selector) */
+      return;
+      }
+
+    /* examine return SS selector and associated descriptor: */
+    if (i->os_32) {
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 12 + pop_bytes,
+        2, 0, BX_READ, &raw_ss_selector);
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8 + pop_bytes,
+        4, 0, BX_READ, &return_ESP);
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, 0, BX_READ, &return_EIP);
+      }
+    else {
+      Bit16u return_SP;
+
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 6 + pop_bytes,
+        2, 0, BX_READ, &raw_ss_selector);
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4 + pop_bytes,
+        2, 0, BX_READ, &return_SP);
+      return_ESP = return_SP;
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        2, 0, BX_READ, &return_IP);
+      return_EIP = return_IP;
+      }
+
+    /* selector must be non-null else #GP(0) */
+    if ( (raw_ss_selector & 0xfffc) == 0 ) {
+      BX_PANIC(("return_protected: SS selector null\n"));
+      /* #GP(0) */
+      return;
+      }
+
+    /* selector index must be within its descriptor table limits,
+     * else #GP(selector) */
+    parse_selector(raw_ss_selector, &ss_selector);
+    fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+      BX_GP_EXCEPTION);
+    parse_descriptor(dword1, dword2, &ss_descriptor);
+
+    /* selector RPL must = RPL of the return CS selector,
+     * else #GP(selector) */
+    if (ss_selector.rpl != cs_selector.rpl) {
+      BX_INFO(("return_protected: ss.rpl != cs.rpl\n"));
+      exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+      return;
+      }
+
+    /* descriptor AR byte must indicate a writable data segment,
+     * else #GP(selector) */
+    if (ss_descriptor.valid==0 ||
+        ss_descriptor.segment==0 ||
+        ss_descriptor.u.segment.executable ||
+        ss_descriptor.u.segment.r_w==0) {
+      BX_PANIC(("return_protected: SS.AR byte not writable data\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    /* descriptor dpl must = RPL of the return CS selector,
+     * else #GP(selector) */
+    if (ss_descriptor.dpl != cs_selector.rpl) {
+      BX_PANIC(("return_protected: SS.dpl != cs.rpl\n"));
+      /* #GP(selector) */
+      return;
+      }
+
+    /* segment must be present else #SS(selector) */
+    if (ss_descriptor.p==0) {
+      BX_PANIC(("ss.p == 0\n"));
+      /* #NP(selector) */
+      return;
+      }
+
+    /* eIP must be in code segment limit, else #GP(0) */
+    if (return_EIP > cs_descriptor.u.segment.limit_scaled) {
+      BX_PANIC(("return_protected: eIP > cs.limit\n"));
+      /* #GP(0) */
+      return;
+      }
+
+    /* set CPL to RPL of return CS selector */
+    /* load CS:IP from stack */
+    /* set CS RPL to CPL */
+    /* load the CS-cache with return CS descriptor */
+    load_cs(&cs_selector, &cs_descriptor, cs_selector.rpl);
+    BX_CPU_THIS_PTR eip = return_EIP;
+
+    /* load SS:SP from stack */
+    /* load SS-cache with return SS descriptor */
+    load_ss(&ss_selector, &ss_descriptor, cs_selector.rpl);
+    if (ss_descriptor.u.segment.d_b)
+      ESP = return_ESP;
+    else
+      SP  = (Bit16u) return_ESP;
+
+    /* check ES, DS, FS, GS for validity */
+    validate_seg_regs();
+
+    return;
+    }
+
+  return;
+}
+#endif
+
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::iret_protected(BxInstruction_t *i)
+{
+  Bit16u raw_cs_selector, raw_ss_selector;
+  bx_selector_t cs_selector, ss_selector;
+  Bit32u dword1, dword2;
+  bx_descriptor_t cs_descriptor, ss_descriptor;
+
+  if (BX_CPU_THIS_PTR eflags.nt) { /* NT = 1: RETURN FROM NESTED TASK */
+    /* what's the deal with NT & VM ? */
+    Bit32u base32;
+    Bit16u raw_link_selector;
+    bx_selector_t   link_selector;
+    bx_descriptor_t tss_descriptor;
+
+    if (BX_CPU_THIS_PTR eflags.vm)
+      BX_PANIC(("IRET: vm set?\n"));
+
+    // TASK_RETURN:
+
+    //BX_INFO(("IRET: nested task return\n"));
+
+    if (BX_CPU_THIS_PTR tr.cache.valid==0)
+      BX_PANIC(("IRET: TR not valid\n"));
+    if (BX_CPU_THIS_PTR tr.cache.type == 1)
+      base32 = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
+    else if (BX_CPU_THIS_PTR tr.cache.type == 9)
+      base32 = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
+    else {
+      BX_PANIC(("IRET: TR not valid\n"));
+      base32 = 0; // keep compiler happy
+      }
+
+    // examine back link selector in TSS addressed by current TR:
+    access_linear(base32 + 0, 2, 0, BX_READ, &raw_link_selector);
+
+    // must specify global, else #TS(new TSS selector)
+    parse_selector(raw_link_selector, &link_selector);
+    if (link_selector.ti) {
+      BX_PANIC(("iret: link selector.ti=1\n"));
+      exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+      }
+
+    // index must be within GDT limits, else #TS(new TSS selector)
+    fetch_raw_descriptor(&link_selector, &dword1, &dword2, BX_TS_EXCEPTION);
+
+    // AR byte must specify TSS, else #TS(new TSS selector)
+    // new TSS must be busy, else #TS(new TSS selector)
+    parse_descriptor(dword1, dword2, &tss_descriptor);
+    if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+      BX_INFO(("iret: TSS selector points to bad TSS\n"));
+      exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+      }
+    if ((tss_descriptor.type!=11) && (tss_descriptor.type!=3)) {
+      BX_INFO(("iret: TSS selector points to bad TSS\n"));
+      exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+      }
+
+
+    // TSS must be present, else #NP(new TSS selector)
+    if (tss_descriptor.p==0) {
+      BX_INFO(("iret: task descriptor.p == 0\n"));
+      exception(BX_NP_EXCEPTION, raw_link_selector & 0xfffc, 0);
+      }
+
+    // switch tasks (without nesting) to TSS specified by back link selector
+    task_switch(&link_selector, &tss_descriptor,
+                BX_TASK_FROM_IRET, dword1, dword2);
+
+    // mark the task just abandoned as not busy
+
+    // eIP must be within code seg limit, else #GP(0)
+    if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+      BX_PANIC(("iret: eIP > cs.limit\n"));
+      exception(BX_GP_EXCEPTION, 0x0000, 0);
+      }
+    return;
+    }
+
+  else { /* NT = 0: INTERRUPT RETURN ON STACK -or STACK_RETURN_TO_V86 */
+    Bit16u top_nbytes_same, top_nbytes_outer;
+    Bit32u cs_offset, ss_offset;
+    Bit32u new_eip, new_esp, temp_ESP, new_eflags;
+    Bit16u new_ip, new_sp, new_flags;
+    Bit8u prev_cpl;
+
+    /* 16bit opsize  |   32bit opsize
+     * ==============================
+     * SS     eSP+8  |   SS     eSP+16
+     * SP     eSP+6  |   ESP    eSP+12
+     * -------------------------------
+     * FLAGS  eSP+4  |   EFLAGS eSP+8
+     * CS     eSP+2  |   CS     eSP+4
+     * IP     eSP+0  |   EIP    eSP+0
+     */
+
+    if (i->os_32) {
+      top_nbytes_same    = 12;
+      top_nbytes_outer   = 20;
+      cs_offset = 4;
+      ss_offset = 16;
+      }
+    else {
+      top_nbytes_same    = 6;
+      top_nbytes_outer   = 10;
+      cs_offset = 2;
+      ss_offset = 8;
+      }
+
+    /* CS on stack must be within stack limits, else #SS(0) */
+    if ( !can_pop(top_nbytes_same) ) {
+      BX_PANIC(("iret: CS not within stack limits\n"));
+      exception(BX_SS_EXCEPTION, 0, 0);
+      return;
+      }
+
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      temp_ESP = ESP;
+    else
+      temp_ESP = SP;
+
+    access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + cs_offset,
+      2, CPL==3, BX_READ, &raw_cs_selector);
+
+    if (i->os_32) {
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        4, CPL==3, BX_READ, &new_eip);
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8,
+        4, CPL==3, BX_READ, &new_eflags);
+
+      // if VM=1 in flags image on stack then STACK_RETURN_TO_V86
+      if (new_eflags & 0x00020000) {
+        if (CPL != 0)
+          BX_PANIC(("iret: VM set on stack, CPL!=0\n"));
+        BX_CPU_THIS_PTR stack_return_to_v86(new_eip, raw_cs_selector, new_eflags);
+        return;
+        }
+      }
+    else {
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+        2, CPL==3, BX_READ, &new_ip);
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4,
+        2, CPL==3, BX_READ, &new_flags);
+      }
+
+    parse_selector(raw_cs_selector, &cs_selector);
+
+    // return CS selector must be non-null, else #GP(0)
+    if ( (raw_cs_selector & 0xfffc) == 0 ) {
+      BX_PANIC(("iret: return CS selector null\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+
+    // selector index must be within descriptor table limits,
+    // else #GP(return selector)
+    fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+      BX_GP_EXCEPTION);
+
+    parse_descriptor(dword1, dword2, &cs_descriptor);
+
+    // AR byte must indicate code segment else #GP(return selector)
+    if ( cs_descriptor.valid==0 ||
+         cs_descriptor.segment==0  ||
+         cs_descriptor.u.segment.executable==0 ) {
+      BX_PANIC(("iret: AR byte indicated non code segment\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    // return CS selector RPL must be >= CPL, else #GP(return selector)
+    if (cs_selector.rpl < CPL) {
+      BX_PANIC(("iret: return selector RPL < CPL\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    // if return code seg descriptor is conforming
+    //   and return code seg DPL > return code seg selector RPL
+    //     then #GP(return selector)
+    if ( cs_descriptor.u.segment.c_ed  &&
+         cs_descriptor.dpl > cs_selector.rpl ) {
+      BX_PANIC(("iret: conforming, DPL > cs_selector.RPL\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    // if return code seg descriptor is non-conforming
+    //   and return code seg DPL != return code seg selector RPL
+    //     then #GP(return selector)
+    if ( cs_descriptor.u.segment.c_ed==0 &&
+         cs_descriptor.dpl != cs_selector.rpl ) {
+      BX_INFO(("(mch) iret: Return with DPL != RPL. #GP(selector)\n"));
+      exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    // segment must be present else #NP(return selector)
+    if ( cs_descriptor.p==0 ) {
+      BX_PANIC(("iret: not present\n"));
+      exception(BX_NP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+      return;
+      }
+
+    if (cs_selector.rpl == CPL) { /* INTERRUPT RETURN TO SAME LEVEL */
+      /* top 6/12 bytes on stack must be within limits, else #SS(0) */
+      /* satisfied above */
+
+      if (i->os_32) {
+        /* return EIP must be in code segment limit else #GP(0) */
+        if ( new_eip > cs_descriptor.u.segment.limit_scaled ) {
+          BX_PANIC(("iret: IP > descriptor limit\n"));
+          exception(BX_GP_EXCEPTION, 0, 0);
+          return;
+          }
+        /* load CS:EIP from stack */
+        /* load CS-cache with new code segment descriptor */
+        load_cs(&cs_selector, &cs_descriptor, CPL);
+        EIP = new_eip;
+
+        /* load EFLAGS with 3rd doubleword from stack */
+        write_eflags(new_eflags, CPL==0, CPL<=IOPL, 0, 1);
+        }
+      else {
+        /* return IP must be in code segment limit else #GP(0) */
+        if ( new_ip > cs_descriptor.u.segment.limit_scaled ) {
+          BX_PANIC(("iret: IP > descriptor limit\n"));
+          exception(BX_GP_EXCEPTION, 0, 0);
+          return;
+          }
+        /* load CS:IP from stack */
+        /* load CS-cache with new code segment descriptor */
+        load_cs(&cs_selector, &cs_descriptor, CPL);
+        EIP = new_ip;
+
+        /* load flags with third word on stack */
+        write_flags(new_flags, CPL==0, CPL<=IOPL);
+        }
+
+      /* increment stack by 6/12 */
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+        ESP += top_nbytes_same;
+      else
+        SP += top_nbytes_same;
+      return;
+      }
+    else { /* INTERRUPT RETURN TO OUTER PRIVILEGE LEVEL */
+      /* 16bit opsize  |   32bit opsize
+       * ==============================
+       * SS     eSP+8  |   SS     eSP+16
+       * SP     eSP+6  |   ESP    eSP+12
+       * FLAGS  eSP+4  |   EFLAGS eSP+8
+       * CS     eSP+2  |   CS     eSP+4
+       * IP     eSP+0  |   EIP    eSP+0
+       */
+
+      /* top 10/20 bytes on stack must be within limits else #SS(0) */
+      if ( !can_pop(top_nbytes_outer) ) {
+        BX_PANIC(("iret: top 10/20 bytes not within stack limits\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+
+      /* examine return SS selector and associated descriptor */
+      access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + ss_offset,
+        2, 0, BX_READ, &raw_ss_selector);
+
+      /* selector must be non-null, else #GP(0) */
+      if ( (raw_ss_selector & 0xfffc) == 0 ) {
+        BX_PANIC(("iret: SS selector null\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        return;
+        }
+
+      parse_selector(raw_ss_selector, &ss_selector);
+
+      /* selector RPL must = RPL of return CS selector,
+       * else #GP(SS selector) */
+      if ( ss_selector.rpl != cs_selector.rpl) {
+        BX_PANIC(("iret: SS.rpl != CS.rpl\n"));
+        exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+        return;
+        }
+
+      /* selector index must be within its descriptor table limits,
+       * else #GP(SS selector) */
+      fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+        BX_GP_EXCEPTION);
+
+      parse_descriptor(dword1, dword2, &ss_descriptor);
+
+      /* AR byte must indicate a writable data segment,
+       * else #GP(SS selector) */
+      if ( ss_descriptor.valid==0 ||
+           ss_descriptor.segment==0  ||
+           ss_descriptor.u.segment.executable  ||
+           ss_descriptor.u.segment.r_w==0 ) {
+        BX_PANIC(("iret: SS AR byte not writable code segment\n"));
+        exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+        return;
+        }
+
+      /* stack segment DPL must equal the RPL of the return CS selector,
+       * else #GP(SS selector) */
+      if ( ss_descriptor.dpl != cs_selector.rpl ) {
+        BX_PANIC(("iret: SS.dpl != CS selector RPL\n"));
+        exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+        return;
+        }
+
+      /* SS must be present, else #NP(SS selector) */
+      if ( ss_descriptor.p==0 ) {
+        BX_PANIC(("iret: SS not present!\n"));
+        exception(BX_NP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+        return;
+        }
+
+
+      if (i->os_32) {
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+          4, 0, BX_READ, &new_eip);
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8,
+          4, 0, BX_READ, &new_eflags);
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 12,
+          4, 0, BX_READ, &new_esp);
+        }
+      else {
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+          2, 0, BX_READ, &new_ip);
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4,
+          2, 0, BX_READ, &new_flags);
+        access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 6,
+          2, 0, BX_READ, &new_sp);
+        new_eip = new_ip;
+        new_esp = new_sp;
+        new_eflags = new_flags;
+        }
+
+      /* EIP must be in code segment limit, else #GP(0) */
+      if ( new_eip > cs_descriptor.u.segment.limit_scaled ) {
+        BX_PANIC(("iret: IP > descriptor limit\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        return;
+        }
+
+      /* load CS:EIP from stack */
+      /* load the CS-cache with CS descriptor */
+      /* set CPL to the RPL of the return CS selector */
+      prev_cpl = CPL; /* previous CPL */
+      load_cs(&cs_selector, &cs_descriptor, cs_selector.rpl);
+      BX_CPU_THIS_PTR eip = new_eip;
+
+      /* load flags from stack */
+      // perhaps I should always write_eflags(), thus zeroing
+      // out the upper 16bits of eflags for CS.D_B==0 ???
+      if (cs_descriptor.u.segment.d_b)
+        write_eflags(new_eflags, prev_cpl==0, prev_cpl<=IOPL, 0, 1);
+      else
+        write_flags((Bit16u) new_eflags, prev_cpl==0, prev_cpl<=IOPL);
+
+      // load SS:eSP from stack
+      // load the SS-cache with SS descriptor
+      load_ss(&ss_selector, &ss_descriptor, cs_selector.rpl);
+      if (ss_descriptor.u.segment.d_b)
+        ESP = new_esp;
+      else
+        SP  = new_esp;
+
+      validate_seg_regs();
+
+      return;
+      }
+    }
+  BX_PANIC(("IRET: shouldn't get here!\n"));
+}
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::validate_seg_regs(void)
+{
+  if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl<CPL ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
+    }
+  if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl<CPL ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0;
+    }
+  if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl<CPL ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = 0;
+    }
+  if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl<CPL ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0;
+    }
+}
+#endif
diff --git a/sid/component/bochs/cpu/data_xfer16.cc b/sid/component/bochs/cpu/data_xfer16.cc
new file mode 100644 (file)
index 0000000..d87a6d7
--- /dev/null
@@ -0,0 +1,378 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::MOV_RXIw(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = i->Iw;
+}
+
+  void
+BX_CPU_C::XCHG_RXAX(BxInstruction_t *i)
+{
+  Bit16u temp16;
+
+  temp16 = AX;
+  AX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = temp16;
+}
+
+
+  void
+BX_CPU_C::MOV_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16;
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    /* now write op2 to op1 */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op2_16);
+      }
+    else {
+      write_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+}
+
+
+  void
+BX_CPU_C::MOV_GwEw(BxInstruction_t *i)
+{
+    Bit16u op2_16;
+
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    BX_WRITE_16BIT_REG(i->nnn, op2_16);
+}
+
+  void
+BX_CPU_C::MOV_EwSw(BxInstruction_t *i)
+{
+  Bit16u seg_reg;
+
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_EwSw: incomplete for CPU < 3\n"));
+#endif
+
+  seg_reg = BX_CPU_THIS_PTR sregs[i->nnn].selector.value;
+
+  if (i->mod == 0xc0) {
+    // ??? BX_WRITE_16BIT_REG(mem_addr, seg_reg);
+    if ( i->os_32 ) {
+      BX_WRITE_32BIT_REG(i->rm, seg_reg);
+      }
+    else {
+      BX_WRITE_16BIT_REG(i->rm, seg_reg);
+      }
+    }
+  else {
+    write_virtual_word(i->seg, i->rm_addr, &seg_reg);
+    }
+}
+
+  void
+BX_CPU_C::MOV_SwEw(BxInstruction_t *i)
+{
+  Bit16u op2_16;
+
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_SwEw: incomplete for CPU < 3\n"));
+#endif
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+  load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn], op2_16);
+
+  if (i->nnn == BX_SEG_REG_SS) {
+    // MOV SS inhibits interrupts, debug exceptions and single-step
+    // trap exceptions until the execution boundary following the
+    // next instruction is reached.
+    // Same code as POP_SS()
+    BX_CPU_THIS_PTR inhibit_mask |=
+      BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG;
+    BX_CPU_THIS_PTR async_event = 1;
+    }
+}
+
+  void
+BX_CPU_C::LEA_GwM(BxInstruction_t *i)
+{
+  if (i->mod == 0xc0) {
+    BX_PANIC(("LEA_GvM: op2 is a register"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+    BX_WRITE_16BIT_REG(i->nnn, (Bit16u) i->rm_addr);
+}
+
+
+  void
+BX_CPU_C::MOV_AXOw(BxInstruction_t *i)
+{
+  Bit16u temp_16;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from memory address */
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    read_virtual_word(i->seg, addr_32, &temp_16);
+    }
+  else {
+    read_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
+    }
+
+  /* write to register */
+  AX = temp_16;
+}
+
+
+  void
+BX_CPU_C::MOV_OwAX(BxInstruction_t *i)
+{
+  Bit16u temp_16;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from register */
+  temp_16 = AX;
+
+  /* write to memory address */
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    write_virtual_word(i->seg, addr_32, &temp_16);
+    }
+  else {
+    write_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
+    }
+}
+
+
+
+  void
+BX_CPU_C::MOV_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16;
+
+    op2_16 = i->Iw;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, op2_16);
+      }
+    else {
+      write_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+}
+
+
+  void
+BX_CPU_C::MOVZX_GwEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVZX_GvEb: not supported on < 386\n"));
+#else
+  Bit8u  op2_8;
+
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+    /* zero extend byte op2 into word op1 */
+    BX_WRITE_16BIT_REG(i->nnn, (Bit16u) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVZX_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVZX_GvEw: not supported on < 386\n"));
+#else
+  Bit16u op2_16;
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+    /* normal move */
+    BX_WRITE_16BIT_REG(i->nnn, op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVSX_GwEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVSX_GvEb: not supported on < 386\n"));
+#else
+  Bit8u op2_8;
+
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+    /* sign extend byte op2 into word op1 */
+    BX_WRITE_16BIT_REG(i->nnn, (Bit8s) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVSX_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVSX_GvEw: not supported on < 386\n"));
+#else
+  Bit16u op2_16;
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+    /* normal move */
+    BX_WRITE_16BIT_REG(i->nnn, op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+
+  void
+BX_CPU_C::XCHG_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16;
+
+#ifdef MAGIC_BREAKPOINT
+#if BX_DEBUGGER
+  // (mch) Magic break point
+  if (i->nnn == 3 && i->mod == 0xc0 && i->rm == 3) {
+    BX_CPU_THIS_PTR magic_break = 1;
+    }
+#endif
+#endif
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      BX_WRITE_16BIT_REG(i->rm, op2_16);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      write_RMW_virtual_word(op2_16);
+      }
+
+    BX_WRITE_16BIT_REG(i->nnn, op1_16);
+}
+
+
+  void
+BX_CPU_C::CMOV_GwEw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 6) || (BX_CPU_LEVEL_HACKED >= 6)
+  // Note: CMOV accesses a memory source operand (read), regardless
+  //       of whether condition is true or not.  Thus, exceptions may
+  //       occur even if the MOV does not take place.
+
+  Boolean condition;
+  Bit16u op2_16;
+
+  switch (i->b1) {
+    // CMOV opcodes:
+    case 0x140: condition = get_OF(); break;
+    case 0x141: condition = !get_OF(); break;
+    case 0x142: condition = get_CF(); break;
+    case 0x143: condition = !get_CF(); break;
+    case 0x144: condition = get_ZF(); break;
+    case 0x145: condition = !get_ZF(); break;
+    case 0x146: condition = get_CF() || get_ZF(); break;
+    case 0x147: condition = !get_CF() && !get_ZF(); break;
+    case 0x148: condition = get_SF(); break;
+    case 0x149: condition = !get_SF(); break;
+    case 0x14A: condition = get_PF(); break;
+    case 0x14B: condition = !get_PF(); break;
+    case 0x14C: condition = get_SF() != get_OF(); break;
+    case 0x14D: condition = get_SF() == get_OF(); break;
+    case 0x14E: condition = get_ZF() || (get_SF() != get_OF()); break;
+    case 0x14F: condition = !get_ZF() && (get_SF() == get_OF()); break;
+    default:
+      condition = 0;
+      BX_PANIC(("CMOV_GwEw: default case\n"));
+    }
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+  if (condition) {
+    BX_WRITE_16BIT_REG(i->nnn, op2_16);
+    }
+#else
+  BX_PANIC(("cmov_gwew called\n"));
+#endif
+}
diff --git a/sid/component/bochs/cpu/data_xfer32.cc b/sid/component/bochs/cpu/data_xfer32.cc
new file mode 100644 (file)
index 0000000..5272010
--- /dev/null
@@ -0,0 +1,318 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+  void
+BX_CPU_C::XCHG_ERXEAX(BxInstruction_t *i)
+{
+  Bit32u temp32;
+
+  temp32 = EAX;
+  EAX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = temp32;
+}
+
+  void
+BX_CPU_C::MOV_ERXId(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = i->Id;
+}
+
+  void
+BX_CPU_C::MOV_EdGd(BxInstruction_t *i)
+{
+    Bit32u op2_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    /* now write op2 to op1 */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op2_32);
+      }
+    else {
+      write_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+}
+
+
+  void
+BX_CPU_C::MOV_GdEd(BxInstruction_t *i)
+{
+    Bit32u op2_32;
+
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    BX_WRITE_32BIT_REG(i->nnn, op2_32);
+}
+
+
+  void
+BX_CPU_C::LEA_GdM(BxInstruction_t *i)
+{
+  if (i->mod == 0xc0) {
+    BX_PANIC(("LEA_GvM: op2 is a register"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+    /* write effective address of op2 in op1 */
+    BX_WRITE_32BIT_REG(i->nnn, i->rm_addr);
+}
+
+
+  void
+BX_CPU_C::MOV_EAXOd(BxInstruction_t *i)
+{
+  Bit32u temp_32;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from memory address */
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    read_virtual_dword(i->seg, addr_32, &temp_32);
+    }
+  else {
+    read_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
+    }
+
+  /* write to register */
+  EAX = temp_32;
+}
+
+
+  void
+BX_CPU_C::MOV_OdEAX(BxInstruction_t *i)
+{
+  Bit32u temp_32;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from register */
+  temp_32 = EAX;
+
+  /* write to memory address */
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    write_virtual_dword(i->seg, addr_32, &temp_32);
+    }
+  else {
+    write_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
+    }
+}
+
+
+
+  void
+BX_CPU_C::MOV_EdId(BxInstruction_t *i)
+{
+    Bit32u op2_32;
+
+    op2_32 = i->Id;
+
+    /* now write sum back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, op2_32);
+      }
+    else {
+      write_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+}
+
+
+  void
+BX_CPU_C::MOVZX_GdEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVZX_GvEb: not supported on < 386\n"));
+#else
+  Bit8u  op2_8;
+
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+    /* zero extend byte op2 into dword op1 */
+    BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVZX_GdEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVZX_GvEw: not supported on < 386\n"));
+#else
+  Bit16u op2_16;
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+    /* zero extend word op2 into dword op1 */
+    BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVSX_GdEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVSX_GvEb: not supported on < 386\n"));
+#else
+  Bit8u op2_8;
+
+  if (i->mod == 0xc0) {
+    op2_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+    }
+
+    /* sign extend byte op2 into dword op1 */
+    BX_WRITE_32BIT_REG(i->nnn, (Bit8s) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+  void
+BX_CPU_C::MOVSX_GdEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOVSX_GvEw: not supported on < 386\n"));
+#else
+  Bit16u op2_16;
+
+  if (i->mod == 0xc0) {
+    op2_16 = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &op2_16);
+    }
+
+    /* sign extend word op2 into dword op1 */
+    BX_WRITE_32BIT_REG(i->nnn, (Bit16s) op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+
+  void
+BX_CPU_C::XCHG_EdGd(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      BX_WRITE_32BIT_REG(i->rm, op2_32);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      write_RMW_virtual_dword(op2_32);
+      }
+
+    BX_WRITE_32BIT_REG(i->nnn, op1_32);
+}
+
+
+  void
+BX_CPU_C::CMOV_GdEd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 6) || (BX_CPU_LEVEL_HACKED >= 6)
+  // Note: CMOV accesses a memory source operand (read), regardless
+  //       of whether condition is true or not.  Thus, exceptions may
+  //       occur even if the MOV does not take place.
+
+  Boolean condition;
+  Bit32u op2_32;
+
+
+  switch (i->b1) {
+    // CMOV opcodes:
+    case 0x140: condition = get_OF(); break;
+    case 0x141: condition = !get_OF(); break;
+    case 0x142: condition = get_CF(); break;
+    case 0x143: condition = !get_CF(); break;
+    case 0x144: condition = get_ZF(); break;
+    case 0x145: condition = !get_ZF(); break;
+    case 0x146: condition = get_CF() || get_ZF(); break;
+    case 0x147: condition = !get_CF() && !get_ZF(); break;
+    case 0x148: condition = get_SF(); break;
+    case 0x149: condition = !get_SF(); break;
+    case 0x14A: condition = get_PF(); break;
+    case 0x14B: condition = !get_PF(); break;
+    case 0x14C: condition = get_SF() != get_OF(); break;
+    case 0x14D: condition = get_SF() == get_OF(); break;
+    case 0x14E: condition = get_ZF() || (get_SF() != get_OF()); break;
+    case 0x14F: condition = !get_ZF() && (get_SF() == get_OF()); break;
+    default:
+      condition = 0;
+      BX_PANIC(("CMOV_GdEd: default case\n"));
+    }
+
+  if (i->mod == 0xc0) {
+    op2_32 = BX_READ_32BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+    }
+
+  if (condition) {
+    BX_WRITE_32BIT_REG(i->nnn, op2_32);
+    }
+#else
+  BX_PANIC(("cmov_gded called\n"));
+#endif
+}
diff --git a/sid/component/bochs/cpu/data_xfer8.cc b/sid/component/bochs/cpu/data_xfer8.cc
new file mode 100644 (file)
index 0000000..736f2b1
--- /dev/null
@@ -0,0 +1,189 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::MOV_RLIb(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x03].word.byte.rl = i->Ib;
+}
+
+  void
+BX_CPU_C::MOV_RHIb(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x03].word.byte.rh = i->Ib;
+}
+
+
+  void
+BX_CPU_C::MOV_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2;
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* now write op2 to op1 */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, op2);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+}
+
+
+  void
+BX_CPU_C::MOV_GbEb(BxInstruction_t *i)
+{
+  Bit8u op2;
+
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  BX_WRITE_8BIT_REG(i->nnn, op2);
+}
+
+
+
+  void
+BX_CPU_C::MOV_ALOb(BxInstruction_t *i)
+{
+  Bit8u  temp_8;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from memory address */
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    read_virtual_byte(i->seg, addr_32, &temp_8);
+    }
+  else {
+    read_virtual_byte(BX_SEG_REG_DS, addr_32, &temp_8);
+    }
+
+
+  /* write to register */
+  AL = temp_8;
+}
+
+
+  void
+BX_CPU_C::MOV_ObAL(BxInstruction_t *i)
+{
+  Bit8u  temp_8;
+  Bit32u addr_32;
+
+  addr_32 = i->Id;
+
+  /* read from register */
+  temp_8 = AL;
+
+  /* write to memory address */
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    write_virtual_byte(i->seg, addr_32, &temp_8);
+    }
+  else {
+    write_virtual_byte(BX_SEG_REG_DS, addr_32, &temp_8);
+    }
+}
+
+
+  void
+BX_CPU_C::MOV_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2;
+
+  op2 = i->Ib;
+
+  /* now write op2 back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, op2);
+    }
+  else {
+    write_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+}
+
+
+
+  void
+BX_CPU_C::XLAT(BxInstruction_t *i)
+{
+  Bit32u offset_32;
+  Bit8u  al;
+
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    offset_32 = EBX + AL;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    {
+    offset_32 = BX + AL;
+    }
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    read_virtual_byte(i->seg, offset_32, &al);
+    }
+  else {
+    read_virtual_byte(BX_SEG_REG_DS, offset_32, &al);
+    }
+  AL = al;
+}
+
+  void
+BX_CPU_C::XCHG_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1;
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    BX_WRITE_8BIT_REG(i->rm, op2);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    write_RMW_virtual_byte(op2);
+    }
+
+  BX_WRITE_8BIT_REG(i->nnn, op1);
+}
diff --git a/sid/component/bochs/cpu/debugstuff-sid.cc b/sid/component/bochs/cpu/debugstuff-sid.cc
new file mode 100644 (file)
index 0000000..fd1014f
--- /dev/null
@@ -0,0 +1,1024 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_DEBUGGER
+
+  void
+BX_CPU_C::debug(Bit32u offset)
+{
+  BX_INFO(("| EAX=%08x  EBX=%08x  ECX=%08x  EDX=%08x\n",
+          (unsigned) EAX, (unsigned) EBX, (unsigned) ECX, (unsigned) EDX));
+  BX_INFO(("| ESP=%08x  EBP=%08x  ESI=%08x  EDI=%08x\n",
+          (unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
+  BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s\n",
+    BX_CPU_THIS_PTR eflags.iopl,
+    BX_CPU_THIS_PTR get_OF()       ? "OV" : "NV",
+    BX_CPU_THIS_PTR eflags.df  ? "DW" : "UP",
+    BX_CPU_THIS_PTR eflags.if_ ? "EI" : "DI",
+    BX_CPU_THIS_PTR get_SF()       ? "NG" : "PL",
+    BX_CPU_THIS_PTR get_ZF()       ? "ZR" : "NZ",
+    BX_CPU_THIS_PTR get_AF()       ? "AC" : "NA",
+    BX_CPU_THIS_PTR get_PF()       ? "PE" : "PO",
+    BX_CPU_THIS_PTR get_CF()       ? "CY" : "NC"));
+  BX_INFO(("| SEG selector     base    limit G D\n"));
+  BX_INFO(("| SEG sltr(index|ti|rpl)     base    limit G D\n"));
+  BX_INFO(("|  DS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b));
+  BX_INFO(("|  ES:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b));
+  BX_INFO(("|  FS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b));
+  BX_INFO(("|  GS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b));
+  BX_INFO(("|  SS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b));
+  BX_INFO(("|  CS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b));
+  BX_INFO(("| EIP=%08x (%08x)\n", (unsigned) BX_CPU_THIS_PTR eip,
+    (unsigned) BX_CPU_THIS_PTR prev_eip));
+
+#if 0
+  /* (mch) Hack to display the area round EIP and prev_EIP */
+  char buf[100];
+  sprintf(buf, "%04x:%08x  ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  for (int i = 0; i < 8; i++) {
+    Bit8u data;
+    BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR eip + i, &data);
+    sprintf(buf+strlen(buf), "%02x ", data);
+    }
+  sprintf(buf+strlen(buf), "\n");
+  BX_INFO((buf));
+
+  sprintf(buf, "%04x:%08x  ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR prev_eip);
+  for (int i = 0; i < 8; i++) {
+    Bit8u data;
+    BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR prev_eip + i, &data);
+    sprintf(buf+strlen(buf), "%02x ", data);
+    }
+  sprintf(buf+strlen(buf), "\n");
+  BX_INFO((buf));
+#endif
+
+
+#if BX_DISASM
+  Boolean valid;
+  Bit32u  phy_addr;
+  Bit8u   instr_buf[32];
+  char    char_buf[256];
+  unsigned isize;
+
+  dbg_xlate_linear2phy(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + offset,
+                       &phy_addr, &valid);
+  if (valid) {
+    BX_CPU_THIS_PTR mem->dbg_fetch_mem(phy_addr, 16, instr_buf);
+    isize = bx_disassemble.disasm(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
+                        instr_buf, char_buf);
+    for (unsigned j=0; j<isize; j++)
+      BX_INFO((">> %02x\n", (unsigned) instr_buf[j]));
+    BX_INFO((">> : %s\n", char_buf));
+    }
+  else {
+    BX_INFO(("(instruction unavailable) page not present\n"));
+    }
+#else
+  UNUSED(offset);
+#endif  // #if BX_DISASM
+}
+
+#endif // BX_DEBUGGER
+
+
+  Bit32u
+sid_cpu_c::dbg_get_reg(unsigned reg)
+{
+  Bit32u return_val32;
+
+  switch (reg) {
+    case BX_DBG_REG_EAX: return(EAX);
+    case BX_DBG_REG_ECX: return(ECX);
+    case BX_DBG_REG_EDX: return(EDX);
+    case BX_DBG_REG_EBX: return(EBX);
+    case BX_DBG_REG_ESP: return(ESP);
+    case BX_DBG_REG_EBP: return(EBP);
+    case BX_DBG_REG_ESI: return(ESI);
+    case BX_DBG_REG_EDI: return(EDI);
+    case BX_DBG_REG_EIP: return(EIP);
+    case BX_DBG_REG_EFLAGS:
+      return_val32 = dbg_get_eflags();
+      return(return_val32);
+    case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+    case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+    case BX_DBG_REG_DS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+    case BX_DBG_REG_ES: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+    case BX_DBG_REG_FS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+    case BX_DBG_REG_GS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+    default:
+      BX_PANIC(("get_reg: request for unknown register\n"));
+      return(0);
+    }
+}
+
+  Boolean
+sid_cpu_c::dbg_set_reg(unsigned reg, Bit32u val)
+{
+  // returns 1=OK, 0=can't change
+  bx_segment_reg_t *seg;
+  Bit32u current_sys_bits;
+
+  switch (reg) {
+    case BX_DBG_REG_EAX: EAX = val; return(1);
+    case BX_DBG_REG_ECX: ECX = val; return(1);
+    case BX_DBG_REG_EDX: EDX = val; return(1);
+    case BX_DBG_REG_EBX: EBX = val; return(1);
+    case BX_DBG_REG_ESP: ESP = val; return(1);
+    case BX_DBG_REG_EBP: EBP = val; return(1);
+    case BX_DBG_REG_ESI: ESI = val; return(1);
+    case BX_DBG_REG_EDI: EDI = val; return(1);
+    case BX_DBG_REG_EIP: EIP = val; return(1);
+    case BX_DBG_REG_EFLAGS:
+#if 0
+      BX_INFO(("dbg_set_reg: can not handle eflags yet.\n"));
+      if ( val & 0xffff0000 ) {
+        BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags.\n"));
+        return(0);
+        }
+      // make sure none of the system bits are being changed
+      current_sys_bits = (BX_CPU_THIS_PTR eflags.nt << 14) |
+                         (BX_CPU_THIS_PTR eflags.iopl << 12) |
+                         (BX_CPU_THIS_PTR eflags.tf << 8);
+      if ( current_sys_bits != (val & 0x0000f100) ) {
+        BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF.\n"));
+        return(0);
+        }
+#endif
+      BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+      BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+      BX_CPU_THIS_PTR eflags.df  = val & 0x01; val >>= 1;
+      BX_CPU_THIS_PTR set_OF(val & 0x01);
+      if (BX_CPU_THIS_PTR eflags.if_)
+        BX_CPU_THIS_PTR async_event = 1;
+      return(1);
+    case BX_DBG_REG_CS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+      break;
+    case BX_DBG_REG_SS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+      break;
+    case BX_DBG_REG_DS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
+      break;
+    case BX_DBG_REG_ES:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES];
+      break;
+    case BX_DBG_REG_FS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS];
+      break;
+    case BX_DBG_REG_GS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS];
+      break;
+    default:
+      BX_PANIC(("dbg_set_reg: unrecognized register ID (%u)\n", reg));
+      return(0);
+    }
+
+  if (BX_CPU_THIS_PTR real_mode()) {
+    seg->selector.value = val;
+    seg->cache.valid = 1;
+    seg->cache.p = 1;
+    seg->cache.dpl = 0;
+    seg->cache.segment = 1; // regular segment
+    if (reg == BX_DBG_REG_CS) {
+      seg->cache.u.segment.executable = 1; // code segment
+      }
+    else {
+      seg->cache.u.segment.executable = 0; // data segment
+      }
+    seg->cache.u.segment.c_ed = 0;       // expand up/non-conforming
+    seg->cache.u.segment.r_w = 1;        // writeable
+    seg->cache.u.segment.a = 1;          // accessed
+    seg->cache.u.segment.base = val << 4;
+    seg->cache.u.segment.limit        = 0xffff;
+    seg->cache.u.segment.limit_scaled = 0xffff;
+    seg->cache.u.segment.g     = 0;      // byte granular
+    seg->cache.u.segment.d_b   = 0;      // default 16bit size
+    seg->cache.u.segment.avl   = 0;
+    return(1); // ok
+    }
+
+  return(0); // can't change when not in real mode
+}
+#if BX_DEBUGGER
+  unsigned
+BX_CPU_C::dbg_query_pending(void)
+{
+  unsigned ret = 0;
+
+  if ( BX_HRQ ) {  // DMA Hold Request
+    ret |= BX_DBG_PENDING_DMA;
+    }
+
+  if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+    ret |= BX_DBG_PENDING_IRQ;
+    }
+
+  return(ret);
+}
+
+#endif // BX_DEBUGGER
+
+  Bit32u
+sid_cpu_c::dbg_get_eflags(void)
+{
+  Bit32u val32;
+
+  val32 =
+    (BX_CPU_THIS_PTR get_CF()) |
+    (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+    ((BX_CPU_THIS_PTR get_PF()) << 2) |
+    (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+    ((BX_CPU_THIS_PTR get_AF()>0) << 4) |
+    (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+    ((BX_CPU_THIS_PTR get_ZF()>0) << 6) |
+    ((BX_CPU_THIS_PTR get_SF()>0) << 7) |
+    (BX_CPU_THIS_PTR eflags.tf << 8) |
+    (BX_CPU_THIS_PTR eflags.if_ << 9) |
+    (BX_CPU_THIS_PTR eflags.df << 10) |
+    ((BX_CPU_THIS_PTR get_OF()>0) << 11) |
+    (BX_CPU_THIS_PTR eflags.iopl << 12) |
+    (BX_CPU_THIS_PTR eflags.nt << 14) |
+    (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+    (BX_CPU_THIS_PTR eflags.rf << 16) |
+    (BX_CPU_THIS_PTR eflags.vm << 17);
+#if BX_CPU_LEVEL >= 4
+  val32 |= (BX_CPU_THIS_PTR eflags.ac << 18);
+  //val32 |= (BX_CPU_THIS_PTR eflags.vif << 19);
+  //val32 |= (BX_CPU_THIS_PTR eflags.vip << 20);
+  val32 |= (BX_CPU_THIS_PTR eflags.id << 21);
+#endif
+  return(val32);
+}
+
+#if BX_DEBUGGER
+  Bit32u
+BX_CPU_C::dbg_get_descriptor_l(bx_descriptor_t *d)
+{
+  Bit32u val;
+
+  if (d->valid == 0) {
+    return(0);
+    }
+
+  if (d->segment) {
+    val = ((d->u.segment.base & 0xffff) << 16) |
+          (d->u.segment.limit & 0xffff);
+    return(val);
+    }
+  else {
+    switch (d->type) {
+      case 0: // Reserved (not yet defined)
+        BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+        return(0);
+
+      case 1: // available 16bit TSS
+        val = ((d->u.tss286.base & 0xffff) << 16) |
+               (d->u.tss286.limit & 0xffff);
+        return(val);
+
+      case 2: // LDT
+        val = ((d->u.ldt.base & 0xffff) << 16) |
+              d->u.ldt.limit;
+        return(val);
+
+      case 9: // available 32bit TSS
+        val = ((d->u.tss386.base & 0xffff) << 16) |
+               (d->u.tss386.limit & 0xffff);
+        return(val);
+
+      default:
+        BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+        return(0);
+      }
+    }
+}
+
+  Bit32u
+BX_CPU_C::dbg_get_descriptor_h(bx_descriptor_t *d)
+{
+  Bit32u val;
+
+  if (d->valid == 0) {
+    return(0);
+    }
+
+  if (d->segment) {
+    val = (d->u.segment.base & 0xff000000) |
+          ((d->u.segment.base >> 16) & 0x000000ff) |
+          (d->u.segment.executable << 11) |
+          (d->u.segment.c_ed << 10) |
+          (d->u.segment.r_w << 9) |
+          (d->u.segment.a << 8) |
+          (d->segment << 12) |
+          (d->dpl << 13) |
+          (d->p << 15) |
+          (d->u.segment.limit & 0xf0000) |
+          (d->u.segment.avl << 20) |
+          (d->u.segment.d_b << 22) |
+          (d->u.segment.g << 23);
+    return(val);
+    }
+  else {
+    switch (d->type) {
+      case 0: // Reserved (not yet defined)
+        BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+        return(0);
+
+      case 1: // available 16bit TSS
+        val = ((d->u.tss286.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15);
+        return(val);
+
+      case 2: // LDT
+        val = ((d->u.ldt.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15) |
+              (d->u.ldt.base & 0xff000000);
+        return(val);
+
+      case 9: // available 32bit TSS
+        val = ((d->u.tss386.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15) |
+              (d->u.tss386.limit & 0xf0000) |
+              (d->u.tss386.avl << 20) |
+              (d->u.tss386.g << 23) |
+              (d->u.tss386.base & 0xff000000);
+        return(val);
+
+      default:
+        BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+        return(0);
+      }
+    }
+}
+
+  Boolean
+BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
+{
+  if (sreg_no > 5)
+    return(0);
+  sreg->sel   = BX_CPU_THIS_PTR sregs[sreg_no].selector.value;
+  sreg->des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+  sreg->des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+  sreg->valid = BX_CPU_THIS_PTR sregs[sreg_no].cache.valid;
+  return(1);
+}
+
+  Boolean
+BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
+{
+  cpu->eax = EAX;
+  cpu->ebx = EBX;
+  cpu->ecx = ECX;
+  cpu->edx = EDX;
+
+  cpu->ebp = EBP;
+  cpu->esi = ESI;
+  cpu->edi = EDI;
+  cpu->esp = ESP;
+
+  cpu->eflags = dbg_get_eflags();
+  cpu->eip    = BX_CPU_THIS_PTR eip;
+
+  cpu->cs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+  cpu->cs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+  cpu->cs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+  cpu->cs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid;
+
+  cpu->ss.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+  cpu->ss.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+  cpu->ss.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+  cpu->ss.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid;
+
+  cpu->ds.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+  cpu->ds.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+  cpu->ds.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+  cpu->ds.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid;
+
+  cpu->es.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+  cpu->es.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+  cpu->es.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+  cpu->es.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid;
+
+  cpu->fs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+  cpu->fs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+  cpu->fs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+  cpu->fs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid;
+
+  cpu->gs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+  cpu->gs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+  cpu->gs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+  cpu->gs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid;
+
+
+  cpu->ldtr.sel   = BX_CPU_THIS_PTR ldtr.selector.value;
+  cpu->ldtr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
+  cpu->ldtr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
+  cpu->ldtr.valid = BX_CPU_THIS_PTR ldtr.cache.valid;
+
+  cpu->tr.sel   = BX_CPU_THIS_PTR tr.selector.value;
+  cpu->tr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
+  cpu->tr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
+  cpu->tr.valid = BX_CPU_THIS_PTR tr.cache.valid;
+
+  cpu->gdtr.base  = BX_CPU_THIS_PTR gdtr.base;
+  cpu->gdtr.limit = BX_CPU_THIS_PTR gdtr.limit;
+
+  cpu->idtr.base  = BX_CPU_THIS_PTR idtr.base;
+  cpu->idtr.limit = BX_CPU_THIS_PTR idtr.limit;
+
+  cpu->dr0 = BX_CPU_THIS_PTR dr0;
+  cpu->dr1 = BX_CPU_THIS_PTR dr1;
+  cpu->dr2 = BX_CPU_THIS_PTR dr2;
+  cpu->dr3 = BX_CPU_THIS_PTR dr3;
+  cpu->dr6 = BX_CPU_THIS_PTR dr6;
+  cpu->dr7 = BX_CPU_THIS_PTR dr7;
+
+  cpu->tr3 = 0;
+  cpu->tr4 = 0;
+  cpu->tr5 = 0;
+  cpu->tr6 = 0;
+  cpu->tr7 = 0;
+
+  // cr0:32=pg,cd,nw,am,wp,ne,ts,em,mp,pe
+  cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
+  cpu->cr1 = 0;
+  cpu->cr2 = BX_CPU_THIS_PTR cr2;
+  cpu->cr3 = BX_CPU_THIS_PTR cr3;
+  cpu->cr4 = 0;
+
+  cpu->inhibit_mask = BX_CPU_THIS_PTR inhibit_mask;
+
+  return(1);
+}
+
+  Boolean
+BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
+{
+  // returns 1=OK, 0=Error
+  Bit32u val;
+  Bit32u type;
+
+  // =================================================
+  // Do checks first, before setting any CPU registers
+  // =================================================
+
+  // CS, SS, DS, ES, FS, GS descriptor checks
+  if (!cpu->cs.valid) {
+    BX_ERROR(( "Error: CS not valid\n" ));
+    return(0); // error
+    }
+  if ( (cpu->cs.des_h & 0x1000) == 0 ) {
+    BX_ERROR(( "Error: CS not application type\n" ));
+    return(0); // error
+    }
+  if ( (cpu->cs.des_h & 0x0800) == 0 ) {
+    BX_ERROR(( "Error: CS not executable\n" ));
+    return(0); // error
+    }
+
+  if (!cpu->ss.valid) {
+    BX_ERROR(( "Error: SS not valid\n" ));
+    return(0); // error
+    }
+  if ( (cpu->ss.des_h & 0x1000) == 0 ) {
+    BX_ERROR(( "Error: SS not application type\n" ));
+    return(0); // error
+    }
+
+  if (cpu->ds.valid) {
+    if ( (cpu->ds.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: DS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->es.valid) {
+    if ( (cpu->es.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: ES not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->fs.valid) {
+    if ( (cpu->fs.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: FS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->gs.valid) {
+    if ( (cpu->gs.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: GS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->ldtr.valid) {
+    if ( cpu->ldtr.des_h & 0x1000 ) {
+      BX_ERROR(( "Error: LDTR not system type\n" ));
+      return(0); // error
+      }
+    if ( ((cpu->ldtr.des_h >> 8) & 0x0f) != 2 ) {
+      BX_ERROR(( "Error: LDTR descriptor type not LDT\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->tr.valid) {
+    if ( cpu->tr.des_h & 0x1000 ) {
+      BX_ERROR(( "Error: TR not system type\n"));
+      return(0); // error
+      }
+    type = (cpu->tr.des_h >> 8) & 0x0f;
+
+    if ( (type != 1) && (type != 9) ) {
+      BX_ERROR(( "Error: TR descriptor type not TSS\n" ));
+      return(0); // error
+      }
+    }
+
+  // =============
+  // end of checks
+  // =============
+
+  EAX = cpu->eax;
+  EBX = cpu->ebx;
+  ECX = cpu->ecx;
+  EDX = cpu->edx;
+  EBP = cpu->ebp;
+  ESI = cpu->esi;
+  EDI = cpu->edi;
+  ESP = cpu->esp;
+
+  // eflags
+  val = cpu->eflags;
+  BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR eflags.tf  = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.df  = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR eflags.iopl = val & 0x03; val >>= 2;
+  BX_CPU_THIS_PTR eflags.nt   = val & 0x01; val >>= 2;
+  BX_CPU_THIS_PTR eflags.rf   = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.vm   = val & 0x01; val >>= 1;
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR eflags.ac   = val & 0x01; val >>= 1;
+  //BX_CPU_THIS_PTR eflags.vif  = val & 0x01;
+  val >>= 1;
+  //BX_CPU_THIS_PTR eflags.vip  = val & 0x01;
+  val >>= 1;
+  BX_CPU_THIS_PTR eflags.id   = val & 0x01;
+#endif
+
+  BX_CPU_THIS_PTR eip = cpu->eip;
+
+
+
+  // CS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti    = (cpu->cs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl   = cpu->cs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid            = cpu->cs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p                = (cpu->cs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl              = (cpu->cs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment          = (cpu->cs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type             = (cpu->cs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (cpu->cs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed   = (cpu->cs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w    = (cpu->cs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a      = (cpu->cs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base   = (cpu->cs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base  |= (cpu->cs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base  |= (cpu->cs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit  = (cpu->cs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit |= (cpu->cs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g      = (cpu->cs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b    = (cpu->cs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl    = (cpu->cs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
+
+
+  // SS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = cpu->ss.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti    = (cpu->ss.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl   = cpu->ss.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid            = cpu->ss.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p                = (cpu->ss.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl              = (cpu->ss.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment          = (cpu->ss.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type             = (cpu->ss.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (cpu->ss.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed   = (cpu->ss.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w    = (cpu->ss.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a      = (cpu->ss.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base   = (cpu->ss.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base  |= (cpu->ss.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base  |= (cpu->ss.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit  = (cpu->ss.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit |= (cpu->ss.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g      = (cpu->ss.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b    = (cpu->ss.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl    = (cpu->ss.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
+
+
+  // DS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti    = (cpu->ds.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl   = cpu->ds.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid            = cpu->ds.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p                = (cpu->ds.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl              = (cpu->ds.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment          = (cpu->ds.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type             = (cpu->ds.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (cpu->ds.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed   = (cpu->ds.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w    = (cpu->ds.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a      = (cpu->ds.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base   = (cpu->ds.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base  |= (cpu->ds.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base  |= (cpu->ds.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit  = (cpu->ds.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit |= (cpu->ds.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g      = (cpu->ds.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b    = (cpu->ds.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl    = (cpu->ds.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
+
+
+
+  // ES:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti    = (cpu->es.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl   = cpu->es.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid            = cpu->es.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p                = (cpu->es.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl              = (cpu->es.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment          = (cpu->es.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type             = (cpu->es.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (cpu->es.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed   = (cpu->es.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w    = (cpu->es.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a      = (cpu->es.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base   = (cpu->es.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base  |= (cpu->es.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base  |= (cpu->es.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit  = (cpu->es.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit |= (cpu->es.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g      = (cpu->es.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b    = (cpu->es.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl    = (cpu->es.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
+
+
+  // FS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti    = (cpu->fs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl   = cpu->fs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid            = cpu->fs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p                = (cpu->fs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl              = (cpu->fs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment          = (cpu->fs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type             = (cpu->fs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = (cpu->fs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed   = (cpu->fs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w    = (cpu->fs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a      = (cpu->fs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base   = (cpu->fs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base  |= (cpu->fs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base  |= (cpu->fs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit  = (cpu->fs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit |= (cpu->fs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g      = (cpu->fs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b    = (cpu->fs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl    = (cpu->fs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
+
+
+  // GS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti    = (cpu->gs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl   = cpu->gs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid            = cpu->gs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p                = (cpu->gs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl              = (cpu->gs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment          = (cpu->gs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type             = (cpu->gs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = (cpu->gs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed   = (cpu->gs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w    = (cpu->gs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a      = (cpu->gs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base   = (cpu->gs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base  |= (cpu->gs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base  |= (cpu->gs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit  = (cpu->gs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit |= (cpu->gs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g      = (cpu->gs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b    = (cpu->gs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl    = (cpu->gs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
+
+  // LDTR:
+  BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
+  BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
+  BX_CPU_THIS_PTR ldtr.selector.ti    = (cpu->ldtr.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR ldtr.selector.rpl   = cpu->ldtr.sel & 0x03;
+
+  BX_CPU_THIS_PTR ldtr.cache.valid            = cpu->ldtr.valid;
+  BX_CPU_THIS_PTR ldtr.cache.p                = (cpu->ldtr.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR ldtr.cache.dpl              = (cpu->ldtr.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR ldtr.cache.segment          = (cpu->ldtr.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR ldtr.cache.type             = (cpu->ldtr.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base       = (cpu->ldtr.des_l >> 16);
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base      |= (cpu->ldtr.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base      |= (cpu->ldtr.des_h & 0xff000000);
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit      = (cpu->ldtr.des_l & 0xffff);
+
+  // TR
+  type = (cpu->tr.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
+  BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
+  BX_CPU_THIS_PTR tr.selector.ti    = (cpu->tr.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR tr.selector.rpl   = cpu->tr.sel & 0x03;
+
+  BX_CPU_THIS_PTR tr.cache.valid            = cpu->tr.valid;
+  BX_CPU_THIS_PTR tr.cache.p                = (cpu->tr.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR tr.cache.dpl              = (cpu->tr.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR tr.cache.segment          = (cpu->tr.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR tr.cache.type             = type;
+  if (type == 1) { // 286 TSS
+    BX_CPU_THIS_PTR tr.cache.u.tss286.base   = (cpu->tr.des_l >> 16);
+    BX_CPU_THIS_PTR tr.cache.u.tss286.base  |= (cpu->tr.des_h & 0xff) << 16;
+    BX_CPU_THIS_PTR tr.cache.u.tss286.limit  = (cpu->tr.des_l & 0xffff);
+    }
+  else { // type == 9, 386 TSS
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base   = (cpu->tr.des_l >> 16);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base  |= (cpu->tr.des_h & 0xff) << 16;
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base  |= (cpu->tr.des_h & 0xff000000);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.limit  = (cpu->tr.des_l & 0xffff);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.g      = (cpu->tr.des_h >> 23) & 0x01;
+    BX_CPU_THIS_PTR tr.cache.u.tss386.avl    = (cpu->tr.des_h >> 20) & 0x01;
+    }
+
+
+  // gdtr
+  BX_CPU_THIS_PTR gdtr.base  = cpu->gdtr.base;
+  BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
+
+  // idtr
+  BX_CPU_THIS_PTR idtr.base  = cpu->idtr.base;
+  BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
+
+
+  BX_CPU_THIS_PTR dr0 = cpu->dr0;
+  BX_CPU_THIS_PTR dr1 = cpu->dr1;
+  BX_CPU_THIS_PTR dr2 = cpu->dr2;
+  BX_CPU_THIS_PTR dr3 = cpu->dr3;
+  BX_CPU_THIS_PTR dr6 = cpu->dr6;
+  BX_CPU_THIS_PTR dr7 = cpu->dr7;
+
+  // BX_CPU_THIS_PTR tr3 = cpu->tr3;
+  // BX_CPU_THIS_PTR tr4 = cpu->tr4;
+  // BX_CPU_THIS_PTR tr5 = cpu->tr5;
+  // BX_CPU_THIS_PTR tr6 = cpu->tr6;
+  // BX_CPU_THIS_PTR tr7 = cpu->tr7;
+
+
+  // cr0, cr1, cr2, cr3, cr4
+  SetCR0(cpu->cr0);
+  BX_CPU_THIS_PTR cr1 = cpu->cr1;
+  BX_CPU_THIS_PTR cr2 = cpu->cr2;
+  BX_CPU_THIS_PTR cr3 = cpu->cr3;
+#if BX_CPU_LEVEL >= 5
+  BX_CPU_THIS_PTR cr4 = cpu->cr4;
+#endif
+
+  BX_CPU_THIS_PTR inhibit_mask = cpu->inhibit_mask;
+
+  //
+  // flush cached items, prefetch, paging, etc
+  //
+  BX_CPU_THIS_PTR CR3_change(cpu->cr3);
+  BX_CPU_THIS_PTR invalidate_prefetch_q();
+  BX_CPU_THIS_PTR async_event = 1;
+
+  return(1);
+}
+
+#if BX_SIM_ID == 0
+#  define BX_DBG_NULL_CALLBACK bx_dbg_null_callback0
+#else
+#  define BX_DBG_NULL_CALLBACK bx_dbg_null_callback1
+#endif
+  void
+BX_DBG_NULL_CALLBACK(unsigned val)
+{
+  // bochs uses the pc_system variables, so this function is
+  // a stub for notification by the debugger, that a change
+  // occurred.
+  UNUSED(val);
+}
+
+  void
+#if BX_SIM_ID == 0
+bx_dbg_init_cpu_mem_env0(bx_dbg_callback_t *callback, int argc, char *argv[])
+#else
+bx_dbg_init_cpu_mem_env1(bx_dbg_callback_t *callback, int argc, char *argv[])
+#endif
+{
+  UNUSED(argc);
+  UNUSED(argv);
+
+#if 0
+#warning hardcoding BX_CPU_THIS_PTR mem[0] and cpu[0]
+  callback->setphymem           = BX_MEM(0)->dbg_set_mem;
+  callback->getphymem           = BX_MEM(0)->dbg_fetch_mem;
+  callback->xlate_linear2phy    = BX_CPU(0)->dbg_xlate_linear2phy;
+  callback->set_reg             = BX_CPU(0)->dbg_set_reg;
+  callback->get_reg             = BX_CPU(0)->dbg_get_reg;
+  callback->get_sreg            = BX_CPU(0)->dbg_get_sreg;
+  callback->get_cpu             = BX_CPU(0)->dbg_get_cpu;
+  callback->set_cpu             = BX_CPU(0)->dbg_set_cpu;
+  callback->dirty_page_tbl_size = sizeof(BX_MEM(0)->dbg_dirty_pages);
+  callback->dirty_page_tbl      = BX_MEM(0)->dbg_dirty_pages;
+  callback->atexit              = BX_CPU(0)->atexit;
+  callback->query_pending       = BX_CPU(0)->dbg_query_pending;
+  callback->execute             = BX_CPU(0)->cpu_loop;
+  callback->take_irq            = BX_CPU(0)->dbg_take_irq;
+  callback->take_dma            = BX_CPU(0)->dbg_take_dma;
+  callback->reset_cpu           = BX_CPU(0)->reset;
+  callback->init_mem            = BX_MEM(0)->init_memory;
+  callback->load_ROM            = BX_MEM(0)->load_ROM;
+  callback->set_A20             = NULL;
+  callback->set_NMI             = BX_DBG_NULL_CALLBACK;
+  callback->set_RESET           = BX_DBG_NULL_CALLBACK;
+  callback->set_INTR            = BX_CPU(0)->set_INTR;
+  callback->force_interrupt     = BX_CPU(0)->dbg_force_interrupt;
+
+#if BX_INSTRUMENTATION
+  callback->instr_start         = bx_instr_start;
+  callback->instr_stop          = bx_instr_stop;
+  callback->instr_reset         = bx_instr_reset;
+  callback->instr_print         = bx_instr_print;
+#endif
+#if BX_USE_LOADER
+  callback->loader              = bx_dbg_loader;
+#endif
+  callback->crc32               = BX_MEM(0)->dbg_crc32;
+#endif
+}
+
+
+
+  void
+BX_CPU_C::atexit(void)
+{
+  if (protected_mode()) BX_INFO(("protected mode\n" ));
+  else if (v8086_mode()) BX_INFO(("v8086 mode\n" ));
+  else BX_INFO(("real mode\n"));
+  BX_INFO(("CS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16 ));
+  if (protected_mode()) BX_INFO(("protected mode\n"));
+  else if (v8086_mode()) BX_INFO(("v8086 mode\n"));
+  else BX_INFO(("real mode\n"));
+  BX_INFO(("CS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16));
+  BX_INFO(("SS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_SS].cache.u.segment.d_b ? 32 : 16));
+
+  debug(BX_CPU_THIS_PTR prev_eip);
+}
+#endif  // #if BX_DEBUGGER
diff --git a/sid/component/bochs/cpu/debugstuff.cc b/sid/component/bochs/cpu/debugstuff.cc
new file mode 100644 (file)
index 0000000..ae4da69
--- /dev/null
@@ -0,0 +1,1019 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::debug(Bit32u offset)
+{
+  BX_INFO(("| EAX=%08x  EBX=%08x  ECX=%08x  EDX=%08x\n",
+          (unsigned) EAX, (unsigned) EBX, (unsigned) ECX, (unsigned) EDX));
+  BX_INFO(("| ESP=%08x  EBP=%08x  ESI=%08x  EDI=%08x\n",
+          (unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
+  BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s\n",
+    BX_CPU_THIS_PTR eflags.iopl,
+    BX_CPU_THIS_PTR get_OF()       ? "OV" : "NV",
+    BX_CPU_THIS_PTR eflags.df  ? "DW" : "UP",
+    BX_CPU_THIS_PTR eflags.if_ ? "EI" : "DI",
+    BX_CPU_THIS_PTR get_SF()       ? "NG" : "PL",
+    BX_CPU_THIS_PTR get_ZF()       ? "ZR" : "NZ",
+    BX_CPU_THIS_PTR get_AF()       ? "AC" : "NA",
+    BX_CPU_THIS_PTR get_PF()       ? "PE" : "PO",
+    BX_CPU_THIS_PTR get_CF()       ? "CY" : "NC"));
+  BX_INFO(("| SEG selector     base    limit G D\n"));
+  BX_INFO(("| SEG sltr(index|ti|rpl)     base    limit G D\n"));
+  BX_INFO(("|  DS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b));
+  BX_INFO(("|  ES:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b));
+  BX_INFO(("|  FS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b));
+  BX_INFO(("|  GS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b));
+  BX_INFO(("|  SS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b));
+  BX_INFO(("|  CS:%04x( %04x| %01u|  %1u) %08x %08x %1u %1u\n",
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g,
+    (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b));
+  BX_INFO(("| EIP=%08x (%08x)\n", (unsigned) BX_CPU_THIS_PTR eip,
+    (unsigned) BX_CPU_THIS_PTR prev_eip));
+
+#if 0
+  /* (mch) Hack to display the area round EIP and prev_EIP */
+  char buf[100];
+  sprintf(buf, "%04x:%08x  ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR eip);
+  for (int i = 0; i < 8; i++) {
+    Bit8u data;
+    BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR eip + i, &data);
+    sprintf(buf+strlen(buf), "%02x ", data);
+    }
+  sprintf(buf+strlen(buf), "\n");
+  BX_INFO((buf));
+
+  sprintf(buf, "%04x:%08x  ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR prev_eip);
+  for (int i = 0; i < 8; i++) {
+    Bit8u data;
+    BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR prev_eip + i, &data);
+    sprintf(buf+strlen(buf), "%02x ", data);
+    }
+  sprintf(buf+strlen(buf), "\n");
+  BX_INFO((buf));
+#endif
+
+
+#if BX_DISASM
+  Boolean valid;
+  Bit32u  phy_addr;
+  Bit8u   instr_buf[32];
+  char    char_buf[256];
+  unsigned isize;
+
+  dbg_xlate_linear2phy(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + offset,
+                       &phy_addr, &valid);
+  if (valid) {
+    BX_CPU_THIS_PTR mem->dbg_fetch_mem(phy_addr, 16, instr_buf);
+    isize = bx_disassemble.disasm(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
+                        instr_buf, char_buf);
+    for (unsigned j=0; j<isize; j++)
+      BX_INFO((">> %02x\n", (unsigned) instr_buf[j]));
+    BX_INFO((">> : %s\n", char_buf));
+    }
+  else {
+    BX_INFO(("(instruction unavailable) page not present\n"));
+    }
+#else
+  UNUSED(offset);
+#endif  // #if BX_DISASM
+}
+
+
+#if BX_DEBUGGER
+  Bit32u
+BX_CPU_C::dbg_get_reg(unsigned reg)
+{
+  Bit32u return_val32;
+
+  switch (reg) {
+    case BX_DBG_REG_EAX: return(EAX);
+    case BX_DBG_REG_ECX: return(ECX);
+    case BX_DBG_REG_EDX: return(EDX);
+    case BX_DBG_REG_EBX: return(EBX);
+    case BX_DBG_REG_ESP: return(ESP);
+    case BX_DBG_REG_EBP: return(EBP);
+    case BX_DBG_REG_ESI: return(ESI);
+    case BX_DBG_REG_EDI: return(EDI);
+    case BX_DBG_REG_EIP: return(EIP);
+    case BX_DBG_REG_EFLAGS:
+      return_val32 = dbg_get_eflags();
+      return(return_val32);
+    case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+    case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+    case BX_DBG_REG_DS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+    case BX_DBG_REG_ES: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+    case BX_DBG_REG_FS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+    case BX_DBG_REG_GS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+    default:
+      BX_PANIC(("get_reg: request for unknown register\n"));
+      return(0);
+    }
+}
+
+  Boolean
+BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
+{
+  // returns 1=OK, 0=can't change
+  bx_segment_reg_t *seg;
+  Bit32u current_sys_bits;
+
+  switch (reg) {
+    case BX_DBG_REG_EAX: EAX = val; return(1);
+    case BX_DBG_REG_ECX: ECX = val; return(1);
+    case BX_DBG_REG_EDX: EDX = val; return(1);
+    case BX_DBG_REG_EBX: EBX = val; return(1);
+    case BX_DBG_REG_ESP: ESP = val; return(1);
+    case BX_DBG_REG_EBP: EBP = val; return(1);
+    case BX_DBG_REG_ESI: ESI = val; return(1);
+    case BX_DBG_REG_EDI: EDI = val; return(1);
+    case BX_DBG_REG_EIP: EIP = val; return(1);
+    case BX_DBG_REG_EFLAGS:
+      BX_INFO(("dbg_set_reg: can not handle eflags yet.\n"));
+      if ( val & 0xffff0000 ) {
+        BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags.\n"));
+        return(0);
+        }
+      // make sure none of the system bits are being changed
+      current_sys_bits = (BX_CPU_THIS_PTR eflags.nt << 14) |
+                         (BX_CPU_THIS_PTR eflags.iopl << 12) |
+                         (BX_CPU_THIS_PTR eflags.tf << 8);
+      if ( current_sys_bits != (val & 0x0000f100) ) {
+        BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF.\n"));
+        return(0);
+        }
+      BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+      BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
+      BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+      BX_CPU_THIS_PTR eflags.df  = val & 0x01; val >>= 1;
+      BX_CPU_THIS_PTR set_OF(val & 0x01);
+      if (BX_CPU_THIS_PTR eflags.if_)
+        BX_CPU_THIS_PTR async_event = 1;
+      return(1);
+    case BX_DBG_REG_CS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+      break;
+    case BX_DBG_REG_SS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+      break;
+    case BX_DBG_REG_DS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
+      break;
+    case BX_DBG_REG_ES:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES];
+      break;
+    case BX_DBG_REG_FS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS];
+      break;
+    case BX_DBG_REG_GS:
+      seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS];
+      break;
+    default:
+      BX_PANIC(("dbg_set_reg: unrecognized register ID (%u)\n", reg));
+      return(0);
+    }
+
+  if (BX_CPU_THIS_PTR real_mode()) {
+    seg->selector.value = val;
+    seg->cache.valid = 1;
+    seg->cache.p = 1;
+    seg->cache.dpl = 0;
+    seg->cache.segment = 1; // regular segment
+    if (reg == BX_DBG_REG_CS) {
+      seg->cache.u.segment.executable = 1; // code segment
+      }
+    else {
+      seg->cache.u.segment.executable = 0; // data segment
+      }
+    seg->cache.u.segment.c_ed = 0;       // expand up/non-conforming
+    seg->cache.u.segment.r_w = 1;        // writeable
+    seg->cache.u.segment.a = 1;          // accessed
+    seg->cache.u.segment.base = val << 4;
+    seg->cache.u.segment.limit        = 0xffff;
+    seg->cache.u.segment.limit_scaled = 0xffff;
+    seg->cache.u.segment.g     = 0;      // byte granular
+    seg->cache.u.segment.d_b   = 0;      // default 16bit size
+    seg->cache.u.segment.avl   = 0;
+    return(1); // ok
+    }
+
+  return(0); // can't change when not in real mode
+}
+
+  unsigned
+BX_CPU_C::dbg_query_pending(void)
+{
+  unsigned ret = 0;
+
+  if ( BX_HRQ ) {  // DMA Hold Request
+    ret |= BX_DBG_PENDING_DMA;
+    }
+
+  if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+    ret |= BX_DBG_PENDING_IRQ;
+    }
+
+  return(ret);
+}
+
+
+
+  Bit32u
+BX_CPU_C::dbg_get_eflags(void)
+{
+  Bit32u val32;
+
+  val32 =
+    (BX_CPU_THIS_PTR get_CF()) |
+    (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+    ((BX_CPU_THIS_PTR get_PF()) << 2) |
+    (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+    ((BX_CPU_THIS_PTR get_AF()>0) << 4) |
+    (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+    ((BX_CPU_THIS_PTR get_ZF()>0) << 6) |
+    ((BX_CPU_THIS_PTR get_SF()>0) << 7) |
+    (BX_CPU_THIS_PTR eflags.tf << 8) |
+    (BX_CPU_THIS_PTR eflags.if_ << 9) |
+    (BX_CPU_THIS_PTR eflags.df << 10) |
+    ((BX_CPU_THIS_PTR get_OF()>0) << 11) |
+    (BX_CPU_THIS_PTR eflags.iopl << 12) |
+    (BX_CPU_THIS_PTR eflags.nt << 14) |
+    (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+    (BX_CPU_THIS_PTR eflags.rf << 16) |
+    (BX_CPU_THIS_PTR eflags.vm << 17);
+#if BX_CPU_LEVEL >= 4
+  val32 |= (BX_CPU_THIS_PTR eflags.ac << 18);
+  //val32 |= (BX_CPU_THIS_PTR eflags.vif << 19);
+  //val32 |= (BX_CPU_THIS_PTR eflags.vip << 20);
+  val32 |= (BX_CPU_THIS_PTR eflags.id << 21);
+#endif
+  return(val32);
+}
+
+
+  Bit32u
+BX_CPU_C::dbg_get_descriptor_l(bx_descriptor_t *d)
+{
+  Bit32u val;
+
+  if (d->valid == 0) {
+    return(0);
+    }
+
+  if (d->segment) {
+    val = ((d->u.segment.base & 0xffff) << 16) |
+          (d->u.segment.limit & 0xffff);
+    return(val);
+    }
+  else {
+    switch (d->type) {
+      case 0: // Reserved (not yet defined)
+        BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+        return(0);
+
+      case 1: // available 16bit TSS
+        val = ((d->u.tss286.base & 0xffff) << 16) |
+               (d->u.tss286.limit & 0xffff);
+        return(val);
+
+      case 2: // LDT
+        val = ((d->u.ldt.base & 0xffff) << 16) |
+              d->u.ldt.limit;
+        return(val);
+
+      case 9: // available 32bit TSS
+        val = ((d->u.tss386.base & 0xffff) << 16) |
+               (d->u.tss386.limit & 0xffff);
+        return(val);
+
+      default:
+        BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+        return(0);
+      }
+    }
+}
+
+  Bit32u
+BX_CPU_C::dbg_get_descriptor_h(bx_descriptor_t *d)
+{
+  Bit32u val;
+
+  if (d->valid == 0) {
+    return(0);
+    }
+
+  if (d->segment) {
+    val = (d->u.segment.base & 0xff000000) |
+          ((d->u.segment.base >> 16) & 0x000000ff) |
+          (d->u.segment.executable << 11) |
+          (d->u.segment.c_ed << 10) |
+          (d->u.segment.r_w << 9) |
+          (d->u.segment.a << 8) |
+          (d->segment << 12) |
+          (d->dpl << 13) |
+          (d->p << 15) |
+          (d->u.segment.limit & 0xf0000) |
+          (d->u.segment.avl << 20) |
+          (d->u.segment.d_b << 22) |
+          (d->u.segment.g << 23);
+    return(val);
+    }
+  else {
+    switch (d->type) {
+      case 0: // Reserved (not yet defined)
+        BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+        return(0);
+
+      case 1: // available 16bit TSS
+        val = ((d->u.tss286.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15);
+        return(val);
+
+      case 2: // LDT
+        val = ((d->u.ldt.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15) |
+              (d->u.ldt.base & 0xff000000);
+        return(val);
+
+      case 9: // available 32bit TSS
+        val = ((d->u.tss386.base >> 16) & 0xff) |
+              (d->type << 8) |
+              (d->dpl << 13) |
+              (d->p << 15) |
+              (d->u.tss386.limit & 0xf0000) |
+              (d->u.tss386.avl << 20) |
+              (d->u.tss386.g << 23) |
+              (d->u.tss386.base & 0xff000000);
+        return(val);
+
+      default:
+        BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+        return(0);
+      }
+    }
+}
+
+  Boolean
+BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
+{
+  if (sreg_no > 5)
+    return(0);
+  sreg->sel   = BX_CPU_THIS_PTR sregs[sreg_no].selector.value;
+  sreg->des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+  sreg->des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+  sreg->valid = BX_CPU_THIS_PTR sregs[sreg_no].cache.valid;
+  return(1);
+}
+
+  Boolean
+BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
+{
+  cpu->eax = EAX;
+  cpu->ebx = EBX;
+  cpu->ecx = ECX;
+  cpu->edx = EDX;
+
+  cpu->ebp = EBP;
+  cpu->esi = ESI;
+  cpu->edi = EDI;
+  cpu->esp = ESP;
+
+  cpu->eflags = dbg_get_eflags();
+  cpu->eip    = BX_CPU_THIS_PTR eip;
+
+  cpu->cs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+  cpu->cs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+  cpu->cs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+  cpu->cs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid;
+
+  cpu->ss.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+  cpu->ss.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+  cpu->ss.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+  cpu->ss.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid;
+
+  cpu->ds.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+  cpu->ds.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+  cpu->ds.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+  cpu->ds.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid;
+
+  cpu->es.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+  cpu->es.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+  cpu->es.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+  cpu->es.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid;
+
+  cpu->fs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+  cpu->fs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+  cpu->fs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+  cpu->fs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid;
+
+  cpu->gs.sel   = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+  cpu->gs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+  cpu->gs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+  cpu->gs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid;
+
+
+  cpu->ldtr.sel   = BX_CPU_THIS_PTR ldtr.selector.value;
+  cpu->ldtr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
+  cpu->ldtr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
+  cpu->ldtr.valid = BX_CPU_THIS_PTR ldtr.cache.valid;
+
+  cpu->tr.sel   = BX_CPU_THIS_PTR tr.selector.value;
+  cpu->tr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
+  cpu->tr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
+  cpu->tr.valid = BX_CPU_THIS_PTR tr.cache.valid;
+
+  cpu->gdtr.base  = BX_CPU_THIS_PTR gdtr.base;
+  cpu->gdtr.limit = BX_CPU_THIS_PTR gdtr.limit;
+
+  cpu->idtr.base  = BX_CPU_THIS_PTR idtr.base;
+  cpu->idtr.limit = BX_CPU_THIS_PTR idtr.limit;
+
+  cpu->dr0 = BX_CPU_THIS_PTR dr0;
+  cpu->dr1 = BX_CPU_THIS_PTR dr1;
+  cpu->dr2 = BX_CPU_THIS_PTR dr2;
+  cpu->dr3 = BX_CPU_THIS_PTR dr3;
+  cpu->dr6 = BX_CPU_THIS_PTR dr6;
+  cpu->dr7 = BX_CPU_THIS_PTR dr7;
+
+  cpu->tr3 = 0;
+  cpu->tr4 = 0;
+  cpu->tr5 = 0;
+  cpu->tr6 = 0;
+  cpu->tr7 = 0;
+
+  // cr0:32=pg,cd,nw,am,wp,ne,ts,em,mp,pe
+  cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
+  cpu->cr1 = 0;
+  cpu->cr2 = BX_CPU_THIS_PTR cr2;
+  cpu->cr3 = BX_CPU_THIS_PTR cr3;
+  cpu->cr4 = 0;
+
+  cpu->inhibit_mask = BX_CPU_THIS_PTR inhibit_mask;
+
+  return(1);
+}
+
+  Boolean
+BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
+{
+  // returns 1=OK, 0=Error
+  Bit32u val;
+  Bit32u type;
+
+  // =================================================
+  // Do checks first, before setting any CPU registers
+  // =================================================
+
+  // CS, SS, DS, ES, FS, GS descriptor checks
+  if (!cpu->cs.valid) {
+    BX_ERROR(( "Error: CS not valid\n" ));
+    return(0); // error
+    }
+  if ( (cpu->cs.des_h & 0x1000) == 0 ) {
+    BX_ERROR(( "Error: CS not application type\n" ));
+    return(0); // error
+    }
+  if ( (cpu->cs.des_h & 0x0800) == 0 ) {
+    BX_ERROR(( "Error: CS not executable\n" ));
+    return(0); // error
+    }
+
+  if (!cpu->ss.valid) {
+    BX_ERROR(( "Error: SS not valid\n" ));
+    return(0); // error
+    }
+  if ( (cpu->ss.des_h & 0x1000) == 0 ) {
+    BX_ERROR(( "Error: SS not application type\n" ));
+    return(0); // error
+    }
+
+  if (cpu->ds.valid) {
+    if ( (cpu->ds.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: DS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->es.valid) {
+    if ( (cpu->es.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: ES not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->fs.valid) {
+    if ( (cpu->fs.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: FS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->gs.valid) {
+    if ( (cpu->gs.des_h & 0x1000) == 0 ) {
+      BX_ERROR(( "Error: GS not application type\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->ldtr.valid) {
+    if ( cpu->ldtr.des_h & 0x1000 ) {
+      BX_ERROR(( "Error: LDTR not system type\n" ));
+      return(0); // error
+      }
+    if ( ((cpu->ldtr.des_h >> 8) & 0x0f) != 2 ) {
+      BX_ERROR(( "Error: LDTR descriptor type not LDT\n" ));
+      return(0); // error
+      }
+    }
+
+  if (cpu->tr.valid) {
+    if ( cpu->tr.des_h & 0x1000 ) {
+      BX_ERROR(( "Error: TR not system type\n"));
+      return(0); // error
+      }
+    type = (cpu->tr.des_h >> 8) & 0x0f;
+
+    if ( (type != 1) && (type != 9) ) {
+      BX_ERROR(( "Error: TR descriptor type not TSS\n" ));
+      return(0); // error
+      }
+    }
+
+  // =============
+  // end of checks
+  // =============
+
+  EAX = cpu->eax;
+  EBX = cpu->ebx;
+  ECX = cpu->ecx;
+  EDX = cpu->edx;
+  EBP = cpu->ebp;
+  ESI = cpu->esi;
+  EDI = cpu->edi;
+  ESP = cpu->esp;
+
+  // eflags
+  val = cpu->eflags;
+  BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+  BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR eflags.tf  = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.df  = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
+  BX_CPU_THIS_PTR eflags.iopl = val & 0x03; val >>= 2;
+  BX_CPU_THIS_PTR eflags.nt   = val & 0x01; val >>= 2;
+  BX_CPU_THIS_PTR eflags.rf   = val & 0x01; val >>= 1;
+  BX_CPU_THIS_PTR eflags.vm   = val & 0x01; val >>= 1;
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR eflags.ac   = val & 0x01; val >>= 1;
+  //BX_CPU_THIS_PTR eflags.vif  = val & 0x01;
+  val >>= 1;
+  //BX_CPU_THIS_PTR eflags.vip  = val & 0x01;
+  val >>= 1;
+  BX_CPU_THIS_PTR eflags.id   = val & 0x01;
+#endif
+
+  BX_CPU_THIS_PTR eip = cpu->eip;
+
+
+
+  // CS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti    = (cpu->cs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl   = cpu->cs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid            = cpu->cs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p                = (cpu->cs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl              = (cpu->cs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment          = (cpu->cs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type             = (cpu->cs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (cpu->cs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed   = (cpu->cs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w    = (cpu->cs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a      = (cpu->cs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base   = (cpu->cs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base  |= (cpu->cs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base  |= (cpu->cs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit  = (cpu->cs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit |= (cpu->cs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g      = (cpu->cs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b    = (cpu->cs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl    = (cpu->cs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
+
+
+  // SS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = cpu->ss.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti    = (cpu->ss.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl   = cpu->ss.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid            = cpu->ss.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p                = (cpu->ss.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl              = (cpu->ss.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment          = (cpu->ss.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type             = (cpu->ss.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (cpu->ss.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed   = (cpu->ss.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w    = (cpu->ss.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a      = (cpu->ss.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base   = (cpu->ss.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base  |= (cpu->ss.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base  |= (cpu->ss.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit  = (cpu->ss.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit |= (cpu->ss.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g      = (cpu->ss.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b    = (cpu->ss.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl    = (cpu->ss.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
+
+
+  // DS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti    = (cpu->ds.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl   = cpu->ds.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid            = cpu->ds.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p                = (cpu->ds.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl              = (cpu->ds.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment          = (cpu->ds.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type             = (cpu->ds.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (cpu->ds.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed   = (cpu->ds.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w    = (cpu->ds.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a      = (cpu->ds.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base   = (cpu->ds.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base  |= (cpu->ds.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base  |= (cpu->ds.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit  = (cpu->ds.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit |= (cpu->ds.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g      = (cpu->ds.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b    = (cpu->ds.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl    = (cpu->ds.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
+
+
+
+  // ES:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti    = (cpu->es.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl   = cpu->es.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid            = cpu->es.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p                = (cpu->es.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl              = (cpu->es.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment          = (cpu->es.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type             = (cpu->es.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (cpu->es.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed   = (cpu->es.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w    = (cpu->es.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a      = (cpu->es.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base   = (cpu->es.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base  |= (cpu->es.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base  |= (cpu->es.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit  = (cpu->es.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit |= (cpu->es.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g      = (cpu->es.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b    = (cpu->es.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl    = (cpu->es.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
+
+
+  // FS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti    = (cpu->fs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl   = cpu->fs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid            = cpu->fs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p                = (cpu->fs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl              = (cpu->fs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment          = (cpu->fs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type             = (cpu->fs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = (cpu->fs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed   = (cpu->fs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w    = (cpu->fs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a      = (cpu->fs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base   = (cpu->fs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base  |= (cpu->fs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base  |= (cpu->fs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit  = (cpu->fs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit |= (cpu->fs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g      = (cpu->fs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b    = (cpu->fs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl    = (cpu->fs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
+
+
+  // GS:
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti    = (cpu->gs.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl   = cpu->gs.sel & 0x03;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid            = cpu->gs.valid;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p                = (cpu->gs.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl              = (cpu->gs.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment          = (cpu->gs.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type             = (cpu->gs.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = (cpu->gs.des_h >> 11) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed   = (cpu->gs.des_h >> 10) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w    = (cpu->gs.des_h >> 9) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a      = (cpu->gs.des_h >> 8) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base   = (cpu->gs.des_l >> 16);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base  |= (cpu->gs.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base  |= (cpu->gs.des_h & 0xff000000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit  = (cpu->gs.des_l & 0xffff);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit |= (cpu->gs.des_h & 0x000f0000);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g      = (cpu->gs.des_h >> 23) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b    = (cpu->gs.des_h >> 22) & 0x01;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl    = (cpu->gs.des_h >> 20) & 0x01;
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g)
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+      (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit << 12) | 0x0fff;
+  else
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
+
+  // LDTR:
+  BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
+  BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
+  BX_CPU_THIS_PTR ldtr.selector.ti    = (cpu->ldtr.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR ldtr.selector.rpl   = cpu->ldtr.sel & 0x03;
+
+  BX_CPU_THIS_PTR ldtr.cache.valid            = cpu->ldtr.valid;
+  BX_CPU_THIS_PTR ldtr.cache.p                = (cpu->ldtr.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR ldtr.cache.dpl              = (cpu->ldtr.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR ldtr.cache.segment          = (cpu->ldtr.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR ldtr.cache.type             = (cpu->ldtr.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base       = (cpu->ldtr.des_l >> 16);
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base      |= (cpu->ldtr.des_h & 0xff) << 16;
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base      |= (cpu->ldtr.des_h & 0xff000000);
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit      = (cpu->ldtr.des_l & 0xffff);
+
+  // TR
+  type = (cpu->tr.des_h >> 8) & 0x0f;
+  BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
+  BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
+  BX_CPU_THIS_PTR tr.selector.ti    = (cpu->tr.sel >> 2) & 0x01;
+  BX_CPU_THIS_PTR tr.selector.rpl   = cpu->tr.sel & 0x03;
+
+  BX_CPU_THIS_PTR tr.cache.valid            = cpu->tr.valid;
+  BX_CPU_THIS_PTR tr.cache.p                = (cpu->tr.des_h >> 15) & 0x01;
+  BX_CPU_THIS_PTR tr.cache.dpl              = (cpu->tr.des_h >> 13) & 0x03;
+  BX_CPU_THIS_PTR tr.cache.segment          = (cpu->tr.des_h >> 12) & 0x01;
+  BX_CPU_THIS_PTR tr.cache.type             = type;
+  if (type == 1) { // 286 TSS
+    BX_CPU_THIS_PTR tr.cache.u.tss286.base   = (cpu->tr.des_l >> 16);
+    BX_CPU_THIS_PTR tr.cache.u.tss286.base  |= (cpu->tr.des_h & 0xff) << 16;
+    BX_CPU_THIS_PTR tr.cache.u.tss286.limit  = (cpu->tr.des_l & 0xffff);
+    }
+  else { // type == 9, 386 TSS
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base   = (cpu->tr.des_l >> 16);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base  |= (cpu->tr.des_h & 0xff) << 16;
+    BX_CPU_THIS_PTR tr.cache.u.tss386.base  |= (cpu->tr.des_h & 0xff000000);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.limit  = (cpu->tr.des_l & 0xffff);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
+    BX_CPU_THIS_PTR tr.cache.u.tss386.g      = (cpu->tr.des_h >> 23) & 0x01;
+    BX_CPU_THIS_PTR tr.cache.u.tss386.avl    = (cpu->tr.des_h >> 20) & 0x01;
+    }
+
+
+  // gdtr
+  BX_CPU_THIS_PTR gdtr.base  = cpu->gdtr.base;
+  BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
+
+  // idtr
+  BX_CPU_THIS_PTR idtr.base  = cpu->idtr.base;
+  BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
+
+
+  BX_CPU_THIS_PTR dr0 = cpu->dr0;
+  BX_CPU_THIS_PTR dr1 = cpu->dr1;
+  BX_CPU_THIS_PTR dr2 = cpu->dr2;
+  BX_CPU_THIS_PTR dr3 = cpu->dr3;
+  BX_CPU_THIS_PTR dr6 = cpu->dr6;
+  BX_CPU_THIS_PTR dr7 = cpu->dr7;
+
+  // BX_CPU_THIS_PTR tr3 = cpu->tr3;
+  // BX_CPU_THIS_PTR tr4 = cpu->tr4;
+  // BX_CPU_THIS_PTR tr5 = cpu->tr5;
+  // BX_CPU_THIS_PTR tr6 = cpu->tr6;
+  // BX_CPU_THIS_PTR tr7 = cpu->tr7;
+
+
+  // cr0, cr1, cr2, cr3, cr4
+  SetCR0(cpu->cr0);
+  BX_CPU_THIS_PTR cr1 = cpu->cr1;
+  BX_CPU_THIS_PTR cr2 = cpu->cr2;
+  BX_CPU_THIS_PTR cr3 = cpu->cr3;
+#if BX_CPU_LEVEL >= 5
+  BX_CPU_THIS_PTR cr4 = cpu->cr4;
+#endif
+
+  BX_CPU_THIS_PTR inhibit_mask = cpu->inhibit_mask;
+
+  //
+  // flush cached items, prefetch, paging, etc
+  //
+  BX_CPU_THIS_PTR CR3_change(cpu->cr3);
+  BX_CPU_THIS_PTR invalidate_prefetch_q();
+  BX_CPU_THIS_PTR async_event = 1;
+
+  return(1);
+}
+
+#if BX_SIM_ID == 0
+#  define BX_DBG_NULL_CALLBACK bx_dbg_null_callback0
+#else
+#  define BX_DBG_NULL_CALLBACK bx_dbg_null_callback1
+#endif
+  void
+BX_DBG_NULL_CALLBACK(unsigned val)
+{
+  // bochs uses the pc_system variables, so this function is
+  // a stub for notification by the debugger, that a change
+  // occurred.
+  UNUSED(val);
+}
+
+  void
+#if BX_SIM_ID == 0
+bx_dbg_init_cpu_mem_env0(bx_dbg_callback_t *callback, int argc, char *argv[])
+#else
+bx_dbg_init_cpu_mem_env1(bx_dbg_callback_t *callback, int argc, char *argv[])
+#endif
+{
+  UNUSED(argc);
+  UNUSED(argv);
+
+#if 0
+#warning hardcoding BX_CPU_THIS_PTR mem[0] and cpu[0]
+  callback->setphymem           = BX_MEM(0)->dbg_set_mem;
+  callback->getphymem           = BX_MEM(0)->dbg_fetch_mem;
+  callback->xlate_linear2phy    = BX_CPU(0)->dbg_xlate_linear2phy;
+  callback->set_reg             = BX_CPU(0)->dbg_set_reg;
+  callback->get_reg             = BX_CPU(0)->dbg_get_reg;
+  callback->get_sreg            = BX_CPU(0)->dbg_get_sreg;
+  callback->get_cpu             = BX_CPU(0)->dbg_get_cpu;
+  callback->set_cpu             = BX_CPU(0)->dbg_set_cpu;
+  callback->dirty_page_tbl_size = sizeof(BX_MEM(0)->dbg_dirty_pages);
+  callback->dirty_page_tbl      = BX_MEM(0)->dbg_dirty_pages;
+  callback->atexit              = BX_CPU(0)->atexit;
+  callback->query_pending       = BX_CPU(0)->dbg_query_pending;
+  callback->execute             = BX_CPU(0)->cpu_loop;
+  callback->take_irq            = BX_CPU(0)->dbg_take_irq;
+  callback->take_dma            = BX_CPU(0)->dbg_take_dma;
+  callback->reset_cpu           = BX_CPU(0)->reset;
+  callback->init_mem            = BX_MEM(0)->init_memory;
+  callback->load_ROM            = BX_MEM(0)->load_ROM;
+  callback->set_A20             = NULL;
+  callback->set_NMI             = BX_DBG_NULL_CALLBACK;
+  callback->set_RESET           = BX_DBG_NULL_CALLBACK;
+  callback->set_INTR            = BX_CPU(0)->set_INTR;
+  callback->force_interrupt     = BX_CPU(0)->dbg_force_interrupt;
+
+#if BX_INSTRUMENTATION
+  callback->instr_start         = bx_instr_start;
+  callback->instr_stop          = bx_instr_stop;
+  callback->instr_reset         = bx_instr_reset;
+  callback->instr_print         = bx_instr_print;
+#endif
+#if BX_USE_LOADER
+  callback->loader              = bx_dbg_loader;
+#endif
+  callback->crc32               = BX_MEM(0)->dbg_crc32;
+#endif
+}
+
+#endif  // #if BX_DEBUGGER
+
+  void
+BX_CPU_C::atexit(void)
+{
+  if (protected_mode()) BX_INFO(("protected mode\n" ));
+  else if (v8086_mode()) BX_INFO(("v8086 mode\n" ));
+  else BX_INFO(("real mode\n"));
+  BX_INFO(("CS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16 ));
+  if (protected_mode()) BX_INFO(("protected mode\n"));
+  else if (v8086_mode()) BX_INFO(("v8086 mode\n"));
+  else BX_INFO(("real mode\n"));
+  BX_INFO(("CS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16));
+  BX_INFO(("SS.d_b = %u bit\n",
+    BX_CPU_THIS_PTR sregs[BX_SREG_SS].cache.u.segment.d_b ? 32 : 16));
+
+  debug(BX_CPU_THIS_PTR prev_eip);
+}
diff --git a/sid/component/bochs/cpu/decode16.cc b/sid/component/bochs/cpu/decode16.cc
new file mode 100644 (file)
index 0000000..c1951b4
--- /dev/null
@@ -0,0 +1,117 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+static Bit16u *aaa[8] = {
+  & BX,
+  & BX,
+  & BP,
+  & BP,
+  & SI,
+  & DI,
+  & BP,
+  & BX,
+  };
+
+static Bit16u *bbb[8] = {
+  & SI,
+  & DI,
+  & SI,
+  & DI,
+  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+  (Bit16u *) & BX_CPU_THIS_PTR empty_register
+  };
+#endif  // BX_USE_CPU_SMF
+
+
+
+  void
+BX_CPU_C::decode_exgx16(unsigned modrm)
+{
+#if 0
+  Bit8u  displ8;
+  Bit16u displ16;
+  unsigned mod, rm;
+
+#if BX_WEIRDISMS
+    i->seg_reg = NULL;
+#endif
+
+  // |  76 | 543 | 210
+  // | mod | ttt |  rm
+
+  BX_INSTR_MODRM16(modrm);
+  i->nnn = (modrm>>3) & 0x07;
+  mod = modrm & 0xc0;
+  rm = modrm & 0x07;
+
+  if (mod == 0xc0) {
+    i->rm_addr = rm;
+    BX_CPU_THIS_PTR rm_type = BX_REGISTER_REF;
+    return;
+    }
+  else { // mod != 3
+    BX_CPU_THIS_PTR rm_type = BX_MEMORY_REF;
+
+    if (mod == 0x40) {
+      displ8 = fetch_next_byte();
+      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit8s) displ8);
+      if (i->seg_reg == NULL)
+        i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+      else
+        i->seg_reg = i->seg_reg;
+      return;
+      }
+    if (mod == 0x80) {
+      displ16 = fetch_next_word();
+      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit16s) displ16);
+      if (i->seg_reg == NULL)
+        i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+      else
+        i->seg_reg = i->seg_reg;
+      return;
+      }
+
+    // mod == 0x00
+    if (rm==6)
+      i->rm_addr = fetch_next_word();
+    else
+      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm]);
+
+    if (i->seg_reg == NULL)
+      i->seg_reg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+    else
+      i->seg_reg = i->seg_reg;
+    return;
+    }
+#endif
+}
diff --git a/sid/component/bochs/cpu/decode32.cc b/sid/component/bochs/cpu/decode32.cc
new file mode 100644 (file)
index 0000000..6316335
--- /dev/null
@@ -0,0 +1,177 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::decode_exgx32(unsigned modrm)
+{
+#if 0
+  unsigned  mod, rm, ss;
+  unsigned sib, base, index;
+  Bit32u displ32, index_reg_val, base_reg_val;
+  Bit8u  displ8;
+
+  /* NOTES:
+   * seg_reg_mod01_base & mod10_base aren't correct???
+   */
+  /* use 32bit addressing modes.  orthogonal base & index registers,
+     scaling available, etc. */
+
+  BX_INSTR_MODRM32(modrm);
+
+  mod = modrm & 0xc0;
+  rm  = modrm & 0x07;
+
+  i->nnn = (modrm>>3) & 0x07;
+
+  if (mod == 0xc0) { /* mod, reg, reg */
+    i->rm_addr = rm;
+    BX_CPU_THIS_PTR rm_type = BX_REGISTER_REF;
+#if BX_WEIRDISMS
+    i->seg_reg = NULL;
+#endif
+    }
+  else { /* mod != 3 */
+    BX_CPU_THIS_PTR rm_type = BX_MEMORY_REF;
+    if (rm != 4) { /* rm != 100b, no s-i-b byte */
+      // one byte modrm
+      if (mod == 0x00) {
+        if (i->seg_reg)
+          i->seg_reg = i->seg_reg;
+        else
+          i->seg_reg = & BX_CPU_THIS_PTR ds;
+        if (rm == 5) { // no reg, 32-bit displacement
+          i->rm_addr = fetch_next_dword();
+          }
+        else {
+          // else reg indirect, no displacement
+          i->rm_addr = BX_READ_32BIT_REG(rm);
+          }
+        return;
+        }
+      if (mod == 0x40) {
+        if (i->seg_reg)
+          i->seg_reg = i->seg_reg;
+        else
+          i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+        // reg, 8-bit displacement, sign extend
+        displ8 = fetch_next_byte();
+        i->rm_addr = BX_READ_32BIT_REG(rm);
+        i->rm_addr += ((Bit8s) displ8);
+        return;
+        }
+      // mod == 0x80
+      if (i->seg_reg)
+        i->seg_reg = i->seg_reg;
+      else
+        i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+      // reg, 32-bit displacement
+      displ32 = fetch_next_dword();
+      i->rm_addr = BX_READ_32BIT_REG(rm);
+      i->rm_addr += displ32;
+      return;
+      }
+    else { /* rm == 4, s-i-b byte follows */
+      sib = fetch_next_byte();
+      BX_INSTR_SIB32(sib);
+      base  = sib & 0x07; sib >>= 3;
+      index = sib & 0x07; sib >>= 3;
+      ss    = sib;
+
+      if (mod == 0x00) {
+        if (i->seg_reg)
+          i->seg_reg = i->seg_reg;
+        else
+          i->seg_reg = BX_CPU_THIS_PTR sreg_mod00_base32[base];
+        if (base != 5) /* base != 101b, no displacement */
+          base_reg_val = BX_READ_32BIT_REG(base);
+        else {
+          BX_INSTR_SIB_mod0_base5(ss);
+          base_reg_val = fetch_next_dword();
+          }
+        index_reg_val = 0;
+        if (index != 4) {
+          index_reg_val = BX_READ_32BIT_REG(index);
+          index_reg_val <<= ss;
+          }
+#ifdef BX_INSTR_SIB_MOD0_IND4
+        else {
+          BX_INSTR_SIB_MOD0_IND4();
+          }
+#endif
+        i->rm_addr = base_reg_val + index_reg_val;
+        return;
+        }
+      if (mod == 0x40) {
+        if (i->seg_reg)
+          i->seg_reg = i->seg_reg;
+        else
+          i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_base32[base];
+        displ8 = fetch_next_byte();
+        base_reg_val = BX_READ_32BIT_REG(base);
+        index_reg_val = 0;
+        if (index != 4) {
+          index_reg_val = BX_READ_32BIT_REG(index);
+          index_reg_val <<= ss;
+          }
+#ifdef BX_INSTR_SIB_MOD1_IND4
+        else {
+          BX_INSTR_SIB_MOD1_IND4();
+          }
+#endif
+        i->rm_addr = base_reg_val + index_reg_val + (Bit8s) displ8;
+        return;
+        }
+
+      // mod == 0x80
+      if (i->seg_reg)
+        i->seg_reg = i->seg_reg;
+      else
+        i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_base32[base];
+      displ32 = fetch_next_dword();
+      base_reg_val = BX_READ_32BIT_REG(base);
+      index_reg_val = 0;
+      if (index != 4) {
+        index_reg_val = BX_READ_32BIT_REG(index);
+        index_reg_val <<= ss;
+        }
+#ifdef BX_INSTR_SIB_MOD2_IND4
+      else {
+        BX_INSTR_SIB_MOD2_IND4();
+        }
+#endif
+      i->rm_addr = base_reg_val + index_reg_val + displ32;
+      return;
+      }
+    } /* if (mod != 3) */
+#endif
+}
diff --git a/sid/component/bochs/cpu/exception-sid.cc b/sid/component/bochs/cpu/exception-sid.cc
new file mode 100644 (file)
index 0000000..9bef31f
--- /dev/null
@@ -0,0 +1,48 @@
+//  exception-sid.cc - override the bochs cpu interrupt member function. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#include "x86.h"
+
+  void
+sid_cpu_c::interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+                    Bit16u error_code)
+{
+    if (vector == 0x80)
+    {
+        int temp = this->gen_reg[0].erx;
+        this->sid_cpu->do_syscall();
+#if X86_CPU_DEBUG
+        printf("Syscall number: %d was executed with the following return value: %d\n", temp, this->gen_reg[0].erx);
+#endif
+    }
+    else if (vector == 0x03)
+    {
+        // INT3 was encountered -- trap to debugger
+        this->sid_cpu->do_breakpoint();
+    }
+    else
+    {
+        BX_CPU_C::interrupt(vector, is_INT, is_error_code, error_code);
+    }
+}
diff --git a/sid/component/bochs/cpu/exception.cc b/sid/component/bochs/cpu/exception.cc
new file mode 100644 (file)
index 0000000..59d5115
--- /dev/null
@@ -0,0 +1,806 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+/* Exception classes.  These are used as indexes into the 'is_exception_OK'
+ * array below, and are stored in the 'exception' array also
+ */
+#define BX_ET_BENIGN       0
+#define BX_ET_CONTRIBUTORY 1
+#define BX_ET_PAGE_FAULT   2
+
+#define BX_ET_DOUBLE_FAULT 10
+
+
+const Boolean BX_CPU_C::is_exception_OK[3][3] = {
+    { 1, 1, 1 }, /* 1st exception is BENIGN */
+    { 1, 0, 1 }, /* 1st exception is CONTRIBUTORY */
+    { 1, 0, 0 }  /* 1st exception is PAGE_FAULT */
+    };
+
+
+  void
+BX_CPU_C::interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+                    Bit16u error_code)
+{
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_intsig;
+#if BX_DEBUG_LINUX
+  if (bx_dbg.linux_syscall) {
+    if (vector == 0x80) bx_dbg_linux_syscall ();
+  }
+#endif
+#endif
+
+//BX_DEBUG(( "::interrupt(%u)\n", vector ));
+
+  BX_INSTR_INTERRUPT(vector);
+  invalidate_prefetch_q();
+
+  // Discard any traps and inhibits for new context; traps will
+  // resume upon return.
+  BX_CPU_THIS_PTR debug_trap = 0;
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+
+#if BX_CPU_LEVEL >= 2
+//  unsigned prev_errno;
+
+#if BX_DEBUGGER
+  if (bx_dbg.interrupts)
+    BX_INFO(("interrupt(): vector = %u, INT = %u, EXT = %u\n",
+      (unsigned) vector, (unsigned) is_INT, (unsigned) BX_CPU_THIS_PTR EXT));
+#endif
+BX_CPU_THIS_PTR save_cs  = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+BX_CPU_THIS_PTR save_ss  = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+BX_CPU_THIS_PTR save_eip = EIP;
+BX_CPU_THIS_PTR save_esp = ESP;
+
+//  prev_errno = BX_CPU_THIS_PTR errorno;
+
+  if(!real_mode()) {
+    Bit32u  dword1, dword2;
+    bx_descriptor_t gate_descriptor, cs_descriptor;
+    bx_selector_t cs_selector;
+
+    Bit16u raw_tss_selector;
+    bx_selector_t   tss_selector;
+    bx_descriptor_t tss_descriptor;
+
+    Bit16u gate_dest_selector;
+    Bit32u gate_dest_offset;
+
+
+    // interrupt vector must be within IDT table limits,
+    // else #GP(vector number*8 + 2 + EXT)
+    if ( (vector*8 + 7) > BX_CPU_THIS_PTR idtr.limit) {
+#if BX_DEBUGGER
+      if (bx_dbg.interrupts) {
+        BX_INFO(("IDT.limit = %04x\n", (unsigned) BX_CPU_THIS_PTR idtr.limit));
+        BX_INFO(("IDT.base  = %06x\n", (unsigned) BX_CPU_THIS_PTR idtr.base));
+        BX_INFO(("interrupt vector must be within IDT table limits\n"));
+        BX_INFO(("bailing\n"));
+        }
+      BX_INFO(("interrupt(): vector > idtr.limit\n"));
+#endif
+      exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+      }
+
+    // descriptor AR byte must indicate interrupt gate, trap gate,
+    // or task gate, else #GP(vector*8 + 2 + EXT)
+    access_linear(BX_CPU_THIS_PTR idtr.base + vector*8,     4, 0,
+      BX_READ, &dword1);
+    access_linear(BX_CPU_THIS_PTR idtr.base + vector*8 + 4, 4, 0,
+      BX_READ, &dword2);
+
+    parse_descriptor(dword1, dword2, &gate_descriptor);
+
+    if ( (gate_descriptor.valid==0) || gate_descriptor.segment) {
+      BX_PANIC(("interrupt(): gate descriptor is not valid sys seg\n"));
+      exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+      }
+
+    switch (gate_descriptor.type) {
+      case 5: // task gate
+      case 6: // 286 interrupt gate
+      case 7: // 286 trap gate
+      case 14: // 386 interrupt gate
+      case 15: // 386 trap gate
+        break;
+      default:
+        BX_INFO(("interrupt(): gate.type(%u) != {5,6,7,14,15}\n",
+          (unsigned) gate_descriptor.type));
+        exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+        return;
+      }
+
+    // if software interrupt, then gate descripor DPL must be >= CPL,
+    // else #GP(vector * 8 + 2 + EXT)
+    if (is_INT  &&  (gate_descriptor.dpl < CPL)) {
+/* ??? */
+      BX_INFO(("interrupt(): is_INT && (dpl < CPL)\n"));
+      exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+      return;
+      }
+
+    // Gate must be present, else #NP(vector * 8 + 2 + EXT)
+    if (gate_descriptor.p == 0) {
+      BX_INFO(("interrupt(): p == 0\n"));
+      exception(BX_NP_EXCEPTION, vector*8 + 2, 0);
+      }
+
+    switch (gate_descriptor.type) {
+      case 5: // 286/386 task gate
+        // examine selector to TSS, given in task gate descriptor
+        raw_tss_selector = gate_descriptor.u.taskgate.tss_selector;
+        parse_selector(raw_tss_selector, &tss_selector);
+
+        // must specify global in the local/global bit,
+        //      else #TS(TSS selector)
+// +++
+// 486/Pent books say #TSS(selector)
+// PPro+ says #GP(selector)
+        if (tss_selector.ti) {
+          BX_PANIC(("interrupt: tss_selector.ti=1\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          return;
+          }
+
+        // index must be within GDT limits, else #TS(TSS selector)
+        fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+          BX_TS_EXCEPTION);
+
+        // AR byte must specify available TSS,
+        //   else #TS(TSS selector)
+        parse_descriptor(dword1, dword2, &tss_descriptor);
+        if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+          BX_PANIC(("exception: TSS selector points to bad TSS\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          return;
+          }
+        if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+          BX_PANIC(("exception: TSS selector points to bad TSS\n"));
+          exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+          return;
+          }
+
+
+        // TSS must be present, else #NP(TSS selector)
+        // done in task_switch()
+
+        // switch tasks with nesting to TSS
+        task_switch(&tss_selector, &tss_descriptor,
+                    BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+        // if interrupt was caused by fault with error code
+        //   stack limits must allow push of 2 more bytes, else #SS(0)
+        // push error code onto stack
+
+        //??? push_16 vs push_32
+        if ( is_error_code ) {
+          //if (tss_descriptor.type==9)
+          if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+            push_32(error_code);
+          else
+            push_16(error_code);
+          }
+
+        // instruction pointer must be in CS limit, else #GP(0)
+        //if (EIP > cs_descriptor.u.segment.limit_scaled) {}
+        if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+          BX_PANIC(("exception(): eIP > CS.limit\n"));
+          exception(BX_GP_EXCEPTION, 0x0000, 0);
+          }
+        return;
+        break;
+
+      case 6: // 286 interrupt gate
+      case 7: // 286 trap gate
+      case 14: // 386 interrupt gate
+      case 15: // 386 trap gate
+        if ( gate_descriptor.type >= 14 ) { // 386 gate
+          gate_dest_selector = gate_descriptor.u.gate386.dest_selector;
+          gate_dest_offset   = gate_descriptor.u.gate386.dest_offset;
+          }
+        else { // 286 gate
+          gate_dest_selector = gate_descriptor.u.gate286.dest_selector;
+          gate_dest_offset   = gate_descriptor.u.gate286.dest_offset;
+          }
+
+        // examine CS selector and descriptor given in gate descriptor
+        // selector must be non-null else #GP(EXT)
+        if ( (gate_dest_selector & 0xfffc) == 0 ) {
+          BX_PANIC(("int_trap_gate(): selector null\n"));
+          exception(BX_GP_EXCEPTION, 0, 0);
+          }
+
+        parse_selector(gate_dest_selector, &cs_selector);
+
+        // selector must be within its descriptor table limits
+        // else #GP(selector+EXT)
+        fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+                                BX_GP_EXCEPTION);
+        parse_descriptor(dword1, dword2, &cs_descriptor);
+
+        // descriptor AR byte must indicate code seg
+        // and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
+        if ( cs_descriptor.valid==0 ||
+             cs_descriptor.segment==0 ||
+             cs_descriptor.u.segment.executable==0 ||
+             cs_descriptor.dpl>CPL ) {
+          BX_INFO(("interrupt(): not code segment\n"));
+          exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+          }
+
+        // segment must be present, else #NP(selector + EXT)
+        if ( cs_descriptor.p==0 ) {
+          BX_PANIC(("interrupt(): segment not present\n"));
+          exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+          }
+
+        // if code segment is non-conforming and DPL < CPL then
+        // INTERRUPT TO INNER PRIVILEGE:
+        if ( cs_descriptor.u.segment.c_ed==0 && cs_descriptor.dpl<CPL ) {
+          Bit16u old_SS, old_CS, SS_for_cpl_x;
+          Bit32u ESP_for_cpl_x, old_EIP, old_ESP;
+          bx_descriptor_t ss_descriptor;
+          bx_selector_t   ss_selector;
+          int bytes;
+#if BX_DEBUGGER
+          if (bx_dbg.interrupts)
+            BX_INFO(("interrupt(): INTERRUPT TO INNER PRIVILEGE\n"));
+#endif
+          // check selector and descriptor for new stack in current TSS
+          get_SS_ESP_from_TSS(cs_descriptor.dpl,
+                              &SS_for_cpl_x, &ESP_for_cpl_x);
+
+          // Selector must be non-null else #TS(EXT)
+          if ( (SS_for_cpl_x & 0xfffc) == 0 ) {
+            BX_PANIC(("interrupt(): SS selector null\n"));
+            /* TS(ext) */
+            exception(BX_TS_EXCEPTION, 0, 0);
+            }
+
+          // selector index must be within its descriptor table limits
+          // else #TS(SS selector + EXT)
+          parse_selector(SS_for_cpl_x, &ss_selector);
+          // fetch 2 dwords of descriptor; call handles out of limits checks
+          fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+                                  BX_TS_EXCEPTION);
+          parse_descriptor(dword1, dword2, &ss_descriptor);
+
+          // selector rpl must = dpl of code segment,
+          // else #TS(SS selector + ext)
+          if (ss_selector.rpl != cs_descriptor.dpl) {
+            BX_PANIC(("interrupt(): SS.rpl != CS.dpl\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            }
+
+          // stack seg DPL must = DPL of code segment,
+          // else #TS(SS selector + ext)
+          if (ss_descriptor.dpl != cs_descriptor.dpl) {
+            BX_PANIC(("interrupt(): SS.dpl != CS.dpl\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            }
+
+          // descriptor must indicate writable data segment,
+          // else #TS(SS selector + EXT)
+          if (ss_descriptor.valid==0 ||
+              ss_descriptor.segment==0  ||
+              ss_descriptor.u.segment.executable==1  ||
+              ss_descriptor.u.segment.r_w==0) {
+            BX_PANIC(("interrupt(): SS not writable data segment\n"));
+            exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            }
+
+          // seg must be present, else #SS(SS selector + ext)
+          if (ss_descriptor.p==0) {
+            BX_PANIC(("interrupt(): SS not present\n"));
+            exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+            }
+
+          if (gate_descriptor.type>=14) {
+            // 386 int/trap gate
+            // new stack must have room for 20|24 bytes, else #SS(0)
+            if ( is_error_code )
+              bytes = 24;
+            else
+              bytes = 20;
+            if (v8086_mode())
+              bytes += 16;
+            }
+          else {
+            // new stack must have room for 10|12 bytes, else #SS(0)
+            if ( is_error_code )
+              bytes = 12;
+            else
+              bytes = 10;
+            if (v8086_mode()) {
+              bytes += 8;
+              BX_PANIC(("interrupt: int/trap gate VM\n"));
+              }
+            }
+
+// 486,Pentium books
+// new stack must have room for 10/12 bytes, else #SS(0) 486 book
+// PPro+
+// new stack must have room for 10/12 bytes, else #SS(seg selector)
+          if ( !can_push(&ss_descriptor, ESP_for_cpl_x, bytes) ) {
+            BX_PANIC(("interrupt(): new stack doesn't have room for %u bytes\n",
+               (unsigned) bytes));
+            // SS(???)
+            }
+
+          // IP must be within CS segment boundaries, else #GP(0)
+          if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
+            BX_PANIC(("interrupt(): gate eIP > CS.limit\n"));
+            exception(BX_GP_EXCEPTION, 0, 0);
+            }
+
+          old_ESP = ESP;
+          old_SS  = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+          old_EIP = EIP;
+          old_CS  = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+
+          // load new SS:SP values from TSS
+          load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
+
+          if (ss_descriptor.u.segment.d_b)
+            ESP = ESP_for_cpl_x;
+          else
+            SP = ESP_for_cpl_x; // leave upper 16bits
+
+          // load new CS:IP values from gate
+          // set CPL to new code segment DPL
+          // set RPL of CS to CPL
+          load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl);
+          EIP = gate_dest_offset;
+
+          if (gate_descriptor.type>=14) { // 386 int/trap gate
+            if (v8086_mode()) {
+              push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+              push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+              push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+              push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+              BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
+              }
+            // push long pointer to old stack onto new stack
+            push_32(old_SS);
+            push_32(old_ESP);
+
+            // push EFLAGS
+            push_32(read_eflags());
+
+            // push long pointer to return address onto new stack
+            push_32(old_CS);
+            push_32(old_EIP);
+
+            if ( is_error_code )
+              push_32(error_code);
+            }
+          else { // 286 int/trap gate
+            if (v8086_mode()) {
+              BX_PANIC(("286 int/trap gate, VM\n"));
+              }
+            // push long pointer to old stack onto new stack
+            push_16(old_SS);
+            push_16(old_ESP); // ignores upper 16bits
+
+            // push FLAGS
+            push_16(read_flags());
+
+            // push return address onto new stack
+            push_16(old_CS);
+            push_16(old_EIP); // ignores upper 16bits
+
+            if ( is_error_code )
+              push_16(error_code);
+            }
+
+          // if INTERRUPT GATE set IF to 0
+          if ( !(gate_descriptor.type & 1) ) // even is int-gate
+            BX_CPU_THIS_PTR eflags.if_ = 0;
+          BX_CPU_THIS_PTR eflags.tf = 0;
+          BX_CPU_THIS_PTR eflags.vm = 0;
+          BX_CPU_THIS_PTR eflags.rf = 0;
+          BX_CPU_THIS_PTR eflags.nt = 0;
+          return;
+          }
+
+        if (v8086_mode()) {
+          exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+          }
+
+        // if code segment is conforming OR code segment DPL = CPL then
+        // INTERRUPT TO SAME PRIVILEGE LEVEL:
+        if ( cs_descriptor.u.segment.c_ed==1 || cs_descriptor.dpl==CPL ) {
+          int bytes;
+          Bit32u temp_ESP;
+
+          if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+            temp_ESP = ESP;
+          else
+            temp_ESP = SP;
+#if BX_DEBUGGER
+          if (bx_dbg.interrupts)
+            BX_INFO(("int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE\n"));
+#endif
+          // Current stack limits must allow pushing 6|8 bytes, else #SS(0)
+          if (gate_descriptor.type >= 14) { // 386 gate
+            if ( is_error_code )
+              bytes = 16;
+            else
+              bytes = 12;
+            }
+          else { // 286 gate
+            if ( is_error_code )
+              bytes = 8;
+            else
+              bytes = 6;
+            }
+
+          if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache,
+                         temp_ESP, bytes) ) {
+            BX_INFO(("interrupt(): stack doesn't have room\n"));
+            exception(BX_SS_EXCEPTION, 0, 0);
+            }
+
+          // eIP must be in CS limit else #GP(0)
+          if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
+            BX_PANIC(("interrupt(): IP > cs descriptor limit\n"));
+            exception(BX_GP_EXCEPTION, 0, 0);
+            }
+
+          // push flags onto stack
+          // push current CS selector onto stack
+          // push return offset onto stack
+          if (gate_descriptor.type >= 14) { // 386 gate
+            push_32(read_eflags());
+            push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+            push_32(EIP);
+            if ( is_error_code )
+              push_32(error_code);
+            }
+          else { // 286 gate
+            push_16(read_flags());
+            push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+            push_16(IP);
+            if ( is_error_code )
+              push_16(error_code);
+            }
+
+          // load CS:IP from gate
+          // load CS descriptor
+          // set the RPL field of CS to CPL
+          load_cs(&cs_selector, &cs_descriptor, CPL);
+          EIP = gate_dest_offset;
+
+          // if interrupt gate then set IF to 0
+          if ( !(gate_descriptor.type & 1) ) // even is int-gate
+            BX_CPU_THIS_PTR eflags.if_ = 0;
+          BX_CPU_THIS_PTR eflags.tf = 0;
+          BX_CPU_THIS_PTR eflags.nt = 0;
+          BX_CPU_THIS_PTR eflags.vm = 0;
+          BX_CPU_THIS_PTR eflags.rf = 0;
+          return;
+          }
+
+        // else #GP(CS selector + ext)
+        BX_INFO(("interrupt: bad descriptor\n"));
+        BX_INFO(("c_ed=%u, descriptor.dpl=%u, CPL=%u\n",
+          (unsigned) cs_descriptor.u.segment.c_ed,
+          (unsigned) cs_descriptor.dpl,
+          (unsigned) CPL));
+        BX_INFO(("cs.segment = %u\n", (unsigned) cs_descriptor.segment));
+        exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+        break;
+
+      default:
+        BX_PANIC(("bad descriptor type in interrupt()!\n"));
+        break;
+      }
+    }
+  else
+#endif
+    { /* real mode */
+    Bit16u cs_selector, ip;
+
+    if ( (vector*4+3) > BX_CPU_THIS_PTR idtr.limit )
+      BX_PANIC(("interrupt(real mode) vector > limit\n"));
+
+    push_16(read_flags());
+
+    cs_selector = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+    push_16(cs_selector);
+    ip = BX_CPU_THIS_PTR eip;
+    push_16(ip);
+
+    access_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector,     2, 0, BX_READ, &ip);
+    IP = ip;
+    access_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector + 2, 2, 0, BX_READ, &cs_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_selector);
+
+    /* INT affects the following flags: I,T */
+    BX_CPU_THIS_PTR eflags.if_ = 0;
+    BX_CPU_THIS_PTR eflags.tf  = 0;
+#if BX_CPU_LEVEL >= 4
+    BX_CPU_THIS_PTR eflags.ac  = 0;
+#endif
+    BX_CPU_THIS_PTR eflags.rf = 0;
+    }
+}
+
+
+
+
+  void
+BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT)
+  // vector:     0..255: vector in IDT
+  // error_code: if exception generates and error, push this error code
+{
+  Boolean  push_error;
+  Bit8u    exception_type;
+  unsigned prev_errno;
+
+//BX_DEBUG(( "::exception(%u)\n", vector ));
+
+  BX_INSTR_EXCEPTION(vector);
+  invalidate_prefetch_q();
+
+  UNUSED(is_INT);
+#if BX_DEBUGGER
+  if (bx_dbg.exceptions)
+    BX_INFO(("exception(%02x h)\n", (unsigned) vector));
+#endif
+  // if not initial error, restore previous register values from
+  // previous attempt to handle exception
+  if (BX_CPU_THIS_PTR errorno) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]  = BX_CPU_THIS_PTR save_cs;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]  = BX_CPU_THIS_PTR save_ss;
+    EIP = BX_CPU_THIS_PTR save_eip;
+    ESP = BX_CPU_THIS_PTR save_esp;
+    }
+
+  BX_CPU_THIS_PTR errorno++;
+  if (BX_CPU_THIS_PTR errorno >= 3) {
+    BX_PANIC(("exception(): 3rd exception with no resolution\n"));
+    }
+
+  /* careful not to get here with curr_exception[1]==DOUBLE_FAULT */
+  /* ...index on DOUBLE_FAULT below, will be out of bounds */
+
+  /* if 1st was a double fault (software INT?), then shutdown */
+  if ( (BX_CPU_THIS_PTR errorno==2) && (BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT) ) {
+    BX_PANIC(("exception(): tripple fault encountered\n"));
+    }
+
+  /* ??? this is not totally correct, should be done depending on
+   * vector */
+  /* backup IP to value before error occurred */
+  EIP = BX_CPU_THIS_PTR prev_eip;
+  ESP = BX_CPU_THIS_PTR prev_esp;
+
+  // note: fault-class exceptions _except_ #DB set RF in
+  //       eflags image.
+
+  switch (vector) {
+    case  0: // DIV by 0
+      push_error = 0;
+      exception_type = BX_ET_CONTRIBUTORY;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case  1: // debug exceptions
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      break;
+    case  2: // NMI
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      break;
+    case  3: // breakpoint
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      break;
+    case  4: // overflow
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      break;
+    case  5: // bounds check
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case  6: // invalid opcode
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case  7: // device not available
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case  8: // double fault
+      push_error = 1;
+      exception_type = BX_ET_DOUBLE_FAULT;
+      break;
+    case  9: // coprocessor segment overrun (286,386 only)
+      push_error = 0;
+      exception_type = BX_ET_CONTRIBUTORY;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      BX_PANIC(("exception(9): unfinished\n"));
+      break;
+    case 10: // invalid TSS
+      push_error = 1;
+      exception_type = BX_ET_CONTRIBUTORY;
+      error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case 11: // segment not present
+      push_error = 1;
+      exception_type = BX_ET_CONTRIBUTORY;
+      error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case 12: // stack fault
+      push_error = 1;
+      exception_type = BX_ET_CONTRIBUTORY;
+      error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case 13: // general protection
+      push_error = 1;
+      exception_type = BX_ET_CONTRIBUTORY;
+      error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case 14: // page fault
+      push_error = 1;
+      exception_type = BX_ET_PAGE_FAULT;
+      // ??? special format error returned
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+    case 15: // reserved
+      BX_PANIC(("exception(15): reserved\n"));
+      push_error = 0;     // keep compiler happy for now
+      exception_type = 0; // keep compiler happy for now
+      break;
+    case 16: // floating-point error
+      push_error = 0;
+      exception_type = BX_ET_BENIGN;
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+#if BX_CPU_LEVEL >= 4
+    case 17: // alignment check
+      BX_PANIC(("exception(): alignment-check, vector 17 unimplemented\n"));
+      push_error = 0;     // keep compiler happy for now
+      exception_type = 0; // keep compiler happy for now
+      BX_CPU_THIS_PTR eflags.rf = 1;
+      break;
+#endif
+#if BX_CPU_LEVEL >= 5
+    case 18: // machine check
+      BX_PANIC(("exception(): machine-check, vector 18 unimplemented\n"));
+      push_error = 0;     // keep compiler happy for now
+      exception_type = 0; // keep compiler happy for now
+      break;
+#endif
+    default:
+      BX_PANIC(("exception(%u): bad vector\n", (unsigned) vector));
+      push_error = 0;     // keep compiler happy for now
+      exception_type = 0; // keep compiler happy for now
+      break;
+    }
+
+  if (exception_type != BX_ET_PAGE_FAULT) {
+    // Page faults have different format
+    error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+    }
+  BX_CPU_THIS_PTR EXT = 1;
+
+  /* if we've already had 1st exception, see if 2nd causes a
+   * Double Fault instead.  Otherwise, just record 1st exception
+   */
+  if (BX_CPU_THIS_PTR errorno >= 2) {
+    if (is_exception_OK[BX_CPU_THIS_PTR curr_exception[0]][exception_type])
+      BX_CPU_THIS_PTR curr_exception[1] = exception_type;
+    else {
+      BX_CPU_THIS_PTR curr_exception[1] = BX_ET_DOUBLE_FAULT;
+      vector = 8;
+    }
+  }
+  else {
+    BX_CPU_THIS_PTR curr_exception[0] = exception_type;
+  }
+
+
+#if BX_CPU_LEVEL >= 2
+  if (!real_mode()) {
+    prev_errno = BX_CPU_THIS_PTR errorno;
+    BX_CPU_THIS_PTR interrupt(vector, 0, push_error, error_code);
+//    if (BX_CPU_THIS_PTR errorno > prev_errno) {
+//      BX_INFO(("segment_exception(): errorno changed\n"));
+//      longjmp(jmp_buf_env, 1); // go back to main decode loop
+//      return;
+//      }
+
+//    if (push_error) {
+//      /* push error code on stack, after handling interrupt */
+//      /* pushed as a word or dword depending upon default size ??? */
+//      if (ss.cache.u.segment.d_b)
+//        push_32((Bit32u) error_code); /* upper bits reserved */
+//      else
+//        push_16(error_code);
+//      if (BX_CPU_THIS_PTR errorno > prev_errno) {
+//        BX_PANIC(("segment_exception(): errorno changed\n"));
+//        return;
+//        }
+//      }
+    BX_CPU_THIS_PTR errorno = 0; // error resolved
+    longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
+    }
+  else // real mode
+#endif
+    {
+    // not INT, no error code pushed
+    BX_CPU_THIS_PTR interrupt(vector, 0, 0, 0);
+    BX_CPU_THIS_PTR errorno = 0; // error resolved
+    longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
+    }
+}
+
+
+  int
+BX_CPU_C::int_number(bx_segment_reg_t *seg)
+{
+  if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS])
+    return(BX_SS_EXCEPTION);
+  else
+    return(BX_GP_EXCEPTION);
+}
+
+  void
+BX_CPU_C::shutdown_cpu(void)
+{
+
+#if BX_CPU_LEVEL > 2
+  BX_PANIC(("shutdown_cpu(): not implemented for 386\n"));
+#endif
+
+  invalidate_prefetch_q();
+  BX_PANIC(("shutdown_cpu(): not finished\n"));
+
+}
diff --git a/sid/component/bochs/cpu/fetchdecode-sid.cc b/sid/component/bochs/cpu/fetchdecode-sid.cc
new file mode 100644 (file)
index 0000000..9aebcae
--- /dev/null
@@ -0,0 +1,1905 @@
+//  fetchdecode-sid.cc - override the bochs cpu fetchdecode member function. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+///////////////////////////
+// prefix bytes
+// opcode bytes
+// modrm/sib
+// address displacement
+// immediate constant
+///////////////////////////
+
+
+
+// sign extended to osize:
+//   6a push ib
+//   6b imul gvevib
+//   70..7f jo..jnle
+//   83 G1 0..7 ADD..CMP Evib
+
+// is 6b imul_gvevib sign extended?  don't think
+//   I'm sign extending it properly in old decode/execute
+
+//check all the groups.  Make sure to add duplicates rather
+// than error.
+
+// mark instructions as changing control transfer, then
+// don't always load from fetch_ptr, etc.
+
+// cant use immediate as another because of Group3 where
+// some have immediate and some don't, and those won't
+// be picked up by logic until indirection.
+
+// get attr and execute ptr at same time
+
+// maybe move 16bit only i's like  MOV_EwSw, MOV_SwEw
+// to 32 bit modules.
+
+// use 0F as a prefix too?
+
+
+
+#if 0
+void BxResolveError(BxInstruction_t *);
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+// For 16-bit address mode, this matrix describes the registers
+// used to formulate the offset, indexed by the RM field.
+// This info is needed by the dynamic translation code for dataflow.
+static unsigned BxMemRegsUsed16[8] = {
+  (1<<3) | (1<<6), // BX + SI
+  (1<<3) | (1<<7), // BX + DI
+  (1<<5) | (1<<6), // BP + SI
+  (1<<5) | (1<<7), // BP + DI
+  (1<<6),          // SI
+  (1<<7),          // DI
+  (1<<5),          // BP
+  (1<<3)           // BX
+  };
+#endif
+
+static BxExecutePtr_t BxResolve16Mod0[8] = {
+  &BX_CPU_C::Resolve16Mod0Rm0,
+  &BX_CPU_C::Resolve16Mod0Rm1,
+  &BX_CPU_C::Resolve16Mod0Rm2,
+  &BX_CPU_C::Resolve16Mod0Rm3,
+  &BX_CPU_C::Resolve16Mod0Rm4,
+  &BX_CPU_C::Resolve16Mod0Rm5,
+  NULL, // d16, no registers used
+  &BX_CPU_C::Resolve16Mod0Rm7
+  };
+
+static BxExecutePtr_t BxResolve16Mod1or2[8] = {
+  &BX_CPU_C::Resolve16Mod1or2Rm0,
+  &BX_CPU_C::Resolve16Mod1or2Rm1,
+  &BX_CPU_C::Resolve16Mod1or2Rm2,
+  &BX_CPU_C::Resolve16Mod1or2Rm3,
+  &BX_CPU_C::Resolve16Mod1or2Rm4,
+  &BX_CPU_C::Resolve16Mod1or2Rm5,
+  &BX_CPU_C::Resolve16Mod1or2Rm6,
+  &BX_CPU_C::Resolve16Mod1or2Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod0[8] = {
+  &BX_CPU_C::Resolve32Mod0Rm0,
+  &BX_CPU_C::Resolve32Mod0Rm1,
+  &BX_CPU_C::Resolve32Mod0Rm2,
+  &BX_CPU_C::Resolve32Mod0Rm3,
+  NULL, // escape to 2-byte
+  NULL, // d32, no registers used
+  &BX_CPU_C::Resolve32Mod0Rm6,
+  &BX_CPU_C::Resolve32Mod0Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod1or2[8] = {
+  &BX_CPU_C::Resolve32Mod1or2Rm0,
+  &BX_CPU_C::Resolve32Mod1or2Rm1,
+  &BX_CPU_C::Resolve32Mod1or2Rm2,
+  &BX_CPU_C::Resolve32Mod1or2Rm3,
+  NULL, // escape to 2-byte
+  &BX_CPU_C::Resolve32Mod1or2Rm5,
+  &BX_CPU_C::Resolve32Mod1or2Rm6,
+  &BX_CPU_C::Resolve32Mod1or2Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod0Base[8] = {
+  &BX_CPU_C::Resolve32Mod0Base0,
+  &BX_CPU_C::Resolve32Mod0Base1,
+  &BX_CPU_C::Resolve32Mod0Base2,
+  &BX_CPU_C::Resolve32Mod0Base3,
+  &BX_CPU_C::Resolve32Mod0Base4,
+  &BX_CPU_C::Resolve32Mod0Base5,
+  &BX_CPU_C::Resolve32Mod0Base6,
+  &BX_CPU_C::Resolve32Mod0Base7,
+  };
+
+static BxExecutePtr_t BxResolve32Mod1or2Base[8] = {
+  &BX_CPU_C::Resolve32Mod1or2Base0,
+  &BX_CPU_C::Resolve32Mod1or2Base1,
+  &BX_CPU_C::Resolve32Mod1or2Base2,
+  &BX_CPU_C::Resolve32Mod1or2Base3,
+  &BX_CPU_C::Resolve32Mod1or2Base4,
+  &BX_CPU_C::Resolve32Mod1or2Base5,
+  &BX_CPU_C::Resolve32Mod1or2Base6,
+  &BX_CPU_C::Resolve32Mod1or2Base7,
+  };
+
+typedef struct BxOpcodeInfo_t {
+  Bit16u         Attr;
+  SidExecutePtr_t ExecutePtr;
+  struct BxOpcodeInfo_t *AnotherArray;
+} BxOpcodeInfo_t;
+
+static BxOpcodeInfo_t BxOpcodeInfoG1EbIb[8] = {
+  /* 0 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_EbIb },
+  /* 1 */  { BxImmediate_Ib,  &BX_CPU_C::OR_EbIb },
+  /* 2 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_EbIb },
+  /* 3 */  { BxImmediate_Ib,  &BX_CPU_C::SBB_EbIb },
+  /* 4 */  { BxImmediate_Ib,  &BX_CPU_C::AND_EbIb },
+  /* 5 */  { BxImmediate_Ib,  &BX_CPU_C::SUB_EbIb },
+  /* 6 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_EbIb },
+  /* 7 */  { BxImmediate_Ib,  &BX_CPU_C::CMP_EbIb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ew[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ADD_EwIw },
+  /* 1 */  { 0,  &BX_CPU_C::OR_EwIw },
+  /* 2 */  { 0,  &BX_CPU_C::ADC_EwIw },
+  /* 3 */  { 0,  &BX_CPU_C::SBB_EwIw },
+  /* 4 */  { 0,  &BX_CPU_C::AND_EwIw },
+  /* 5 */  { 0,  &BX_CPU_C::SUB_EwIw },
+  /* 6 */  { 0,  &BX_CPU_C::XOR_EwIw },
+  /* 7 */  { 0,  &BX_CPU_C::CMP_EwIw }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ed[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ADD_EdId },
+  /* 1 */  { 0,  &BX_CPU_C::OR_EdId },
+  /* 2 */  { 0,  &BX_CPU_C::ADC_EdId },
+  /* 3 */  { 0,  &BX_CPU_C::SBB_EdId },
+  /* 4 */  { 0,  &BX_CPU_C::AND_EdId },
+  /* 5 */  { 0,  &BX_CPU_C::SUB_EdId },
+  /* 6 */  { 0,  &BX_CPU_C::XOR_EdId },
+  /* 7 */  { 0,  &BX_CPU_C::CMP_EdId }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Eb[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Eb },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Eb },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Eb },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Eb },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Eb },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Eb },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Eb },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Eb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ew[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Ew },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Ew },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Ew }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ed[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Ed },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Ed },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Ed },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Ed },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Ed },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Ed },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Ed },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Ed }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Eb[8] = {
+  /* 0 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_EbIb },
+  /* 1 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_EbIb },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Eb },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Eb },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_ALEb },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_ALEb },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_ALEb },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_ALEb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ew[8] = {
+  /* 0 */  { BxImmediate_Iw,  &BX_CPU_C::TEST_EwIw },
+  /* 1 */  { BxImmediate_Iw,  &BX_CPU_C::TEST_EwIw },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Ew },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Ew },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_AXEw },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_AXEw },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_AXEw },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_AXEw }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ed[8] = {
+  /* 0 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EdId },
+  /* 1 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EdId },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Ed },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Ed },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_EAXEd },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_EAXEd },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_EAXEd },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_EAXEd }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG4[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::INC_Eb },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Eb },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { 0,  &BX_CPU_C::BxError },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG5w[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::INC_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::CALL_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::CALL16_Ep },
+  /* 4 */  { 0,  &BX_CPU_C::JMP_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::JMP16_Ep },
+  /* 6 */  { 0,  &BX_CPU_C::PUSH_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG5d[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::INC_Ed },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Ed },
+  /* 2 */  { 0,  &BX_CPU_C::CALL_Ed },
+  /* 3 */  { 0,  &BX_CPU_C::CALL32_Ep },
+  /* 4 */  { 0,  &BX_CPU_C::JMP_Ed },
+  /* 5 */  { 0,  &BX_CPU_C::JMP32_Ep },
+  /* 6 */  { 0,  &BX_CPU_C::PUSH_Ed },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::SLDT_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::STR_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::LLDT_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::LTR_Ew },
+  /* 4 */  { 0,  &BX_CPU_C::VERR_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::VERW_Ew },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG7[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::SGDT_Ms },
+  /* 1 */  { 0,  &BX_CPU_C::SIDT_Ms },
+  /* 2 */  { 0,  &BX_CPU_C::LGDT_Ms },
+  /* 3 */  { 0,  &BX_CPU_C::LIDT_Ms },
+  /* 4 */  { 0,  &BX_CPU_C::SMSW_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::LMSW_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::INVLPG }
+  }; 
+
+
+static BxOpcodeInfo_t BxOpcodeInfoG8EvIb[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::BxError },
+  /* 1 */  { 0,  &BX_CPU_C::BxError },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { BxImmediate_Ib,  &BX_CPU_C::BT_EvIb },
+  /* 5 */  { BxImmediate_Ib,  &BX_CPU_C::BTS_EvIb },
+  /* 6 */  { BxImmediate_Ib,  &BX_CPU_C::BTR_EvIb },
+  /* 7 */  { BxImmediate_Ib,  &BX_CPU_C::BTC_EvIb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG9[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::BxError },
+  /* 1 */  { 0,  &BX_CPU_C::CMPXCHG8B },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { 0,  &BX_CPU_C::BxError },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  };
+
+
+// 512 entries for 16bit mode
+// 512 entries for 32bit mode
+
+static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
+  // 512 entries for 16bit mode
+  /* 00 */  { BxAnother,  &BX_CPU_C::ADD_EbGb },
+  /* 01 */  { BxAnother,  &BX_CPU_C::ADD_EwGw },
+  /* 02 */  { BxAnother,  &BX_CPU_C::ADD_GbEb },
+  /* 03 */  { BxAnother,  &BX_CPU_C::ADD_GwEw },
+  /* 04 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_ALIb },
+  /* 05 */  { BxImmediate_Iv,  &BX_CPU_C::ADD_AXIw },
+  /* 06 */  { 0,  &BX_CPU_C::PUSH_ES },
+  /* 07 */  { 0,  &BX_CPU_C::POP_ES },
+  /* 08 */  { BxAnother,  &BX_CPU_C::OR_EbGb },
+  /* 09 */  { BxAnother,  &BX_CPU_C::OR_EwGw },
+  /* 0A */  { BxAnother,  &BX_CPU_C::OR_GbEb },
+  /* 0B */  { BxAnother,  &BX_CPU_C::OR_GwEw },
+  /* 0C */  { BxImmediate_Ib,  &BX_CPU_C::OR_ALIb },
+  /* 0D */  { BxImmediate_Iv,  &BX_CPU_C::OR_AXIw },
+  /* 0E */  { 0,  &BX_CPU_C::PUSH_CS },
+  /* 0F */  { BxAnother,  &BX_CPU_C::BxError }, // 2-byte escape
+  /* 10 */  { BxAnother,  &BX_CPU_C::ADC_EbGb },
+  /* 11 */  { BxAnother,  &BX_CPU_C::ADC_EwGw },
+  /* 12 */  { BxAnother,  &BX_CPU_C::ADC_GbEb },
+  /* 13 */  { BxAnother,  &BX_CPU_C::ADC_GwEw },
+  /* 14 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_ALIb },
+  /* 15 */  { BxImmediate_Iv,  &BX_CPU_C::ADC_AXIw },
+  /* 16 */  { 0,  &BX_CPU_C::PUSH_SS },
+  /* 17 */  { 0,  &BX_CPU_C::POP_SS },
+  /* 18 */  { BxAnother,  &BX_CPU_C::SBB_EbGb },
+  /* 19 */  { BxAnother,  &BX_CPU_C::SBB_EwGw },
+  /* 1A */  { BxAnother,  &BX_CPU_C::SBB_GbEb },
+  /* 1B */  { BxAnother,  &BX_CPU_C::SBB_GwEw },
+  /* 1C */  { BxImmediate_Ib,  &BX_CPU_C::SBB_ALIb },
+  /* 1D */  { BxImmediate_Iv,  &BX_CPU_C::SBB_AXIw },
+  /* 1E */  { 0,  &BX_CPU_C::PUSH_DS },
+  /* 1F */  { 0,  &BX_CPU_C::POP_DS },
+  /* 20 */  { BxAnother,  &BX_CPU_C::AND_EbGb },
+  /* 21 */  { BxAnother,  &BX_CPU_C::AND_EwGw },
+  /* 22 */  { BxAnother,  &BX_CPU_C::AND_GbEb },
+  /* 23 */  { BxAnother,  &BX_CPU_C::AND_GwEw },
+  /* 24 */  { BxImmediate_Ib,  &BX_CPU_C::AND_ALIb },
+  /* 25 */  { BxImmediate_Iv,  &BX_CPU_C::AND_AXIw },
+  /* 26 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // ES:
+  /* 27 */  { 0,  &BX_CPU_C::DAA },
+  /* 28 */  { BxAnother,  &BX_CPU_C::SUB_EbGb },
+  /* 29 */  { BxAnother,  &BX_CPU_C::SUB_EwGw },
+  /* 2A */  { BxAnother,  &BX_CPU_C::SUB_GbEb },
+  /* 2B */  { BxAnother,  &BX_CPU_C::SUB_GwEw },
+  /* 2C */  { BxImmediate_Ib,  &BX_CPU_C::SUB_ALIb },
+  /* 2D */  { BxImmediate_Iv,  &BX_CPU_C::SUB_AXIw },
+  /* 2E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // CS:
+  /* 2F */  { 0,  &BX_CPU_C::DAS },
+  /* 30 */  { BxAnother,  &BX_CPU_C::XOR_EbGb },
+  /* 31 */  { BxAnother,  &BX_CPU_C::XOR_EwGw },
+  /* 32 */  { BxAnother,  &BX_CPU_C::XOR_GbEb },
+  /* 33 */  { BxAnother,  &BX_CPU_C::XOR_GwEw },
+  /* 34 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_ALIb },
+  /* 35 */  { BxImmediate_Iv,  &BX_CPU_C::XOR_AXIw },
+  /* 36 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // SS:
+  /* 37 */  { 0,  &BX_CPU_C::AAA },
+  /* 38 */  { BxAnother,  &BX_CPU_C::CMP_EbGb },
+  /* 39 */  { BxAnother,  &BX_CPU_C::CMP_EwGw },
+  /* 3A */  { BxAnother,  &BX_CPU_C::CMP_GbEb },
+  /* 3B */  { BxAnother,  &BX_CPU_C::CMP_GwEw },
+  /* 3C */  { BxImmediate_Ib,  &BX_CPU_C::CMP_ALIb },
+  /* 3D */  { BxImmediate_Iv,  &BX_CPU_C::CMP_AXIw },
+  /* 3E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // DS:
+  /* 3F */  { 0,  &BX_CPU_C::AAS },
+  /* 40 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 41 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 42 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 43 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 44 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 45 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 46 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 47 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 48 */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 49 */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4A */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4B */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4C */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4D */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4E */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4F */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 50 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 51 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 52 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 53 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 54 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 55 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 56 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 57 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 58 */  { 0,  &BX_CPU_C::POP_RX },
+  /* 59 */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5A */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5B */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5C */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5D */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5E */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5F */  { 0,  &BX_CPU_C::POP_RX },
+  /* 60 */  { 0,  &BX_CPU_C::PUSHAD16 },
+  /* 61 */  { 0,  &BX_CPU_C::POPAD16 },
+  /* 62 */  { BxAnother,  &BX_CPU_C::BOUND_GvMa },
+  /* 63 */  { BxAnother,  &BX_CPU_C::ARPL_EwGw },
+  /* 64 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // FS:
+  /* 65 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // GS:
+  /* 66 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // OS:
+  /* 67 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // AS:
+  /* 68 */  { BxImmediate_Iv,  &BX_CPU_C::PUSH_Iw },
+  /* 69 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::IMUL_GwEwIw },
+  /* 6A */  { BxImmediate_Ib_SE,  &BX_CPU_C::PUSH_Iw },
+  /* 6B */  { BxAnother | BxImmediate_Ib_SE,  &BX_CPU_C::IMUL_GwEwIw },
+  /* 6C */  { BxRepeatable,  &BX_CPU_C::INSB_YbDX },
+  /* 6D */  { BxRepeatable,  &BX_CPU_C::INSW_YvDX },
+  /* 6E */  { BxRepeatable,  &BX_CPU_C::OUTSB_DXXb },
+  /* 6F */  { BxRepeatable,  &BX_CPU_C::OUTSW_DXXv },
+  /* 70 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 71 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 72 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 73 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 74 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 75 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 76 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 77 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 78 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 79 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7A */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7B */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7C */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7D */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7E */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7F */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 80 */  { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+  /* 81 */  { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ew },
+  /* 82 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 83 */  { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ew },
+  /* 84 */  { BxAnother,  &BX_CPU_C::TEST_EbGb },
+  /* 85 */  { BxAnother,  &BX_CPU_C::TEST_EwGw },
+  /* 86 */  { BxAnother,  &BX_CPU_C::XCHG_EbGb },
+  /* 87 */  { BxAnother,  &BX_CPU_C::XCHG_EwGw },
+  /* 88 */  { BxAnother,  &BX_CPU_C::MOV_EbGb },
+  /* 89 */  { BxAnother,  &BX_CPU_C::MOV_EwGw },
+  /* 8A */  { BxAnother,  &BX_CPU_C::MOV_GbEb },
+  /* 8B */  { BxAnother,  &BX_CPU_C::MOV_GwEw },
+  /* 8C */  { BxAnother,  &BX_CPU_C::MOV_EwSw },
+  /* 8D */  { BxAnother,  &BX_CPU_C::LEA_GwM },
+  /* 8E */  { BxAnother,  &BX_CPU_C::MOV_SwEw },
+  /* 8F */  { BxAnother,  &BX_CPU_C::POP_Ew },
+  /* 90 */  { 0,  &BX_CPU_C::NOP },
+  /* 91 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 92 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 93 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 94 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 95 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 96 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 97 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 98 */  { 0,  &BX_CPU_C::CBW },
+  /* 99 */  { 0,  &BX_CPU_C::CWD },
+  /* 9A */  { BxImmediate_IvIw,  &BX_CPU_C::CALL16_Ap },
+  /* 9B */  { 0,  &BX_CPU_C::FWAIT },
+  /* 9C */  { 0,  &BX_CPU_C::PUSHF_Fv },
+  /* 9D */  { 0,  &BX_CPU_C::POPF_Fv },
+  /* 9E */  { 0,  &BX_CPU_C::SAHF },
+  /* 9F */  { 0,  &BX_CPU_C::LAHF },
+  /* A0 */  { BxImmediate_O,  &BX_CPU_C::MOV_ALOb },
+  /* A1 */  { BxImmediate_O,  &BX_CPU_C::MOV_AXOw },
+  /* A2 */  { BxImmediate_O,  &BX_CPU_C::MOV_ObAL },
+  /* A3 */  { BxImmediate_O,  &BX_CPU_C::MOV_OwAX },
+  /* A4 */  { BxRepeatable,  &BX_CPU_C::MOVSB_XbYb },
+  /* A5 */  { BxRepeatable,  &BX_CPU_C::MOVSW_XvYv },
+  /* A6 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSB_XbYb },
+  /* A7 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSW_XvYv },
+  /* A8 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_ALIb },
+  /* A9 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_AXIw },
+  /* AA */  { BxRepeatable,  &BX_CPU_C::STOSB_YbAL },
+  /* AB */  { BxRepeatable,  &BX_CPU_C::STOSW_YveAX },
+  /* AC */  { BxRepeatable,  &BX_CPU_C::LODSB_ALXb },
+  /* AD */  { BxRepeatable,  &BX_CPU_C::LODSW_eAXXv },
+  /* AE */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASB_ALXb },
+  /* AF */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASW_eAXXv },
+  /* B0 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B1 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B2 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B3 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B4 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B5 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B6 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B7 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B8 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* B9 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BA */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BB */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BC */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BD */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BE */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BF */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* C0 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+  /* C1 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ew },
+  /* C2 */  { BxImmediate_Iw,  &BX_CPU_C::RETnear16_Iw },
+  /* C3 */  { 0,             &BX_CPU_C::RETnear16 },
+  /* C4 */  { BxAnother,  &BX_CPU_C::LES_GvMp },
+  /* C5 */  { BxAnother,  &BX_CPU_C::LDS_GvMp },
+  /* C6 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::MOV_EbIb },
+  /* C7 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::MOV_EwIw },
+  /* C8 */  { BxImmediate_IwIb,  &BX_CPU_C::ENTER_IwIb },
+  /* C9 */  { 0,  &BX_CPU_C::LEAVE },
+  /* CA */  { BxImmediate_Iw,  &BX_CPU_C::RETfar16_Iw },
+  /* CB */  { 0,  &BX_CPU_C::RETfar16 },
+  /* CC */  { 0,  &sid_cpu_c::INT3 },
+  /* CD */  { BxImmediate_Ib,  &sid_cpu_c::INT_Ib },
+  /* CE */  { 0,  &BX_CPU_C::INTO },
+  /* CF */  { 0,  &BX_CPU_C::IRET16 },
+  /* D0 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D1 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ew },
+  /* D2 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D3 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ew },
+  /* D4 */  { BxImmediate_Ib,  &BX_CPU_C::AAM },
+  /* D5 */  { BxImmediate_Ib,  &BX_CPU_C::AAD },
+  /* D6 */  { 0,  &BX_CPU_C::SALC },
+  /* D7 */  { 0,  &BX_CPU_C::XLAT },
+  /* D8 */  { BxAnother,  &BX_CPU_C::ESC0 },
+  /* D9 */  { BxAnother,  &BX_CPU_C::ESC1 },
+  /* DA */  { BxAnother,  &BX_CPU_C::ESC2 },
+  /* DB */  { BxAnother,  &BX_CPU_C::ESC3 },
+  /* DC */  { BxAnother,  &BX_CPU_C::ESC4 },
+  /* DD */  { BxAnother,  &BX_CPU_C::ESC5 },
+  /* DE */  { BxAnother,  &BX_CPU_C::ESC6 },
+  /* DF */  { BxAnother,  &BX_CPU_C::ESC7 },
+  /* E0 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPNE_Jb },
+  /* E1 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPE_Jb },
+  /* E2 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOP_Jb },
+  /* E3 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCXZ_Jb },
+  /* E4 */  { BxImmediate_Ib,  &BX_CPU_C::IN_ALIb },
+  /* E5 */  { BxImmediate_Ib,  &BX_CPU_C::IN_eAXIb },
+  /* E6 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbAL },
+  /* E7 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbeAX },
+  /* E8 */  { BxImmediate_BrOff16,  &BX_CPU_C::CALL_Aw },
+  /* E9 */  { BxImmediate_BrOff16,  &BX_CPU_C::JMP_Jw },
+  /* EA */  { BxImmediate_IvIw,  &BX_CPU_C::JMP_Ap },
+  /* EB */  { BxImmediate_BrOff8,  &BX_CPU_C::JMP_Jw },
+  /* EC */  { 0,  &BX_CPU_C::IN_ALDX },
+  /* ED */  { 0,  &BX_CPU_C::IN_eAXDX },
+  /* EE */  { 0,  &BX_CPU_C::OUT_DXAL },
+  /* EF */  { 0,  &BX_CPU_C::OUT_DXeAX },
+  /* F0 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // LOCK
+  /* F1 */  { 0,  &BX_CPU_C::INT1 },
+  /* F2 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REPNE/REPNZ
+  /* F3 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REP, REPE/REPZ
+  /* F4 */  { 0,  &BX_CPU_C::HLT },
+  /* F5 */  { 0,  &BX_CPU_C::CMC },
+  /* F6 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Eb },
+  /* F7 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Ew },
+  /* F8 */  { 0,  &BX_CPU_C::CLC },
+  /* F9 */  { 0,  &BX_CPU_C::STC },
+  /* FA */  { 0,  &BX_CPU_C::CLI },
+  /* FB */  { 0,  &BX_CPU_C::STI },
+  /* FC */  { 0,  &BX_CPU_C::CLD },
+  /* FD */  { 0,  &BX_CPU_C::STD },
+  /* FE */  { BxAnother | BxGroup4,  NULL, BxOpcodeInfoG4 },
+  /* FF */  { BxAnother | BxGroup5,  NULL, BxOpcodeInfoG5w },
+
+  /* 0F 00 */  { BxAnother | BxGroup6,  NULL, BxOpcodeInfoG6 },
+  /* 0F 01 */  { BxAnother | BxGroup7,  NULL, BxOpcodeInfoG7 },
+  /* 0F 02 */  { BxAnother,  &BX_CPU_C::LAR_GvEw },
+  /* 0F 03 */  { BxAnother,  &BX_CPU_C::LSL_GvEw },
+  /* 0F 04 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 05 */  { 0,  &BX_CPU_C::LOADALL },
+  /* 0F 06 */  { 0,  &BX_CPU_C::CLTS },
+  /* 0F 07 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 08 */  { 0,  &BX_CPU_C::INVD },
+  /* 0F 09 */  { 0,  &BX_CPU_C::WBINVD },
+  /* 0F 0A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 10 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 11 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 12 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 13 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 14 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 15 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 16 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 17 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 18 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 19 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 20 */  { BxAnother,  &BX_CPU_C::MOV_RdCd },
+  /* 0F 21 */  { BxAnother,  &BX_CPU_C::MOV_RdDd },
+  /* 0F 22 */  { BxAnother,  &BX_CPU_C::MOV_CdRd },
+  /* 0F 23 */  { BxAnother,  &BX_CPU_C::MOV_DdRd },
+  /* 0F 24 */  { BxAnother,  &BX_CPU_C::MOV_RdTd },
+  /* 0F 25 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 26 */  { BxAnother,  &BX_CPU_C::MOV_TdRd },
+  /* 0F 27 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 28 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 29 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 30 */  { 0,  &BX_CPU_C::WRMSR },
+  /* 0F 31 */  { 0,  &BX_CPU_C::RDTSC },
+  /* 0F 32 */  { 0,  &BX_CPU_C::RDMSR },
+  /* 0F 33 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 34 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 35 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 36 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 37 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 38 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 39 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 40 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 41 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 42 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 43 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 44 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 45 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 46 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 47 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 48 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 49 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4A */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4B */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4C */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4D */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4E */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4F */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 50 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 51 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 52 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 53 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 54 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 55 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 56 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 57 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 58 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 59 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 60 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 61 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 62 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 63 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 64 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 65 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 66 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 67 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 68 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 69 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 70 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 71 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 72 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 73 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 74 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 75 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 76 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 77 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 78 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 79 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 80 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 81 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 82 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 83 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 84 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 85 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 86 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 87 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 88 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 89 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8A */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8B */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8C */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8D */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8E */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8F */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 90 */  { BxAnother,  &BX_CPU_C::SETO_Eb },
+  /* 0F 91 */  { BxAnother,  &BX_CPU_C::SETNO_Eb },
+  /* 0F 92 */  { BxAnother,  &BX_CPU_C::SETB_Eb },
+  /* 0F 93 */  { BxAnother,  &BX_CPU_C::SETNB_Eb },
+  /* 0F 94 */  { BxAnother,  &BX_CPU_C::SETZ_Eb },
+  /* 0F 95 */  { BxAnother,  &BX_CPU_C::SETNZ_Eb },
+  /* 0F 96 */  { BxAnother,  &BX_CPU_C::SETBE_Eb },
+  /* 0F 97 */  { BxAnother,  &BX_CPU_C::SETNBE_Eb },
+  /* 0F 98 */  { BxAnother,  &BX_CPU_C::SETS_Eb },
+  /* 0F 99 */  { BxAnother,  &BX_CPU_C::SETNS_Eb },
+  /* 0F 9A */  { BxAnother,  &BX_CPU_C::SETP_Eb },
+  /* 0F 9B */  { BxAnother,  &BX_CPU_C::SETNP_Eb },
+  /* 0F 9C */  { BxAnother,  &BX_CPU_C::SETL_Eb },
+  /* 0F 9D */  { BxAnother,  &BX_CPU_C::SETNL_Eb },
+  /* 0F 9E */  { BxAnother,  &BX_CPU_C::SETLE_Eb },
+  /* 0F 9F */  { BxAnother,  &BX_CPU_C::SETNLE_Eb },
+  /* 0F A0 */  { 0,  &BX_CPU_C::PUSH_FS },
+  /* 0F A1 */  { 0,  &BX_CPU_C::POP_FS },
+  /* 0F A2 */  { 0,  &BX_CPU_C::CPUID },
+  /* 0F A3 */  { BxAnother,  &BX_CPU_C::BT_EvGv },
+  /* 0F A4 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHLD_EwGw },
+  /* 0F A5 */  { BxAnother,                 &BX_CPU_C::SHLD_EwGw },
+  /* 0F A6 */  { 0,  &BX_CPU_C::CMPXCHG_XBTS },
+  /* 0F A7 */  { 0,  &BX_CPU_C::CMPXCHG_IBTS },
+  /* 0F A8 */  { 0,  &BX_CPU_C::PUSH_GS },
+  /* 0F A9 */  { 0,  &BX_CPU_C::POP_GS },
+  /* 0F AA */  { 0,  &BX_CPU_C::RSM },
+  /* 0F AB */  { BxAnother,  &BX_CPU_C::BTS_EvGv },
+  /* 0F AC */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHRD_EwGw },
+  /* 0F AD */  { BxAnother,                 &BX_CPU_C::SHRD_EwGw },
+  /* 0F AE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F AF */  { BxAnother,  &BX_CPU_C::IMUL_GwEw },
+  /* 0F B0 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EbGb },
+  /* 0F B1 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EwGw },
+  /* 0F B2 */  { BxAnother,  &BX_CPU_C::LSS_GvMp },
+  /* 0F B3 */  { BxAnother,  &BX_CPU_C::BTR_EvGv },
+  /* 0F B4 */  { BxAnother,  &BX_CPU_C::LFS_GvMp },
+  /* 0F B5 */  { BxAnother,  &BX_CPU_C::LGS_GvMp },
+  /* 0F B6 */  { BxAnother,  &BX_CPU_C::MOVZX_GwEb },
+  /* 0F B7 */  { BxAnother,  &BX_CPU_C::MOVZX_GwEw },
+  /* 0F B8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F B9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F BA */  { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+  /* 0F BB */  { BxAnother,  &BX_CPU_C::BTC_EvGv },
+  /* 0F BC */  { BxAnother,  &BX_CPU_C::BSF_GvEv },
+  /* 0F BD */  { BxAnother,  &BX_CPU_C::BSR_GvEv },
+  /* 0F BE */  { BxAnother,  &BX_CPU_C::MOVSX_GwEb },
+  /* 0F BF */  { BxAnother,  &BX_CPU_C::MOVSX_GwEw },
+  /* 0F C0 */  { BxAnother,  &BX_CPU_C::XADD_EbGb },
+  /* 0F C1 */  { BxAnother,  &BX_CPU_C::XADD_EwGw },
+  /* 0F C2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C7 */  { BxAnother | BxGroup9,  NULL, BxOpcodeInfoG9 },
+  /* 0F C8 */  { 0,  &BX_CPU_C::BSWAP_EAX },
+  /* 0F C9 */  { 0,  &BX_CPU_C::BSWAP_ECX },
+  /* 0F CA */  { 0,  &BX_CPU_C::BSWAP_EDX },
+  /* 0F CB */  { 0,  &BX_CPU_C::BSWAP_EBX },
+  /* 0F CC */  { 0,  &BX_CPU_C::BSWAP_ESP },
+  /* 0F CD */  { 0,  &BX_CPU_C::BSWAP_EBP },
+  /* 0F CE */  { 0,  &BX_CPU_C::BSWAP_ESI },
+  /* 0F CF */  { 0,  &BX_CPU_C::BSWAP_EDI },
+  /* 0F D0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DD */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F ED */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F F0 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F1 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F2 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F3 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F4 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F5 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F6 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F7 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F8 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F9 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FA */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FB */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FC */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FD */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FE */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FF */  { 0,  &BX_CPU_C::UndefinedOpcode },
+
+  // 512 entries for 32bit mod
+  /* 00 */  { BxAnother,  &BX_CPU_C::ADD_EbGb },
+  /* 01 */  { BxAnother,  &BX_CPU_C::ADD_EdGd },
+  /* 02 */  { BxAnother,  &BX_CPU_C::ADD_GbEb },
+  /* 03 */  { BxAnother,  &BX_CPU_C::ADD_GdEd },
+  /* 04 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_ALIb },
+  /* 05 */  { BxImmediate_Iv,  &BX_CPU_C::ADD_EAXId },
+  /* 06 */  { 0,  &BX_CPU_C::PUSH_ES },
+  /* 07 */  { 0,  &BX_CPU_C::POP_ES },
+  /* 08 */  { BxAnother,  &BX_CPU_C::OR_EbGb },
+  /* 09 */  { BxAnother,  &BX_CPU_C::OR_EdGd },
+  /* 0A */  { BxAnother,  &BX_CPU_C::OR_GbEb },
+  /* 0B */  { BxAnother,  &BX_CPU_C::OR_GdEd },
+  /* 0C */  { BxImmediate_Ib,  &BX_CPU_C::OR_ALIb },
+  /* 0D */  { BxImmediate_Iv,  &BX_CPU_C::OR_EAXId },
+  /* 0E */  { 0,  &BX_CPU_C::PUSH_CS },
+  /* 0F */  { BxAnother,  &BX_CPU_C::BxError }, // 2-byte escape
+  /* 10 */  { BxAnother,  &BX_CPU_C::ADC_EbGb },
+  /* 11 */  { BxAnother,  &BX_CPU_C::ADC_EdGd },
+  /* 12 */  { BxAnother,  &BX_CPU_C::ADC_GbEb },
+  /* 13 */  { BxAnother,  &BX_CPU_C::ADC_GdEd },
+  /* 14 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_ALIb },
+  /* 15 */  { BxImmediate_Iv,  &BX_CPU_C::ADC_EAXId },
+  /* 16 */  { 0,  &BX_CPU_C::PUSH_SS },
+  /* 17 */  { 0,  &BX_CPU_C::POP_SS },
+  /* 18 */  { BxAnother,  &BX_CPU_C::SBB_EbGb },
+  /* 19 */  { BxAnother,  &BX_CPU_C::SBB_EdGd },
+  /* 1A */  { BxAnother,  &BX_CPU_C::SBB_GbEb },
+  /* 1B */  { BxAnother,  &BX_CPU_C::SBB_GdEd },
+  /* 1C */  { BxImmediate_Ib,  &BX_CPU_C::SBB_ALIb },
+  /* 1D */  { BxImmediate_Iv,  &BX_CPU_C::SBB_EAXId },
+  /* 1E */  { 0,  &BX_CPU_C::PUSH_DS },
+  /* 1F */  { 0,  &BX_CPU_C::POP_DS },
+  /* 20 */  { BxAnother,  &BX_CPU_C::AND_EbGb },
+  /* 21 */  { BxAnother,  &BX_CPU_C::AND_EdGd },
+  /* 22 */  { BxAnother,  &BX_CPU_C::AND_GbEb },
+  /* 23 */  { BxAnother,  &BX_CPU_C::AND_GdEd },
+  /* 24 */  { BxImmediate_Ib,  &BX_CPU_C::AND_ALIb },
+  /* 25 */  { BxImmediate_Iv,  &BX_CPU_C::AND_EAXId },
+  /* 26 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // ES:
+  /* 27 */  { 0,  &BX_CPU_C::DAA },
+  /* 28 */  { BxAnother,  &BX_CPU_C::SUB_EbGb },
+  /* 29 */  { BxAnother,  &BX_CPU_C::SUB_EdGd },
+  /* 2A */  { BxAnother,  &BX_CPU_C::SUB_GbEb },
+  /* 2B */  { BxAnother,  &BX_CPU_C::SUB_GdEd },
+  /* 2C */  { BxImmediate_Ib,  &BX_CPU_C::SUB_ALIb },
+  /* 2D */  { BxImmediate_Iv,  &BX_CPU_C::SUB_EAXId },
+  /* 2E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // CS:
+  /* 2F */  { 0,  &BX_CPU_C::DAS },
+  /* 30 */  { BxAnother,  &BX_CPU_C::XOR_EbGb },
+  /* 31 */  { BxAnother,  &BX_CPU_C::XOR_EdGd },
+  /* 32 */  { BxAnother,  &BX_CPU_C::XOR_GbEb },
+  /* 33 */  { BxAnother,  &BX_CPU_C::XOR_GdEd },
+  /* 34 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_ALIb },
+  /* 35 */  { BxImmediate_Iv,  &BX_CPU_C::XOR_EAXId },
+  /* 36 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // SS:
+  /* 37 */  { 0,  &BX_CPU_C::AAA },
+  /* 38 */  { BxAnother,  &BX_CPU_C::CMP_EbGb },
+  /* 39 */  { BxAnother,  &BX_CPU_C::CMP_EdGd },
+  /* 3A */  { BxAnother,  &BX_CPU_C::CMP_GbEb },
+  /* 3B */  { BxAnother,  &BX_CPU_C::CMP_GdEd },
+  /* 3C */  { BxImmediate_Ib,  &BX_CPU_C::CMP_ALIb },
+  /* 3D */  { BxImmediate_Iv,  &BX_CPU_C::CMP_EAXId },
+  /* 3E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // DS:
+  /* 3F */  { 0,  &BX_CPU_C::AAS },
+  /* 40 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 41 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 42 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 43 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 44 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 45 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 46 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 47 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 48 */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 49 */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4A */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4B */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4C */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4D */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4E */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4F */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 50 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 51 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 52 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 53 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 54 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 55 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 56 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 57 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 58 */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 59 */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5A */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5B */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5C */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5D */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5E */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5F */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 60 */  { 0,  &BX_CPU_C::PUSHAD32 },
+  /* 61 */  { 0,  &BX_CPU_C::POPAD32 },
+  /* 62 */  { BxAnother,  &BX_CPU_C::BOUND_GvMa },
+  /* 63 */  { BxAnother,  &BX_CPU_C::ARPL_EwGw },
+  /* 64 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // FS:
+  /* 65 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // GS:
+  /* 66 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // OS:
+  /* 67 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // AS:
+  /* 68 */  { BxImmediate_Iv,  &BX_CPU_C::PUSH_Id },
+  /* 69 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::IMUL_GdEdId },
+  /* 6A */  { BxImmediate_Ib_SE,  &BX_CPU_C::PUSH_Id },
+  /* 6B */  { BxAnother | BxImmediate_Ib_SE,  &BX_CPU_C::IMUL_GdEdId },
+  /* 6C */  { BxRepeatable,  &BX_CPU_C::INSB_YbDX },
+  /* 6D */  { BxRepeatable,  &BX_CPU_C::INSW_YvDX },
+  /* 6E */  { BxRepeatable,  &BX_CPU_C::OUTSB_DXXb },
+  /* 6F */  { BxRepeatable,  &BX_CPU_C::OUTSW_DXXv },
+  /* 70 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 71 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 72 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 73 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 74 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 75 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 76 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 77 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 78 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 79 */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7A */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7B */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7C */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7D */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7E */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 7F */  { BxImmediate_BrOff8,  &sid_cpu_c::JCC_Jd },
+  /* 80 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 81 */  { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ed },
+  /* 82 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 83 */  { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ed },
+  /* 84 */  { BxAnother,  &BX_CPU_C::TEST_EbGb },
+  /* 85 */  { BxAnother,  &BX_CPU_C::TEST_EdGd },
+  /* 86 */  { BxAnother,  &BX_CPU_C::XCHG_EbGb },
+  /* 87 */  { BxAnother,  &BX_CPU_C::XCHG_EdGd },
+  /* 88 */  { BxAnother,  &BX_CPU_C::MOV_EbGb },
+  /* 89 */  { BxAnother,  &BX_CPU_C::MOV_EdGd },
+  /* 8A */  { BxAnother,  &BX_CPU_C::MOV_GbEb },
+  /* 8B */  { BxAnother,  &BX_CPU_C::MOV_GdEd },
+  /* 8C */  { BxAnother,  &BX_CPU_C::MOV_EwSw },
+  /* 8D */  { BxAnother,  &BX_CPU_C::LEA_GdM },
+  /* 8E */  { BxAnother,  &BX_CPU_C::MOV_SwEw },
+  /* 8F */  { BxAnother,  &BX_CPU_C::POP_Ed },
+  /* 90 */  { 0,  &BX_CPU_C::NOP },
+  /* 91 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 92 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 93 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 94 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 95 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 96 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 97 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 98 */  { 0,  &BX_CPU_C::CWDE },
+  /* 99 */  { 0,  &BX_CPU_C::CDQ },
+  /* 9A */  { BxImmediate_IvIw,  &BX_CPU_C::CALL32_Ap },
+  /* 9B */  { 0,  &BX_CPU_C::FWAIT },
+  /* 9C */  { 0,  &BX_CPU_C::PUSHF_Fv },
+  /* 9D */  { 0,  &BX_CPU_C::POPF_Fv },
+  /* 9E */  { 0,  &BX_CPU_C::SAHF },
+  /* 9F */  { 0,  &BX_CPU_C::LAHF },
+  /* A0 */  { BxImmediate_O,  &BX_CPU_C::MOV_ALOb },
+  /* A1 */  { BxImmediate_O,  &BX_CPU_C::MOV_EAXOd },
+  /* A2 */  { BxImmediate_O,  &BX_CPU_C::MOV_ObAL },
+  /* A3 */  { BxImmediate_O,  &BX_CPU_C::MOV_OdEAX },
+  /* A4 */  { BxRepeatable,  &BX_CPU_C::MOVSB_XbYb },
+  /* A5 */  { BxRepeatable,  &BX_CPU_C::MOVSW_XvYv },
+  /* A6 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSB_XbYb },
+  /* A7 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSW_XvYv },
+  /* A8 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_ALIb },
+  /* A9 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EAXId },
+  /* AA */  { BxRepeatable,  &BX_CPU_C::STOSB_YbAL },
+  /* AB */  { BxRepeatable,  &BX_CPU_C::STOSW_YveAX },
+  /* AC */  { BxRepeatable,  &BX_CPU_C::LODSB_ALXb },
+  /* AD */  { BxRepeatable,  &BX_CPU_C::LODSW_eAXXv },
+  /* AE */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASB_ALXb },
+  /* AF */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASW_eAXXv },
+  /* B0 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B1 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B2 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B3 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B4 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B5 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B6 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B7 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B8 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* B9 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BA */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BB */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BC */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BD */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BE */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BF */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* C0 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+  /* C1 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ed },
+  /* C2 */  { BxImmediate_Iw,  &BX_CPU_C::RETnear32_Iw },
+  /* C3 */  { 0,             &BX_CPU_C::RETnear32 },
+  /* C4 */  { BxAnother,  &BX_CPU_C::LES_GvMp },
+  /* C5 */  { BxAnother,  &BX_CPU_C::LDS_GvMp },
+  /* C6 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::MOV_EbIb },
+  /* C7 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::MOV_EdId },
+  /* C8 */  { BxImmediate_IwIb,  &BX_CPU_C::ENTER_IwIb },
+  /* C9 */  { 0,  &BX_CPU_C::LEAVE },
+  /* CA */  { BxImmediate_Iw,  &BX_CPU_C::RETfar32_Iw },
+  /* CB */  { 0,  &BX_CPU_C::RETfar32 },
+  /* CC */  { 0,  &sid_cpu_c::INT3 },
+  /* CD */  { BxImmediate_Ib,  &sid_cpu_c::INT_Ib },
+  /* CE */  { 0,  &BX_CPU_C::INTO },
+  /* CF */  { 0,  &BX_CPU_C::IRET32 },
+  /* D0 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D1 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ed },
+  /* D2 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D3 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ed },
+  /* D4 */  { BxImmediate_Ib,  &BX_CPU_C::AAM },
+  /* D5 */  { BxImmediate_Ib,  &BX_CPU_C::AAD },
+  /* D6 */  { 0,  &BX_CPU_C::SALC },
+  /* D7 */  { 0,  &BX_CPU_C::XLAT },
+  /* D8 */  { BxAnother,  &BX_CPU_C::ESC0 },
+  /* D9 */  { BxAnother,  &BX_CPU_C::ESC1 },
+  /* DA */  { BxAnother,  &BX_CPU_C::ESC2 },
+  /* DB */  { BxAnother,  &BX_CPU_C::ESC3 },
+  /* DC */  { BxAnother,  &BX_CPU_C::ESC4 },
+  /* DD */  { BxAnother,  &BX_CPU_C::ESC5 },
+  /* DE */  { BxAnother,  &BX_CPU_C::ESC6 },
+  /* DF */  { BxAnother,  &BX_CPU_C::ESC7 },
+  /* E0 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPNE_Jb },
+  /* E1 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPE_Jb },
+  /* E2 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOP_Jb },
+  /* E3 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCXZ_Jb },
+  /* E4 */  { BxImmediate_Ib,  &BX_CPU_C::IN_ALIb },
+  /* E5 */  { BxImmediate_Ib,  &BX_CPU_C::IN_eAXIb },
+  /* E6 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbAL },
+  /* E7 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbeAX },
+  /* E8 */  { BxImmediate_BrOff32,  &BX_CPU_C::CALL_Ad },
+  /* E9 */  { BxImmediate_BrOff32,  &BX_CPU_C::JMP_Jd },
+  /* EA */  { BxImmediate_IvIw,  &BX_CPU_C::JMP_Ap },
+  /* EB */  { BxImmediate_BrOff8,  &BX_CPU_C::JMP_Jd },
+  /* EC */  { 0,  &BX_CPU_C::IN_ALDX },
+  /* ED */  { 0,  &BX_CPU_C::IN_eAXDX },
+  /* EE */  { 0,  &BX_CPU_C::OUT_DXAL },
+  /* EF */  { 0,  &BX_CPU_C::OUT_DXeAX },
+  /* F0 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // LOCK:
+  /* F1 */  { 0,  &BX_CPU_C::INT1 },
+  /* F2 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REPNE/REPNZ
+  /* F3 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REP,REPE/REPZ
+  /* F4 */  { 0,  &BX_CPU_C::HLT },
+  /* F5 */  { 0,  &BX_CPU_C::CMC },
+  /* F6 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Eb },
+  /* F7 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Ed },
+  /* F8 */  { 0,  &BX_CPU_C::CLC },
+  /* F9 */  { 0,  &BX_CPU_C::STC },
+  /* FA */  { 0,  &BX_CPU_C::CLI },
+  /* FB */  { 0,  &BX_CPU_C::STI },
+  /* FC */  { 0,  &BX_CPU_C::CLD },
+  /* FD */  { 0,  &BX_CPU_C::STD },
+  /* FE */  { BxAnother | BxGroup4,  NULL, BxOpcodeInfoG4 },
+  /* FF */  { BxAnother | BxGroup5,  NULL, BxOpcodeInfoG5d },
+
+  /* 0F 00 */  { BxAnother | BxGroup6,  NULL, BxOpcodeInfoG6 },
+  /* 0F 01 */  { BxAnother | BxGroup7,  NULL, BxOpcodeInfoG7 },
+  /* 0F 02 */  { BxAnother,  &BX_CPU_C::LAR_GvEw },
+  /* 0F 03 */  { BxAnother,  &BX_CPU_C::LSL_GvEw },
+  /* 0F 04 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 05 */  { 0,  &BX_CPU_C::LOADALL },
+  /* 0F 06 */  { 0,  &BX_CPU_C::CLTS },
+  /* 0F 07 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 08 */  { 0,  &BX_CPU_C::INVD },
+  /* 0F 09 */  { 0,  &BX_CPU_C::WBINVD },
+  /* 0F 0A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 10 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 11 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 12 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 13 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 14 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 15 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 16 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 17 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 18 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 19 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 20 */  { BxAnother,  &BX_CPU_C::MOV_RdCd },
+  /* 0F 21 */  { BxAnother,  &BX_CPU_C::MOV_RdDd },
+  /* 0F 22 */  { BxAnother,  &BX_CPU_C::MOV_CdRd },
+  /* 0F 23 */  { BxAnother,  &BX_CPU_C::MOV_DdRd },
+  /* 0F 24 */  { BxAnother,  &BX_CPU_C::MOV_RdTd },
+  /* 0F 25 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 26 */  { BxAnother,  &BX_CPU_C::MOV_TdRd },
+  /* 0F 27 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 28 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 29 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 30 */  { 0,  &BX_CPU_C::WRMSR },
+  /* 0F 31 */  { 0,  &BX_CPU_C::RDTSC },
+  /* 0F 32 */  { 0,  &BX_CPU_C::RDMSR },
+  /* 0F 33 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 34 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 35 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 36 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 37 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 38 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 39 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 40 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 41 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 42 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 43 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 44 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 45 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 46 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 47 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 48 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 49 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4A */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4B */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4C */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4D */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4E */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4F */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 50 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 51 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 52 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 53 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 54 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 55 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 56 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 57 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 58 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 59 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 60 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 61 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 62 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 63 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 64 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 65 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 66 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 67 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 68 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 69 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 70 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 71 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 72 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 73 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 74 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 75 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 76 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 77 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 78 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 79 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 80 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 81 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 82 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 83 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 84 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 85 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 86 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 87 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 88 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 89 */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8A */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8B */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8C */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8D */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8E */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 8F */  { BxImmediate_BrOff32,  &sid_cpu_c::JCC_Jd },
+  /* 0F 90 */  { BxAnother,  &BX_CPU_C::SETO_Eb },
+  /* 0F 91 */  { BxAnother,  &BX_CPU_C::SETNO_Eb },
+  /* 0F 92 */  { BxAnother,  &BX_CPU_C::SETB_Eb },
+  /* 0F 93 */  { BxAnother,  &BX_CPU_C::SETNB_Eb },
+  /* 0F 94 */  { BxAnother,  &BX_CPU_C::SETZ_Eb },
+  /* 0F 95 */  { BxAnother,  &BX_CPU_C::SETNZ_Eb },
+  /* 0F 96 */  { BxAnother,  &BX_CPU_C::SETBE_Eb },
+  /* 0F 97 */  { BxAnother,  &BX_CPU_C::SETNBE_Eb },
+  /* 0F 98 */  { BxAnother,  &BX_CPU_C::SETS_Eb },
+  /* 0F 99 */  { BxAnother,  &BX_CPU_C::SETNS_Eb },
+  /* 0F 9A */  { BxAnother,  &BX_CPU_C::SETP_Eb },
+  /* 0F 9B */  { BxAnother,  &BX_CPU_C::SETNP_Eb },
+  /* 0F 9C */  { BxAnother,  &BX_CPU_C::SETL_Eb },
+  /* 0F 9D */  { BxAnother,  &BX_CPU_C::SETNL_Eb },
+  /* 0F 9E */  { BxAnother,  &BX_CPU_C::SETLE_Eb },
+  /* 0F 9F */  { BxAnother,  &BX_CPU_C::SETNLE_Eb },
+  /* 0F A0 */  { 0,  &BX_CPU_C::PUSH_FS },
+  /* 0F A1 */  { 0,  &BX_CPU_C::POP_FS },
+  /* 0F A2 */  { 0,  &BX_CPU_C::CPUID },
+  /* 0F A3 */  { BxAnother,  &BX_CPU_C::BT_EvGv },
+  /* 0F A4 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHLD_EdGd },
+  /* 0F A5 */  { BxAnother,                 &BX_CPU_C::SHLD_EdGd },
+  /* 0F A6 */  { 0,  &BX_CPU_C::CMPXCHG_XBTS },
+  /* 0F A7 */  { 0,  &BX_CPU_C::CMPXCHG_IBTS },
+  /* 0F A8 */  { 0,  &BX_CPU_C::PUSH_GS },
+  /* 0F A9 */  { 0,  &BX_CPU_C::POP_GS },
+  /* 0F AA */  { 0,  &BX_CPU_C::RSM },
+  /* 0F AB */  { BxAnother,  &BX_CPU_C::BTS_EvGv },
+  /* 0F AC */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHRD_EdGd },
+  /* 0F AD */  { BxAnother,                 &BX_CPU_C::SHRD_EdGd },
+  /* 0F AE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F AF */  { BxAnother,  &BX_CPU_C::IMUL_GdEd },
+  /* 0F B0 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EbGb },
+  /* 0F B1 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EdGd },
+  /* 0F B2 */  { BxAnother,  &BX_CPU_C::LSS_GvMp },
+  /* 0F B3 */  { BxAnother,  &BX_CPU_C::BTR_EvGv },
+  /* 0F B4 */  { BxAnother,  &BX_CPU_C::LFS_GvMp },
+  /* 0F B5 */  { BxAnother,  &BX_CPU_C::LGS_GvMp },
+  /* 0F B6 */  { BxAnother,  &BX_CPU_C::MOVZX_GdEb },
+  /* 0F B7 */  { BxAnother,  &BX_CPU_C::MOVZX_GdEw },
+  /* 0F B8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F B9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F BA */  { BxAnother | BxGroup8,  NULL, BxOpcodeInfoG8EvIb },
+  /* 0F BB */  { BxAnother,  &BX_CPU_C::BTC_EvGv },
+  /* 0F BC */  { BxAnother,  &BX_CPU_C::BSF_GvEv },
+  /* 0F BD */  { BxAnother,  &BX_CPU_C::BSR_GvEv },
+  /* 0F BE */  { BxAnother,  &BX_CPU_C::MOVSX_GdEb },
+  /* 0F BF */  { BxAnother,  &BX_CPU_C::MOVSX_GdEw },
+  /* 0F C0 */  { BxAnother,  &BX_CPU_C::XADD_EbGb },
+  /* 0F C1 */  { BxAnother,  &BX_CPU_C::XADD_EdGd },
+  /* 0F C2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C7 */  { BxAnother | BxGroup9,  NULL, BxOpcodeInfoG9 },
+  /* 0F C8 */  { 0,  &BX_CPU_C::BSWAP_EAX },
+  /* 0F C9 */  { 0,  &BX_CPU_C::BSWAP_ECX },
+  /* 0F CA */  { 0,  &BX_CPU_C::BSWAP_EDX },
+  /* 0F CB */  { 0,  &BX_CPU_C::BSWAP_EBX },
+  /* 0F CC */  { 0,  &BX_CPU_C::BSWAP_ESP },
+  /* 0F CD */  { 0,  &BX_CPU_C::BSWAP_EBP },
+  /* 0F CE */  { 0,  &BX_CPU_C::BSWAP_ESI },
+  /* 0F CF */  { 0,  &BX_CPU_C::BSWAP_EDI },
+  /* 0F D0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DD */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F ED */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F F0 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F1 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F2 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F3 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F4 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F5 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F6 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F7 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F8 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F9 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FA */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FB */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FC */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FD */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FE */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FF */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  };
+
+
+
+
+  unsigned
+sid_cpu_c::FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+                      unsigned remain, Boolean is_32)
+{
+  // remain must be at least 1
+
+  unsigned b1, b2, ilen=1, attr;
+  unsigned imm_mode, offset;
+
+  instruction->os_32 = instruction->as_32 = is_32;
+  instruction->ResolveModrm = NULL;
+  instruction->seg = BX_SEG_REG_NULL;
+  instruction->rep_used = 0;
+
+fetch_b1:
+  b1 = *iptr++;
+
+another_byte:
+  offset = instruction->os_32 << 9; // * 512
+  instruction->attr = attr = BxOpcodeInfo[b1+offset].Attr;
+
+  if (attr & BxAnother) {
+    if (attr & BxPrefix) {
+      switch (b1) {
+        case 0x66: // OpSize
+          instruction->os_32 = !is_32;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+
+        case 0x67: // AddrSize
+          instruction->as_32 = !is_32;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+
+        case 0xf2: // REPNE/REPNZ
+        case 0xf3: // REP/REPE/REPZ
+          instruction->rep_used = b1;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+          break;
+
+        case 0x2e: // CS:
+          instruction->seg = BX_SEG_REG_CS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x26: // ES:
+          instruction->seg = BX_SEG_REG_ES;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x36: // SS:
+          instruction->seg = BX_SEG_REG_SS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x3e: // DS:
+          instruction->seg = BX_SEG_REG_DS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x64: // FS:
+          instruction->seg = BX_SEG_REG_FS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x65: // GS:
+          instruction->seg = BX_SEG_REG_GS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0xf0: // LOCK:
+          ilen++; goto fetch_b1;
+          break;
+
+        default:
+BX_PANIC(("fetch_decode: prefix default = 0x%02x\n", b1));
+        }
+      }
+    // opcode requires another byte
+    if (ilen < remain) {
+      ilen++;
+      b2 = *iptr++;
+      if (b1 == 0x0f) {
+        // 2-byte prefix
+        b1 = 0x100 | b2;
+        goto another_byte;
+        }
+      }
+    else
+      return(0);
+
+    // Parse mod-nnn-rm and related bytes
+    unsigned rm;
+    instruction->modrm = b2;
+    rm =
+    instruction->rm    = b2 & 0x07;
+    instruction->mod   = b2 & 0xc0; // leave unshifted
+    instruction->nnn   = (b2 >> 3) & 0x07;
+    if (instruction->mod == 0xc0) { // mod == 11b
+      goto modrm_done;
+      }
+    if (instruction->as_32) {
+      // 32-bit addressing modes; note that mod==11b handled above
+      if (rm != 4) { // no s-i-b byte
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
+#endif
+        if (instruction->mod == 0x00) { // mod == 00b
+          instruction->ResolveModrm = BxResolve32Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_SEG_REG_DS;
+          if (rm == 5) {
+            if ((ilen+3) < remain) {
+              Bit32u imm32u;
+              imm32u = *iptr++;
+              imm32u |= (*iptr++) << 8;
+              imm32u |= (*iptr++) << 16;
+              imm32u |= (*iptr++) << 24;
+              instruction->rm_addr = imm32u;
+              ilen += 4;
+#if BX_DYNAMIC_TRANSLATION
+              instruction->DTMemRegsUsed = 0;
+#endif
+              goto modrm_done;
+              }
+            else {
+              return(0);
+              }
+            }
+          // mod==00b, rm!=4, rm!=5
+          goto modrm_done;
+          }
+        if (instruction->mod == 0x40) { // mod == 01b
+          instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+get_8bit_displ:
+          if (ilen < remain) {
+            // 8 sign extended to 32
+            instruction->displ32u = (Bit8s) *iptr++;
+            ilen++;
+            goto modrm_done;
+            }
+          else {
+            return(0);
+            }
+          }
+        // (mod == 0x80) mod == 10b
+        instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+get_32bit_displ:
+        if ((ilen+3) < remain) {
+          Bit32u imm32u;
+          imm32u = *iptr++;
+          imm32u |= (*iptr++) << 8;
+          imm32u |= (*iptr++) << 16;
+          imm32u |= (*iptr++) << 24;
+          instruction->displ32u = imm32u;
+          ilen += 4;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      else { // mod!=11b, rm==4, s-i-b byte follows
+        unsigned sib, base;
+        if (ilen < remain) {
+          sib = *iptr++;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        instruction->sib   = sib;
+        base =
+        instruction->base  = sib & 0x07; sib >>= 3;
+        instruction->index = sib & 0x07; sib >>= 3;
+        instruction->scale = sib;
+#if BX_DYNAMIC_TRANSLATION
+        if (instruction->index == 0x04) // 100b
+          instruction->DTMemRegsUsed = 0;
+        else
+          instruction->DTMemRegsUsed = 1<<instruction->index;
+#endif
+        if (instruction->mod == 0x00) { // mod==00b, rm==4
+          instruction->ResolveModrm = BxResolve32Mod0Base[base];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod0_base32[base];
+          if (instruction->base == 0x05) {
+            goto get_32bit_displ;
+            }
+          // mod==00b, rm==4, base!=5
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTMemRegsUsed |= 1<<base;
+#endif
+          goto modrm_done;
+          }
+#if BX_DYNAMIC_TRANSLATION
+        // for remaining 32bit cases
+        instruction->DTMemRegsUsed |= 1<<base;
+#endif
+        if (instruction->mod == 0x40) { // mod==01b, rm==4
+          instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+          goto get_8bit_displ;
+          }
+        // (instruction->mod == 0x80),  mod==10b, rm==4
+        instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+        goto get_32bit_displ;
+        }
+      }
+    else {
+      // 16-bit addressing modes, mod==11b handled above
+      if (instruction->mod == 0x40) { // mod == 01b
+        instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+        if (ilen < remain) {
+          // 8 sign extended to 16
+          instruction->displ16u = (Bit8s) *iptr++;
+          ilen++;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      if (instruction->mod == 0x80) { // mod == 10b
+        instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+        if ((ilen+1) < remain) {
+          Bit16u displ16u;
+          displ16u = *iptr++;
+          displ16u |= (*iptr++) << 8;
+          instruction->displ16u = displ16u;
+          ilen += 2;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      // mod must be 00b at this point
+      instruction->ResolveModrm = BxResolve16Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod0[rm];
+#endif
+      if (BX_NULL_SEG_REG(instruction->seg))
+        instruction->seg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+      if (rm == 0x06) {
+        if ((ilen+1) < remain) {
+          Bit16u displ16u;
+          displ16u = *iptr++;
+          displ16u |= (*iptr++) << 8;
+          instruction->rm_addr = displ16u;
+          ilen += 2;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      // mod=00b rm!=6
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+      }
+
+modrm_done:
+    if (attr & BxGroupN) {
+      BxOpcodeInfo_t *OpcodeInfoPtr;
+
+      OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
+      instruction->execute_sid = OpcodeInfoPtr[instruction->nnn].ExecutePtr;
+      // get additional attributes from group table
+      attr |= OpcodeInfoPtr[instruction->nnn].Attr;
+      instruction->attr = attr;
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTAttr = 0; // for now
+#endif
+      }
+    else {
+      instruction->execute_sid = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+      instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+      }
+    }
+  else {
+    // Opcode does not require a MODRM byte.
+    // Note that a 2-byte opcode (0F XX) will jump to before
+    // the if() above after fetching the 2nd byte, so this path is
+    // taken in all cases if a modrm byte is NOT required.
+    instruction->execute_sid = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+    instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+    instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+    }
+
+
+  imm_mode = attr & BxImmediate;
+
+  if (imm_mode) {
+    switch (imm_mode) {
+      case BxImmediate_Ib:
+        if (ilen < remain) {
+          instruction->Ib = *iptr;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_Ib_SE: // Sign extend to OS size
+        if (ilen < remain) {
+          Bit8s temp8s;
+          temp8s = *iptr;
+          if (instruction->os_32)
+            instruction->Id = (Bit32s) temp8s;
+          else
+            instruction->Iw = (Bit16s) temp8s;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_Iv: // same as BxImmediate_BrOff32
+      case BxImmediate_IvIw: // CALL_Ap
+        if (instruction->os_32) {
+          if ((ilen+3) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr++) << 8;
+            imm32u |= (*iptr++) << 16;
+            imm32u |= (*iptr) << 24;
+            instruction->Id = imm32u;
+            ilen += 4;
+            }
+          else {
+            return(0);
+            }
+          }
+        else {
+          if ((ilen+1) < remain) {
+            Bit16u imm16u;
+            imm16u = *iptr++;
+            imm16u |= (*iptr) << 8;
+            instruction->Iw = imm16u;
+            ilen += 2;
+            }
+          else {
+            return(0);
+            }
+          }
+        if (imm_mode != BxImmediate_IvIw)
+          break;
+        iptr++;
+        // Get Iw for BxImmediate_IvIw
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Iw2 = imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_O:
+        if (instruction->as_32) {
+          // fetch 32bit address into Id
+          if ((ilen+3) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr++) << 8;
+            imm32u |= (*iptr++) << 16;
+            imm32u |= (*iptr) << 24;
+            instruction->Id = imm32u;
+            ilen += 4;
+            }
+          else {
+            return(0);
+            }
+          }
+        else {
+          // fetch 16bit address into Id
+          if ((ilen+1) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr) << 8;
+            instruction->Id = imm32u;
+            ilen += 2;
+            }
+          else {
+            return(0);
+            }
+          }
+        break;
+      case BxImmediate_Iw:
+      case BxImmediate_IwIb:
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Iw = imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        if (imm_mode == BxImmediate_Iw) break;
+        iptr++;
+        if (ilen < remain) {
+          instruction->Ib2 = *iptr;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_BrOff8:
+        if (ilen < remain) {
+          Bit8s temp8s;
+          temp8s = *iptr;
+          instruction->Id = temp8s;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_BrOff16:
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Id = (Bit16s) imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        break;
+      default:
+BX_INFO(("b1 was %x\n", b1));
+        BX_PANIC(("fetchdecode: imm_mode = %u\n", imm_mode));
+      }
+    }
+
+  instruction->b1 = b1;
+  instruction->ilen = ilen;
+  //instruction->flags_in  = 0; // for now
+  //instruction->flags_out = 0; // for now
+  return(1);
+}
+#if 0
+  void
+BX_CPU_C::BxError(BxInstruction_t *i)
+{
+  // extern void dump_core();
+  BX_INFO(("BxError: instruction with op1=0x%x\n", i->b1));
+  BX_INFO(("nnn was %u\n", i->nnn));
+
+  BX_INFO(("WARNING: Encountered an unknown instruction (signalling illegal instruction):\n"));
+  // dump_core();
+
+  BX_CPU_THIS_PTR UndefinedOpcode(i);
+}
+
+  void
+BX_CPU_C::BxResolveError(BxInstruction_t *i)
+{
+  BX_PANIC(("BxResolveError: instruction with op1=0x%x\n", i->b1));
+}
+#endif
diff --git a/sid/component/bochs/cpu/fetchdecode.cc b/sid/component/bochs/cpu/fetchdecode.cc
new file mode 100644 (file)
index 0000000..0dbaf43
--- /dev/null
@@ -0,0 +1,1901 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+///////////////////////////
+// prefix bytes
+// opcode bytes
+// modrm/sib
+// address displacement
+// immediate constant
+///////////////////////////
+
+
+
+// sign extended to osize:
+//   6a push ib
+//   6b imul gvevib
+//   70..7f jo..jnle
+//   83 G1 0..7 ADD..CMP Evib
+
+// is 6b imul_gvevib sign extended?  don't think
+//   I'm sign extending it properly in old decode/execute
+
+//check all the groups.  Make sure to add duplicates rather
+// than error.
+
+// mark instructions as changing control transfer, then
+// don't always load from fetch_ptr, etc.
+
+// cant use immediate as another because of Group3 where
+// some have immediate and some don't, and those won't
+// be picked up by logic until indirection.
+
+// get attr and execute ptr at same time
+
+// maybe move 16bit only i's like  MOV_EwSw, MOV_SwEw
+// to 32 bit modules.
+
+// use 0F as a prefix too?
+
+
+
+
+void BxResolveError(BxInstruction_t *);
+
+#if BX_DYNAMIC_TRANSLATION
+// For 16-bit address mode, this matrix describes the registers
+// used to formulate the offset, indexed by the RM field.
+// This info is needed by the dynamic translation code for dataflow.
+static unsigned BxMemRegsUsed16[8] = {
+  (1<<3) | (1<<6), // BX + SI
+  (1<<3) | (1<<7), // BX + DI
+  (1<<5) | (1<<6), // BP + SI
+  (1<<5) | (1<<7), // BP + DI
+  (1<<6),          // SI
+  (1<<7),          // DI
+  (1<<5),          // BP
+  (1<<3)           // BX
+  };
+#endif
+
+static BxExecutePtr_t BxResolve16Mod0[8] = {
+  &BX_CPU_C::Resolve16Mod0Rm0,
+  &BX_CPU_C::Resolve16Mod0Rm1,
+  &BX_CPU_C::Resolve16Mod0Rm2,
+  &BX_CPU_C::Resolve16Mod0Rm3,
+  &BX_CPU_C::Resolve16Mod0Rm4,
+  &BX_CPU_C::Resolve16Mod0Rm5,
+  NULL, // d16, no registers used
+  &BX_CPU_C::Resolve16Mod0Rm7
+  };
+
+static BxExecutePtr_t BxResolve16Mod1or2[8] = {
+  &BX_CPU_C::Resolve16Mod1or2Rm0,
+  &BX_CPU_C::Resolve16Mod1or2Rm1,
+  &BX_CPU_C::Resolve16Mod1or2Rm2,
+  &BX_CPU_C::Resolve16Mod1or2Rm3,
+  &BX_CPU_C::Resolve16Mod1or2Rm4,
+  &BX_CPU_C::Resolve16Mod1or2Rm5,
+  &BX_CPU_C::Resolve16Mod1or2Rm6,
+  &BX_CPU_C::Resolve16Mod1or2Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod0[8] = {
+  &BX_CPU_C::Resolve32Mod0Rm0,
+  &BX_CPU_C::Resolve32Mod0Rm1,
+  &BX_CPU_C::Resolve32Mod0Rm2,
+  &BX_CPU_C::Resolve32Mod0Rm3,
+  NULL, // escape to 2-byte
+  NULL, // d32, no registers used
+  &BX_CPU_C::Resolve32Mod0Rm6,
+  &BX_CPU_C::Resolve32Mod0Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod1or2[8] = {
+  &BX_CPU_C::Resolve32Mod1or2Rm0,
+  &BX_CPU_C::Resolve32Mod1or2Rm1,
+  &BX_CPU_C::Resolve32Mod1or2Rm2,
+  &BX_CPU_C::Resolve32Mod1or2Rm3,
+  NULL, // escape to 2-byte
+  &BX_CPU_C::Resolve32Mod1or2Rm5,
+  &BX_CPU_C::Resolve32Mod1or2Rm6,
+  &BX_CPU_C::Resolve32Mod1or2Rm7
+  };
+
+static BxExecutePtr_t BxResolve32Mod0Base[8] = {
+  &BX_CPU_C::Resolve32Mod0Base0,
+  &BX_CPU_C::Resolve32Mod0Base1,
+  &BX_CPU_C::Resolve32Mod0Base2,
+  &BX_CPU_C::Resolve32Mod0Base3,
+  &BX_CPU_C::Resolve32Mod0Base4,
+  &BX_CPU_C::Resolve32Mod0Base5,
+  &BX_CPU_C::Resolve32Mod0Base6,
+  &BX_CPU_C::Resolve32Mod0Base7,
+  };
+
+static BxExecutePtr_t BxResolve32Mod1or2Base[8] = {
+  &BX_CPU_C::Resolve32Mod1or2Base0,
+  &BX_CPU_C::Resolve32Mod1or2Base1,
+  &BX_CPU_C::Resolve32Mod1or2Base2,
+  &BX_CPU_C::Resolve32Mod1or2Base3,
+  &BX_CPU_C::Resolve32Mod1or2Base4,
+  &BX_CPU_C::Resolve32Mod1or2Base5,
+  &BX_CPU_C::Resolve32Mod1or2Base6,
+  &BX_CPU_C::Resolve32Mod1or2Base7,
+  };
+
+typedef struct BxOpcodeInfo_t {
+  Bit16u         Attr;
+  BxExecutePtr_t ExecutePtr;
+  struct BxOpcodeInfo_t *AnotherArray;
+} BxOpcodeInfo_t;
+
+static BxOpcodeInfo_t BxOpcodeInfoG1EbIb[8] = {
+  /* 0 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_EbIb },
+  /* 1 */  { BxImmediate_Ib,  &BX_CPU_C::OR_EbIb },
+  /* 2 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_EbIb },
+  /* 3 */  { BxImmediate_Ib,  &BX_CPU_C::SBB_EbIb },
+  /* 4 */  { BxImmediate_Ib,  &BX_CPU_C::AND_EbIb },
+  /* 5 */  { BxImmediate_Ib,  &BX_CPU_C::SUB_EbIb },
+  /* 6 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_EbIb },
+  /* 7 */  { BxImmediate_Ib,  &BX_CPU_C::CMP_EbIb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ew[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ADD_EwIw },
+  /* 1 */  { 0,  &BX_CPU_C::OR_EwIw },
+  /* 2 */  { 0,  &BX_CPU_C::ADC_EwIw },
+  /* 3 */  { 0,  &BX_CPU_C::SBB_EwIw },
+  /* 4 */  { 0,  &BX_CPU_C::AND_EwIw },
+  /* 5 */  { 0,  &BX_CPU_C::SUB_EwIw },
+  /* 6 */  { 0,  &BX_CPU_C::XOR_EwIw },
+  /* 7 */  { 0,  &BX_CPU_C::CMP_EwIw }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ed[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ADD_EdId },
+  /* 1 */  { 0,  &BX_CPU_C::OR_EdId },
+  /* 2 */  { 0,  &BX_CPU_C::ADC_EdId },
+  /* 3 */  { 0,  &BX_CPU_C::SBB_EdId },
+  /* 4 */  { 0,  &BX_CPU_C::AND_EdId },
+  /* 5 */  { 0,  &BX_CPU_C::SUB_EdId },
+  /* 6 */  { 0,  &BX_CPU_C::XOR_EdId },
+  /* 7 */  { 0,  &BX_CPU_C::CMP_EdId }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Eb[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Eb },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Eb },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Eb },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Eb },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Eb },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Eb },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Eb },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Eb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ew[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Ew },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Ew },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Ew }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ed[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::ROL_Ed },
+  /* 1 */  { 0,  &BX_CPU_C::ROR_Ed },
+  /* 2 */  { 0,  &BX_CPU_C::RCL_Ed },
+  /* 3 */  { 0,  &BX_CPU_C::RCR_Ed },
+  /* 4 */  { 0,  &BX_CPU_C::SHL_Ed },
+  /* 5 */  { 0,  &BX_CPU_C::SHR_Ed },
+  /* 6 */  { 0,  &BX_CPU_C::SHL_Ed },
+  /* 7 */  { 0,  &BX_CPU_C::SAR_Ed }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Eb[8] = {
+  /* 0 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_EbIb },
+  /* 1 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_EbIb },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Eb },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Eb },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_ALEb },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_ALEb },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_ALEb },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_ALEb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ew[8] = {
+  /* 0 */  { BxImmediate_Iw,  &BX_CPU_C::TEST_EwIw },
+  /* 1 */  { BxImmediate_Iw,  &BX_CPU_C::TEST_EwIw },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Ew },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Ew },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_AXEw },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_AXEw },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_AXEw },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_AXEw }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ed[8] = {
+  /* 0 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EdId },
+  /* 1 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EdId },
+  /* 2 */  { 0,             &BX_CPU_C::NOT_Ed },
+  /* 3 */  { 0,             &BX_CPU_C::NEG_Ed },
+  /* 4 */  { 0,             &BX_CPU_C::MUL_EAXEd },
+  /* 5 */  { 0,             &BX_CPU_C::IMUL_EAXEd },
+  /* 6 */  { 0,             &BX_CPU_C::DIV_EAXEd },
+  /* 7 */  { 0,             &BX_CPU_C::IDIV_EAXEd }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG4[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::INC_Eb },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Eb },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { 0,  &BX_CPU_C::BxError },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG5w[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::INC_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::CALL_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::CALL16_Ep },
+  /* 4 */  { 0,  &BX_CPU_C::JMP_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::JMP16_Ep },
+  /* 6 */  { 0,  &BX_CPU_C::PUSH_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG5d[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::INC_Ed },
+  /* 1 */  { 0,  &BX_CPU_C::DEC_Ed },
+  /* 2 */  { 0,  &BX_CPU_C::CALL_Ed },
+  /* 3 */  { 0,  &BX_CPU_C::CALL32_Ep },
+  /* 4 */  { 0,  &BX_CPU_C::JMP_Ed },
+  /* 5 */  { 0,  &BX_CPU_C::JMP32_Ep },
+  /* 6 */  { 0,  &BX_CPU_C::PUSH_Ed },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
+  // attributes defined in main area
+  /* 0 */  { 0,  &BX_CPU_C::SLDT_Ew },
+  /* 1 */  { 0,  &BX_CPU_C::STR_Ew },
+  /* 2 */  { 0,  &BX_CPU_C::LLDT_Ew },
+  /* 3 */  { 0,  &BX_CPU_C::LTR_Ew },
+  /* 4 */  { 0,  &BX_CPU_C::VERR_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::VERW_Ew },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG7[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::SGDT_Ms },
+  /* 1 */  { 0,  &BX_CPU_C::SIDT_Ms },
+  /* 2 */  { 0,  &BX_CPU_C::LGDT_Ms },
+  /* 3 */  { 0,  &BX_CPU_C::LIDT_Ms },
+  /* 4 */  { 0,  &BX_CPU_C::SMSW_Ew },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::LMSW_Ew },
+  /* 7 */  { 0,  &BX_CPU_C::INVLPG }
+  }; 
+
+
+static BxOpcodeInfo_t BxOpcodeInfoG8EvIb[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::BxError },
+  /* 1 */  { 0,  &BX_CPU_C::BxError },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { BxImmediate_Ib,  &BX_CPU_C::BT_EvIb },
+  /* 5 */  { BxImmediate_Ib,  &BX_CPU_C::BTS_EvIb },
+  /* 6 */  { BxImmediate_Ib,  &BX_CPU_C::BTR_EvIb },
+  /* 7 */  { BxImmediate_Ib,  &BX_CPU_C::BTC_EvIb }
+  }; 
+
+static BxOpcodeInfo_t BxOpcodeInfoG9[8] = {
+  /* 0 */  { 0,  &BX_CPU_C::BxError },
+  /* 1 */  { 0,  &BX_CPU_C::CMPXCHG8B },
+  /* 2 */  { 0,  &BX_CPU_C::BxError },
+  /* 3 */  { 0,  &BX_CPU_C::BxError },
+  /* 4 */  { 0,  &BX_CPU_C::BxError },
+  /* 5 */  { 0,  &BX_CPU_C::BxError },
+  /* 6 */  { 0,  &BX_CPU_C::BxError },
+  /* 7 */  { 0,  &BX_CPU_C::BxError }
+  };
+
+
+// 512 entries for 16bit mode
+// 512 entries for 32bit mode
+
+static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
+  // 512 entries for 16bit mode
+  /* 00 */  { BxAnother,  &BX_CPU_C::ADD_EbGb },
+  /* 01 */  { BxAnother,  &BX_CPU_C::ADD_EwGw },
+  /* 02 */  { BxAnother,  &BX_CPU_C::ADD_GbEb },
+  /* 03 */  { BxAnother,  &BX_CPU_C::ADD_GwEw },
+  /* 04 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_ALIb },
+  /* 05 */  { BxImmediate_Iv,  &BX_CPU_C::ADD_AXIw },
+  /* 06 */  { 0,  &BX_CPU_C::PUSH_ES },
+  /* 07 */  { 0,  &BX_CPU_C::POP_ES },
+  /* 08 */  { BxAnother,  &BX_CPU_C::OR_EbGb },
+  /* 09 */  { BxAnother,  &BX_CPU_C::OR_EwGw },
+  /* 0A */  { BxAnother,  &BX_CPU_C::OR_GbEb },
+  /* 0B */  { BxAnother,  &BX_CPU_C::OR_GwEw },
+  /* 0C */  { BxImmediate_Ib,  &BX_CPU_C::OR_ALIb },
+  /* 0D */  { BxImmediate_Iv,  &BX_CPU_C::OR_AXIw },
+  /* 0E */  { 0,  &BX_CPU_C::PUSH_CS },
+  /* 0F */  { BxAnother,  &BX_CPU_C::BxError }, // 2-byte escape
+  /* 10 */  { BxAnother,  &BX_CPU_C::ADC_EbGb },
+  /* 11 */  { BxAnother,  &BX_CPU_C::ADC_EwGw },
+  /* 12 */  { BxAnother,  &BX_CPU_C::ADC_GbEb },
+  /* 13 */  { BxAnother,  &BX_CPU_C::ADC_GwEw },
+  /* 14 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_ALIb },
+  /* 15 */  { BxImmediate_Iv,  &BX_CPU_C::ADC_AXIw },
+  /* 16 */  { 0,  &BX_CPU_C::PUSH_SS },
+  /* 17 */  { 0,  &BX_CPU_C::POP_SS },
+  /* 18 */  { BxAnother,  &BX_CPU_C::SBB_EbGb },
+  /* 19 */  { BxAnother,  &BX_CPU_C::SBB_EwGw },
+  /* 1A */  { BxAnother,  &BX_CPU_C::SBB_GbEb },
+  /* 1B */  { BxAnother,  &BX_CPU_C::SBB_GwEw },
+  /* 1C */  { BxImmediate_Ib,  &BX_CPU_C::SBB_ALIb },
+  /* 1D */  { BxImmediate_Iv,  &BX_CPU_C::SBB_AXIw },
+  /* 1E */  { 0,  &BX_CPU_C::PUSH_DS },
+  /* 1F */  { 0,  &BX_CPU_C::POP_DS },
+  /* 20 */  { BxAnother,  &BX_CPU_C::AND_EbGb },
+  /* 21 */  { BxAnother,  &BX_CPU_C::AND_EwGw },
+  /* 22 */  { BxAnother,  &BX_CPU_C::AND_GbEb },
+  /* 23 */  { BxAnother,  &BX_CPU_C::AND_GwEw },
+  /* 24 */  { BxImmediate_Ib,  &BX_CPU_C::AND_ALIb },
+  /* 25 */  { BxImmediate_Iv,  &BX_CPU_C::AND_AXIw },
+  /* 26 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // ES:
+  /* 27 */  { 0,  &BX_CPU_C::DAA },
+  /* 28 */  { BxAnother,  &BX_CPU_C::SUB_EbGb },
+  /* 29 */  { BxAnother,  &BX_CPU_C::SUB_EwGw },
+  /* 2A */  { BxAnother,  &BX_CPU_C::SUB_GbEb },
+  /* 2B */  { BxAnother,  &BX_CPU_C::SUB_GwEw },
+  /* 2C */  { BxImmediate_Ib,  &BX_CPU_C::SUB_ALIb },
+  /* 2D */  { BxImmediate_Iv,  &BX_CPU_C::SUB_AXIw },
+  /* 2E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // CS:
+  /* 2F */  { 0,  &BX_CPU_C::DAS },
+  /* 30 */  { BxAnother,  &BX_CPU_C::XOR_EbGb },
+  /* 31 */  { BxAnother,  &BX_CPU_C::XOR_EwGw },
+  /* 32 */  { BxAnother,  &BX_CPU_C::XOR_GbEb },
+  /* 33 */  { BxAnother,  &BX_CPU_C::XOR_GwEw },
+  /* 34 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_ALIb },
+  /* 35 */  { BxImmediate_Iv,  &BX_CPU_C::XOR_AXIw },
+  /* 36 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // SS:
+  /* 37 */  { 0,  &BX_CPU_C::AAA },
+  /* 38 */  { BxAnother,  &BX_CPU_C::CMP_EbGb },
+  /* 39 */  { BxAnother,  &BX_CPU_C::CMP_EwGw },
+  /* 3A */  { BxAnother,  &BX_CPU_C::CMP_GbEb },
+  /* 3B */  { BxAnother,  &BX_CPU_C::CMP_GwEw },
+  /* 3C */  { BxImmediate_Ib,  &BX_CPU_C::CMP_ALIb },
+  /* 3D */  { BxImmediate_Iv,  &BX_CPU_C::CMP_AXIw },
+  /* 3E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // DS:
+  /* 3F */  { 0,  &BX_CPU_C::AAS },
+  /* 40 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 41 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 42 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 43 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 44 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 45 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 46 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 47 */  { 0,  &BX_CPU_C::INC_RX },
+  /* 48 */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 49 */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4A */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4B */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4C */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4D */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4E */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 4F */  { 0,  &BX_CPU_C::DEC_RX },
+  /* 50 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 51 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 52 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 53 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 54 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 55 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 56 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 57 */  { 0,  &BX_CPU_C::PUSH_RX },
+  /* 58 */  { 0,  &BX_CPU_C::POP_RX },
+  /* 59 */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5A */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5B */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5C */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5D */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5E */  { 0,  &BX_CPU_C::POP_RX },
+  /* 5F */  { 0,  &BX_CPU_C::POP_RX },
+  /* 60 */  { 0,  &BX_CPU_C::PUSHAD16 },
+  /* 61 */  { 0,  &BX_CPU_C::POPAD16 },
+  /* 62 */  { BxAnother,  &BX_CPU_C::BOUND_GvMa },
+  /* 63 */  { BxAnother,  &BX_CPU_C::ARPL_EwGw },
+  /* 64 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // FS:
+  /* 65 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // GS:
+  /* 66 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // OS:
+  /* 67 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // AS:
+  /* 68 */  { BxImmediate_Iv,  &BX_CPU_C::PUSH_Iw },
+  /* 69 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::IMUL_GwEwIw },
+  /* 6A */  { BxImmediate_Ib_SE,  &BX_CPU_C::PUSH_Iw },
+  /* 6B */  { BxAnother | BxImmediate_Ib_SE,  &BX_CPU_C::IMUL_GwEwIw },
+  /* 6C */  { BxRepeatable,  &BX_CPU_C::INSB_YbDX },
+  /* 6D */  { BxRepeatable,  &BX_CPU_C::INSW_YvDX },
+  /* 6E */  { BxRepeatable,  &BX_CPU_C::OUTSB_DXXb },
+  /* 6F */  { BxRepeatable,  &BX_CPU_C::OUTSW_DXXv },
+  /* 70 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 71 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 72 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 73 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 74 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 75 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 76 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 77 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 78 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 79 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7A */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7B */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7C */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7D */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7E */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 7F */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jw },
+  /* 80 */  { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+  /* 81 */  { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ew },
+  /* 82 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 83 */  { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ew },
+  /* 84 */  { BxAnother,  &BX_CPU_C::TEST_EbGb },
+  /* 85 */  { BxAnother,  &BX_CPU_C::TEST_EwGw },
+  /* 86 */  { BxAnother,  &BX_CPU_C::XCHG_EbGb },
+  /* 87 */  { BxAnother,  &BX_CPU_C::XCHG_EwGw },
+  /* 88 */  { BxAnother,  &BX_CPU_C::MOV_EbGb },
+  /* 89 */  { BxAnother,  &BX_CPU_C::MOV_EwGw },
+  /* 8A */  { BxAnother,  &BX_CPU_C::MOV_GbEb },
+  /* 8B */  { BxAnother,  &BX_CPU_C::MOV_GwEw },
+  /* 8C */  { BxAnother,  &BX_CPU_C::MOV_EwSw },
+  /* 8D */  { BxAnother,  &BX_CPU_C::LEA_GwM },
+  /* 8E */  { BxAnother,  &BX_CPU_C::MOV_SwEw },
+  /* 8F */  { BxAnother,  &BX_CPU_C::POP_Ew },
+  /* 90 */  { 0,  &BX_CPU_C::NOP },
+  /* 91 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 92 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 93 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 94 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 95 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 96 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 97 */  { 0,  &BX_CPU_C::XCHG_RXAX },
+  /* 98 */  { 0,  &BX_CPU_C::CBW },
+  /* 99 */  { 0,  &BX_CPU_C::CWD },
+  /* 9A */  { BxImmediate_IvIw,  &BX_CPU_C::CALL16_Ap },
+  /* 9B */  { 0,  &BX_CPU_C::FWAIT },
+  /* 9C */  { 0,  &BX_CPU_C::PUSHF_Fv },
+  /* 9D */  { 0,  &BX_CPU_C::POPF_Fv },
+  /* 9E */  { 0,  &BX_CPU_C::SAHF },
+  /* 9F */  { 0,  &BX_CPU_C::LAHF },
+  /* A0 */  { BxImmediate_O,  &BX_CPU_C::MOV_ALOb },
+  /* A1 */  { BxImmediate_O,  &BX_CPU_C::MOV_AXOw },
+  /* A2 */  { BxImmediate_O,  &BX_CPU_C::MOV_ObAL },
+  /* A3 */  { BxImmediate_O,  &BX_CPU_C::MOV_OwAX },
+  /* A4 */  { BxRepeatable,  &BX_CPU_C::MOVSB_XbYb },
+  /* A5 */  { BxRepeatable,  &BX_CPU_C::MOVSW_XvYv },
+  /* A6 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSB_XbYb },
+  /* A7 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSW_XvYv },
+  /* A8 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_ALIb },
+  /* A9 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_AXIw },
+  /* AA */  { BxRepeatable,  &BX_CPU_C::STOSB_YbAL },
+  /* AB */  { BxRepeatable,  &BX_CPU_C::STOSW_YveAX },
+  /* AC */  { BxRepeatable,  &BX_CPU_C::LODSB_ALXb },
+  /* AD */  { BxRepeatable,  &BX_CPU_C::LODSW_eAXXv },
+  /* AE */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASB_ALXb },
+  /* AF */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASW_eAXXv },
+  /* B0 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B1 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B2 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B3 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B4 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B5 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B6 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B7 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B8 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* B9 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BA */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BB */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BC */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BD */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BE */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* BF */  { BxImmediate_Iv,  &BX_CPU_C::MOV_RXIw },
+  /* C0 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+  /* C1 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ew },
+  /* C2 */  { BxImmediate_Iw,  &BX_CPU_C::RETnear16_Iw },
+  /* C3 */  { 0,             &BX_CPU_C::RETnear16 },
+  /* C4 */  { BxAnother,  &BX_CPU_C::LES_GvMp },
+  /* C5 */  { BxAnother,  &BX_CPU_C::LDS_GvMp },
+  /* C6 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::MOV_EbIb },
+  /* C7 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::MOV_EwIw },
+  /* C8 */  { BxImmediate_IwIb,  &BX_CPU_C::ENTER_IwIb },
+  /* C9 */  { 0,  &BX_CPU_C::LEAVE },
+  /* CA */  { BxImmediate_Iw,  &BX_CPU_C::RETfar16_Iw },
+  /* CB */  { 0,  &BX_CPU_C::RETfar16 },
+  /* CC */  { 0,  &BX_CPU_C::INT3 },
+  /* CD */  { BxImmediate_Ib,  &BX_CPU_C::INT_Ib },
+  /* CE */  { 0,  &BX_CPU_C::INTO },
+  /* CF */  { 0,  &BX_CPU_C::IRET16 },
+  /* D0 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D1 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ew },
+  /* D2 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D3 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ew },
+  /* D4 */  { BxImmediate_Ib,  &BX_CPU_C::AAM },
+  /* D5 */  { BxImmediate_Ib,  &BX_CPU_C::AAD },
+  /* D6 */  { 0,  &BX_CPU_C::SALC },
+  /* D7 */  { 0,  &BX_CPU_C::XLAT },
+  /* D8 */  { BxAnother,  &BX_CPU_C::ESC0 },
+  /* D9 */  { BxAnother,  &BX_CPU_C::ESC1 },
+  /* DA */  { BxAnother,  &BX_CPU_C::ESC2 },
+  /* DB */  { BxAnother,  &BX_CPU_C::ESC3 },
+  /* DC */  { BxAnother,  &BX_CPU_C::ESC4 },
+  /* DD */  { BxAnother,  &BX_CPU_C::ESC5 },
+  /* DE */  { BxAnother,  &BX_CPU_C::ESC6 },
+  /* DF */  { BxAnother,  &BX_CPU_C::ESC7 },
+  /* E0 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPNE_Jb },
+  /* E1 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPE_Jb },
+  /* E2 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOP_Jb },
+  /* E3 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCXZ_Jb },
+  /* E4 */  { BxImmediate_Ib,  &BX_CPU_C::IN_ALIb },
+  /* E5 */  { BxImmediate_Ib,  &BX_CPU_C::IN_eAXIb },
+  /* E6 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbAL },
+  /* E7 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbeAX },
+  /* E8 */  { BxImmediate_BrOff16,  &BX_CPU_C::CALL_Aw },
+  /* E9 */  { BxImmediate_BrOff16,  &BX_CPU_C::JMP_Jw },
+  /* EA */  { BxImmediate_IvIw,  &BX_CPU_C::JMP_Ap },
+  /* EB */  { BxImmediate_BrOff8,  &BX_CPU_C::JMP_Jw },
+  /* EC */  { 0,  &BX_CPU_C::IN_ALDX },
+  /* ED */  { 0,  &BX_CPU_C::IN_eAXDX },
+  /* EE */  { 0,  &BX_CPU_C::OUT_DXAL },
+  /* EF */  { 0,  &BX_CPU_C::OUT_DXeAX },
+  /* F0 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // LOCK
+  /* F1 */  { 0,  &BX_CPU_C::INT1 },
+  /* F2 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REPNE/REPNZ
+  /* F3 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REP, REPE/REPZ
+  /* F4 */  { 0,  &BX_CPU_C::HLT },
+  /* F5 */  { 0,  &BX_CPU_C::CMC },
+  /* F6 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Eb },
+  /* F7 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Ew },
+  /* F8 */  { 0,  &BX_CPU_C::CLC },
+  /* F9 */  { 0,  &BX_CPU_C::STC },
+  /* FA */  { 0,  &BX_CPU_C::CLI },
+  /* FB */  { 0,  &BX_CPU_C::STI },
+  /* FC */  { 0,  &BX_CPU_C::CLD },
+  /* FD */  { 0,  &BX_CPU_C::STD },
+  /* FE */  { BxAnother | BxGroup4,  NULL, BxOpcodeInfoG4 },
+  /* FF */  { BxAnother | BxGroup5,  NULL, BxOpcodeInfoG5w },
+
+  /* 0F 00 */  { BxAnother | BxGroup6,  NULL, BxOpcodeInfoG6 },
+  /* 0F 01 */  { BxAnother | BxGroup7,  NULL, BxOpcodeInfoG7 },
+  /* 0F 02 */  { BxAnother,  &BX_CPU_C::LAR_GvEw },
+  /* 0F 03 */  { BxAnother,  &BX_CPU_C::LSL_GvEw },
+  /* 0F 04 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 05 */  { 0,  &BX_CPU_C::LOADALL },
+  /* 0F 06 */  { 0,  &BX_CPU_C::CLTS },
+  /* 0F 07 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 08 */  { 0,  &BX_CPU_C::INVD },
+  /* 0F 09 */  { 0,  &BX_CPU_C::WBINVD },
+  /* 0F 0A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 10 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 11 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 12 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 13 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 14 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 15 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 16 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 17 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 18 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 19 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 20 */  { BxAnother,  &BX_CPU_C::MOV_RdCd },
+  /* 0F 21 */  { BxAnother,  &BX_CPU_C::MOV_RdDd },
+  /* 0F 22 */  { BxAnother,  &BX_CPU_C::MOV_CdRd },
+  /* 0F 23 */  { BxAnother,  &BX_CPU_C::MOV_DdRd },
+  /* 0F 24 */  { BxAnother,  &BX_CPU_C::MOV_RdTd },
+  /* 0F 25 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 26 */  { BxAnother,  &BX_CPU_C::MOV_TdRd },
+  /* 0F 27 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 28 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 29 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 30 */  { 0,  &BX_CPU_C::WRMSR },
+  /* 0F 31 */  { 0,  &BX_CPU_C::RDTSC },
+  /* 0F 32 */  { 0,  &BX_CPU_C::RDMSR },
+  /* 0F 33 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 34 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 35 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 36 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 37 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 38 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 39 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 40 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 41 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 42 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 43 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 44 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 45 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 46 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 47 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 48 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 49 */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4A */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4B */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4C */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4D */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4E */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 4F */  { BxAnother,  &BX_CPU_C::CMOV_GwEw },
+  /* 0F 50 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 51 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 52 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 53 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 54 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 55 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 56 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 57 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 58 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 59 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 60 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 61 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 62 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 63 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 64 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 65 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 66 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 67 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 68 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 69 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 70 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 71 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 72 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 73 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 74 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 75 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 76 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 77 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 78 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 79 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 80 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 81 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 82 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 83 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 84 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 85 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 86 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 87 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 88 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 89 */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8A */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8B */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8C */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8D */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8E */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 8F */  { BxImmediate_BrOff16,  &BX_CPU_C::JCC_Jw },
+  /* 0F 90 */  { BxAnother,  &BX_CPU_C::SETO_Eb },
+  /* 0F 91 */  { BxAnother,  &BX_CPU_C::SETNO_Eb },
+  /* 0F 92 */  { BxAnother,  &BX_CPU_C::SETB_Eb },
+  /* 0F 93 */  { BxAnother,  &BX_CPU_C::SETNB_Eb },
+  /* 0F 94 */  { BxAnother,  &BX_CPU_C::SETZ_Eb },
+  /* 0F 95 */  { BxAnother,  &BX_CPU_C::SETNZ_Eb },
+  /* 0F 96 */  { BxAnother,  &BX_CPU_C::SETBE_Eb },
+  /* 0F 97 */  { BxAnother,  &BX_CPU_C::SETNBE_Eb },
+  /* 0F 98 */  { BxAnother,  &BX_CPU_C::SETS_Eb },
+  /* 0F 99 */  { BxAnother,  &BX_CPU_C::SETNS_Eb },
+  /* 0F 9A */  { BxAnother,  &BX_CPU_C::SETP_Eb },
+  /* 0F 9B */  { BxAnother,  &BX_CPU_C::SETNP_Eb },
+  /* 0F 9C */  { BxAnother,  &BX_CPU_C::SETL_Eb },
+  /* 0F 9D */  { BxAnother,  &BX_CPU_C::SETNL_Eb },
+  /* 0F 9E */  { BxAnother,  &BX_CPU_C::SETLE_Eb },
+  /* 0F 9F */  { BxAnother,  &BX_CPU_C::SETNLE_Eb },
+  /* 0F A0 */  { 0,  &BX_CPU_C::PUSH_FS },
+  /* 0F A1 */  { 0,  &BX_CPU_C::POP_FS },
+  /* 0F A2 */  { 0,  &BX_CPU_C::CPUID },
+  /* 0F A3 */  { BxAnother,  &BX_CPU_C::BT_EvGv },
+  /* 0F A4 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHLD_EwGw },
+  /* 0F A5 */  { BxAnother,                 &BX_CPU_C::SHLD_EwGw },
+  /* 0F A6 */  { 0,  &BX_CPU_C::CMPXCHG_XBTS },
+  /* 0F A7 */  { 0,  &BX_CPU_C::CMPXCHG_IBTS },
+  /* 0F A8 */  { 0,  &BX_CPU_C::PUSH_GS },
+  /* 0F A9 */  { 0,  &BX_CPU_C::POP_GS },
+  /* 0F AA */  { 0,  &BX_CPU_C::RSM },
+  /* 0F AB */  { BxAnother,  &BX_CPU_C::BTS_EvGv },
+  /* 0F AC */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHRD_EwGw },
+  /* 0F AD */  { BxAnother,                 &BX_CPU_C::SHRD_EwGw },
+  /* 0F AE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F AF */  { BxAnother,  &BX_CPU_C::IMUL_GwEw },
+  /* 0F B0 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EbGb },
+  /* 0F B1 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EwGw },
+  /* 0F B2 */  { BxAnother,  &BX_CPU_C::LSS_GvMp },
+  /* 0F B3 */  { BxAnother,  &BX_CPU_C::BTR_EvGv },
+  /* 0F B4 */  { BxAnother,  &BX_CPU_C::LFS_GvMp },
+  /* 0F B5 */  { BxAnother,  &BX_CPU_C::LGS_GvMp },
+  /* 0F B6 */  { BxAnother,  &BX_CPU_C::MOVZX_GwEb },
+  /* 0F B7 */  { BxAnother,  &BX_CPU_C::MOVZX_GwEw },
+  /* 0F B8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F B9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F BA */  { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+  /* 0F BB */  { BxAnother,  &BX_CPU_C::BTC_EvGv },
+  /* 0F BC */  { BxAnother,  &BX_CPU_C::BSF_GvEv },
+  /* 0F BD */  { BxAnother,  &BX_CPU_C::BSR_GvEv },
+  /* 0F BE */  { BxAnother,  &BX_CPU_C::MOVSX_GwEb },
+  /* 0F BF */  { BxAnother,  &BX_CPU_C::MOVSX_GwEw },
+  /* 0F C0 */  { BxAnother,  &BX_CPU_C::XADD_EbGb },
+  /* 0F C1 */  { BxAnother,  &BX_CPU_C::XADD_EwGw },
+  /* 0F C2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C7 */  { BxAnother | BxGroup9,  NULL, BxOpcodeInfoG9 },
+  /* 0F C8 */  { 0,  &BX_CPU_C::BSWAP_EAX },
+  /* 0F C9 */  { 0,  &BX_CPU_C::BSWAP_ECX },
+  /* 0F CA */  { 0,  &BX_CPU_C::BSWAP_EDX },
+  /* 0F CB */  { 0,  &BX_CPU_C::BSWAP_EBX },
+  /* 0F CC */  { 0,  &BX_CPU_C::BSWAP_ESP },
+  /* 0F CD */  { 0,  &BX_CPU_C::BSWAP_EBP },
+  /* 0F CE */  { 0,  &BX_CPU_C::BSWAP_ESI },
+  /* 0F CF */  { 0,  &BX_CPU_C::BSWAP_EDI },
+  /* 0F D0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DD */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F ED */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F F0 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F1 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F2 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F3 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F4 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F5 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F6 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F7 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F8 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F9 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FA */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FB */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FC */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FD */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FE */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FF */  { 0,  &BX_CPU_C::UndefinedOpcode },
+
+  // 512 entries for 32bit mod
+  /* 00 */  { BxAnother,  &BX_CPU_C::ADD_EbGb },
+  /* 01 */  { BxAnother,  &BX_CPU_C::ADD_EdGd },
+  /* 02 */  { BxAnother,  &BX_CPU_C::ADD_GbEb },
+  /* 03 */  { BxAnother,  &BX_CPU_C::ADD_GdEd },
+  /* 04 */  { BxImmediate_Ib,  &BX_CPU_C::ADD_ALIb },
+  /* 05 */  { BxImmediate_Iv,  &BX_CPU_C::ADD_EAXId },
+  /* 06 */  { 0,  &BX_CPU_C::PUSH_ES },
+  /* 07 */  { 0,  &BX_CPU_C::POP_ES },
+  /* 08 */  { BxAnother,  &BX_CPU_C::OR_EbGb },
+  /* 09 */  { BxAnother,  &BX_CPU_C::OR_EdGd },
+  /* 0A */  { BxAnother,  &BX_CPU_C::OR_GbEb },
+  /* 0B */  { BxAnother,  &BX_CPU_C::OR_GdEd },
+  /* 0C */  { BxImmediate_Ib,  &BX_CPU_C::OR_ALIb },
+  /* 0D */  { BxImmediate_Iv,  &BX_CPU_C::OR_EAXId },
+  /* 0E */  { 0,  &BX_CPU_C::PUSH_CS },
+  /* 0F */  { BxAnother,  &BX_CPU_C::BxError }, // 2-byte escape
+  /* 10 */  { BxAnother,  &BX_CPU_C::ADC_EbGb },
+  /* 11 */  { BxAnother,  &BX_CPU_C::ADC_EdGd },
+  /* 12 */  { BxAnother,  &BX_CPU_C::ADC_GbEb },
+  /* 13 */  { BxAnother,  &BX_CPU_C::ADC_GdEd },
+  /* 14 */  { BxImmediate_Ib,  &BX_CPU_C::ADC_ALIb },
+  /* 15 */  { BxImmediate_Iv,  &BX_CPU_C::ADC_EAXId },
+  /* 16 */  { 0,  &BX_CPU_C::PUSH_SS },
+  /* 17 */  { 0,  &BX_CPU_C::POP_SS },
+  /* 18 */  { BxAnother,  &BX_CPU_C::SBB_EbGb },
+  /* 19 */  { BxAnother,  &BX_CPU_C::SBB_EdGd },
+  /* 1A */  { BxAnother,  &BX_CPU_C::SBB_GbEb },
+  /* 1B */  { BxAnother,  &BX_CPU_C::SBB_GdEd },
+  /* 1C */  { BxImmediate_Ib,  &BX_CPU_C::SBB_ALIb },
+  /* 1D */  { BxImmediate_Iv,  &BX_CPU_C::SBB_EAXId },
+  /* 1E */  { 0,  &BX_CPU_C::PUSH_DS },
+  /* 1F */  { 0,  &BX_CPU_C::POP_DS },
+  /* 20 */  { BxAnother,  &BX_CPU_C::AND_EbGb },
+  /* 21 */  { BxAnother,  &BX_CPU_C::AND_EdGd },
+  /* 22 */  { BxAnother,  &BX_CPU_C::AND_GbEb },
+  /* 23 */  { BxAnother,  &BX_CPU_C::AND_GdEd },
+  /* 24 */  { BxImmediate_Ib,  &BX_CPU_C::AND_ALIb },
+  /* 25 */  { BxImmediate_Iv,  &BX_CPU_C::AND_EAXId },
+  /* 26 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // ES:
+  /* 27 */  { 0,  &BX_CPU_C::DAA },
+  /* 28 */  { BxAnother,  &BX_CPU_C::SUB_EbGb },
+  /* 29 */  { BxAnother,  &BX_CPU_C::SUB_EdGd },
+  /* 2A */  { BxAnother,  &BX_CPU_C::SUB_GbEb },
+  /* 2B */  { BxAnother,  &BX_CPU_C::SUB_GdEd },
+  /* 2C */  { BxImmediate_Ib,  &BX_CPU_C::SUB_ALIb },
+  /* 2D */  { BxImmediate_Iv,  &BX_CPU_C::SUB_EAXId },
+  /* 2E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // CS:
+  /* 2F */  { 0,  &BX_CPU_C::DAS },
+  /* 30 */  { BxAnother,  &BX_CPU_C::XOR_EbGb },
+  /* 31 */  { BxAnother,  &BX_CPU_C::XOR_EdGd },
+  /* 32 */  { BxAnother,  &BX_CPU_C::XOR_GbEb },
+  /* 33 */  { BxAnother,  &BX_CPU_C::XOR_GdEd },
+  /* 34 */  { BxImmediate_Ib,  &BX_CPU_C::XOR_ALIb },
+  /* 35 */  { BxImmediate_Iv,  &BX_CPU_C::XOR_EAXId },
+  /* 36 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // SS:
+  /* 37 */  { 0,  &BX_CPU_C::AAA },
+  /* 38 */  { BxAnother,  &BX_CPU_C::CMP_EbGb },
+  /* 39 */  { BxAnother,  &BX_CPU_C::CMP_EdGd },
+  /* 3A */  { BxAnother,  &BX_CPU_C::CMP_GbEb },
+  /* 3B */  { BxAnother,  &BX_CPU_C::CMP_GdEd },
+  /* 3C */  { BxImmediate_Ib,  &BX_CPU_C::CMP_ALIb },
+  /* 3D */  { BxImmediate_Iv,  &BX_CPU_C::CMP_EAXId },
+  /* 3E */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // DS:
+  /* 3F */  { 0,  &BX_CPU_C::AAS },
+  /* 40 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 41 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 42 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 43 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 44 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 45 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 46 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 47 */  { 0,  &BX_CPU_C::INC_ERX },
+  /* 48 */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 49 */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4A */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4B */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4C */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4D */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4E */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 4F */  { 0,  &BX_CPU_C::DEC_ERX },
+  /* 50 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 51 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 52 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 53 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 54 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 55 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 56 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 57 */  { 0,  &BX_CPU_C::PUSH_ERX },
+  /* 58 */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 59 */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5A */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5B */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5C */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5D */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5E */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 5F */  { 0,  &BX_CPU_C::POP_ERX },
+  /* 60 */  { 0,  &BX_CPU_C::PUSHAD32 },
+  /* 61 */  { 0,  &BX_CPU_C::POPAD32 },
+  /* 62 */  { BxAnother,  &BX_CPU_C::BOUND_GvMa },
+  /* 63 */  { BxAnother,  &BX_CPU_C::ARPL_EwGw },
+  /* 64 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // FS:
+  /* 65 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // GS:
+  /* 66 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // OS:
+  /* 67 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // AS:
+  /* 68 */  { BxImmediate_Iv,  &BX_CPU_C::PUSH_Id },
+  /* 69 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::IMUL_GdEdId },
+  /* 6A */  { BxImmediate_Ib_SE,  &BX_CPU_C::PUSH_Id },
+  /* 6B */  { BxAnother | BxImmediate_Ib_SE,  &BX_CPU_C::IMUL_GdEdId },
+  /* 6C */  { BxRepeatable,  &BX_CPU_C::INSB_YbDX },
+  /* 6D */  { BxRepeatable,  &BX_CPU_C::INSW_YvDX },
+  /* 6E */  { BxRepeatable,  &BX_CPU_C::OUTSB_DXXb },
+  /* 6F */  { BxRepeatable,  &BX_CPU_C::OUTSW_DXXv },
+  /* 70 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 71 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 72 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 73 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 74 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 75 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 76 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 77 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 78 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 79 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7A */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7B */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7C */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7D */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7E */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 7F */  { BxImmediate_BrOff8,  &BX_CPU_C::JCC_Jd },
+  /* 80 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 81 */  { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ed },
+  /* 82 */  { BxAnother | BxGroup1,  NULL, BxOpcodeInfoG1EbIb },
+  /* 83 */  { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ed },
+  /* 84 */  { BxAnother,  &BX_CPU_C::TEST_EbGb },
+  /* 85 */  { BxAnother,  &BX_CPU_C::TEST_EdGd },
+  /* 86 */  { BxAnother,  &BX_CPU_C::XCHG_EbGb },
+  /* 87 */  { BxAnother,  &BX_CPU_C::XCHG_EdGd },
+  /* 88 */  { BxAnother,  &BX_CPU_C::MOV_EbGb },
+  /* 89 */  { BxAnother,  &BX_CPU_C::MOV_EdGd },
+  /* 8A */  { BxAnother,  &BX_CPU_C::MOV_GbEb },
+  /* 8B */  { BxAnother,  &BX_CPU_C::MOV_GdEd },
+  /* 8C */  { BxAnother,  &BX_CPU_C::MOV_EwSw },
+  /* 8D */  { BxAnother,  &BX_CPU_C::LEA_GdM },
+  /* 8E */  { BxAnother,  &BX_CPU_C::MOV_SwEw },
+  /* 8F */  { BxAnother,  &BX_CPU_C::POP_Ed },
+  /* 90 */  { 0,  &BX_CPU_C::NOP },
+  /* 91 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 92 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 93 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 94 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 95 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 96 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 97 */  { 0,  &BX_CPU_C::XCHG_ERXEAX },
+  /* 98 */  { 0,  &BX_CPU_C::CWDE },
+  /* 99 */  { 0,  &BX_CPU_C::CDQ },
+  /* 9A */  { BxImmediate_IvIw,  &BX_CPU_C::CALL32_Ap },
+  /* 9B */  { 0,  &BX_CPU_C::FWAIT },
+  /* 9C */  { 0,  &BX_CPU_C::PUSHF_Fv },
+  /* 9D */  { 0,  &BX_CPU_C::POPF_Fv },
+  /* 9E */  { 0,  &BX_CPU_C::SAHF },
+  /* 9F */  { 0,  &BX_CPU_C::LAHF },
+  /* A0 */  { BxImmediate_O,  &BX_CPU_C::MOV_ALOb },
+  /* A1 */  { BxImmediate_O,  &BX_CPU_C::MOV_EAXOd },
+  /* A2 */  { BxImmediate_O,  &BX_CPU_C::MOV_ObAL },
+  /* A3 */  { BxImmediate_O,  &BX_CPU_C::MOV_OdEAX },
+  /* A4 */  { BxRepeatable,  &BX_CPU_C::MOVSB_XbYb },
+  /* A5 */  { BxRepeatable,  &BX_CPU_C::MOVSW_XvYv },
+  /* A6 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSB_XbYb },
+  /* A7 */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::CMPSW_XvYv },
+  /* A8 */  { BxImmediate_Ib,  &BX_CPU_C::TEST_ALIb },
+  /* A9 */  { BxImmediate_Iv,  &BX_CPU_C::TEST_EAXId },
+  /* AA */  { BxRepeatable,  &BX_CPU_C::STOSB_YbAL },
+  /* AB */  { BxRepeatable,  &BX_CPU_C::STOSW_YveAX },
+  /* AC */  { BxRepeatable,  &BX_CPU_C::LODSB_ALXb },
+  /* AD */  { BxRepeatable,  &BX_CPU_C::LODSW_eAXXv },
+  /* AE */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASB_ALXb },
+  /* AF */  { BxRepeatable | BxRepeatableZF,  &BX_CPU_C::SCASW_eAXXv },
+  /* B0 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B1 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B2 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B3 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RLIb },
+  /* B4 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B5 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B6 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B7 */  { BxImmediate_Ib,  &BX_CPU_C::MOV_RHIb },
+  /* B8 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* B9 */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BA */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BB */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BC */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BD */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BE */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* BF */  { BxImmediate_Iv,  &BX_CPU_C::MOV_ERXId },
+  /* C0 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+  /* C1 */  { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ed },
+  /* C2 */  { BxImmediate_Iw,  &BX_CPU_C::RETnear32_Iw },
+  /* C3 */  { 0,             &BX_CPU_C::RETnear32 },
+  /* C4 */  { BxAnother,  &BX_CPU_C::LES_GvMp },
+  /* C5 */  { BxAnother,  &BX_CPU_C::LDS_GvMp },
+  /* C6 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::MOV_EbIb },
+  /* C7 */  { BxAnother | BxImmediate_Iv,  &BX_CPU_C::MOV_EdId },
+  /* C8 */  { BxImmediate_IwIb,  &BX_CPU_C::ENTER_IwIb },
+  /* C9 */  { 0,  &BX_CPU_C::LEAVE },
+  /* CA */  { BxImmediate_Iw,  &BX_CPU_C::RETfar32_Iw },
+  /* CB */  { 0,  &BX_CPU_C::RETfar32 },
+  /* CC */  { 0,  &BX_CPU_C::INT3 },
+  /* CD */  { BxImmediate_Ib,  &BX_CPU_C::INT_Ib },
+  /* CE */  { 0,  &BX_CPU_C::INTO },
+  /* CF */  { 0,  &BX_CPU_C::IRET32 },
+  /* D0 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D1 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ed },
+  /* D2 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Eb },
+  /* D3 */  { BxAnother | BxGroup2,  NULL, BxOpcodeInfoG2Ed },
+  /* D4 */  { BxImmediate_Ib,  &BX_CPU_C::AAM },
+  /* D5 */  { BxImmediate_Ib,  &BX_CPU_C::AAD },
+  /* D6 */  { 0,  &BX_CPU_C::SALC },
+  /* D7 */  { 0,  &BX_CPU_C::XLAT },
+  /* D8 */  { BxAnother,  &BX_CPU_C::ESC0 },
+  /* D9 */  { BxAnother,  &BX_CPU_C::ESC1 },
+  /* DA */  { BxAnother,  &BX_CPU_C::ESC2 },
+  /* DB */  { BxAnother,  &BX_CPU_C::ESC3 },
+  /* DC */  { BxAnother,  &BX_CPU_C::ESC4 },
+  /* DD */  { BxAnother,  &BX_CPU_C::ESC5 },
+  /* DE */  { BxAnother,  &BX_CPU_C::ESC6 },
+  /* DF */  { BxAnother,  &BX_CPU_C::ESC7 },
+  /* E0 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPNE_Jb },
+  /* E1 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOPE_Jb },
+  /* E2 */  { BxImmediate_BrOff8,  &BX_CPU_C::LOOP_Jb },
+  /* E3 */  { BxImmediate_BrOff8,  &BX_CPU_C::JCXZ_Jb },
+  /* E4 */  { BxImmediate_Ib,  &BX_CPU_C::IN_ALIb },
+  /* E5 */  { BxImmediate_Ib,  &BX_CPU_C::IN_eAXIb },
+  /* E6 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbAL },
+  /* E7 */  { BxImmediate_Ib,  &BX_CPU_C::OUT_IbeAX },
+  /* E8 */  { BxImmediate_BrOff32,  &BX_CPU_C::CALL_Ad },
+  /* E9 */  { BxImmediate_BrOff32,  &BX_CPU_C::JMP_Jd },
+  /* EA */  { BxImmediate_IvIw,  &BX_CPU_C::JMP_Ap },
+  /* EB */  { BxImmediate_BrOff8,  &BX_CPU_C::JMP_Jd },
+  /* EC */  { 0,  &BX_CPU_C::IN_ALDX },
+  /* ED */  { 0,  &BX_CPU_C::IN_eAXDX },
+  /* EE */  { 0,  &BX_CPU_C::OUT_DXAL },
+  /* EF */  { 0,  &BX_CPU_C::OUT_DXeAX },
+  /* F0 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // LOCK:
+  /* F1 */  { 0,  &BX_CPU_C::INT1 },
+  /* F2 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REPNE/REPNZ
+  /* F3 */  { BxPrefix | BxAnother,  &BX_CPU_C::BxError }, // REP,REPE/REPZ
+  /* F4 */  { 0,  &BX_CPU_C::HLT },
+  /* F5 */  { 0,  &BX_CPU_C::CMC },
+  /* F6 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Eb },
+  /* F7 */  { BxAnother | BxGroup3,  NULL, BxOpcodeInfoG3Ed },
+  /* F8 */  { 0,  &BX_CPU_C::CLC },
+  /* F9 */  { 0,  &BX_CPU_C::STC },
+  /* FA */  { 0,  &BX_CPU_C::CLI },
+  /* FB */  { 0,  &BX_CPU_C::STI },
+  /* FC */  { 0,  &BX_CPU_C::CLD },
+  /* FD */  { 0,  &BX_CPU_C::STD },
+  /* FE */  { BxAnother | BxGroup4,  NULL, BxOpcodeInfoG4 },
+  /* FF */  { BxAnother | BxGroup5,  NULL, BxOpcodeInfoG5d },
+
+  /* 0F 00 */  { BxAnother | BxGroup6,  NULL, BxOpcodeInfoG6 },
+  /* 0F 01 */  { BxAnother | BxGroup7,  NULL, BxOpcodeInfoG7 },
+  /* 0F 02 */  { BxAnother,  &BX_CPU_C::LAR_GvEw },
+  /* 0F 03 */  { BxAnother,  &BX_CPU_C::LSL_GvEw },
+  /* 0F 04 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 05 */  { 0,  &BX_CPU_C::LOADALL },
+  /* 0F 06 */  { 0,  &BX_CPU_C::CLTS },
+  /* 0F 07 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 08 */  { 0,  &BX_CPU_C::INVD },
+  /* 0F 09 */  { 0,  &BX_CPU_C::WBINVD },
+  /* 0F 0A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 0F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 10 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 11 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 12 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 13 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 14 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 15 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 16 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 17 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 18 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 19 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 1F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 20 */  { BxAnother,  &BX_CPU_C::MOV_RdCd },
+  /* 0F 21 */  { BxAnother,  &BX_CPU_C::MOV_RdDd },
+  /* 0F 22 */  { BxAnother,  &BX_CPU_C::MOV_CdRd },
+  /* 0F 23 */  { BxAnother,  &BX_CPU_C::MOV_DdRd },
+  /* 0F 24 */  { BxAnother,  &BX_CPU_C::MOV_RdTd },
+  /* 0F 25 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 26 */  { BxAnother,  &BX_CPU_C::MOV_TdRd },
+  /* 0F 27 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 28 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 29 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 2F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 30 */  { 0,  &BX_CPU_C::WRMSR },
+  /* 0F 31 */  { 0,  &BX_CPU_C::RDTSC },
+  /* 0F 32 */  { 0,  &BX_CPU_C::RDMSR },
+  /* 0F 33 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 34 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 35 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 36 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 37 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 38 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 39 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 3F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 40 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 41 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 42 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 43 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 44 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 45 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 46 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 47 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 48 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 49 */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4A */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4B */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4C */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4D */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4E */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 4F */  { BxAnother,  &BX_CPU_C::CMOV_GdEd },
+  /* 0F 50 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 51 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 52 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 53 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 54 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 55 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 56 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 57 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 58 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 59 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 5F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 60 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 61 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 62 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 63 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 64 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 65 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 66 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 67 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 68 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 69 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 6F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 70 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 71 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 72 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 73 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 74 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 75 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 76 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 77 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 78 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 79 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7A */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7B */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7C */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7D */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7E */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 7F */  { 0,  &BX_CPU_C::BxError },
+  /* 0F 80 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 81 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 82 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 83 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 84 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 85 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 86 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 87 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 88 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 89 */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8A */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8B */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8C */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8D */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8E */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 8F */  { BxImmediate_BrOff32,  &BX_CPU_C::JCC_Jd },
+  /* 0F 90 */  { BxAnother,  &BX_CPU_C::SETO_Eb },
+  /* 0F 91 */  { BxAnother,  &BX_CPU_C::SETNO_Eb },
+  /* 0F 92 */  { BxAnother,  &BX_CPU_C::SETB_Eb },
+  /* 0F 93 */  { BxAnother,  &BX_CPU_C::SETNB_Eb },
+  /* 0F 94 */  { BxAnother,  &BX_CPU_C::SETZ_Eb },
+  /* 0F 95 */  { BxAnother,  &BX_CPU_C::SETNZ_Eb },
+  /* 0F 96 */  { BxAnother,  &BX_CPU_C::SETBE_Eb },
+  /* 0F 97 */  { BxAnother,  &BX_CPU_C::SETNBE_Eb },
+  /* 0F 98 */  { BxAnother,  &BX_CPU_C::SETS_Eb },
+  /* 0F 99 */  { BxAnother,  &BX_CPU_C::SETNS_Eb },
+  /* 0F 9A */  { BxAnother,  &BX_CPU_C::SETP_Eb },
+  /* 0F 9B */  { BxAnother,  &BX_CPU_C::SETNP_Eb },
+  /* 0F 9C */  { BxAnother,  &BX_CPU_C::SETL_Eb },
+  /* 0F 9D */  { BxAnother,  &BX_CPU_C::SETNL_Eb },
+  /* 0F 9E */  { BxAnother,  &BX_CPU_C::SETLE_Eb },
+  /* 0F 9F */  { BxAnother,  &BX_CPU_C::SETNLE_Eb },
+  /* 0F A0 */  { 0,  &BX_CPU_C::PUSH_FS },
+  /* 0F A1 */  { 0,  &BX_CPU_C::POP_FS },
+  /* 0F A2 */  { 0,  &BX_CPU_C::CPUID },
+  /* 0F A3 */  { BxAnother,  &BX_CPU_C::BT_EvGv },
+  /* 0F A4 */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHLD_EdGd },
+  /* 0F A5 */  { BxAnother,                 &BX_CPU_C::SHLD_EdGd },
+  /* 0F A6 */  { 0,  &BX_CPU_C::CMPXCHG_XBTS },
+  /* 0F A7 */  { 0,  &BX_CPU_C::CMPXCHG_IBTS },
+  /* 0F A8 */  { 0,  &BX_CPU_C::PUSH_GS },
+  /* 0F A9 */  { 0,  &BX_CPU_C::POP_GS },
+  /* 0F AA */  { 0,  &BX_CPU_C::RSM },
+  /* 0F AB */  { BxAnother,  &BX_CPU_C::BTS_EvGv },
+  /* 0F AC */  { BxAnother | BxImmediate_Ib,  &BX_CPU_C::SHRD_EdGd },
+  /* 0F AD */  { BxAnother,                 &BX_CPU_C::SHRD_EdGd },
+  /* 0F AE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F AF */  { BxAnother,  &BX_CPU_C::IMUL_GdEd },
+  /* 0F B0 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EbGb },
+  /* 0F B1 */  { BxAnother,  &BX_CPU_C::CMPXCHG_EdGd },
+  /* 0F B2 */  { BxAnother,  &BX_CPU_C::LSS_GvMp },
+  /* 0F B3 */  { BxAnother,  &BX_CPU_C::BTR_EvGv },
+  /* 0F B4 */  { BxAnother,  &BX_CPU_C::LFS_GvMp },
+  /* 0F B5 */  { BxAnother,  &BX_CPU_C::LGS_GvMp },
+  /* 0F B6 */  { BxAnother,  &BX_CPU_C::MOVZX_GdEb },
+  /* 0F B7 */  { BxAnother,  &BX_CPU_C::MOVZX_GdEw },
+  /* 0F B8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F B9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F BA */  { BxAnother | BxGroup8,  NULL, BxOpcodeInfoG8EvIb },
+  /* 0F BB */  { BxAnother,  &BX_CPU_C::BTC_EvGv },
+  /* 0F BC */  { BxAnother,  &BX_CPU_C::BSF_GvEv },
+  /* 0F BD */  { BxAnother,  &BX_CPU_C::BSR_GvEv },
+  /* 0F BE */  { BxAnother,  &BX_CPU_C::MOVSX_GdEb },
+  /* 0F BF */  { BxAnother,  &BX_CPU_C::MOVSX_GdEw },
+  /* 0F C0 */  { BxAnother,  &BX_CPU_C::XADD_EbGb },
+  /* 0F C1 */  { BxAnother,  &BX_CPU_C::XADD_EdGd },
+  /* 0F C2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F C7 */  { BxAnother | BxGroup9,  NULL, BxOpcodeInfoG9 },
+  /* 0F C8 */  { 0,  &BX_CPU_C::BSWAP_EAX },
+  /* 0F C9 */  { 0,  &BX_CPU_C::BSWAP_ECX },
+  /* 0F CA */  { 0,  &BX_CPU_C::BSWAP_EDX },
+  /* 0F CB */  { 0,  &BX_CPU_C::BSWAP_EBX },
+  /* 0F CC */  { 0,  &BX_CPU_C::BSWAP_ESP },
+  /* 0F CD */  { 0,  &BX_CPU_C::BSWAP_EBP },
+  /* 0F CE */  { 0,  &BX_CPU_C::BSWAP_ESI },
+  /* 0F CF */  { 0,  &BX_CPU_C::BSWAP_EDI },
+  /* 0F D0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F D9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DD */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F DF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E0 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E1 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E2 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E3 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E4 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E5 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E6 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E7 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E8 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F E9 */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EA */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EB */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EC */  { 0,  &BX_CPU_C::BxError },
+  /* 0F ED */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EE */  { 0,  &BX_CPU_C::BxError },
+  /* 0F EF */  { 0,  &BX_CPU_C::BxError },
+  /* 0F F0 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F1 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F2 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F3 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F4 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F5 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F6 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F7 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F8 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F F9 */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FA */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FB */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FC */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FD */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FE */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  /* 0F FF */  { 0,  &BX_CPU_C::UndefinedOpcode },
+  };
+
+
+
+
+  unsigned
+BX_CPU_C::FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+                      unsigned remain, Boolean is_32)
+{
+  // remain must be at least 1
+
+  unsigned b1, b2, ilen=1, attr;
+  unsigned imm_mode, offset;
+
+  instruction->os_32 = instruction->as_32 = is_32;
+  instruction->ResolveModrm = NULL;
+  instruction->seg = BX_SEG_REG_NULL;
+  instruction->rep_used = 0;
+
+
+fetch_b1:
+  b1 = *iptr++;
+
+another_byte:
+  offset = instruction->os_32 << 9; // * 512
+  instruction->attr = attr = BxOpcodeInfo[b1+offset].Attr;
+
+  if (attr & BxAnother) {
+    if (attr & BxPrefix) {
+      switch (b1) {
+        case 0x66: // OpSize
+          instruction->os_32 = !is_32;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+
+        case 0x67: // AddrSize
+          instruction->as_32 = !is_32;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+
+        case 0xf2: // REPNE/REPNZ
+        case 0xf3: // REP/REPE/REPZ
+          instruction->rep_used = b1;
+          if (ilen < remain) {
+            ilen++;
+            goto fetch_b1;
+            }
+          return(0);
+          break;
+
+        case 0x2e: // CS:
+          instruction->seg = BX_SEG_REG_CS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x26: // ES:
+          instruction->seg = BX_SEG_REG_ES;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x36: // SS:
+          instruction->seg = BX_SEG_REG_SS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x3e: // DS:
+          instruction->seg = BX_SEG_REG_DS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x64: // FS:
+          instruction->seg = BX_SEG_REG_FS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0x65: // GS:
+          instruction->seg = BX_SEG_REG_GS;
+          ilen++; goto fetch_b1;
+          break;
+        case 0xf0: // LOCK:
+          ilen++; goto fetch_b1;
+          break;
+
+        default:
+BX_PANIC(("fetch_decode: prefix default = 0x%02x\n", b1));
+        }
+      }
+    // opcode requires another byte
+    if (ilen < remain) {
+      ilen++;
+      b2 = *iptr++;
+      if (b1 == 0x0f) {
+        // 2-byte prefix
+        b1 = 0x100 | b2;
+        goto another_byte;
+        }
+      }
+    else
+      return(0);
+
+    // Parse mod-nnn-rm and related bytes
+    unsigned rm;
+    instruction->modrm = b2;
+    rm =
+    instruction->rm    = b2 & 0x07;
+    instruction->mod   = b2 & 0xc0; // leave unshifted
+    instruction->nnn   = (b2 >> 3) & 0x07;
+    if (instruction->mod == 0xc0) { // mod == 11b
+      goto modrm_done;
+      }
+    if (instruction->as_32) {
+      // 32-bit addressing modes; note that mod==11b handled above
+      if (rm != 4) { // no s-i-b byte
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
+#endif
+        if (instruction->mod == 0x00) { // mod == 00b
+          instruction->ResolveModrm = BxResolve32Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_SEG_REG_DS;
+          if (rm == 5) {
+            if ((ilen+3) < remain) {
+              Bit32u imm32u;
+              imm32u = *iptr++;
+              imm32u |= (*iptr++) << 8;
+              imm32u |= (*iptr++) << 16;
+              imm32u |= (*iptr++) << 24;
+              instruction->rm_addr = imm32u;
+              ilen += 4;
+#if BX_DYNAMIC_TRANSLATION
+              instruction->DTMemRegsUsed = 0;
+#endif
+              goto modrm_done;
+              }
+            else {
+              return(0);
+              }
+            }
+          // mod==00b, rm!=4, rm!=5
+          goto modrm_done;
+          }
+        if (instruction->mod == 0x40) { // mod == 01b
+          instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+get_8bit_displ:
+          if (ilen < remain) {
+            // 8 sign extended to 32
+            instruction->displ32u = (Bit8s) *iptr++;
+            ilen++;
+            goto modrm_done;
+            }
+          else {
+            return(0);
+            }
+          }
+        // (mod == 0x80) mod == 10b
+        instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+get_32bit_displ:
+        if ((ilen+3) < remain) {
+          Bit32u imm32u;
+          imm32u = *iptr++;
+          imm32u |= (*iptr++) << 8;
+          imm32u |= (*iptr++) << 16;
+          imm32u |= (*iptr++) << 24;
+          instruction->displ32u = imm32u;
+          ilen += 4;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      else { // mod!=11b, rm==4, s-i-b byte follows
+        unsigned sib, base;
+        if (ilen < remain) {
+          sib = *iptr++;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        instruction->sib   = sib;
+        base =
+        instruction->base  = sib & 0x07; sib >>= 3;
+        instruction->index = sib & 0x07; sib >>= 3;
+        instruction->scale = sib;
+#if BX_DYNAMIC_TRANSLATION
+        if (instruction->index == 0x04) // 100b
+          instruction->DTMemRegsUsed = 0;
+        else
+          instruction->DTMemRegsUsed = 1<<instruction->index;
+#endif
+        if (instruction->mod == 0x00) { // mod==00b, rm==4
+          instruction->ResolveModrm = BxResolve32Mod0Base[base];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod0_base32[base];
+          if (instruction->base == 0x05) {
+            goto get_32bit_displ;
+            }
+          // mod==00b, rm==4, base!=5
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTMemRegsUsed |= 1<<base;
+#endif
+          goto modrm_done;
+          }
+#if BX_DYNAMIC_TRANSLATION
+        // for remaining 32bit cases
+        instruction->DTMemRegsUsed |= 1<<base;
+#endif
+        if (instruction->mod == 0x40) { // mod==01b, rm==4
+          instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+          instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+          if (BX_NULL_SEG_REG(instruction->seg))
+            instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+          goto get_8bit_displ;
+          }
+        // (instruction->mod == 0x80),  mod==10b, rm==4
+        instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+        goto get_32bit_displ;
+        }
+      }
+    else {
+      // 16-bit addressing modes, mod==11b handled above
+      if (instruction->mod == 0x40) { // mod == 01b
+        instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+        if (ilen < remain) {
+          // 8 sign extended to 16
+          instruction->displ16u = (Bit8s) *iptr++;
+          ilen++;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      if (instruction->mod == 0x80) { // mod == 10b
+        instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+        if (BX_NULL_SEG_REG(instruction->seg))
+          instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+        instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+        if ((ilen+1) < remain) {
+          Bit16u displ16u;
+          displ16u = *iptr++;
+          displ16u |= (*iptr++) << 8;
+          instruction->displ16u = displ16u;
+          ilen += 2;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      // mod must be 00b at this point
+      instruction->ResolveModrm = BxResolve16Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod0[rm];
+#endif
+      if (BX_NULL_SEG_REG(instruction->seg))
+        instruction->seg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+      if (rm == 0x06) {
+        if ((ilen+1) < remain) {
+          Bit16u displ16u;
+          displ16u = *iptr++;
+          displ16u |= (*iptr++) << 8;
+          instruction->rm_addr = displ16u;
+          ilen += 2;
+          goto modrm_done;
+          }
+        else {
+          return(0);
+          }
+        }
+      // mod=00b rm!=6
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+      }
+
+modrm_done:
+    if (attr & BxGroupN) {
+      BxOpcodeInfo_t *OpcodeInfoPtr;
+
+      OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
+      instruction->execute = OpcodeInfoPtr[instruction->nnn].ExecutePtr;
+      // get additional attributes from group table
+      attr |= OpcodeInfoPtr[instruction->nnn].Attr;
+      instruction->attr = attr;
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTAttr = 0; // for now
+#endif
+      }
+    else {
+      instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+      instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+      instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+      }
+    }
+  else {
+    // Opcode does not require a MODRM byte.
+    // Note that a 2-byte opcode (0F XX) will jump to before
+    // the if() above after fetching the 2nd byte, so this path is
+    // taken in all cases if a modrm byte is NOT required.
+    instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+    instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+    instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+    }
+
+
+  imm_mode = attr & BxImmediate;
+
+  if (imm_mode) {
+    switch (imm_mode) {
+      case BxImmediate_Ib:
+        if (ilen < remain) {
+          instruction->Ib = *iptr;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_Ib_SE: // Sign extend to OS size
+        if (ilen < remain) {
+          Bit8s temp8s;
+          temp8s = *iptr;
+          if (instruction->os_32)
+            instruction->Id = (Bit32s) temp8s;
+          else
+            instruction->Iw = (Bit16s) temp8s;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_Iv: // same as BxImmediate_BrOff32
+      case BxImmediate_IvIw: // CALL_Ap
+        if (instruction->os_32) {
+          if ((ilen+3) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr++) << 8;
+            imm32u |= (*iptr++) << 16;
+            imm32u |= (*iptr) << 24;
+            instruction->Id = imm32u;
+            ilen += 4;
+            }
+          else {
+            return(0);
+            }
+          }
+        else {
+          if ((ilen+1) < remain) {
+            Bit16u imm16u;
+            imm16u = *iptr++;
+            imm16u |= (*iptr) << 8;
+            instruction->Iw = imm16u;
+            ilen += 2;
+            }
+          else {
+            return(0);
+            }
+          }
+        if (imm_mode != BxImmediate_IvIw)
+          break;
+        iptr++;
+        // Get Iw for BxImmediate_IvIw
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Iw2 = imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_O:
+        if (instruction->as_32) {
+          // fetch 32bit address into Id
+          if ((ilen+3) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr++) << 8;
+            imm32u |= (*iptr++) << 16;
+            imm32u |= (*iptr) << 24;
+            instruction->Id = imm32u;
+            ilen += 4;
+            }
+          else {
+            return(0);
+            }
+          }
+        else {
+          // fetch 16bit address into Id
+          if ((ilen+1) < remain) {
+            Bit32u imm32u;
+            imm32u = *iptr++;
+            imm32u |= (*iptr) << 8;
+            instruction->Id = imm32u;
+            ilen += 2;
+            }
+          else {
+            return(0);
+            }
+          }
+        break;
+      case BxImmediate_Iw:
+      case BxImmediate_IwIb:
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Iw = imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        if (imm_mode == BxImmediate_Iw) break;
+        iptr++;
+        if (ilen < remain) {
+          instruction->Ib2 = *iptr;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_BrOff8:
+        if (ilen < remain) {
+          Bit8s temp8s;
+          temp8s = *iptr;
+          instruction->Id = temp8s;
+          ilen++;
+          }
+        else {
+          return(0);
+          }
+        break;
+      case BxImmediate_BrOff16:
+        if ((ilen+1) < remain) {
+          Bit16u imm16u;
+          imm16u = *iptr++;
+          imm16u |= (*iptr) << 8;
+          instruction->Id = (Bit16s) imm16u;
+          ilen += 2;
+          }
+        else {
+          return(0);
+          }
+        break;
+      default:
+BX_INFO(("b1 was %x\n", b1));
+        BX_PANIC(("fetchdecode: imm_mode = %u\n", imm_mode));
+      }
+    }
+
+
+  instruction->b1 = b1;
+  instruction->ilen = ilen;
+  //instruction->flags_in  = 0; // for now
+  //instruction->flags_out = 0; // for now
+  return(1);
+}
+
+  void
+BX_CPU_C::BxError(BxInstruction_t *i)
+{
+  // extern void dump_core();
+  BX_INFO(("BxError: instruction with op1=0x%x\n", i->b1));
+  BX_INFO(("nnn was %u\n", i->nnn));
+
+  BX_INFO(("WARNING: Encountered an unknown instruction (signalling illegal instruction):\n"));
+  // dump_core();
+
+  BX_CPU_THIS_PTR UndefinedOpcode(i);
+}
+
+  void
+BX_CPU_C::BxResolveError(BxInstruction_t *i)
+{
+  BX_PANIC(("BxResolveError: instruction with op1=0x%x\n", i->b1));
+}
diff --git a/sid/component/bochs/cpu/flag_ctrl.cc b/sid/component/bochs/cpu/flag_ctrl.cc
new file mode 100644 (file)
index 0000000..5b59852
--- /dev/null
@@ -0,0 +1,218 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::SAHF(BxInstruction_t *i)
+{
+  set_SF((AH & 0x80) >> 7);
+  set_ZF((AH & 0x40) >> 6);
+  set_AF((AH & 0x10) >> 4);
+  set_CF(AH & 0x01);
+  set_PF((AH & 0x04) >> 2);
+}
+
+  void
+BX_CPU_C::LAHF(BxInstruction_t *i)
+{
+  AH = (get_SF() ? 0x80 : 0) |
+       (get_ZF() ? 0x40 : 0) |
+       (get_AF() ? 0x10 : 0) |
+       (get_PF() ? 0x04 : 0) |
+       (0x02) |
+       (get_CF() ? 0x01 : 0);
+}
+
+  void
+BX_CPU_C::CLC(BxInstruction_t *i)
+{
+  set_CF(0);
+}
+
+  void
+BX_CPU_C::STC(BxInstruction_t *i)
+{
+  set_CF(1);
+}
+
+  void
+BX_CPU_C::CLI(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (CPL > IOPL) {
+      //BX_INFO(("CLI: CPL > IOPL\n")); /* ??? */
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+#if BX_CPU_LEVEL >= 3
+  else if (v8086_mode()) {
+    if (IOPL != 3) {
+      //BX_INFO(("CLI: IOPL != 3\n")); /* ??? */
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+#endif
+#endif
+
+  BX_CPU_THIS_PTR eflags.if_ = 0;
+}
+
+  void
+BX_CPU_C::STI(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (CPL > IOPL) {
+      //BX_INFO(("STI: CPL > IOPL\n")); /* ??? */
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+#if BX_CPU_LEVEL >= 3
+  else if (v8086_mode()) {
+    if (IOPL != 3) {
+      //BX_INFO(("STI: IOPL != 3\n")); /* ??? */
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+#endif
+#endif
+
+  if (!BX_CPU_THIS_PTR eflags.if_) {
+    BX_CPU_THIS_PTR eflags.if_ = 1;
+    BX_CPU_THIS_PTR inhibit_mask |= BX_INHIBIT_INTERRUPTS;
+    BX_CPU_THIS_PTR async_event = 1;
+    }
+}
+
+  void
+BX_CPU_C::CLD(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR eflags.df = 0;
+}
+
+  void
+BX_CPU_C::STD(BxInstruction_t *i)
+{
+  BX_CPU_THIS_PTR eflags.df = 1;
+}
+
+  void
+BX_CPU_C::CMC(BxInstruction_t *i)
+{
+  set_CF( !get_CF() );
+}
+
+  void
+BX_CPU_C::PUSHF_Fv(BxInstruction_t *i)
+{
+  if (v8086_mode() && (IOPL<3)) {
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->os_32) {
+    push_32(read_eflags() & 0x00fcffff);
+    }
+  else
+#endif
+    {
+    push_16(read_flags());
+    }
+}
+
+
+  void
+BX_CPU_C::POPF_Fv(BxInstruction_t *i)
+{
+
+#if BX_CPU_LEVEL >= 3
+  if (v8086_mode()) {
+    if (IOPL < 3) {
+      //BX_INFO(("popf_fv: IOPL < 3\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    if (i->os_32) {
+      BX_PANIC(("POPFD(): not supported in virtual mode\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  if (i->os_32) {
+    Bit32u eflags;
+
+    pop_32(&eflags);
+
+    eflags &= 0x00277fd7;
+    if (!real_mode()) {
+      write_eflags(eflags, /* change IOPL? */ CPL==0, /* change IF? */ CPL<=IOPL, 0, 0);
+      }
+    else { /* real mode */
+      write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 0);
+      }
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16 bit opsize */
+    Bit16u flags;
+
+    pop_16(&flags);
+
+    if (!real_mode()) {
+      write_flags(flags, /* change IOPL? */ CPL==0, /* change IF? */ CPL<=IOPL);
+      }
+    else { /* real mode */
+      write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
+      }
+    }
+}
+
+
+  void
+BX_CPU_C::SALC(BxInstruction_t *i)
+{
+  if ( get_CF() ) {
+    AL = 0xff;
+    }
+  else {
+    AL = 0x00;
+    }
+}
diff --git a/sid/component/bochs/cpu/flag_ctrl_pro.cc b/sid/component/bochs/cpu/flag_ctrl_pro.cc
new file mode 100644 (file)
index 0000000..f9c72d5
--- /dev/null
@@ -0,0 +1,209 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+  void
+BX_CPU_C::write_flags(Bit16u flags, Boolean change_IOPL, Boolean change_IF)
+{
+  BX_CPU_THIS_PTR set_CF(flags & 0x01);
+  BX_CPU_THIS_PTR set_PF((flags >> 2) & 0x01);
+  BX_CPU_THIS_PTR set_AF((flags >> 4) & 0x01);
+  BX_CPU_THIS_PTR set_ZF((flags >> 6) & 0x01);
+  BX_CPU_THIS_PTR set_SF((flags >> 7) & 0x01);
+
+#if 0
+// +++
+if (BX_CPU_THIS_PTR eflags.tf==0 && (flags&0x0100))
+  BX_DEBUG(( "TF 0->1\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && !(flags&0x0100))
+  BX_DEBUG(( "TF 1->0\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && (flags&0x0100))
+  BX_DEBUG(( "TF 1->1\n" ));
+#endif
+
+  BX_CPU_THIS_PTR eflags.tf = (flags >> 8) & 0x01;
+  if (BX_CPU_THIS_PTR eflags.tf) {
+    BX_CPU_THIS_PTR async_event = 1;
+    }
+
+  if (change_IF)
+    BX_CPU_THIS_PTR eflags.if_ = (flags >> 9) & 0x01;
+
+  BX_CPU_THIS_PTR eflags.df = (flags >> 10) & 0x01;
+  BX_CPU_THIS_PTR set_OF((flags >> 11) & 0x01);
+
+
+#if BX_CPU_LEVEL == 2
+  BX_CPU_THIS_PTR eflags.iopl = 0;
+  BX_CPU_THIS_PTR eflags.nt = 0;
+#else
+  if (change_IOPL)
+    BX_CPU_THIS_PTR eflags.iopl = (flags >> 12) & 0x03;
+  BX_CPU_THIS_PTR eflags.nt = (flags >> 14) & 0x01;
+#endif
+}
+
+
+#if BX_CPU_LEVEL >= 3
+  void
+BX_CPU_C::write_eflags(Bit32u eflags_raw, Boolean change_IOPL, Boolean change_IF,
+                Boolean change_VM, Boolean change_RF)
+{
+  BX_CPU_THIS_PTR set_CF(eflags_raw & 0x01);
+  BX_CPU_THIS_PTR set_PF((eflags_raw >> 2) & 0x01);
+  BX_CPU_THIS_PTR set_AF((eflags_raw >> 4) & 0x01);
+  BX_CPU_THIS_PTR set_ZF((eflags_raw >> 6) & 0x01);
+  BX_CPU_THIS_PTR set_SF((eflags_raw >> 7) & 0x01);
+
+#if 0
+// +++
+if (BX_CPU_THIS_PTR eflags.tf==0 && (eflags_raw&0x0100))
+  BX_DEBUG(( "TF 0->1\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && !(eflags_raw&0x0100))
+  BX_DEBUG(( "TF 1->0\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && (eflags_raw&0x0100))
+  BX_DEBUG(( "TF 1->1\n" ));
+#endif
+
+  BX_CPU_THIS_PTR eflags.tf = (eflags_raw >> 8) & 0x01;
+  if (BX_CPU_THIS_PTR eflags.tf) {
+    BX_CPU_THIS_PTR async_event = 1;
+    }
+
+  if (change_IF)
+    BX_CPU_THIS_PTR eflags.if_ = (eflags_raw >> 9) & 0x01;
+
+  BX_CPU_THIS_PTR eflags.df = (eflags_raw >> 10) & 0x01;
+  BX_CPU_THIS_PTR set_OF((eflags_raw >> 11) & 0x01);
+
+  if (change_IOPL)
+    BX_CPU_THIS_PTR eflags.iopl = (eflags_raw >> 12) & 0x03;
+  BX_CPU_THIS_PTR eflags.nt = (eflags_raw >> 14) & 0x01;
+
+  if (change_VM) {
+    BX_CPU_THIS_PTR eflags.vm = (eflags_raw >> 17) & 0x01;
+#if BX_SUPPORT_V8086_MODE == 0
+    if (BX_CPU_THIS_PTR eflags.vm)
+      BX_PANIC(("write_eflags: VM bit set: BX_SUPPORT_V8086_MODE==0\n"));
+#endif
+    }
+  if (change_RF) {
+    BX_CPU_THIS_PTR eflags.rf = (eflags_raw >> 16) & 0x01;
+    }
+
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR eflags.ac = (eflags_raw >> 18) & 0x01;
+  BX_CPU_THIS_PTR eflags.id = (eflags_raw >> 21) & 0x01;
+#endif
+
+}
+#endif /* BX_CPU_LEVEL >= 3 */
+
+
+  Bit16u
+BX_CPU_C::read_flags(void)
+{
+  Bit16u flags;
+
+  flags = (get_CF()) |
+          (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+          ((get_PF()) << 2) |
+          (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+          ((get_AF()>0) << 4) |
+          (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+          ((get_ZF()>0) << 6) |
+          ((get_SF()>0) << 7) |
+          (BX_CPU_THIS_PTR eflags.tf << 8) |
+          (BX_CPU_THIS_PTR eflags.if_ << 9) |
+          (BX_CPU_THIS_PTR eflags.df << 10) |
+          ((get_OF()>0) << 11) |
+          (BX_CPU_THIS_PTR eflags.iopl << 12) |
+          (BX_CPU_THIS_PTR eflags.nt << 14) |
+          (BX_CPU_THIS_PTR eflags.bit15 << 15);
+
+  /* 8086: bits 12-15 always set to 1.
+   * 286: in real mode, bits 12-15 always cleared.
+   * 386+: real-mode: bit15 cleared, bits 14..12 are last loaded value
+   *       protected-mode: bit 15 clear, bit 14 = last loaded, IOPL?
+   */
+#if BX_CPU_LEVEL < 2
+  flags |= 0xF000;  /* 8086 nature */
+#elif BX_CPU_LEVEL == 2
+  if (real_mode()) {
+    flags &= 0x0FFF;  /* 80286 in real mode nature */
+    }
+#else /* 386+ */
+#endif
+
+  return(flags);
+}
+
+
+#if BX_CPU_LEVEL >= 3
+  Bit32u
+BX_CPU_C::read_eflags(void)
+{
+  Bit32u eflags_raw;
+
+  eflags_raw =
+          (get_CF()) |
+          (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+          ((get_PF()) << 2) |
+          (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+          ((get_AF()>0) << 4) |
+          (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+          ((get_ZF()>0) << 6) |
+          ((get_SF()>0) << 7) |
+          (BX_CPU_THIS_PTR eflags.tf << 8) |
+          (BX_CPU_THIS_PTR eflags.if_ << 9) |
+          (BX_CPU_THIS_PTR eflags.df << 10) |
+          ((get_OF()>0) << 11) |
+          (BX_CPU_THIS_PTR eflags.iopl << 12) |
+          (BX_CPU_THIS_PTR eflags.nt << 14) |
+          (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+          (BX_CPU_THIS_PTR eflags.rf << 16) |
+          (BX_CPU_THIS_PTR eflags.vm << 17)
+#if BX_CPU_LEVEL >= 4
+          | (BX_CPU_THIS_PTR eflags.ac << 18)
+          | (BX_CPU_THIS_PTR eflags.id << 21)
+#endif
+           ;
+
+#if 0
+  /*
+   * 386+: real-mode: bit15 cleared, bits 14..12 are last loaded value
+   *       protected-mode: bit 15 clear, bit 14 = last loaded, IOPL?
+   */
+#endif
+
+  return(eflags_raw);
+}
+#endif /* BX_CPU_LEVEL >= 3 */
diff --git a/sid/component/bochs/cpu/init-sid.cc b/sid/component/bochs/cpu/init-sid.cc
new file mode 100644 (file)
index 0000000..fa9dbc1
--- /dev/null
@@ -0,0 +1,185 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+     // sid_cpu_c constructor
+void sid_cpu_c::init(sid_mem_c *addrspace)
+{
+    // To deal with initialization order problems inherent in C++, use
+  // the macros SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog"
+  // in all constructors or functions called by constructors.  The macros
+  // test for NULL and create the object if necessary, then return it.
+  // Ensure that io and genlog get created, by making one reference to
+  // each macro right here.  All other code can call them directly.
+  SAFE_GET_IOFUNC();
+  SAFE_GET_GENLOG();
+
+  BX_CPU_THIS_PTR set_INTR (0);
+#if BX_SUPPORT_APIC
+  local_apic.init ();
+#endif
+  setprefix("[CPU ]");
+  // in SMP mode, the prefix of the CPU will be changed to [CPUn] in 
+  // bx_local_apic_c::set_id as soon as the apic ID is assigned.
+
+  /* hack for the following fields.  Its easier to decode mod-rm bytes if
+     you can assume there's always a base & index register used.  For
+     modes which don't really use them, point to an empty (zeroed) register.
+   */
+  empty_register = 0;
+
+  // 16bit address mode base register, used for mod-rm decoding
+
+  _16bit_base_reg[0] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+  _16bit_base_reg[1] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+  _16bit_base_reg[2] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[3] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[4] = (Bit16u*) &empty_register;
+  _16bit_base_reg[5] = (Bit16u*) &empty_register;
+  _16bit_base_reg[6] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[7] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+
+  // 16bit address mode index register, used for mod-rm decoding
+  _16bit_index_reg[0] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[1] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[2] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[3] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[4] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[5] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[6] = (Bit16u*) &empty_register;
+  _16bit_index_reg[7] = (Bit16u*) &empty_register;
+
+  // for decoding instructions: access to seg reg's via index number
+  sreg_mod00_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod00_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod00_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[6] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[7] = BX_SEG_REG_DS;
+
+  sreg_mod01_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[6] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[7] = BX_SEG_REG_DS;
+
+  sreg_mod10_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[6] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a one-byte modrm with mod==01b
+  // and rm==i
+  //
+  sreg_mod01_rm32[0] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[1] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[2] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[3] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[4] = BX_SEG_REG_NULL;
+    // this entry should never be accessed
+    // (escape to 2-byte)
+  sreg_mod01_rm32[5] = BX_SEG_REG_SS;
+  sreg_mod01_rm32[6] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a one-byte modrm with mod==10b
+  // and rm==i
+  //
+  sreg_mod10_rm32[0] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[1] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[2] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[3] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[4] = BX_SEG_REG_NULL;
+    // this entry should never be accessed
+    // (escape to 2-byte)
+  sreg_mod10_rm32[5] = BX_SEG_REG_SS;
+  sreg_mod10_rm32[6] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[7] = BX_SEG_REG_DS;
+
+
+  // the default segment to use for a two-byte modrm with mod==00b
+  // and base==i
+  //
+  sreg_mod0_base32[0] = BX_SEG_REG_DS;
+  sreg_mod0_base32[1] = BX_SEG_REG_DS;
+  sreg_mod0_base32[2] = BX_SEG_REG_DS;
+  sreg_mod0_base32[3] = BX_SEG_REG_DS;
+  sreg_mod0_base32[4] = BX_SEG_REG_SS;
+  sreg_mod0_base32[5] = BX_SEG_REG_DS;
+  sreg_mod0_base32[6] = BX_SEG_REG_DS;
+  sreg_mod0_base32[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a two-byte modrm with
+  // mod==01b or mod==10b and base==i
+  sreg_mod1or2_base32[0] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[1] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[2] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[3] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[4] = BX_SEG_REG_SS;
+  sreg_mod1or2_base32[5] = BX_SEG_REG_SS;
+  sreg_mod1or2_base32[6] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[7] = BX_SEG_REG_DS;
+
+#if BX_DYNAMIC_TRANSLATION
+  DTWrite8vShim = NULL;
+  DTWrite16vShim = NULL;
+  DTWrite32vShim = NULL;
+  DTRead8vShim = NULL;
+  DTRead16vShim = NULL;
+  DTRead32vShim = NULL;
+  DTReadRMW8vShim = (BxDTShim_t) DTASReadRMW8vShim;
+  BX_DEBUG(( "DTReadRMW8vShim is %x\n", (unsigned) DTReadRMW8vShim ));
+  BX_DEBUG(( "&DTReadRMW8vShim is %x\n", (unsigned) &DTReadRMW8vShim ));
+  DTReadRMW16vShim = NULL;
+  DTReadRMW32vShim = NULL;
+  DTWriteRMW8vShim = (BxDTShim_t) DTASWriteRMW8vShim;
+  DTWriteRMW16vShim = NULL;
+  DTWriteRMW32vShim = NULL;
+  DTSetFlagsOSZAPCPtr = (BxDTShim_t) DTASSetFlagsOSZAPC;
+  DTIndBrHandler = (BxDTShim_t) DTASIndBrHandler;
+  DTDirBrHandler = (BxDTShim_t) DTASDirBrHandler;
+#endif
+
+  mem = addrspace;
+  sprintf (name, "CPU %p", this);
+
+  BX_INSTR_INIT();
+  BX_DEBUG(( "Init.\n"));
+}
+
+  void
+sid_cpu_c::set_INTR(Boolean value)
+{
+  BX_CPU_THIS_PTR INTR = value;
+  BX_CPU_THIS_PTR async_event = 0;
+}
diff --git a/sid/component/bochs/cpu/init.cc b/sid/component/bochs/cpu/init.cc
new file mode 100644 (file)
index 0000000..a4934bc
--- /dev/null
@@ -0,0 +1,689 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+/* the device id and stepping id are loaded into DH & DL upon processor
+   startup.  for device id: 3 = 80386, 4 = 80486.  just make up a
+   number for the stepping (revision) id. */
+#define BX_DEVICE_ID     3
+#define BX_STEPPING_ID   0
+
+BX_CPU_C::BX_CPU_C()
+#if BX_SUPPORT_APIC
+   : local_apic (this)
+#endif
+{
+  // in case of SMF, you cannot reference any member data
+  // in the constructor because the only access to it is via
+  // global variables which aren't initialized quite yet.
+}
+
+#if BX_SUPPORT_SID
+void BX_CPU_C::init(sid_mem_c *addrspace)
+#else
+void BX_CPU_C::init(BX_MEM_C *addrspace)
+#endif
+{
+  // BX_CPU_C constructor
+  BX_CPU_THIS_PTR set_INTR (0);
+#if BX_SUPPORT_APIC
+  local_apic.init ();
+#endif
+  setprefix("[CPU ]");
+  // in SMP mode, the prefix of the CPU will be changed to [CPUn] in 
+  // bx_local_apic_c::set_id as soon as the apic ID is assigned.
+
+  /* hack for the following fields.  Its easier to decode mod-rm bytes if
+     you can assume there's always a base & index register used.  For
+     modes which don't really use them, point to an empty (zeroed) register.
+   */
+  empty_register = 0;
+
+  // 16bit address mode base register, used for mod-rm decoding
+
+  _16bit_base_reg[0] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+  _16bit_base_reg[1] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+  _16bit_base_reg[2] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[3] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[4] = (Bit16u*) &empty_register;
+  _16bit_base_reg[5] = (Bit16u*) &empty_register;
+  _16bit_base_reg[6] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+  _16bit_base_reg[7] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+
+  // 16bit address mode index register, used for mod-rm decoding
+  _16bit_index_reg[0] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[1] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[2] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[3] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[4] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+  _16bit_index_reg[5] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+  _16bit_index_reg[6] = (Bit16u*) &empty_register;
+  _16bit_index_reg[7] = (Bit16u*) &empty_register;
+
+  // for decoding instructions: access to seg reg's via index number
+  sreg_mod00_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod00_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod00_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[6] = BX_SEG_REG_DS;
+  sreg_mod00_rm16[7] = BX_SEG_REG_DS;
+
+  sreg_mod01_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod01_rm16[6] = BX_SEG_REG_SS;
+  sreg_mod01_rm16[7] = BX_SEG_REG_DS;
+
+  sreg_mod10_rm16[0] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[1] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[2] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[3] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[4] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[5] = BX_SEG_REG_DS;
+  sreg_mod10_rm16[6] = BX_SEG_REG_SS;
+  sreg_mod10_rm16[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a one-byte modrm with mod==01b
+  // and rm==i
+  //
+  sreg_mod01_rm32[0] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[1] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[2] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[3] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[4] = BX_SEG_REG_NULL;
+    // this entry should never be accessed
+    // (escape to 2-byte)
+  sreg_mod01_rm32[5] = BX_SEG_REG_SS;
+  sreg_mod01_rm32[6] = BX_SEG_REG_DS;
+  sreg_mod01_rm32[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a one-byte modrm with mod==10b
+  // and rm==i
+  //
+  sreg_mod10_rm32[0] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[1] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[2] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[3] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[4] = BX_SEG_REG_NULL;
+    // this entry should never be accessed
+    // (escape to 2-byte)
+  sreg_mod10_rm32[5] = BX_SEG_REG_SS;
+  sreg_mod10_rm32[6] = BX_SEG_REG_DS;
+  sreg_mod10_rm32[7] = BX_SEG_REG_DS;
+
+
+  // the default segment to use for a two-byte modrm with mod==00b
+  // and base==i
+  //
+  sreg_mod0_base32[0] = BX_SEG_REG_DS;
+  sreg_mod0_base32[1] = BX_SEG_REG_DS;
+  sreg_mod0_base32[2] = BX_SEG_REG_DS;
+  sreg_mod0_base32[3] = BX_SEG_REG_DS;
+  sreg_mod0_base32[4] = BX_SEG_REG_SS;
+  sreg_mod0_base32[5] = BX_SEG_REG_DS;
+  sreg_mod0_base32[6] = BX_SEG_REG_DS;
+  sreg_mod0_base32[7] = BX_SEG_REG_DS;
+
+  // the default segment to use for a two-byte modrm with
+  // mod==01b or mod==10b and base==i
+  sreg_mod1or2_base32[0] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[1] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[2] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[3] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[4] = BX_SEG_REG_SS;
+  sreg_mod1or2_base32[5] = BX_SEG_REG_SS;
+  sreg_mod1or2_base32[6] = BX_SEG_REG_DS;
+  sreg_mod1or2_base32[7] = BX_SEG_REG_DS;
+
+#if BX_DYNAMIC_TRANSLATION
+  DTWrite8vShim = NULL;
+  DTWrite16vShim = NULL;
+  DTWrite32vShim = NULL;
+  DTRead8vShim = NULL;
+  DTRead16vShim = NULL;
+  DTRead32vShim = NULL;
+  DTReadRMW8vShim = (BxDTShim_t) DTASReadRMW8vShim;
+  BX_DEBUG(( "DTReadRMW8vShim is %x\n", (unsigned) DTReadRMW8vShim ));
+  BX_DEBUG(( "&DTReadRMW8vShim is %x\n", (unsigned) &DTReadRMW8vShim ));
+  DTReadRMW16vShim = NULL;
+  DTReadRMW32vShim = NULL;
+  DTWriteRMW8vShim = (BxDTShim_t) DTASWriteRMW8vShim;
+  DTWriteRMW16vShim = NULL;
+  DTWriteRMW32vShim = NULL;
+  DTSetFlagsOSZAPCPtr = (BxDTShim_t) DTASSetFlagsOSZAPC;
+  DTIndBrHandler = (BxDTShim_t) DTASIndBrHandler;
+  DTDirBrHandler = (BxDTShim_t) DTASDirBrHandler;
+#endif
+
+  mem = addrspace;
+  sprintf (name, "CPU %p", this);
+
+  BX_INSTR_INIT();
+  BX_DEBUG(( "Init.\n"));
+}
+
+
+BX_CPU_C::~BX_CPU_C(void)
+{
+  BX_INSTR_SHUTDOWN();
+  BX_DEBUG(( "Exit.\n"));
+}
+
+
+
+  void
+BX_CPU_C::reset(unsigned source)
+{
+  UNUSED(source); // either BX_RESET_HARDWARE or BX_RESET_SOFTWARE
+
+  // general registers
+  EAX = 0; // processor passed test :-)
+  EBX = 0; // undefined
+  ECX = 0; // undefined
+  EDX = (BX_DEVICE_ID << 8) | BX_STEPPING_ID; // ???
+  EBP = 0; // undefined
+  ESI = 0; // undefined
+  EDI = 0; // undefined
+  ESP = 0; // undefined
+
+  // all status flags at known values, use BX_CPU_THIS_PTR eflags structure
+  BX_CPU_THIS_PTR lf_flags_status = 0x000000;
+  BX_CPU_THIS_PTR lf_pf = 0;
+
+  // status and control flags register set
+  BX_CPU_THIS_PTR set_CF(0);
+  BX_CPU_THIS_PTR eflags.bit1 = 1;
+  BX_CPU_THIS_PTR set_PF(0);
+  BX_CPU_THIS_PTR eflags.bit3 = 0;
+  BX_CPU_THIS_PTR set_AF(0);
+  BX_CPU_THIS_PTR eflags.bit5 = 0;
+  BX_CPU_THIS_PTR set_ZF(0);
+  BX_CPU_THIS_PTR set_SF(0);
+  BX_CPU_THIS_PTR eflags.tf = 0;
+  BX_CPU_THIS_PTR eflags.if_ = 0;
+  BX_CPU_THIS_PTR eflags.df = 0;
+  BX_CPU_THIS_PTR set_OF(0);
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR eflags.iopl = 0;
+  BX_CPU_THIS_PTR eflags.nt = 0;
+#endif
+  BX_CPU_THIS_PTR eflags.bit15 = 0;
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR eflags.rf = 0;
+  BX_CPU_THIS_PTR eflags.vm = 0;
+#endif
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR eflags.ac = 0;
+#endif
+
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+  BX_CPU_THIS_PTR debug_trap = 0;
+
+  /* instruction pointer */
+#if BX_CPU_LEVEL < 2
+  BX_CPU_THIS_PTR prev_eip =
+  BX_CPU_THIS_PTR eip = 0x00000000;
+#else /* from 286 up */
+  BX_CPU_THIS_PTR prev_eip =
+  BX_CPU_THIS_PTR eip = 0x0000FFF0;
+#endif
+
+
+  /* CS (Code Segment) and descriptor cache */
+  /* Note: on a real cpu, CS initially points to upper memory.  After
+   * the 1st jump, the descriptor base is zero'd out.  Since I'm just
+   * going to jump to my BIOS, I don't need to do this.
+   * For future reference:
+   *   processor  cs.selector   cs.base    cs.limit    EIP
+   *        8086    FFFF          FFFF0        FFFF   0000
+   *        286     F000         FF0000        FFFF   FFF0
+   *        386+    F000       FFFF0000        FFFF   FFF0
+   */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value =     0xf000;
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable   = 1; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base         = 0x000F0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =     0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* SS (Stack Segment) and descriptor cache */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value =     0x0000;
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable   = 0; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base         = 0x00000000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =     0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* DS (Data Segment) and descriptor cache */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value =     0x0000;
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable   = 0; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base         = 0x00000000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =     0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* ES (Extra Segment) and descriptor cache */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value =     0x0000;
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable   = 0; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base         = 0x00000000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =     0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+
+  /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable   = 0; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base         = 0x00000000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index =     0x0000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid =     1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable   = 0; /* data/stack segment */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w          = 1; /* writeable */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a            = 1; /* accessed */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base         = 0x00000000;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit        =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =     0xFFFF;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g   = 0; /* byte granular */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 0; /* 16bit default size */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR gdtr.base         = 0x00000000;  /* undefined */
+  BX_CPU_THIS_PTR gdtr.limit        =     0x0000;  /* undefined */
+  /* ??? AR=Present, Read/Write */
+#endif
+
+  /* IDTR (Interrupt Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR idtr.base         = 0x00000000;
+  BX_CPU_THIS_PTR idtr.limit        =     0x03FF; /* always byte granular */ /* ??? */
+  /* ??? AR=Present, Read/Write */
+#endif
+
+  /* LDTR (Local Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+  BX_CPU_THIS_PTR ldtr.selector.value =     0x0000;
+  BX_CPU_THIS_PTR ldtr.selector.index =     0x0000;
+  BX_CPU_THIS_PTR ldtr.selector.ti = 0;
+  BX_CPU_THIS_PTR ldtr.selector.rpl = 0;
+
+  BX_CPU_THIS_PTR ldtr.cache.valid   = 0; /* not valid */
+  BX_CPU_THIS_PTR ldtr.cache.p       = 0; /* not present */
+  BX_CPU_THIS_PTR ldtr.cache.dpl     = 0; /* field not used */
+  BX_CPU_THIS_PTR ldtr.cache.segment = 0; /* system segment */
+  BX_CPU_THIS_PTR ldtr.cache.type    = 2; /* LDT descriptor */
+
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.base      = 0x00000000;
+  BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit     =     0xFFFF;
+#endif
+
+  /* TR (Task Register) */
+#if BX_CPU_LEVEL >= 2
+  /* ??? I don't know what state the TR comes up in */
+  BX_CPU_THIS_PTR tr.selector.value =     0x0000;
+  BX_CPU_THIS_PTR tr.selector.index =     0x0000; /* undefined */
+  BX_CPU_THIS_PTR tr.selector.ti    =     0;
+  BX_CPU_THIS_PTR tr.selector.rpl   =     0;
+
+  BX_CPU_THIS_PTR tr.cache.valid    = 0;
+  BX_CPU_THIS_PTR tr.cache.p        = 0;
+  BX_CPU_THIS_PTR tr.cache.dpl      = 0; /* field not used */
+  BX_CPU_THIS_PTR tr.cache.segment  = 0;
+  BX_CPU_THIS_PTR tr.cache.type     = 0; /* invalid */
+  BX_CPU_THIS_PTR tr.cache.u.tss286.base             = 0x00000000; /* undefined */
+  BX_CPU_THIS_PTR tr.cache.u.tss286.limit            =     0x0000; /* undefined */
+#endif
+
+  // DR0 - DR7 (Debug Registers)
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR dr0 = 0;   /* undefined */
+  BX_CPU_THIS_PTR dr1 = 0;   /* undefined */
+  BX_CPU_THIS_PTR dr2 = 0;   /* undefined */
+  BX_CPU_THIS_PTR dr3 = 0;   /* undefined */
+#endif
+#if   BX_CPU_LEVEL == 3
+  BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
+  BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 4
+  BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
+  BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 5
+  BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
+  BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 6
+  BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
+  BX_CPU_THIS_PTR dr7 = 0x00000400;
+#else
+#  error "DR6,7: CPU > 6"
+#endif
+
+#if 0
+  /* test registers 3-7 (unimplemented) */
+  BX_CPU_THIS_PTR tr3 = 0;   /* undefined */
+  BX_CPU_THIS_PTR tr4 = 0;   /* undefined */
+  BX_CPU_THIS_PTR tr5 = 0;   /* undefined */
+  BX_CPU_THIS_PTR tr6 = 0;   /* undefined */
+  BX_CPU_THIS_PTR tr7 = 0;   /* undefined */
+#endif
+
+#if BX_CPU_LEVEL >= 2
+  // MSW (Machine Status Word), so called on 286
+  // CR0 (Control Register 0), so called on 386+
+  BX_CPU_THIS_PTR cr0.ts = 0; // no task switch
+  BX_CPU_THIS_PTR cr0.em = 0; // emulate math coprocessor
+  BX_CPU_THIS_PTR cr0.mp = 0; // wait instructions not trapped
+  BX_CPU_THIS_PTR cr0.pe = 0; // real mode
+  BX_CPU_THIS_PTR cr0.val32 = 0;
+
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR cr0.pg = 0; // paging disabled
+  // no change to cr0.val32
+#endif
+
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR cr0.cd = 1; // caching disabled
+  BX_CPU_THIS_PTR cr0.nw = 1; // not write-through
+  BX_CPU_THIS_PTR cr0.am = 0; // disable alignment check
+  BX_CPU_THIS_PTR cr0.wp = 0; // disable write-protect
+  BX_CPU_THIS_PTR cr0.ne = 0; // ndp exceptions through int 13H, DOS compat
+  BX_CPU_THIS_PTR cr0.val32 |= 0x60000000;
+#endif
+
+  // handle reserved bits
+#if BX_CPU_LEVEL == 3
+  // reserved bits all set to 1 on 386
+  BX_CPU_THIS_PTR cr0.val32 |= 0x7ffffff0;
+#elif BX_CPU_LEVEL >= 4
+  // bit 4 is hardwired to 1 on all x86
+  BX_CPU_THIS_PTR cr0.val32 |= 0x00000010;
+#endif
+#endif // CPU >= 2
+
+
+#if BX_CPU_LEVEL >= 3
+  BX_CPU_THIS_PTR cr2 = 0;
+  BX_CPU_THIS_PTR cr3 = 0;
+#endif
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR cr4 = 0;
+#endif
+
+
+
+  BX_CPU_THIS_PTR EXT = 0;
+  //BX_INTR = 0;
+  
+#if BX_SUPPORT_PAGING
+#if BX_USE_TLB
+  TLB_init();
+#endif
+#endif // BX_SUPPORT_PAGING
+
+  BX_CPU_THIS_PTR bytesleft = 0;
+  BX_CPU_THIS_PTR fetch_ptr = NULL;
+  BX_CPU_THIS_PTR prev_linear_page = 0;
+  BX_CPU_THIS_PTR prev_phy_page = 0;
+  BX_CPU_THIS_PTR max_phy_addr = 0;
+
+#if BX_DEBUGGER
+#ifdef MAGIC_BREAKPOINT
+  BX_CPU_THIS_PTR magic_break = 0;
+#endif
+  BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+  BX_CPU_THIS_PTR trace = 0;
+#endif
+
+  // Init the Floating Point Unit
+  fpu_init();
+
+#if BX_DYNAMIC_TRANSLATION
+  dynamic_init();
+#endif
+
+#if (BX_SMP_PROCESSORS > 1)
+  // notice if I'm the bootstrap processor.  If not, do the equivalent of
+  // a HALT instruction.
+  int apic_id = local_apic.get_id ();
+  if (BX_BOOTSTRAP_PROCESSOR == apic_id)
+  {
+    // boot normally
+    BX_INFO(("CPU[%d] is the bootstrap processor\n", apic_id));
+  } else {
+    // it's an application processor, halt until IPI is heard.
+    BX_INFO(("CPU[%d] is an application processor. Halting until IPI.\n", apic_id));
+    debug_trap |= 0x80000000;
+    async_event = 1;
+  }
+#endif
+}
+
+
+  void
+BX_CPU_C::sanity_checks(void)
+{
+  Bit8u al, cl, dl, bl, ah, ch, dh, bh;
+  Bit16u ax, cx, dx, bx, sp, bp, si, di;
+  Bit32u eax, ecx, edx, ebx, esp, ebp, esi, edi;
+
+  EAX = 0xFFEEDDCC;
+  ECX = 0xBBAA9988;
+  EDX = 0x77665544;
+  EBX = 0x332211FF;
+  ESP = 0xEEDDCCBB;
+  EBP = 0xAA998877;
+  ESI = 0x66554433;
+  EDI = 0x2211FFEE;
+
+  al = AL;
+  cl = CL;
+  dl = DL;
+  bl = BL;
+  ah = AH;
+  ch = CH;
+  dh = DH;
+  bh = BH;
+
+  if ( al != (EAX & 0xFF) ||
+       cl != (ECX & 0xFF) ||
+       dl != (EDX & 0xFF) ||
+       bl != (EBX & 0xFF) ||
+       ah != ((EAX >> 8) & 0xFF) ||
+       ch != ((ECX >> 8) & 0xFF) ||
+       dh != ((EDX >> 8) & 0xFF) ||
+       bh != ((EBX >> 8) & 0xFF) ) {
+    BX_PANIC(("problems using BX_READ_8BIT_REG()!\n"));
+    }
+
+  ax = AX;
+  cx = CX;
+  dx = DX;
+  bx = BX;
+  sp = SP;
+  bp = BP;
+  si = SI;
+  di = DI;
+
+  if ( ax != (EAX & 0xFFFF) ||
+       cx != (ECX & 0xFFFF) ||
+       dx != (EDX & 0xFFFF) ||
+       bx != (EBX & 0xFFFF) ||
+       sp != (ESP & 0xFFFF) ||
+       bp != (EBP & 0xFFFF) ||
+       si != (ESI & 0xFFFF) ||
+       di != (EDI & 0xFFFF) ) {
+    BX_PANIC(("problems using BX_READ_16BIT_REG()!\n"));
+    }
+
+
+  eax = EAX;
+  ecx = ECX;
+  edx = EDX;
+  ebx = EBX;
+  esp = ESP;
+  ebp = EBP;
+  esi = ESI;
+  edi = EDI;
+
+
+  if (sizeof(Bit8u)  != 1  ||  sizeof(Bit8s)  != 1)
+    BX_PANIC(("data type Bit8u or Bit8s is not of length 1 byte!\n"));
+  if (sizeof(Bit16u) != 2  ||  sizeof(Bit16s) != 2)
+    BX_PANIC(("data type Bit16u or Bit16s is not of length 2 bytes!\n"));
+  if (sizeof(Bit32u) != 4  ||  sizeof(Bit32s) != 4)
+    BX_PANIC(("data type Bit32u or Bit32s is not of length 4 bytes!\n"));
+
+  BX_DEBUG(( "#(%u)all sanity checks passed!\n", BX_SIM_ID ));
+}
+
+
+  void
+BX_CPU_C::set_INTR(Boolean value)
+{
+  BX_CPU_THIS_PTR INTR = value;
+  BX_CPU_THIS_PTR async_event = 1;
+}
diff --git a/sid/component/bochs/cpu/io.cc b/sid/component/bochs/cpu/io.cc
new file mode 100644 (file)
index 0000000..2bed6f0
--- /dev/null
@@ -0,0 +1,389 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::INSB_YbDX(BxInstruction_t *i)
+{
+#if 0
+  Bit8u value8=0;
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+
+  if (i->as_32) {
+    // Write a zero to memory, to trigger any segment or page
+    // faults before reading from IO port.
+    write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
+
+    value8 = BX_INP(DX, 1);
+
+    /* no seg override possible */
+    write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      EDI = EDI - 1;
+      }
+    else {
+      EDI = EDI + 1;
+      }
+    }
+  else {
+    // Write a zero to memory, to trigger any segment or page
+    // faults before reading from IO port.
+    write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
+
+    value8 = BX_INP(DX, 1);
+
+    /* no seg override possible */
+    write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      DI = DI - 1;
+      }
+    else {
+      DI = DI + 1;
+      }
+    }
+#endif
+}
+
+  void
+BX_CPU_C::INSW_YvDX(BxInstruction_t *i)
+  // input word/doubleword from port to string
+{
+#if 0
+  Bit32u edi;
+  unsigned int incr;
+
+  if (i->as_32)
+    edi = EDI;
+  else
+    edi = DI;
+
+  if (i->os_32) {
+    Bit32u value32=0;
+
+    if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+      if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+
+    // Write a zero to memory, to trigger any segment or page
+    // faults before reading from IO port.
+    write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
+
+    value32 = BX_INP(DX, 4);
+
+    /* no seg override allowed */
+    write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
+    incr = 4;
+    }
+  else {
+    Bit16u value16=0;
+
+    if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+      if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+
+    // Write a zero to memory, to trigger any segment or page
+    // faults before reading from IO port.
+    write_virtual_word(BX_SEG_REG_ES, edi, &value16);
+
+    value16 = BX_INP(DX, 2);
+
+    /* no seg override allowed */
+    write_virtual_word(BX_SEG_REG_ES, edi, &value16);
+    incr = 2;
+    }
+
+  if (i->as_32) {
+    if (BX_CPU_THIS_PTR eflags.df)
+      EDI = EDI - incr;
+    else
+      EDI = EDI + incr;
+    }
+  else {
+    if (BX_CPU_THIS_PTR eflags.df)
+      DI = DI - incr;
+    else
+      DI = DI + incr;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::OUTSB_DXXb(BxInstruction_t *i)
+{
+#if 0
+  unsigned seg;
+  Bit8u value8;
+  Bit32u esi;
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+  if (i->as_32)
+    esi = ESI;
+  else
+    esi = SI;
+
+  read_virtual_byte(seg, esi, &value8);
+
+  BX_OUTP(DX, value8, 1);
+
+  if (i->as_32) {
+    if (BX_CPU_THIS_PTR eflags.df)
+      ESI -= 1;
+    else
+      ESI += 1;
+    }
+  else {
+    if (BX_CPU_THIS_PTR eflags.df)
+      SI -= 1;
+    else
+      SI += 1;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::OUTSW_DXXv(BxInstruction_t *i)
+  // output word/doubleword string to port
+{
+#if 0
+  unsigned seg;
+  Bit32u esi;
+  unsigned int incr;
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+  if (i->as_32)
+    esi = ESI;
+  else
+    esi = SI;
+
+  if (i->os_32) {
+    Bit32u value32;
+
+    if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+      if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+
+    read_virtual_dword(seg, esi, &value32);
+
+    BX_OUTP(DX, value32, 4);
+    incr = 4;
+    }
+  else {
+    Bit16u value16;
+
+    if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+      if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
+        exception(BX_GP_EXCEPTION, 0, 0);
+        }
+      }
+
+    read_virtual_word(seg, esi, &value16);
+
+    BX_OUTP(DX, value16, 2);
+    incr = 2;
+    }
+
+  if (i->as_32) {
+    if (BX_CPU_THIS_PTR eflags.df)
+      ESI = ESI - incr;
+    else
+      ESI = ESI + incr;
+    }
+  else {
+    if (BX_CPU_THIS_PTR eflags.df)
+      SI = SI - incr;
+    else
+      SI = SI + incr;
+    }
+#endif
+}
+
+
+  void
+BX_CPU_C::IN_ALIb(BxInstruction_t *i)
+{
+  Bit8u al, imm8;
+
+  imm8 = i->Ib;
+
+  al = BX_CPU_THIS_PTR inp8(imm8);
+
+  AL = al;
+}
+
+  void
+BX_CPU_C::IN_eAXIb(BxInstruction_t *i)
+{
+  Bit8u imm8;
+
+
+  imm8 = i->Ib;
+
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    Bit32u eax;
+
+    eax = BX_CPU_THIS_PTR inp32(imm8);
+    EAX = eax;
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    {
+    Bit16u ax;
+
+    ax = BX_CPU_THIS_PTR inp16(imm8);
+    AX = ax;
+    }
+}
+
+  void
+BX_CPU_C::OUT_IbAL(BxInstruction_t *i)
+{
+  Bit8u al, imm8;
+
+  imm8 = i->Ib;
+
+  al = AL;
+
+  BX_CPU_THIS_PTR outp8(imm8, al);
+}
+
+  void
+BX_CPU_C::OUT_IbeAX(BxInstruction_t *i)
+{
+  Bit8u imm8;
+
+  imm8 = i->Ib;
+
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    BX_CPU_THIS_PTR outp32(imm8, EAX);
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    {
+    BX_CPU_THIS_PTR outp16(imm8, AX);
+    }
+}
+
+  void
+BX_CPU_C::IN_ALDX(BxInstruction_t *i)
+{
+  Bit8u al;
+
+  al = BX_CPU_THIS_PTR inp8(DX);
+
+  AL = al;
+}
+
+  void
+BX_CPU_C::IN_eAXDX(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    Bit32u eax;
+
+    eax = BX_CPU_THIS_PTR inp32(DX);
+    EAX = eax;
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    {
+    Bit16u ax;
+
+    ax = BX_CPU_THIS_PTR inp16(DX);
+    AX = ax;
+    }
+}
+
+  void
+BX_CPU_C::OUT_DXAL(BxInstruction_t *i)
+{
+  Bit16u dx;
+  Bit8u al;
+
+  dx = DX;
+  al = AL;
+
+  BX_CPU_THIS_PTR outp8(dx, al);
+}
+
+  void
+BX_CPU_C::OUT_DXeAX(BxInstruction_t *i)
+{
+  Bit16u dx;
+
+  dx = DX;
+
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    BX_CPU_THIS_PTR outp32(dx, EAX);
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    {
+    BX_CPU_THIS_PTR outp16(dx, AX);
+    }
+}
diff --git a/sid/component/bochs/cpu/io_pro.cc b/sid/component/bochs/cpu/io_pro.cc
new file mode 100644 (file)
index 0000000..65d28e4
--- /dev/null
@@ -0,0 +1,204 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  Bit16u
+BX_CPU_C::inp16(Bit16u addr)
+{
+#if 0
+  Bit16u ret16;
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
+      // BX_INFO(("cpu_inp16: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return(0);
+      }
+    }
+
+  ret16 = BX_INP(addr, 2);
+  return( ret16 );
+#endif
+  return 0;
+}
+
+  void
+BX_CPU_C::outp16(Bit16u addr, Bit16u value)
+{
+#if 0
+  /* If CPL <= IOPL, then all IO addresses are accessible.
+   * Otherwise, must check the IO permission map on >286.
+   * On the 286, there is no IO permissions map */
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
+      // BX_INFO(("cpu_outp16: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  BX_OUTP(addr, value, 2);
+#endif
+}
+
+  Bit32u
+BX_CPU_C::inp32(Bit16u addr)
+{
+#if 0
+  Bit32u ret32;
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
+      // BX_INFO(("cpu_inp32: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return(0);
+      }
+    }
+
+  ret32 = BX_INP(addr, 4);
+  return( ret32 );
+#endif
+  return 0;
+}
+
+  void
+BX_CPU_C::outp32(Bit16u addr, Bit32u value)
+{
+#if 0
+  /* If CPL <= IOPL, then all IO addresses are accessible.
+   * Otherwise, must check the IO permission map on >286.
+   * On the 286, there is no IO permissions map */
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
+      // BX_INFO(("cpu_outp32: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  BX_OUTP(addr, value, 4);
+#endif 
+}
+
+  Bit8u
+BX_CPU_C::inp8(Bit16u addr)
+{
+#if 0
+  Bit8u ret8;
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
+      // BX_INFO(("cpu_inp8: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return(0);
+      }
+    }
+
+  ret8 = BX_INP(addr, 1);
+  return( ret8 );
+#endif
+  return 0;
+}
+
+
+  void
+BX_CPU_C::outp8(Bit16u addr, Bit8u value)
+{
+#if 0
+  /* If CPL <= IOPL, then all IO addresses are accessible.
+   * Otherwise, must check the IO permission map on >286.
+   * On the 286, there is no IO permissions map */
+
+  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
+      // BX_INFO(("cpu_outp8: GP0()!\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  BX_OUTP(addr, value, 1);
+#endif
+}
+
+
+  Boolean
+BX_CPU_C::allow_io(Bit16u addr, unsigned len)
+{
+#if 0
+  Bit16u io_base, permission16;
+  unsigned bit_index, i;
+
+  if (BX_CPU_THIS_PTR tr.cache.valid==0 || BX_CPU_THIS_PTR tr.cache.type!=9) {
+    BX_INFO(("allow_io(): TR doesn't point to a valid 32bit TSS\n"));
+    return(0);
+    }
+
+  if (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled < 103) {
+    BX_PANIC(("allow_io(): TR.limit < 103\n"));
+    }
+
+  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102, 2, 0, BX_READ,
+                         &io_base);
+  if (io_base <= 103) {
+BX_INFO(("PE is %u\n", BX_CPU_THIS_PTR cr0.pe));
+BX_INFO(("VM is %u\n", BX_CPU_THIS_PTR eflags.vm));
+BX_INFO(("CPL is %u\n", CPL));
+BX_INFO(("IOPL is %u\n", IOPL));
+BX_INFO(("addr is %u\n", addr));
+BX_INFO(("len is %u\n", len));
+    BX_PANIC(("allow_io(): TR:io_base <= 103\n"));
+    }
+
+  if (io_base > BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled) {
+    BX_INFO(("allow_io(): CPL > IOPL: no IO bitmap defined #GP(0)\n"));
+    return(0);
+    }
+
+  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base + addr/8,
+                   2, 0, BX_READ, &permission16);
+
+  bit_index = addr & 0x07;
+  permission16 >>= bit_index;
+  for (i=0; i<len; i++) {
+    if (permission16 & 0x01)
+      return(0);
+    permission16 >>= 1;
+    }
+#endif
+
+  return(1);
+}
diff --git a/sid/component/bochs/cpu/lazy_flags.cc b/sid/component/bochs/cpu/lazy_flags.cc
new file mode 100644 (file)
index 0000000..2d3f176
--- /dev/null
@@ -0,0 +1,801 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+
+  Boolean
+BX_CPU_C::get_CF(void)
+{
+  switch ( BX_CPU_THIS_PTR lf_flags_status & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR eflags.cf);
+
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_XADD8:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_8 <
+                              BX_CPU_THIS_PTR oszapc.op1_8);
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_XADD16:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_16 <
+                              BX_CPU_THIS_PTR oszapc.op1_16);
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_XADD32:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_32 <
+                              BX_CPU_THIS_PTR oszapc.op1_32);
+          break;
+        case BX_INSTR_ADC8:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.result_8 <
+             BX_CPU_THIS_PTR oszapc.op1_8) ||
+            (BX_CPU_THIS_PTR oszapc.prev_CF &&
+             BX_CPU_THIS_PTR oszapc.result_8 ==
+             BX_CPU_THIS_PTR oszapc.op1_8);
+          break;
+        case BX_INSTR_ADC16:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.result_16 <
+             BX_CPU_THIS_PTR oszapc.op1_16) ||
+            (BX_CPU_THIS_PTR oszapc.prev_CF &&
+             BX_CPU_THIS_PTR oszapc.result_16 ==
+             BX_CPU_THIS_PTR oszapc.op1_16);
+          break;
+        case BX_INSTR_ADC32:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.result_32 <
+             BX_CPU_THIS_PTR oszapc.op1_32) ||
+            (BX_CPU_THIS_PTR oszapc.prev_CF &&
+             BX_CPU_THIS_PTR oszapc.result_32 ==
+             BX_CPU_THIS_PTR oszapc.op1_32);
+          break;
+        case BX_INSTR_SUB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_8 <
+                              BX_CPU_THIS_PTR oszapc.op2_8);
+          break;
+        case BX_INSTR_SUB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_16 <
+                              BX_CPU_THIS_PTR oszapc.op2_16);
+          break;
+        case BX_INSTR_SUB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+          BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_32 <
+                              BX_CPU_THIS_PTR oszapc.op2_32);
+          break;
+        case BX_INSTR_SBB8:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_8 <
+             BX_CPU_THIS_PTR oszapc.result_8) ||
+            ((BX_CPU_THIS_PTR oszapc.op2_8==0xff) &&
+             BX_CPU_THIS_PTR oszapc.prev_CF);
+          break;
+        case BX_INSTR_SBB16:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_16 <
+             BX_CPU_THIS_PTR oszapc.result_16) ||
+            ((BX_CPU_THIS_PTR oszapc.op2_16==0xffff) &&
+             BX_CPU_THIS_PTR oszapc.prev_CF);
+          break;
+        case BX_INSTR_SBB32:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_32 <
+             BX_CPU_THIS_PTR oszapc.result_32) ||
+            ((BX_CPU_THIS_PTR oszapc.op2_32==0xffffffff) &&
+             BX_CPU_THIS_PTR oszapc.prev_CF);
+          break;
+        case BX_INSTR_NEG8:
+          BX_CPU_THIS_PTR eflags.cf =
+            BX_CPU_THIS_PTR oszapc.op1_8 != 0;
+          break;
+        case BX_INSTR_NEG16:
+          BX_CPU_THIS_PTR eflags.cf =
+            BX_CPU_THIS_PTR oszapc.op1_16 != 0;
+          break;
+        case BX_INSTR_NEG32:
+          BX_CPU_THIS_PTR eflags.cf =
+            BX_CPU_THIS_PTR oszapc.op1_32 != 0;
+          break;
+        case BX_INSTR_OR8:
+        case BX_INSTR_OR16:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND8:
+        case BX_INSTR_AND16:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_XOR32:
+          BX_CPU_THIS_PTR eflags.cf = 0;
+          break;
+        case BX_INSTR_SHR8:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_8 >>
+              (BX_CPU_THIS_PTR oszapc.op2_8 - 1)) & 0x01;
+          break;
+        case BX_INSTR_SHR16:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_16 >>
+              (BX_CPU_THIS_PTR oszapc.op2_16 - 1)) & 0x01;
+          break;
+        case BX_INSTR_SHR32:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_32 >>
+              (BX_CPU_THIS_PTR oszapc.op2_32 - 1)) & 0x01;
+          break;
+        case BX_INSTR_SHL8:
+          if (BX_CPU_THIS_PTR oszapc.op2_8 <= 8) {
+            BX_CPU_THIS_PTR eflags.cf =
+              (BX_CPU_THIS_PTR oszapc.op1_8 >>
+                (8 - BX_CPU_THIS_PTR oszapc.op2_8)) & 0x01;
+            }
+          else {
+            BX_CPU_THIS_PTR eflags.cf = 0;
+            }
+          break;
+        case BX_INSTR_SHL16:
+          if (BX_CPU_THIS_PTR oszapc.op2_16 <= 16) {
+            BX_CPU_THIS_PTR eflags.cf =
+              (BX_CPU_THIS_PTR oszapc.op1_16 >>
+                (16 - BX_CPU_THIS_PTR oszapc.op2_16)) & 0x01;
+            }
+          else {
+            BX_CPU_THIS_PTR eflags.cf = 0;
+            }
+          break;
+        case BX_INSTR_SHL32:
+          BX_CPU_THIS_PTR eflags.cf =
+            (BX_CPU_THIS_PTR oszapc.op1_32 >>
+              (32 - BX_CPU_THIS_PTR oszapc.op2_32)) & 0x01;
+          break;
+        default:
+          BX_PANIC(("get_CF: OSZAPC: unknown instr %u\n",
+            (unsigned) BX_CPU_THIS_PTR oszapc.instr));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xfffff0;
+      return(BX_CPU_THIS_PTR eflags.cf);
+
+    default:
+      BX_PANIC(("get_CF: unknown case\n"));
+      return(0);
+    }
+}
+
+
+  Boolean
+BX_CPU_C::get_AF(void)
+{
+  switch ( (BX_CPU_THIS_PTR lf_flags_status>>8) & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR eflags.af);
+
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_ADC8:
+        case BX_INSTR_SUB8:
+        case BX_INSTR_SBB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_XADD8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+          BX_CPU_THIS_PTR eflags.af =
+            ((BX_CPU_THIS_PTR oszapc.op1_8 ^
+              BX_CPU_THIS_PTR oszapc.op2_8) ^
+             BX_CPU_THIS_PTR oszapc.result_8) & 0x10;
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_ADC16:
+        case BX_INSTR_SUB16:
+        case BX_INSTR_SBB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_XADD16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+          BX_CPU_THIS_PTR eflags.af =
+            ((BX_CPU_THIS_PTR oszapc.op1_16 ^
+              BX_CPU_THIS_PTR oszapc.op2_16) ^
+             BX_CPU_THIS_PTR oszapc.result_16) & 0x10;
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_ADC32:
+        case BX_INSTR_SUB32:
+        case BX_INSTR_SBB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_XADD32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+          BX_CPU_THIS_PTR eflags.af =
+            ((BX_CPU_THIS_PTR oszapc.op1_32 ^
+              BX_CPU_THIS_PTR oszapc.op2_32) ^
+             BX_CPU_THIS_PTR oszapc.result_32) & 0x10;
+          break;
+        case BX_INSTR_NEG8:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszapc.op1_8 & 0x0f) > 0;
+          break;
+        case BX_INSTR_NEG16:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszapc.op1_16 & 0x0f) > 0;
+          break;
+        case BX_INSTR_NEG32:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszapc.op1_32 & 0x0f) > 0;
+          break;
+        case BX_INSTR_OR8:
+        case BX_INSTR_OR16:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND8:
+        case BX_INSTR_AND16:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_XOR32:
+        case BX_INSTR_SHR8:
+        case BX_INSTR_SHR16:
+        case BX_INSTR_SHR32:
+        case BX_INSTR_SHL8:
+        case BX_INSTR_SHL16:
+        case BX_INSTR_SHL32:
+          BX_CPU_THIS_PTR eflags.af = 0;
+          /* undefined */
+          break;
+        default:
+          BX_PANIC(("get_AF: OSZAPC: unknown instr %u\n",
+            (unsigned) BX_CPU_THIS_PTR oszapc.instr));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+      return(BX_CPU_THIS_PTR eflags.af);
+
+    case BX_LF_INDEX_OSZAP:
+      switch (BX_CPU_THIS_PTR oszap.instr) {
+        case BX_INSTR_INC8:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_8 & 0x0f) == 0;
+          break;
+        case BX_INSTR_INC16:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_16 & 0x0f) == 0;
+          break;
+        case BX_INSTR_INC32:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_32 & 0x0f) == 0;
+          break;
+        case BX_INSTR_DEC8:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_8 & 0x0f) == 0x0f;
+          break;
+        case BX_INSTR_DEC16:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_16 & 0x0f) == 0x0f;
+          break;
+        case BX_INSTR_DEC32:
+          BX_CPU_THIS_PTR eflags.af =
+            (BX_CPU_THIS_PTR oszap.result_32 & 0x0f) == 0x0f;
+          break;
+        default:
+          BX_PANIC(("get_AF: OSZAP: unknown instr %u\n",
+            (unsigned) BX_CPU_THIS_PTR oszap.instr));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+      return(BX_CPU_THIS_PTR eflags.af);
+
+    default:
+      BX_PANIC(("get_AF: unknown case\n"));
+      return(0);
+    }
+}
+
+
+  Boolean
+BX_CPU_C::get_ZF(void)
+{
+  switch ( (BX_CPU_THIS_PTR lf_flags_status>>12) & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR eflags.zf);
+
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_ADC8:
+        case BX_INSTR_SUB8:
+        case BX_INSTR_SBB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_NEG8:
+        case BX_INSTR_XADD8:
+        case BX_INSTR_OR8:
+        case BX_INSTR_AND8:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+        case BX_INSTR_SHR8:
+        case BX_INSTR_SHL8:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_8 == 0);
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_ADC16:
+        case BX_INSTR_SUB16:
+        case BX_INSTR_SBB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_NEG16:
+        case BX_INSTR_XADD16:
+        case BX_INSTR_OR16:
+        case BX_INSTR_AND16:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+        case BX_INSTR_SHR16:
+        case BX_INSTR_SHL16:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_16 == 0);
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_ADC32:
+        case BX_INSTR_SUB32:
+        case BX_INSTR_SBB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_NEG32:
+        case BX_INSTR_XADD32:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+        case BX_INSTR_SHR32:
+        case BX_INSTR_SHL32:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_32 == 0);
+          break;
+        default:
+          BX_PANIC(("get_ZF: OSZAPC: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+      return(BX_CPU_THIS_PTR eflags.zf);
+
+    case BX_LF_INDEX_OSZAP:
+      switch (BX_CPU_THIS_PTR oszap.instr) {
+        case BX_INSTR_INC8:
+        case BX_INSTR_DEC8:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_8 == 0);
+          break;
+        case BX_INSTR_INC16:
+        case BX_INSTR_DEC16:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_16 == 0);
+          break;
+        case BX_INSTR_INC32:
+        case BX_INSTR_DEC32:
+          BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_32 == 0);
+          break;
+        default:
+          BX_PANIC(("get_ZF: OSZAP: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+      return(BX_CPU_THIS_PTR eflags.zf);
+
+    default:
+      BX_PANIC(("get_ZF: unknown case\n"));
+      return(0);
+    }
+}
+
+
+  Boolean
+BX_CPU_C::get_SF(void)
+{
+  switch ( (BX_CPU_THIS_PTR lf_flags_status>>16) & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR eflags.sf);
+
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_ADC8:
+        case BX_INSTR_SUB8:
+        case BX_INSTR_SBB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_NEG8:
+        case BX_INSTR_XADD8:
+        case BX_INSTR_OR8:
+        case BX_INSTR_AND8:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+        case BX_INSTR_SHR8:
+        case BX_INSTR_SHL8:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszapc.result_8 >= 0x80);
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_ADC16:
+        case BX_INSTR_SUB16:
+        case BX_INSTR_SBB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_NEG16:
+        case BX_INSTR_XADD16:
+        case BX_INSTR_OR16:
+        case BX_INSTR_AND16:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+        case BX_INSTR_SHR16:
+        case BX_INSTR_SHL16:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszapc.result_16 >= 0x8000);
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_ADC32:
+        case BX_INSTR_SUB32:
+        case BX_INSTR_SBB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_NEG32:
+        case BX_INSTR_XADD32:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+        case BX_INSTR_SHR32:
+        case BX_INSTR_SHL32:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszapc.result_32 >= 0x80000000);
+          break;
+        default:
+          BX_PANIC(("get_SF: OSZAPC: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+      return(BX_CPU_THIS_PTR eflags.sf);
+
+    case BX_LF_INDEX_OSZAP:
+      switch (BX_CPU_THIS_PTR oszap.instr) {
+        case BX_INSTR_INC8:
+        case BX_INSTR_DEC8:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszap.result_8 >= 0x80);
+          break;
+        case BX_INSTR_INC16:
+        case BX_INSTR_DEC16:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszap.result_16 >= 0x8000);
+          break;
+        case BX_INSTR_INC32:
+        case BX_INSTR_DEC32:
+          BX_CPU_THIS_PTR eflags.sf =
+            (BX_CPU_THIS_PTR oszap.result_32 >= 0x80000000);
+          break;
+        default:
+          BX_PANIC(("get_SF: OSZAP: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+      return(BX_CPU_THIS_PTR eflags.sf);
+
+    default:
+      BX_PANIC(("get_SF: unknown case\n"));
+      return(0);
+    }
+}
+
+  Boolean
+BX_CPU_C::get_OF(void)
+{
+  Bit8u op1_b7, op2_b7, result_b7;
+  Bit16u op1_b15, op2_b15, result_b15;
+  Bit32u op1_b31, op2_b31, result_b31;
+
+  switch ( (BX_CPU_THIS_PTR lf_flags_status>>20) & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR eflags.of);
+
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_ADC8:
+        case BX_INSTR_XADD8:
+          op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
+          op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
+          result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b7 == op2_b7) && (result_b7 ^ op2_b7);
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_ADC16:
+        case BX_INSTR_XADD16:
+          op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
+          op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
+          result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b15 == op2_b15) && (result_b15 ^ op2_b15);
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_ADC32:
+        case BX_INSTR_XADD32:
+          op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
+          op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
+          result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b31 == op2_b31) && (result_b31 ^ op2_b31);
+          break;
+        case BX_INSTR_SUB8:
+        case BX_INSTR_SBB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+          op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
+          op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
+          result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b7 ^ op2_b7) && (op1_b7 ^ result_b7);
+          break;
+        case BX_INSTR_SUB16:
+        case BX_INSTR_SBB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+          op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
+          op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
+          result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b15 ^ op2_b15) && (op1_b15 ^ result_b15);
+          break;
+        case BX_INSTR_SUB32:
+        case BX_INSTR_SBB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+          op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
+          op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
+          result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
+
+          BX_CPU_THIS_PTR eflags.of =  (op1_b31 ^ op2_b31) && (op1_b31 ^ result_b31);
+          break;
+        case BX_INSTR_NEG8:
+          BX_CPU_THIS_PTR eflags.of =
+            (BX_CPU_THIS_PTR oszapc.op1_8 == 0x80);
+          break;
+        case BX_INSTR_NEG16:
+          BX_CPU_THIS_PTR eflags.of =
+            (BX_CPU_THIS_PTR oszapc.op1_16 == 0x8000);
+          break;
+        case BX_INSTR_NEG32:
+          BX_CPU_THIS_PTR eflags.of =
+            (BX_CPU_THIS_PTR oszapc.op1_32 == 0x80000000);
+          break;
+        case BX_INSTR_OR8:
+        case BX_INSTR_OR16:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND8:
+        case BX_INSTR_AND16:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_XOR32:
+          BX_CPU_THIS_PTR eflags.of = 0;
+          break;
+        case BX_INSTR_SHR8:
+          if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              (BX_CPU_THIS_PTR oszapc.op1_8 >= 0x80);
+          break;
+        case BX_INSTR_SHR16:
+          if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              (BX_CPU_THIS_PTR oszapc.op1_16 >= 0x8000);
+          break;
+        case BX_INSTR_SHR32:
+          if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              (BX_CPU_THIS_PTR oszapc.op1_32 >= 0x80000000);
+          break;
+        case BX_INSTR_SHL8:
+          if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              ((BX_CPU_THIS_PTR oszapc.op1_8 ^
+                BX_CPU_THIS_PTR oszapc.result_8) & 0x80) > 0;
+          break;
+        case BX_INSTR_SHL16:
+          if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              ((BX_CPU_THIS_PTR oszapc.op1_16 ^
+                BX_CPU_THIS_PTR oszapc.result_16) & 0x8000) > 0;
+          break;
+        case BX_INSTR_SHL32:
+          if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
+            BX_CPU_THIS_PTR eflags.of =
+              ((BX_CPU_THIS_PTR oszapc.op1_32 ^
+                BX_CPU_THIS_PTR oszapc.result_32) & 0x80000000) > 0;
+          break;
+        default:
+          BX_PANIC(("get_OF: OSZAPC: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+      return(BX_CPU_THIS_PTR eflags.of);
+
+    case BX_LF_INDEX_OSZAP:
+      switch (BX_CPU_THIS_PTR oszap.instr) {
+        case BX_INSTR_INC8:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_8 == 0x80;
+          break;
+        case BX_INSTR_INC16:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_16 == 0x8000;
+          break;
+        case BX_INSTR_INC32:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_32 == 0x80000000;
+          break;
+        case BX_INSTR_DEC8:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_8 == 0x7F;
+          break;
+        case BX_INSTR_DEC16:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_16 == 0x7FFF;
+          break;
+        case BX_INSTR_DEC32:
+          BX_CPU_THIS_PTR eflags.of =
+            BX_CPU_THIS_PTR oszap.result_32 == 0x7FFFFFFF;
+          break;
+        default:
+          BX_PANIC(("get_OF: OSZAP: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+      return(BX_CPU_THIS_PTR eflags.of);
+
+    default:
+      BX_PANIC(("get_OF: unknown case\n"));
+      return(0);
+    }
+}
+
+  Boolean
+BX_CPU_C::get_PF(void)
+{
+  switch ( (BX_CPU_THIS_PTR lf_flags_status>>4) & 0x00000f ) {
+    case BX_LF_INDEX_KNOWN:
+      return(BX_CPU_THIS_PTR lf_pf);
+    case BX_LF_INDEX_OSZAPC:
+      switch (BX_CPU_THIS_PTR oszapc.instr) {
+        case BX_INSTR_ADD8:
+        case BX_INSTR_ADC8:
+        case BX_INSTR_SUB8:
+        case BX_INSTR_SBB8:
+        case BX_INSTR_CMP8:
+        case BX_INSTR_NEG8:
+        case BX_INSTR_XADD8:
+        case BX_INSTR_OR8:
+        case BX_INSTR_AND8:
+        case BX_INSTR_TEST8:
+        case BX_INSTR_XOR8:
+        case BX_INSTR_CMPS8:
+        case BX_INSTR_SCAS8:
+        case BX_INSTR_SHR8:
+        case BX_INSTR_SHL8:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[BX_CPU_THIS_PTR oszapc.result_8];
+          break;
+        case BX_INSTR_ADD16:
+        case BX_INSTR_ADC16:
+        case BX_INSTR_SUB16:
+        case BX_INSTR_SBB16:
+        case BX_INSTR_CMP16:
+        case BX_INSTR_NEG16:
+        case BX_INSTR_XADD16:
+        case BX_INSTR_OR16:
+        case BX_INSTR_AND16:
+        case BX_INSTR_TEST16:
+        case BX_INSTR_XOR16:
+        case BX_INSTR_CMPS16:
+        case BX_INSTR_SCAS16:
+        case BX_INSTR_SHR16:
+        case BX_INSTR_SHL16:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_16];
+          break;
+        case BX_INSTR_ADD32:
+        case BX_INSTR_ADC32:
+        case BX_INSTR_SUB32:
+        case BX_INSTR_SBB32:
+        case BX_INSTR_CMP32:
+        case BX_INSTR_NEG32:
+        case BX_INSTR_XADD32:
+        case BX_INSTR_OR32:
+        case BX_INSTR_AND32:
+        case BX_INSTR_TEST32:
+        case BX_INSTR_XOR32:
+        case BX_INSTR_CMPS32:
+        case BX_INSTR_SCAS32:
+        case BX_INSTR_SHR32:
+        case BX_INSTR_SHL32:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_32];
+          break;
+        default:
+          BX_PANIC(("get_PF: OSZAPC: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+      return(BX_CPU_THIS_PTR lf_pf);
+
+    case BX_LF_INDEX_OSZAP:
+      switch (BX_CPU_THIS_PTR oszap.instr) {
+        case BX_INSTR_INC8:
+        case BX_INSTR_DEC8:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[BX_CPU_THIS_PTR oszap.result_8];
+          break;
+        case BX_INSTR_INC16:
+        case BX_INSTR_DEC16:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszap.result_16];
+          break;
+        case BX_INSTR_INC32:
+        case BX_INSTR_DEC32:
+          BX_CPU_THIS_PTR lf_pf =
+            bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszap.result_32];
+          break;
+        default:
+          BX_PANIC(("get_PF: OSZAP: unknown instr\n"));
+        }
+      BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+      return(BX_CPU_THIS_PTR lf_pf);
+
+    case BX_LF_INDEX_P:
+      BX_CPU_THIS_PTR lf_pf = bx_parity_lookup[BX_CPU_THIS_PTR eflags.pf_byte];
+      BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+      return(BX_CPU_THIS_PTR lf_pf);
+
+    default:
+      BX_PANIC(("get_PF: unknown case\n"));
+      return(0);
+    }
+}
diff --git a/sid/component/bochs/cpu/lazy_flags.h b/sid/component/bochs/cpu/lazy_flags.h
new file mode 100644 (file)
index 0000000..2709927
--- /dev/null
@@ -0,0 +1,125 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+
+#define BX_INSTR_ADD8   1
+#define BX_INSTR_ADD16  2
+#define BX_INSTR_ADD32  3
+
+#define BX_INSTR_SUB8   4
+#define BX_INSTR_SUB16  5
+#define BX_INSTR_SUB32  6
+
+#define BX_INSTR_ADC8   7
+#define BX_INSTR_ADC16  8
+#define BX_INSTR_ADC32  9
+
+#define BX_INSTR_SBB8   10
+#define BX_INSTR_SBB16  11
+#define BX_INSTR_SBB32  12
+
+#define BX_INSTR_CMP8   13
+#define BX_INSTR_CMP16  14
+#define BX_INSTR_CMP32  15
+
+#define BX_INSTR_INC8   16
+#define BX_INSTR_INC16  17
+#define BX_INSTR_INC32  18
+
+#define BX_INSTR_DEC8   19
+#define BX_INSTR_DEC16  20
+#define BX_INSTR_DEC32  21
+
+#define BX_INSTR_NEG8   22
+#define BX_INSTR_NEG16  23
+#define BX_INSTR_NEG32  24
+
+#define BX_INSTR_XADD8  25
+#define BX_INSTR_XADD16 26
+#define BX_INSTR_XADD32 27
+
+#define BX_INSTR_OR8    28
+#define BX_INSTR_OR16   29
+#define BX_INSTR_OR32   30
+
+#define BX_INSTR_AND8   31
+#define BX_INSTR_AND16  32
+#define BX_INSTR_AND32  33
+
+#define BX_INSTR_TEST8   34
+#define BX_INSTR_TEST16  35
+#define BX_INSTR_TEST32  36
+
+#define BX_INSTR_XOR8    37
+#define BX_INSTR_XOR16   38
+#define BX_INSTR_XOR32   39
+
+#define BX_INSTR_CMPS8   40
+#define BX_INSTR_CMPS16  41
+#define BX_INSTR_CMPS32  42
+
+#define BX_INSTR_SCAS8   43
+#define BX_INSTR_SCAS16  44
+#define BX_INSTR_SCAS32  45
+
+#define BX_INSTR_SHR8    46
+#define BX_INSTR_SHR16   47
+#define BX_INSTR_SHR32   48
+
+#define BX_INSTR_SHL8    49
+#define BX_INSTR_SHL16   50
+#define BX_INSTR_SHL32   51
+
+
+
+#define BX_LF_INDEX_KNOWN   0
+#define BX_LF_INDEX_OSZAPC  1
+#define BX_LF_INDEX_OSZAP   2
+#define BX_LF_INDEX_P       3
+
+#define BX_LF_MASK_OSZAPC 0x111111
+#define BX_LF_MASK_OSZAP  0x222220
+#define BX_LF_MASK_P      0x000030
+
+
+typedef struct {
+  Bit8u op1_8;
+  Bit8u op2_8;
+  Bit8u result_8;
+
+  Bit16u op1_16;
+  Bit16u op2_16;
+  Bit16u result_16;
+
+  Bit32u op1_32;
+  Bit32u op2_32;
+  Bit32u result_32;
+
+  Boolean prev_CF;
+  unsigned instr;
+  } bx_lf_flags_entry;
+
+
+#endif /* BX_PROVIDE_CPU_MEMORY==1 */
diff --git a/sid/component/bochs/cpu/logical16.cc b/sid/component/bochs/cpu/logical16.cc
new file mode 100644 (file)
index 0000000..5f35acf
--- /dev/null
@@ -0,0 +1,442 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::XOR_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 ^ op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+  void
+BX_CPU_C::XOR_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, result_16;
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    result_16 = op1_16 ^ op2_16;
+
+    /* now write result back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+  void
+BX_CPU_C::XOR_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, sum_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    sum_16 = op1_16 ^ op2_16;
+
+    /* now write sum back to destination */
+    AX = sum_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XOR16);
+}
+
+  void
+BX_CPU_C::XOR_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 ^ op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+  void
+BX_CPU_C::OR_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 | op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+  void
+BX_CPU_C::NOT_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16, result_16;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = ~op1_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+}
+
+
+  void
+BX_CPU_C::OR_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 | op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+  void
+BX_CPU_C::OR_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, result_16;
+
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    result_16 = op1_16 | op2_16;
+
+    /* now write result back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+  void
+BX_CPU_C::OR_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, sum_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    sum_16 = op1_16 | op2_16;
+
+    /* now write sum back to destination */
+    AX = sum_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_OR16);
+}
+
+
+
+  void
+BX_CPU_C::AND_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 & op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+  void
+BX_CPU_C::AND_GwEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, result_16;
+
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op2_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    result_16 = op1_16 & op2_16;
+
+    /* now write result back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+  void
+BX_CPU_C::AND_AXIw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, sum_16;
+
+    op1_16 = AX;
+
+    op2_16 = i->Iw;
+
+    sum_16 = op1_16 & op2_16;
+
+    /* now write sum back to destination */
+    AX = sum_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_AND16);
+}
+
+  void
+BX_CPU_C::AND_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 & op2_16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+  void
+BX_CPU_C::TEST_EwGw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    /* op2_16 is a register, op2_addr is an index of a register */
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 & op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
+
+
+
+  void
+BX_CPU_C::TEST_AXIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+    op1_16 = AX;
+
+    /* op2_16 is imm16 */
+    op2_16 = i->Iw;
+
+    result_16 = op1_16 & op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
+
+
+  void
+BX_CPU_C::TEST_EwIw(BxInstruction_t *i)
+{
+    Bit16u op2_16, op1_16, result_16;
+
+
+    /* op2_16 is imm16 */
+    op2_16 = i->Iw;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    result_16 = op1_16 & op2_16;
+
+    SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
diff --git a/sid/component/bochs/cpu/logical32.cc b/sid/component/bochs/cpu/logical32.cc
new file mode 100644 (file)
index 0000000..d68ee80
--- /dev/null
@@ -0,0 +1,435 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::XOR_EdGd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 ^ op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+  void
+BX_CPU_C::XOR_GdEd(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, result_32;
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    result_32 = op1_32 ^ op2_32;
+
+    /* now write result back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+  void
+BX_CPU_C::XOR_EAXId(BxInstruction_t *i)
+{
+    /* for 32 bit operand size mode */
+    Bit32u op1_32, op2_32, sum_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    sum_32 = op1_32 ^ op2_32;
+
+    /* now write sum back to destination */
+    EAX = sum_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XOR32);
+}
+
+  void
+BX_CPU_C::XOR_EdId(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 ^ op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+  void
+BX_CPU_C::OR_EdId(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 | op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+  void
+BX_CPU_C::NOT_Ed(BxInstruction_t *i)
+{
+    Bit32u op1_32, result_32;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = ~op1_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+}
+
+
+  void
+BX_CPU_C::OR_EdGd(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 | op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+
+  void
+BX_CPU_C::OR_GdEd(BxInstruction_t *i)
+{
+    Bit32u op1_32, op2_32, result_32;
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    result_32 = op1_32 | op2_32;
+
+    /* now write result back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+
+  void
+BX_CPU_C::OR_EAXId(BxInstruction_t *i)
+{
+    Bit32u op1_32, op2_32, sum_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    sum_32 = op1_32 | op2_32;
+
+    /* now write sum back to destination */
+    EAX = sum_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_OR32);
+}
+
+
+
+  void
+BX_CPU_C::AND_EdGd(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 & op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+  void
+BX_CPU_C::AND_GdEd(BxInstruction_t *i)
+{
+    Bit32u op1_32, op2_32, result_32;
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op2_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    result_32 = op1_32 & op2_32;
+
+    /* now write result back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+  void
+BX_CPU_C::AND_EAXId(BxInstruction_t *i)
+{
+    Bit32u op1_32, op2_32, sum_32;
+
+    op1_32 = EAX;
+
+    op2_32 = i->Id;
+
+    sum_32 = op1_32 & op2_32;
+
+    /* now write sum back to destination */
+    EAX = sum_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_AND32);
+}
+
+  void
+BX_CPU_C::AND_EdId(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 & op2_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+  void
+BX_CPU_C::TEST_EdGd(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op2_32 is a register, op2_addr is an index of a register */
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 & op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
+
+
+
+  void
+BX_CPU_C::TEST_EAXId(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op1 is EAX register */
+    op1_32 = EAX;
+
+    /* op2 is imm32 */
+    op2_32 = i->Id;
+
+    result_32 = op1_32 & op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
+
+
+  void
+BX_CPU_C::TEST_EdId(BxInstruction_t *i)
+{
+    Bit32u op2_32, op1_32, result_32;
+
+    /* op2 is imm32 */
+    op2_32 = i->Id;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    result_32 = op1_32 & op2_32;
+
+    SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
diff --git a/sid/component/bochs/cpu/logical8.cc b/sid/component/bochs/cpu/logical8.cc
new file mode 100644 (file)
index 0000000..0b40047
--- /dev/null
@@ -0,0 +1,442 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+  void
+BX_CPU_C::XOR_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 ^ op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+  void
+BX_CPU_C::XOR_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, result;
+
+  op1 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  result = op1 ^ op2;
+
+  /* now write result back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, result);
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+
+  void
+BX_CPU_C::XOR_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+
+  op1 = AL;
+
+  op2 = i->Ib;
+
+  sum = op1 ^ op2;
+
+  /* now write sum back to destination, which is a register */
+  AL = sum;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_XOR8);
+}
+
+
+  void
+BX_CPU_C::XOR_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 ^ op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+
+
+  void
+BX_CPU_C::OR_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 | op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+  void
+BX_CPU_C::NOT_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  result_8 = ~op1_8;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_RMW_virtual_byte(result_8);
+    }
+}
+
+
+  void
+BX_CPU_C::OR_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 | op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+  void
+BX_CPU_C::OR_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, result;
+
+
+  op1 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  result = op1 | op2;
+
+  /* now write result back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, result);
+
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+  void
+BX_CPU_C::OR_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+
+
+  op1 = AL;
+
+  op2 = i->Ib;
+
+  sum = op1 | op2;
+
+  /* now write sum back to destination, which is a register */
+  AL = sum;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_OR8);
+}
+
+
+
+  void
+BX_CPU_C::AND_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 & op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+  void
+BX_CPU_C::AND_GbEb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, result;
+
+  op1 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  result = op1 & op2;
+
+  /* now write result back to destination, which is a register */
+  BX_WRITE_8BIT_REG(i->nnn, result);
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+  void
+BX_CPU_C::AND_ALIb(BxInstruction_t *i)
+{
+  Bit8u op1, op2, sum;
+
+
+  op1 = AL;
+
+  op2 = i->Ib;
+
+  sum = op1 & op2;
+
+  /* now write sum back to destination, which is a register */
+  AL = sum;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_AND8);
+}
+
+
+
+
+  void
+BX_CPU_C::AND_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 & op2;
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result);
+    }
+  else {
+    write_RMW_virtual_byte(result);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+  void
+BX_CPU_C::TEST_EbGb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  /* op2 is a register, op2_addr is an index of a register */
+  op2 = BX_READ_8BIT_REG(i->nnn);
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 & op2;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
+
+
+  void
+BX_CPU_C::TEST_ALIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  /* op1 is the AL register */
+  op1 = AL;
+
+  /* op2 is imm8 */
+  op2 = i->Ib;
+
+  result = op1 & op2;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
+
+
+
+  void
+BX_CPU_C::TEST_EbIb(BxInstruction_t *i)
+{
+  Bit8u op2, op1, result;
+
+  op2 = i->Ib;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op1);
+    }
+
+  result = op1 & op2;
+
+  SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
diff --git a/sid/component/bochs/cpu/main-hack.cc b/sid/component/bochs/cpu/main-hack.cc
new file mode 100644 (file)
index 0000000..e389654
--- /dev/null
@@ -0,0 +1,1269 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#include "bochs.h"
+#include <assert.h>
+#include "state_file.h"
+
+extern "C" {
+#include <signal.h>
+}
+
+#ifdef __MINGW32__
+void alarm(int);
+#endif
+
+
+#if BX_PROVIDE_DEVICE_MODELS==1
+// some prototypes from iodev/
+// I want to stay away from including iodev/iodev.h here
+Bit32u bx_unmapped_io_read_handler(Bit32u address, unsigned io_len);
+void   bx_unmapped_io_write_handler(Bit32u address, Bit32u value,
+                                    unsigned io_len);
+void   bx_close_harddrive(void);
+#endif
+
+
+
+void bx_init_debug(void);
+void bx_emulate_hga_dumps_timer(void);
+static char *divider = "========================================================================";
+
+
+/* typedefs */
+
+
+#if ( BX_PROVIDE_DEVICE_MODELS==1 )
+bx_pc_system_c bx_pc_system;
+class state_file state_stuff("state_file.out", "options");
+#endif
+
+bx_debug_t bx_dbg;
+
+bx_options_t bx_options = {
+  { "", BX_FLOPPY_NONE, BX_EJECTED },   // floppya
+  { "", BX_FLOPPY_NONE, BX_EJECTED },   // floppyb
+  { 0, "", 0, 0, 0 },                   // diskc
+  { 0, "", 0, 0, 0 },                   // diskd
+  { 0, "", 0 },                         // cdromd
+  { NULL, 0 },                          // rom
+  { NULL },                             // vgarom
+  { BX_DEFAULT_MEM_MEGS },              // memory
+  { NULL, NULL, NULL, 0, 0, 0, 0 },     // SB16
+  "a",                                  // boot drive
+  300000,                               // vga update interval
+  20000,  // default keyboard serial path delay (usec)
+  50000,  // default floppy command delay (usec)
+  500000,  // default ips (instructions-per-second)
+  0,       // default mouse_enabled
+  0,       // default private_colormap
+  0,          // default i440FXSupport
+  {NULL, 0},  // cmos path, cmos image boolean
+  { 0, 0, 0, {0,0,0,0,0,0}, NULL, NULL }, // ne2k
+  1,          // newHardDriveSupport
+  { 0, NULL, NULL, NULL }, // load32bitOSImage hack stuff
+  { 
+    ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL 
+  }  // ignore debugs, report infos and errors, fatal on panics.
+  };
+
+static char bochsrc_path[512];
+static char logfilename[512] = "-";
+
+
+static void parse_line_unformatted(char *line);
+static void parse_line_formatted(int num_params, char *params[]);
+static void parse_bochsrc(int argc);
+
+
+// Just for the iofunctions
+
+#define LOG_THIS this->log->
+
+int Allocio=0;
+
+void
+iofunctions::flush(void) {
+       if(logfd && magic == MAGIC_LOGNUM) {
+               fflush(logfd);
+       }
+}
+
+void
+iofunctions::init(void) {
+       // iofunctions methods must not be called before this magic
+       // number is set.
+       magic=MAGIC_LOGNUM;
+       showtick = 1;
+       n_logfn = 0;
+       init_log(stderr);
+       log = new logfunc_t(this);
+       LOG_THIS setprefix("[IO  ]");
+       LOG_THIS settype(IOLOG);
+       BX_DEBUG(("Init(log file: '%s').\n",logfn));
+}
+
+void
+iofunctions::add_logfn (logfunc_t *fn)
+{
+  assert (n_logfn < MAX_LOGFNS);
+  logfn_list[n_logfn++] = fn;
+}
+
+void
+iofunctions::set_log_action (int loglevel, int action)
+{
+  for (int i=0; i<n_logfn; i++)
+    logfn_list[i]->setonoff(loglevel, action);
+}
+
+void
+iofunctions::init_log(char *fn)
+{
+       assert (magic==MAGIC_LOGNUM);
+       // use newfd/newfn so that we can log the message to the OLD log
+       // file descriptor.
+       FILE *newfd = stderr;
+       char *newfn = "/dev/stderr";
+       if( strcmp( fn, "-" ) != 0 ) {
+               newfd = fopen(fn, "w");
+               if(newfd != NULL) {
+                       newfn = strdup(fn);
+                       BX_DEBUG(("Opened log file '%s'.\n", fn ));
+               } else {
+                       BX_DEBUG(("Log file '%s' not there?\n", fn));
+                       newfd = NULL;
+                       logfn = "(none)";
+               }
+       }
+       logfd = newfd;
+       logfn = newfn;
+}
+
+void
+iofunctions::init_log(FILE *fs)
+{
+       assert (magic==MAGIC_LOGNUM);
+       logfd = fs;
+
+       if(fs == stderr) {
+               logfn = "/dev/stderr";
+       } else if(fs == stdout) { 
+               logfn = "/dev/stdout";
+       } else {
+               logfn = "(unknown)";
+       }
+}
+
+void
+iofunctions::init_log(int fd)
+{
+       assert (magic==MAGIC_LOGNUM);
+       FILE *tmpfd;
+       if( (tmpfd = fdopen(fd,"w")) == NULL ) {
+         BX_PANIC(("Couldn't open fd %d as a stream for writing\n", fd));
+         return;
+       }
+
+       init_log(tmpfd);
+       return;
+};
+
+//  iofunctions::out( class, level, prefix, fmt, ap)
+//  DO NOT nest out() from ::info() and the like.
+//    fmt and ap retained for direct printinf from iofunctions only!
+
+void
+iofunctions::out(int f, int l, char *prefix, char *fmt, va_list ap)
+{
+       assert (magic==MAGIC_LOGNUM);
+       assert (this != NULL);
+       assert (logfd != NULL);
+
+#if BX_PROVIDE_DEVICE_MODELS
+       if( showtick )
+               fprintf(logfd, "%011lld ", bx_pc_system.time_ticks());
+#endif
+       if(prefix != NULL)
+               fprintf(logfd, "%s ", prefix);
+
+       if(l==LOGLEV_PANIC)
+               fprintf(logfd, ">>PANIC<< ");
+
+       vfprintf(logfd, fmt, ap);
+       fflush(logfd);
+
+       return;
+}
+
+iofunctions::iofunctions(FILE *fs)
+{
+       init();
+       init_log(fs);
+}
+
+iofunctions::iofunctions(char *fn)
+{
+       init();
+       init_log(fn);
+}
+
+iofunctions::iofunctions(int fd)
+{
+       init();
+       init_log(fd);
+}
+
+iofunctions::iofunctions(void)
+{
+       this->init();
+}
+
+iofunctions::~iofunctions(void)
+{
+       // flush before erasing magic number, or flush does nothing.
+       this->flush();
+       this->magic=0;
+}
+
+#undef LOG_THIS
+#define LOG_THIS genlog->
+
+logfunctions::logfunctions(void)
+{
+       setprefix("[    ]");
+       settype(GENLOG);
+       if(io == NULL && Allocio == 0) {
+               Allocio = 1;
+               io = new iofunc_t(stderr);
+       }
+       setio(io);
+       // BUG: unfortunately this can be called before the bochsrc is read,
+       // which means that the bochsrc has no effect on the actions.
+       for (int i=0; i<MAX_LOGLEV; i++)
+         onoff[i] = bx_options.log_actions[i];
+}
+
+logfunctions::logfunctions(iofunc_t *iofunc)
+{
+       setprefix("[    ]");
+       settype(GENLOG);
+       setio(iofunc);
+       // BUG: unfortunately this can be called before the bochsrc is read,
+       // which means that the bochsrc has no effect on the actions.
+       for (int i=0; i<MAX_LOGLEV; i++)
+         onoff[i] = bx_options.log_actions[i];
+}
+
+logfunctions::~logfunctions(void)
+{
+}
+
+void
+logfunctions::setio(iofunc_t *i)
+{
+       // add pointer to iofunction object to use
+       this->logio = i;
+       // give iofunction a pointer to me
+       i->add_logfn (this);
+}
+
+void
+logfunctions::setprefix(char *p)
+{
+       this->prefix=strdup(p);
+}
+
+void
+logfunctions::settype(int t)
+{
+       type=t;
+}
+
+void
+logfunctions::info(char *fmt, ...)
+{
+       va_list ap;
+       FILE *fs;
+
+       assert (this != NULL);
+       assert (this->logio != NULL);
+
+       if(!onoff[LOGLEV_INFO]) return;
+
+       va_start(ap, fmt);
+       this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap);
+       if (onoff[LOGLEV_INFO] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+       va_end(ap);
+
+}
+
+void
+logfunctions::error(char *fmt, ...)
+{
+       va_list ap;
+       FILE *fs;
+
+       assert (this != NULL);
+       assert (this->logio != NULL);
+
+       if(!onoff[LOGLEV_ERROR]) return;
+
+       va_start(ap, fmt);
+       this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap);
+       if (onoff[LOGLEV_ERROR] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+       va_end(ap);
+}
+
+void
+logfunctions::panic(char *fmt, ...)
+{
+       va_list ap;
+       FILE *fs;
+
+       assert (this != NULL);
+       assert (this->logio != NULL);
+
+       if(!onoff[LOGLEV_PANIC]) return;
+
+       va_start(ap, fmt);
+       this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap);
+       if (onoff[LOGLEV_PANIC] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+       va_end(ap);
+}
+
+void
+logfunctions::ldebug(char *fmt, ...)
+{
+       va_list ap;
+       FILE *fs;
+
+       assert (this != NULL);
+       assert (this->logio != NULL);
+
+       if(!onoff[LOGLEV_DEBUG]) return;
+
+       va_start(ap, fmt);
+       this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap);
+       if (onoff[LOGLEV_DEBUG] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+       va_end(ap);
+}
+
+void
+logfunctions::fatal (char *prefix, char *fmt, va_list ap)
+{
+  static int fatal_reentry = 0;
+  if (fatal_reentry) return;
+  fatal_reentry++;
+  bx_atexit();
+  fprintf (stderr, "%s\n", divider);
+  fprintf (stderr, "Bochs is exiting with the following message:\n");
+  fprintf (stderr, "%s ", prefix);
+  vfprintf (stderr, fmt, ap);
+  fprintf (stderr, "%s\n", divider);
+#if 0 && defined(WIN32)
+#error disabled because it  is not working yet!
+  // wait for a keypress before quitting.  Depending on how bochs is
+  // installed, the console window can disappear before the user has
+  // a chance to read the final message.
+  fprintf (stderr, "\n\nPress Enter to exit...\n");
+  char buf[8];
+  fgets (buf, 8, stdin);
+#endif
+#if !BX_DEBUGGER
+  exit(1);
+#else
+  static Boolean dbg_exit_called = 0;
+  if (dbg_exit_called == 0) {
+    dbg_exit_called = 1;
+    bx_dbg_exit(1);
+    }
+#endif
+  fatal_reentry--;
+}
+
+iofunc_t *io = NULL;
+logfunc_t *genlog = NULL;
+
+void bx_center_print (FILE *file, char *line, int maxwidth)
+{
+  int imax;
+  imax = (maxwidth - strlen(line)) >> 1;
+  for (int i=0; i<imax; i++) fputc (' ', file);
+  fputs (line, file);
+}
+
+void bx_print_header ()
+{
+  fprintf (stderr, "%s\n", divider);
+  char buffer[128];
+  sprintf (buffer, "Bochs x86 Emulator %s\n", VER_STRING);
+  bx_center_print (stderr, buffer, 72);
+  if (REL_STRING[0]) {
+    sprintf (buffer, "%s\n", REL_STRING);
+    bx_center_print (stderr, buffer, 72);
+  }
+  fprintf (stderr, "%s\n", divider);
+}
+
+
+#if BX_SUPPORT_SID==0
+int
+main(int argc, char *argv[])
+{
+  // To deal with initialization order problems inherent in C++, use
+  // the macros SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog"
+  // in all constructors or functions called by constructors.  The macros
+  // test for NULL and create the object if necessary, then return it.
+  // Ensure that io and genlog get created, by making one reference to
+  // each macro right here.  All other code can call them directly.
+  SAFE_GET_IOFUNC();
+  SAFE_GET_GENLOG();
+
+  bx_print_header ();
+
+#if BX_DEBUGGER
+  // If using the debugger, it will take control and call
+  // bx_bochs_init() and cpu_loop()
+  bx_dbg_main(argc, argv);
+#else
+  // If not using the debugger, pass control on normally
+  bx_bochs_init(argc, argv);
+
+  if (bx_options.load32bitOSImage.whichOS) {
+    void bx_load32bitOSimagehack(void);
+    bx_load32bitOSimagehack();
+    }
+
+  if (BX_SMP_PROCESSORS == 1) {
+    // only one processor, run as fast as possible by not messing with
+    // quantums and loops.
+    BX_CPU(0)->cpu_loop(1);
+  } else {
+    // SMP simulation: do 5 instructions on each processor, then switch
+    // to another.  I'm sure that increasing quantum speeds up overall
+    // performance.
+    int processor = 0;
+    int quantum = 5;
+    while (1) {
+      // do some instructions in each processor
+      BX_CPU(processor)->cpu_loop(quantum);
+      processor = (processor+1) % BX_SMP_PROCESSORS;
+      if (processor == 0) 
+       BX_TICKN(quantum);
+    }
+  }
+#endif
+
+  return(0);
+}
+#endif // BX_SUPPORT_SID
+
+
+  int
+bx_bochs_init(int argc, char *argv[])
+{
+  int n;
+
+#ifdef MAGIC_BREAKPOINT
+  bx_dbg.magic_break_enabled = 0;
+#endif
+#if BX_PROVIDE_MAIN
+  /* read the .bochsrc file */
+  parse_bochsrc(argc);
+#endif
+  for (int level=0; level<MAX_LOGLEV; level++)
+    io->set_log_action (level, bx_options.log_actions[level]);
+
+//#if BX_PROVIDE_CPU_MEMORY==1
+//    else if (!strcmp(argv[n-1], "-sanity-check")) {
+//      BX_CPU.sanity_checks();
+//      n += 1;
+//      exit(0);
+//      }
+//#endif
+
+  // Pass all command line options to be parsed,
+  // just like they came from the .bochsrc.  Thus
+  // command line options will override .bochsrc options.
+#if BX_SUPPORT_SID==0
+  n = 2;
+  while (n <= argc) {
+    parse_line_unformatted(argv[n-1]);
+    n++;
+    }
+#endif
+#if BX_PROVIDE_DEVICE_MODELS
+  bx_pc_system.init_ips(bx_options.ips);
+#endif
+  if(logfilename[0]!='-') {
+    BX_INFO (("using log file %s\n", logfilename));
+    io->init_log(logfilename);
+  }
+
+  // set up memory and CPU objects
+#if BX_SUPPORT_APIC
+  memset(apic_index, 0, sizeof(apic_index[0]) * APIC_MAX_ID);
+#endif
+
+#if BX_SMP_PROCESSORS==1
+  BX_MEM(0)->init_memory(bx_options.memory.megs * 1024*1024);
+  BX_MEM(0)->load_ROM(bx_options.rom.path, bx_options.rom.address);
+  BX_MEM(0)->load_ROM(bx_options.vgarom.path, 0xc0000);
+  BX_CPU(0)->init (BX_MEM(0));
+  BX_CPU(0)->reset(BX_RESET_HARDWARE);
+#else
+  // SMP initialization
+  bx_mem_array[0] = new BX_MEM_C ();
+  bx_mem_array[0]->init_memory(bx_options.memory.megs * 1024*1024);
+  bx_mem_array[0]->load_ROM(bx_options.rom.path, bx_options.rom.address);
+  bx_mem_array[0]->load_ROM(bx_options.vgarom.path, 0xc0000);
+  for (int i=0; i<BX_SMP_PROCESSORS; i++) {
+    BX_CPU(i) = new BX_CPU_C ();
+    BX_CPU(i)->init (bx_mem_array[0]);
+    // assign apic ID from the index of this loop
+    // if !BX_SUPPORT_APIC, this will not compile.
+    BX_CPU(i)->local_apic.set_id (i);
+    BX_CPU(i)->reset(BX_RESET_HARDWARE);
+  }
+#endif
+
+  bx_init_debug();
+
+#if BX_DEBUGGER == 0
+#if BX_SUPPORT_SID==0
+  bx_devices.init(BX_MEM(0));
+  bx_gui.init_signal_handlers ();
+  bx_pc_system.start_timers();
+#endif
+#endif
+  BX_INFO(("bx_bochs_init is setting signal handlers\n"));
+// if not using debugger, then we can take control of SIGINT.
+// If using debugger, it needs control of this.
+#if BX_DEBUGGER==0
+  signal(SIGINT, bx_signal_handler);
+#endif
+
+#if BX_SHOW_IPS
+#ifndef __MINGW32__
+  signal(SIGALRM, bx_signal_handler);
+#endif
+  alarm( 1 );
+#endif
+
+  return(0);
+}
+
+
+
+  void
+bx_init_debug(void)
+{
+  bx_dbg.floppy = 0;
+  bx_dbg.keyboard = 0;
+  bx_dbg.video = 0;
+  bx_dbg.disk = 0;
+  bx_dbg.pit = 0;
+  bx_dbg.pic = 0;
+  bx_dbg.bios = 0;
+  bx_dbg.cmos = 0;
+  bx_dbg.a20 = 0;
+  bx_dbg.interrupts = 0;
+  bx_dbg.exceptions = 0;
+  bx_dbg.unsupported = 0;
+  bx_dbg.temp = 0;
+  bx_dbg.reset = 0;
+  bx_dbg.mouse = 0;
+  bx_dbg.io = 0;
+  bx_dbg.debugger = 0;
+  bx_dbg.xms = 0;
+  bx_dbg.v8086 = 0;
+  bx_dbg.paging = 0;
+  bx_dbg.creg = 0;
+  bx_dbg.dreg = 0;
+  bx_dbg.dma = 0;
+  bx_dbg.unsupported_io = 0;
+  bx_dbg.record_io = 0;
+  bx_dbg.serial = 0;
+  bx_dbg.cdrom = 0;
+}
+
+
+  void
+bx_atexit(void)
+{
+  static Boolean been_here = 0;
+
+
+#if BX_PROVIDE_DEVICE_MODELS==1
+  if (been_here == 0) {
+    bx_pc_system.exit();
+    }
+#endif
+
+#if BX_DEBUGGER == 0
+  for (int cpu=0; cpu<BX_SMP_PROCESSORS; cpu++)
+    if (BX_CPU(cpu)) BX_CPU(cpu)->atexit();
+#endif
+
+#if BX_PCI_SUPPORT
+    if (bx_options.i440FXSupport) {
+      bx_devices.pci->print_i440fx_state();
+      }
+#endif
+}
+
+#if (BX_PROVIDE_CPU_MEMORY==1) && (BX_EMULATE_HGA_DUMPS>0)
+  void
+bx_emulate_hga_dumps_timer(void)
+{
+  void bx_hga_set_video_memory(Bit8u *ptr);
+
+  bx_hga_set_video_memory(&bx_phy_memory[0xb0000]);
+}
+#endif
+
+
+#if BX_PROVIDE_MAIN
+  static void
+parse_bochsrc(int argc)
+{
+  FILE *fd = NULL;
+  char *ret;
+  char line[512];
+  Bit32u retry = 0, found = 0;
+
+  // try several possibilities for the bochsrc before giving up
+  while (!found) {
+    bochsrc_path[0] = 0;
+    switch (retry++) {
+    case 0: strcpy (bochsrc_path, ".bochsrc"); break;
+    case 1: strcpy (bochsrc_path, "bochsrc"); break;
+    case 2: strcpy (bochsrc_path, "bochsrc.txt"); break;
+    case 3:
+#if (!defined(WIN32) && !defined(macintosh))
+      // only try this on unix
+      {
+      char *ptr = getenv("HOME");
+      if (ptr) sprintf (bochsrc_path, "%s/.bochsrc", ptr);
+      }
+#endif
+      break;
+    default:
+      // no bochsrc used.  This is still legal since they may have 
+      // everything on the command line.  However if they have no
+      // arguments then give them some friendly advice.
+      BX_INFO(( "could not find a bochsrc file\n"));
+      if (argc==1) {
+       fprintf (stderr, "%s\n", divider);
+       fprintf (stderr, "Before running Bochs, you should cd to a directory which contains\n");
+       fprintf (stderr, "a .bochsrc file and a disk image.  If you downloaded a binary package,\n");
+       fprintf (stderr, "all the necessary files are already on your disk.\n");
+#if defined(WIN32)
+       fprintf (stderr, "\nFor Windows installations, go to the dlxlinux direectory and\n");
+       fprintf (stderr, "double-click on the start.bat script.\n");
+#elif !defined(macintosh)
+       fprintf (stderr, "\nFor UNIX installations, try running \"bochs-dlx\" for a demo.  This script\n");
+       fprintf (stderr, "is basically equivalent to typing:\n");
+       fprintf (stderr, "   cd /usr/local/bochs/dlxlinux\n");
+       fprintf (stderr, "   bochs\n");
+#endif
+       exit(1);
+      }
+      return;
+    }
+    if (bochsrc_path[0]) {
+      BX_INFO (("looking for configuration in %s\n", bochsrc_path));
+      fd = fopen(bochsrc_path, "r");
+      if (fd) found = 1;
+    }
+  }
+  assert (fd != NULL && bochsrc_path[0] != 0);
+
+  BX_INFO(("reading configuration from %s\n", bochsrc_path));
+
+#if BX_SUPPORT_SID==0
+  do {
+    ret = fgets(line, sizeof(line)-1, fd);
+    line[sizeof(line) - 1] = '\0';
+    int len = strlen(line);
+    if (len>0)
+      line[len-1] = '\0';
+
+    if ((ret != NULL) && strlen(line)) {
+      parse_line_unformatted(line);
+      }
+    } while (!feof(fd));
+#endif
+}
+
+  static void
+parse_line_unformatted(char *line)
+{
+  char *ptr;
+  unsigned i, string_i;
+  char string[512];
+  char *params[40];
+  int num_params;
+  Boolean inquotes = 0;
+
+  if (line == NULL) return;
+
+  // if passed nothing but whitespace, just return
+  for (i=0; i<strlen(line); i++) {
+    if (!isspace(line[i])) break;
+    }
+  if (i>=strlen(line))
+    return;
+
+  num_params = 0;
+
+  ptr = strtok(line, ":");
+  while (ptr) {
+    string_i = 0;
+    for (i=0; i<strlen(ptr); i++) {
+      if (ptr[i] == '"')
+        inquotes = !inquotes;
+      else
+        if (!isspace(ptr[i]) || inquotes) {
+          string[string_i++] = ptr[i];
+          }
+      }
+    string[string_i] = '\0';
+    strcpy(ptr, string);
+    params[num_params++] = ptr;
+    ptr = strtok(NULL, ",");
+    }
+  parse_line_formatted(num_params, &params[0]);
+}
+
+  static void
+parse_line_formatted(int num_params, char *params[])
+{
+  int i;
+
+  if (num_params < 1) return;
+
+  if (params[0][0] == '#') return; /* comment */
+  else if (!strcmp(params[0], "floppya")) {
+    for (i=1; i<num_params; i++) {
+      if (!strncmp(params[i], "2_88=", 5)) {
+        strcpy(bx_options.floppya.path, &params[i][5]);
+        bx_options.floppya.type = BX_FLOPPY_2_88;
+        }
+      else if (!strncmp(params[i], "1_44=", 5)) {
+        strcpy(bx_options.floppya.path, &params[i][5]);
+        bx_options.floppya.type = BX_FLOPPY_1_44;
+        }
+      else if (!strncmp(params[i], "1_2=", 4)) {
+        strcpy(bx_options.floppya.path, &params[i][4]);
+        bx_options.floppya.type = BX_FLOPPY_1_2;
+        }
+      else if (!strncmp(params[i], "720k=", 5)) {
+        strcpy(bx_options.floppya.path, &params[i][5]);
+        bx_options.floppya.type = BX_FLOPPY_720K;
+        }
+      else if (!strncmp(params[i], "status=ejected", 14)) {
+        bx_options.floppya.initial_status = BX_EJECTED;
+        }
+      else if (!strncmp(params[i], "status=inserted", 15)) {
+        bx_options.floppya.initial_status = BX_INSERTED;
+        }
+      else {
+        BX_PANIC(("%s: floppya attribute '%s' not understood.\n", bochsrc_path,
+          params[i]));
+        }
+      }
+    }
+
+  else if (!strcmp(params[0], "floppyb")) {
+    for (i=1; i<num_params; i++) {
+      if (!strncmp(params[i], "2_88=", 5)) {
+        strcpy(bx_options.floppyb.path, &params[i][5]);
+        bx_options.floppyb.type = BX_FLOPPY_2_88;
+        }
+      else if (!strncmp(params[i], "1_44=", 5)) {
+        strcpy(bx_options.floppyb.path, &params[i][5]);
+        bx_options.floppyb.type = BX_FLOPPY_1_44;
+        }
+      else if (!strncmp(params[i], "1_2=", 4)) {
+        strcpy(bx_options.floppyb.path, &params[i][4]);
+        bx_options.floppyb.type = BX_FLOPPY_1_2;
+        }
+      else if (!strncmp(params[i], "720k=", 5)) {
+        strcpy(bx_options.floppyb.path, &params[i][5]);
+        bx_options.floppyb.type = BX_FLOPPY_720K;
+        }
+      else if (!strncmp(params[i], "status=ejected", 14)) {
+        bx_options.floppyb.initial_status = BX_EJECTED;
+        }
+      else if (!strncmp(params[i], "status=inserted", 15)) {
+        bx_options.floppyb.initial_status = BX_INSERTED;
+        }
+      else {
+        BX_PANIC(("%s: floppyb attribute '%s' not understood.\n", bochsrc_path,
+          params[i]));
+        }
+      }
+    }
+
+  else if (!strcmp(params[0], "diskc")) {
+    if (num_params != 5) {
+      BX_PANIC(("%s: diskc directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "file=", 5) ||
+        strncmp(params[2], "cyl=", 4) ||
+        strncmp(params[3], "heads=", 6) ||
+        strncmp(params[4], "spt=", 4)) {
+      BX_PANIC(("%s: diskc directive malformed.\n", bochsrc_path));
+      }
+    strcpy(bx_options.diskc.path, &params[1][5]);
+    bx_options.diskc.cylinders = atol( &params[2][4] );
+    bx_options.diskc.heads     = atol( &params[3][6] );
+    bx_options.diskc.spt       = atol( &params[4][4] );
+    bx_options.diskc.present = 1;
+    }
+  else if (!strcmp(params[0], "diskd")) {
+    if (num_params != 5) {
+      BX_PANIC(("%s: diskd directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "file=", 5) ||
+        strncmp(params[2], "cyl=", 4) ||
+        strncmp(params[3], "heads=", 6) ||
+        strncmp(params[4], "spt=", 4)) {
+      BX_PANIC(("%s: diskd directive malformed.\n", bochsrc_path));
+      }
+    strcpy(bx_options.diskd.path, &params[1][5]);
+    bx_options.diskd.cylinders = atol( &params[2][4] );
+    bx_options.diskd.heads     = atol( &params[3][6] );
+    bx_options.diskd.spt       = atol( &params[4][4] );
+    bx_options.diskd.present = 1;
+    }
+
+  else if (!strcmp(params[0], "cdromd")) {
+    if (num_params != 3) {
+      BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
+      BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+      }
+    strcpy(bx_options.cdromd.dev, &params[1][4]);
+    if (!strcmp(params[2], "status=inserted"))
+      bx_options.cdromd.inserted = 1;
+    else if (!strcmp(params[2], "status=ejected"))
+      bx_options.cdromd.inserted = 0;
+    else {
+      BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+      }
+    bx_options.cdromd.present = 1;
+    }
+
+  else if (!strcmp(params[0], "boot")) {
+    if (!strcmp(params[1], "a") ||
+        !strcmp(params[1], "c")) {
+      strcpy(bx_options.bootdrive, params[1]);
+      }
+    else {
+      BX_PANIC(("%s: boot directive with unknown boot device '%s'.  use 'a' or 'c'.\n", bochsrc_path, params[1]));
+      }
+    }
+  else if (!strcmp(params[0], "log")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: log directive has wrong # args.\n", bochsrc_path));
+      }
+    strcpy(logfilename, params[1]);
+    }
+  else if (!strcmp(params[0], "panic")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "action=", 7)) {
+      BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+      }
+    char *action = 7 + params[1];
+    if (!strcmp(action, "fatal"))
+      bx_options.log_actions[LOGLEV_PANIC] = ACT_FATAL;
+    else if (!strcmp (action, "report"))
+      bx_options.log_actions[LOGLEV_PANIC] = ACT_REPORT;
+    else if (!strcmp (action, "ignore"))
+      bx_options.log_actions[LOGLEV_PANIC] = ACT_IGNORE;
+    else {
+      BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "error")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "action=", 7)) {
+      BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+      }
+    char *action = 7 + params[1];
+    if (!strcmp(action, "fatal"))
+      bx_options.log_actions[LOGLEV_ERROR] = ACT_FATAL;
+    else if (!strcmp (action, "report"))
+      bx_options.log_actions[LOGLEV_ERROR] = ACT_REPORT;
+    else if (!strcmp (action, "ignore"))
+      bx_options.log_actions[LOGLEV_ERROR] = ACT_IGNORE;
+    else {
+      BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "info")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "action=", 7)) {
+      BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+      }
+    char *action = 7 + params[1];
+    if (!strcmp(action, "fatal"))
+      bx_options.log_actions[LOGLEV_INFO] = ACT_FATAL;
+    else if (!strcmp (action, "report"))
+      bx_options.log_actions[LOGLEV_INFO] = ACT_REPORT;
+    else if (!strcmp (action, "ignore"))
+      bx_options.log_actions[LOGLEV_INFO] = ACT_IGNORE;
+    else {
+      BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "debug")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "action=", 7)) {
+      BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+      }
+    char *action = 7 + params[1];
+    if (!strcmp(action, "fatal"))
+      bx_options.log_actions[LOGLEV_DEBUG] = ACT_FATAL;
+    else if (!strcmp (action, "report"))
+      bx_options.log_actions[LOGLEV_DEBUG] = ACT_REPORT;
+    else if (!strcmp (action, "ignore"))
+      bx_options.log_actions[LOGLEV_DEBUG] = ACT_IGNORE;
+    else {
+      BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "romimage")) {
+    if (num_params != 3) {
+      BX_PANIC(("%s: romimage directive: wrong # args.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "file=", 5)) {
+      BX_PANIC(("%s: romimage directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[2], "address=", 8)) {
+      BX_PANIC(("%s: romimage directive malformed.\n", bochsrc_path));
+      }
+    bx_options.rom.path    = strdup(&params[1][5]);
+    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
+      bx_options.rom.address = strtoul(&params[2][8], NULL, 16);
+    else
+      bx_options.rom.address = strtoul(&params[2][8], NULL, 10);
+    }
+  else if (!strcmp(params[0], "vgaromimage")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: vgaromimage directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.vgarom.path = strdup(params[1]);
+    }
+  else if (!strcmp(params[0], "vga_update_interval")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: vga_update_interval directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.vga_update_interval = atol(params[1]);
+    if (bx_options.vga_update_interval < 50000) {
+      BX_INFO(("%s: vga_update_interval not big enough!\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "keyboard_serial_delay")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: keyboard_serial_delay directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.keyboard_serial_delay = atol(params[1]);
+    if (bx_options.keyboard_serial_delay < 5) {
+      BX_PANIC(("%s: keyboard_serial_delay not big enough!\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "megs")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: megs directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.memory.megs = atol(params[1]);
+    }
+  else if (!strcmp(params[0], "floppy_command_delay")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: floppy_command_delay directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.floppy_command_delay = atol(params[1]);
+    if (bx_options.floppy_command_delay < 100) {
+      BX_PANIC(("%s: floppy_command_delay not big enough!\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "ips")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: ips directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.ips = atol(params[1]);
+    if (bx_options.ips < 200000) {
+      BX_INFO(("%s: WARNING: ips is AWFULLY low!\n", bochsrc_path));
+      }
+    }
+
+  else if (!strcmp(params[0], "mouse")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "enabled=", 8)) {
+      BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+      }
+    if (params[1][8] == '0')
+      bx_options.mouse_enabled = 0;
+    else if (params[1][8] == '1')
+      bx_options.mouse_enabled = 1;
+    else {
+      BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "private_colormap")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "enabled=", 8)) {
+      BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+      }
+    if (params[1][8] == '0')
+      bx_options.private_colormap = 0;
+    else if (params[1][8] == '1')
+      bx_options.private_colormap = 1;
+    else {
+      BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+      }
+    }
+
+  else if (!strcmp(params[0], "sb16")) {
+    for (i=1; i<num_params; i++) {
+      if (!strncmp(params[i], "midi=", 5)) {
+       bx_options.sb16.midifile = strdup(&params[i][5]);
+        }
+      else if (!strncmp(params[i], "midimode=", 9)) {
+       bx_options.sb16.midimode = atol(&params[i][9]);
+        }
+      else if (!strncmp(params[i], "wave=", 5)) {
+       bx_options.sb16.wavefile = strdup(&params[i][5]);
+        }
+      else if (!strncmp(params[i], "wavemode=", 9)) {
+       bx_options.sb16.wavemode = atol(&params[i][9]);
+        }
+      else if (!strncmp(params[i], "log=", 4)) {
+       bx_options.sb16.logfile = strdup(&params[i][4]);
+        }
+      else if (!strncmp(params[i], "loglevel=", 9)) {
+       bx_options.sb16.loglevel = atol(&params[i][9]);
+        }
+      else if (!strncmp(params[i], "dmatimer=", 9)) {
+       bx_options.sb16.dmatimer = atol(&params[i][9]);
+        }
+      }
+    }
+
+  else if (!strcmp(params[0], "i440fxsupport")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "enabled=", 8)) {
+      BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+      }
+    if (params[1][8] == '0')
+      bx_options.i440FXSupport = 0;
+    else if (params[1][8] == '1')
+      bx_options.i440FXSupport = 1;
+    else {
+      BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "newharddrivesupport")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "enabled=", 8)) {
+      BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+      }
+    if (params[1][8] == '0')
+      bx_options.newHardDriveSupport = 0;
+    else if (params[1][8] == '1')
+      bx_options.newHardDriveSupport = 1;
+    else {
+      BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+      }
+    }
+  else if (!strcmp(params[0], "cmosimage")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: cmosimage directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.cmos.path = strdup(params[1]);
+    bx_options.cmos.cmosImage = 1;                // CMOS Image is true
+    }
+  else if (!strcmp(params[0], "time0")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: time0 directive: wrong # args.\n", bochsrc_path));
+      }
+    bx_options.cmos.time0 = atoi(params[1]);
+    }
+#ifdef MAGIC_BREAKPOINT
+  else if (!strcmp(params[0], "magic_break")) {
+    if (num_params != 2) {
+      BX_PANIC(("%s: magic_break directive: wrong # args.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "enabled=", 8)) {
+      BX_PANIC(("%s: magic_break directive malformed.\n", bochsrc_path));
+      }
+    if (params[1][8] == '0') {
+      BX_INFO(("Ignoring magic break points\n"));
+      bx_dbg.magic_break_enabled = 0;
+      }
+    else if (params[1][8] == '1') {
+      BX_INFO(("Stopping on magic break points\n"));
+      bx_dbg.magic_break_enabled = 1;
+      }
+    else {
+      BX_PANIC(("%s: magic_break directive malformed.\n", bochsrc_path));
+      }
+    }
+#endif
+  else if (!strcmp(params[0], "ne2k")) {
+    int tmp[6];
+    bx_options.ne2k.valid = 0;
+    if ((num_params < 4) || (num_params > 6)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+      }
+    bx_options.ne2k.ethmod = "null";
+    if (strncmp(params[1], "ioaddr=", 7)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[2], "irq=", 4)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[3], "mac=", 4)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+      }
+    bx_options.ne2k.ioaddr = strtoul(&params[1][7], NULL, 16);
+    bx_options.ne2k.irq = atol(&params[2][4]);
+    i = sscanf(&params[3][4], "%x:%x:%x:%x:%x:%x",
+             &tmp[0],&tmp[1],&tmp[2],&tmp[3],&tmp[4],&tmp[5]);
+    if (i != 6) {
+      BX_PANIC(("%s: ne2k mac address malformed.\n", bochsrc_path));
+      }
+    for (i=0;i<6;i++)
+      bx_options.ne2k.macaddr[i] = tmp[i];
+    if (num_params > 4) {
+      if (strncmp(params[4], "ethmod=", 7)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+        }
+      bx_options.ne2k.ethmod = strdup(&params[4][7]);
+      if (num_params == 6) {
+      if (strncmp(params[5], "ethdev=", 7)) {
+      BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+          }
+      bx_options.ne2k.ethdev = strdup(&params[5][7]);
+        }
+      }
+    bx_options.ne2k.valid = 1;
+    }
+
+  else if (!strcmp(params[0], "load32bitOSImage")) {
+    if ( (num_params!=4) && (num_params!=5) ) {
+      BX_PANIC(("%s: load32bitOSImage directive: wrong # args.\n", bochsrc_path));
+      }
+    if (strncmp(params[1], "os=", 3)) {
+      BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+      }
+    if (!strcmp(&params[1][3], "nullkernel")) {
+      bx_options.load32bitOSImage.whichOS = Load32bitOSNullKernel;
+      }
+    else if (!strcmp(&params[1][3], "linux")) {
+      bx_options.load32bitOSImage.whichOS = Load32bitOSLinux;
+      }
+    else {
+      BX_PANIC(("%s: load32bitOSImage: unsupported OS.\n", bochsrc_path));
+      }
+    if (strncmp(params[2], "path=", 5)) {
+      BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+      }
+    if (strncmp(params[3], "iolog=", 6)) {
+      BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+      }
+    bx_options.load32bitOSImage.path = strdup(&params[2][5]);
+    bx_options.load32bitOSImage.iolog = strdup(&params[3][6]);
+    if (num_params == 5) {
+      if (strncmp(params[4], "initrd=", 7)) {
+        BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+        }
+      bx_options.load32bitOSImage.initrd = strdup(&params[4][7]);
+      }
+    }
+
+  else {
+    BX_PANIC(( "%s: directive '%s' not understood\n", bochsrc_path, params[0]));
+    }
+
+  if (bx_options.diskd.present && bx_options.cdromd.present)
+    BX_PANIC(("At present, using both diskd and cdromd at once is not supported."));
+}
+#endif // #if BX_PROVIDE_MAIN
+
+  void
+bx_signal_handler( int signum)
+{
+#if BX_GUI_SIGHANDLER
+  // GUI signal handler gets first priority, if the mask says it's wanted
+  if ((1<<signum) & bx_gui.get_sighandler_mask ()) {
+    bx_gui.sighandler (signum);
+    return;
+  }
+#endif
+
+#if BX_SHOW_IPS
+  extern unsigned long ips_count;
+
+  if (signum == SIGALRM ) {
+    BX_INFO(("ips = %lu\n", ips_count));
+    ips_count = 0;
+#ifndef __MINGW32__
+    signal(SIGALRM, bx_signal_handler);
+    alarm( 1 );
+#endif
+    return;
+    }
+#endif
+
+#if BX_GUI_SIGHANDLER
+  if ((1<<signum) & bx_gui.get_sighandler_mask ()) {
+    bx_gui.sighandler (signum);
+    return;
+  }
+#endif
+  BX_PANIC(("SIGNAL %u caught\n", signum));
+}
+
diff --git a/sid/component/bochs/cpu/mult16.cc b/sid/component/bochs/cpu/mult16.cc
new file mode 100644 (file)
index 0000000..866dbf7
--- /dev/null
@@ -0,0 +1,292 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::MUL_AXEw(BxInstruction_t *i)
+{
+    Bit16u op1_16, op2_16, product_16h, product_16l;
+    Bit32u product_32;
+    Boolean temp_flag;
+
+    op1_16 = AX;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    product_32 = ((Bit32u) op1_16) * ((Bit32u) op2_16);
+
+    product_16l = (product_32 & 0xFFFF);
+    product_16h = product_32 >> 16;
+
+    /* now write product back to destination */
+
+    AX = product_16l;
+    DX = product_16h;
+
+    /* set eflags:
+     * MUL affects the following flags: C,O
+     */
+
+    temp_flag = (product_16h != 0);
+    SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+}
+
+
+
+  void
+BX_CPU_C::IMUL_AXEw(BxInstruction_t *i)
+{
+    Bit16s op1_16, op2_16;
+    Bit32s product_32;
+    Bit16u product_16h, product_16l;
+
+    op1_16 = AX;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+      }
+
+    product_32 = ((Bit32s) op1_16) * ((Bit32s) op2_16);
+
+    product_16l = (product_32 & 0xFFFF);
+    product_16h = product_32 >> 16;
+
+    /* now write product back to destination */
+
+    AX = product_16l;
+    DX = product_16h;
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r/m16: condition for clearing CF & OF:
+     *   DX:AX = sign-extend of AX
+     */
+
+    if ( (DX==0xffff) && (AX & 0x8000) ) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else if ( (DX==0x0000) && (AX < 0x8000) ) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+}
+
+
+  void
+BX_CPU_C::DIV_AXEw(BxInstruction_t *i)
+{
+    Bit16u op2_16, remainder_16, quotient_16l;
+    Bit32u op1_32, quotient_32;
+
+    op1_32 = (((Bit32u) DX) << 16) | ((Bit32u) AX);
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op2_16);
+      }
+
+    if (op2_16 == 0) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+    quotient_32 = op1_32 / op2_16;
+    remainder_16 = op1_32 % op2_16;
+    quotient_16l = quotient_32 & 0xFFFF;
+
+    if (quotient_32 != quotient_16l) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+
+    /* set EFLAGS:
+     * DIV affects the following flags: O,S,Z,A,P,C are undefined
+     */
+
+#if INTEL_DIV_FLAG_BUG == 1
+    set_CF(1);
+#endif
+
+    /* now write quotient back to destination */
+
+    AX = quotient_16l;
+    DX = remainder_16;
+}
+
+
+  void
+BX_CPU_C::IDIV_AXEw(BxInstruction_t *i)
+{
+    Bit16s op2_16, remainder_16, quotient_16l;
+    Bit32s op1_32, quotient_32;
+
+    op1_32 = ((((Bit32u) DX) << 16) | ((Bit32u) AX));
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+      }
+
+    if (op2_16 == 0) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+    quotient_32 = op1_32 / op2_16;
+    remainder_16 = op1_32 % op2_16;
+    quotient_16l = quotient_32 & 0xFFFF;
+
+    if (quotient_32 != quotient_16l) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+
+    /* set EFLAGS:
+     * IDIV affects the following flags: O,S,Z,A,P,C are undefined
+     */
+
+#if INTEL_DIV_FLAG_BUG == 1
+    set_CF(1);
+#endif
+
+    /* now write quotient back to destination */
+
+    AX = quotient_16l;
+    DX = remainder_16;
+}
+
+
+  void
+BX_CPU_C::IMUL_GwEwIw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("IMUL_GvEvIv() unsupported on 8086!\n"));
+#else
+
+
+    Bit16u product_16l;
+    Bit16s op2_16, op3_16;
+    Bit32s product_32;
+
+    op3_16 = i->Iw;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+      }
+
+    product_32 = op2_16 * op3_16;
+
+    product_16l = (product_32 & 0xFFFF);
+
+    /* now write product back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, product_16l);
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+     *   result exactly fits within r16
+     */
+
+    if (product_32 > -32768  && product_32 < 32767) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+#endif
+}
+
+  void
+BX_CPU_C::IMUL_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("IMUL_GvEv() unsupported on 8086!\n"));
+#else
+
+    Bit16u product_16l;
+    Bit16s op1_16, op2_16;
+    Bit32s product_32;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+      }
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    product_32 = op1_16 * op2_16;
+
+    product_16l = (product_32 & 0xFFFF);
+
+    /* now write product back to destination */
+    BX_WRITE_16BIT_REG(i->nnn, product_16l);
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+     *   result exactly fits within r16
+     */
+
+    if (product_32 > -32768  && product_32 < 32767) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+#endif
+}
diff --git a/sid/component/bochs/cpu/mult32.cc b/sid/component/bochs/cpu/mult32.cc
new file mode 100644 (file)
index 0000000..89668b6
--- /dev/null
@@ -0,0 +1,281 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::MUL_EAXEd(BxInstruction_t *i)
+{
+    Bit32u op1_32, op2_32, product_32h, product_32l;
+    Bit64u product_64;
+    Boolean temp_flag;
+
+    op1_32 = EAX;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    product_64 = ((Bit64u) op1_32) * ((Bit64u) op2_32);
+
+    product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
+    product_32h = (Bit32u) (product_64 >> 32);
+
+    /* now write product back to destination */
+
+    EAX = product_32l;
+    EDX = product_32h;
+
+    /* set eflags:
+     * MUL affects the following flags: C,O
+     */
+
+    temp_flag = (product_32h != 0);
+    SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+}
+
+
+
+  void
+BX_CPU_C::IMUL_EAXEd(BxInstruction_t *i)
+{
+    Bit32s op1_32, op2_32;
+    Bit64s product_64;
+    Bit32u product_32h, product_32l;
+
+    op1_32 = EAX;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+      }
+
+    product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
+
+    product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
+    product_32h = (Bit32u) (product_64 >> 32);
+
+    /* now write product back to destination */
+
+    EAX = product_32l;
+    EDX = product_32h;
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r/m16: condition for clearing CF & OF:
+     *   EDX:EAX = sign-extend of EAX
+     */
+
+    if ( (EDX==0xffffffff) && (EAX & 0x80000000) ) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else if ( (EDX==0x00000000) && (EAX < 0x80000000) ) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+}
+
+
+  void
+BX_CPU_C::DIV_EAXEd(BxInstruction_t *i)
+{
+    Bit32u op2_32, remainder_32, quotient_32l;
+    Bit64u op1_64, quotient_64;
+
+    op1_64 = (((Bit64u) EDX) << 32) + ((Bit64u) EAX);
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+      }
+
+    if (op2_32 == 0) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+    quotient_64 = op1_64 / op2_32;
+    remainder_32 = (Bit32u) (op1_64 % op2_32);
+    quotient_32l = (Bit32u) (quotient_64 & 0xFFFFFFFF);
+
+    if (quotient_64 != quotient_32l) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+
+    /* set EFLAGS:
+     * DIV affects the following flags: O,S,Z,A,P,C are undefined
+     */
+
+    /* now write quotient back to destination */
+
+    EAX = quotient_32l;
+    EDX = remainder_32;
+}
+
+
+  void
+BX_CPU_C::IDIV_EAXEd(BxInstruction_t *i)
+{
+    Bit32s op2_32, remainder_32, quotient_32l;
+    Bit64s op1_64, quotient_64;
+
+    op1_64 = (((Bit64u) EDX) << 32) | ((Bit64u) EAX);
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+      }
+
+    if (op2_32 == 0) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+    quotient_64 = op1_64 / op2_32;
+    remainder_32 = (Bit32s) (op1_64 % op2_32);
+    quotient_32l = (Bit32s) (quotient_64 & 0xFFFFFFFF);
+
+    if (quotient_64 != quotient_32l) {
+      exception(BX_DE_EXCEPTION, 0, 0);
+      }
+
+    /* set EFLAGS:
+     * IDIV affects the following flags: O,S,Z,A,P,C are undefined
+     */
+
+    /* now write quotient back to destination */
+
+    EAX = quotient_32l;
+    EDX = remainder_32;
+}
+
+
+  void
+BX_CPU_C::IMUL_GdEdId(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("IMUL_GdEdId() unsupported on 8086!\n"));
+#else
+
+
+    Bit32s op2_32, op3_32, product_32;
+    Bit64s product_64;
+
+    op3_32 = i->Id;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+      }
+
+    product_32 = op2_32 * op3_32;
+    product_64 = ((Bit64s) op2_32) * ((Bit64s) op3_32);
+
+    /* now write product back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, product_32);
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+     *   result exactly fits within r16
+     */
+
+    if (product_64 == product_32) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+#endif
+}
+
+
+  void
+BX_CPU_C::IMUL_GdEd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("IMUL_GvEv() unsupported on 8086!\n"));
+#else
+
+    Bit32s op1_32, op2_32, product_32;
+    Bit64s product_64;
+
+    /* op2 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op2_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+      }
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    product_32 = op1_32 * op2_32;
+    product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
+
+    /* now write product back to destination */
+    BX_WRITE_32BIT_REG(i->nnn, product_32);
+
+    /* set eflags:
+     * IMUL affects the following flags: C,O
+     * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+     *   result exactly fits within r16
+     */
+
+    if (product_64 == product_32) {
+      SET_FLAGS_OxxxxC(0, 0);
+      }
+    else {
+      SET_FLAGS_OxxxxC(1, 1);
+      }
+#endif
+}
diff --git a/sid/component/bochs/cpu/mult8.cc b/sid/component/bochs/cpu/mult8.cc
new file mode 100644 (file)
index 0000000..765be0d
--- /dev/null
@@ -0,0 +1,200 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+  void
+BX_CPU_C::MUL_ALEb(BxInstruction_t *i)
+{
+  Bit8u op2, op1;
+  Bit16u product_16;
+  Boolean temp_flag;
+
+  op1 = AL;
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  product_16 = op1 * op2;
+
+  /* set EFLAGS:
+   * MUL affects the following flags: C,O
+   */
+
+  temp_flag = ((product_16 & 0xFF00) != 0);
+  SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+
+  /* now write product back to destination */
+
+  AX = product_16;
+}
+
+
+  void
+BX_CPU_C::IMUL_ALEb(BxInstruction_t *i)
+{
+  Bit8s op2, op1;
+  Bit16s product_16;
+  Bit16u upper_bits;
+
+
+  op1 = AL;
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, (Bit8u *) &op2);
+    }
+
+  product_16 = op1 * op2;
+
+  /* now write product back to destination */
+
+  AX = product_16;
+
+  /* set EFLAGS:
+   * IMUL affects the following flags: C,O
+   * IMUL r/m8: condition for clearing CF & OF:
+   *   AL = sign-extend of AL to 16 bits
+   */
+  upper_bits = AX & 0xff80;
+  if (upper_bits==0xff80  ||  upper_bits==0x0000) {
+    SET_FLAGS_OxxxxC(0, 0);
+    }
+  else {
+    SET_FLAGS_OxxxxC(1, 1);
+    }
+}
+
+
+
+  void
+BX_CPU_C::DIV_ALEb(BxInstruction_t *i)
+{
+  Bit8u op2, quotient_8l, remainder_8;
+  Bit16u quotient_16, op1;
+
+
+  op1 = AX;
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, &op2);
+    }
+
+  if (op2 == 0) {
+    exception(BX_DE_EXCEPTION, 0, 0);
+    }
+  quotient_16 = op1 / op2;
+  remainder_8 = op1 % op2;
+  quotient_8l = quotient_16 & 0xFF;
+
+  if (quotient_16 != quotient_8l) {
+    exception(BX_DE_EXCEPTION, 0, 0);
+    }
+
+  /* set EFLAGS:
+   * DIV affects the following flags: O,S,Z,A,P,C are undefined
+   */
+
+#if INTEL_DIV_FLAG_BUG == 1
+    set_CF(1);
+#endif
+
+  /* now write quotient back to destination */
+
+  AL = quotient_8l;
+  AH = remainder_8;
+}
+
+
+  void
+BX_CPU_C::IDIV_ALEb(BxInstruction_t *i)
+{
+  Bit8s op2, quotient_8l, remainder_8;
+  Bit16s quotient_16, op1;
+
+
+  op1 = AX;
+
+
+  /* op2 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op2 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_byte(i->seg, i->rm_addr, (Bit8u *) &op2);
+    }
+
+  if (op2 == 0) {
+    exception(BX_DE_EXCEPTION, 0, 0);
+    }
+
+  quotient_16 = op1 / op2;
+  remainder_8 = op1 % op2;
+  quotient_8l = quotient_16 & 0xFF;
+
+  if (quotient_16 != quotient_8l) {
+BX_INFO(("quotient_16: %04x, remainder_8: %02x, quotient_8l: %02x\n",
+  (unsigned) quotient_16, (unsigned) remainder_8, (unsigned) quotient_8l));
+AL = quotient_8l;
+AH = remainder_8;
+BX_INFO(("AH: %02x, AL: %02x\n", (unsigned) AH, (unsigned) AL));
+    exception(BX_DE_EXCEPTION, 0, 0);
+    }
+
+  /* set EFLAGS:
+   * DIV affects the following flags: O,S,Z,A,P,C are undefined
+   */
+
+#if INTEL_DIV_FLAG_BUG == 1
+    set_CF(1);
+#endif
+
+  /* now write quotient back to destination */
+
+  AL = quotient_8l;
+  AH = remainder_8;
+}
diff --git a/sid/component/bochs/cpu/paging.cc b/sid/component/bochs/cpu/paging.cc
new file mode 100644 (file)
index 0000000..7f75c9a
--- /dev/null
@@ -0,0 +1,960 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#if 0
+  // - what should the reserved bits in the error code be ?
+  // - move CR0.wp bit in lookup table to cache.  Then dump
+  //   cache whenever it is changed.  This eliminates the
+  //   extra calculation and shifting.
+  // - change BX_READ and BX_WRITE to 0,1 ???
+#endif
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+
+
+#if 0
+// X86 Registers Which Affect Paging:
+// ==================================
+//
+// CR0:
+//   bit 31: PG, Paging (386+)
+//   bit 16: WP, Write Protect (486+)
+//     0: allow   supervisor level writes into user level RO pages
+//     1: inhibit supervisor level writes into user level RO pages
+//
+// CR3:
+//   bit 31..12: PDBR, Page Directory Base Register (386+)
+//   bit      4: PCD, Page level Cache Disable (486+)
+//     Controls caching of current page directory.  Affects only the processor's
+//     internal caches (L1 and L2).
+//     This flag ignored if paging disabled (PG=0) or cache disabled (CD=1).
+//     Values:
+//       0: Page Directory can be cached
+//       1: Page Directory not cached
+//   bit      3: PWT, Page level Writes Transparent (486+)
+//     Controls write-through or write-back caching policy of current page
+//     directory.  Affects only the processor's internal caches (L1 and L2).
+//     This flag ignored if paging disabled (PG=0) or cache disabled (CD=1).
+//     Values:
+//       0: write-back caching enabled
+//       1: write-through caching enabled
+//
+// CR4:
+//   bit 4: PSE, Page Size Extension (Pentium+)
+//     0: 4KByte pages (typical)
+//     1: 4MByte or 2MByte pages
+//   bit 5: PAE, Physical Address Extension (Pentium Pro+)
+//     0: 32bit physical addresses
+//     1: 36bit physical addresses
+//   bit 7: PGE, Page Global Enable (Pentium Pro+)
+//     The global page feature allows frequently used or shared pages
+//     to be marked as global (PDE or PTE bit 8).  Global pages are
+//     not flushed from TLB on a task switch or write to CR3.
+//     Values:
+//       0: disables global page feature
+//       1: enables global page feature
+//
+//     Page size extention and physical address size extention matrix
+//   ====================================================================
+//   CR0.PG  CR4.PAE  CR4.PSE  PDE.PS | page size   physical address size
+//   ====================================================================
+//      0       X        X        X   |    -          paging disabled
+//      1       0        0        X   |   4K              32bits
+//      1       0        1        0   |   4K              32bits
+//      1       0        1        1   |   4M              32bits
+//      1       1        X        0   |   4K              36bits
+//      1       1        X        1   |   2M              36bits
+
+
+\f
+// Page Directory/Table Entry format when P=0:
+// ===========================================
+//
+//   31.. 1: available
+//        0: P=0
+
+// Page Directory Entry format when P=1 (4-Kbyte Page Table):
+// ==========================================================
+//
+//   31..12: page table base address
+//   11.. 9: available
+//        8: G (Pentium Pro+), 0=reserved otherwise
+//        7: PS (Pentium+), 0=reserved otherwise
+//        6: 0=reserved
+//        5: A   (386+)
+//        4: PCD (486+), 0=reserved otherwise
+//        3: PWT (486+), 0=reserved otherwise
+//        2: U/S (386+)
+//        1: R/W (386+)
+//        0: P=1 (386+)
+
+// Page Table Entry format when P=1 (4-Kbyte Page):
+// ================================================
+//
+//   31..12: page base address
+//   11.. 9: available
+//        8: G (Pentium Pro+), 0=reserved otherwise
+//        7: 0=reserved
+//        6: D   (386+)
+//        5: A   (386+)
+//        4: PCD (486+), 0=reserved otherwise
+//        3: PWT (486+), 0=reserved otherwise
+//        2: U/S (386+)
+//        1: R/W (386+)
+//        0: P=1 (386+)
+
+\f
+// Page Directory/Table Entry Fields Defined:
+// ==========================================
+// G: Global flag
+//   Indiciates a global page when set.  When a page is marked
+//   global and the PGE flag in CR4 is set, the page table or
+//   directory entry for the page is not invalidated in the TLB
+//   when CR3 is loaded or a task switch occurs.  Only software
+//   clears and sets this flag.  For page directory entries that
+//   point to page tables, this flag is ignored and the global
+//   characteristics of a page are set in the page table entries.
+//
+// PS: Page Size flag
+//   Only used in page directory entries.  When PS=0, the page
+//   size is 4KBytes and the page directory entry points to a
+//   page table.  When PS=1, the page size is 4MBytes for
+//   normal 32-bit addressing and 2MBytes if extended physical
+//   addressing
+//
+// D: Dirty bit:
+//   Processor sets the Dirty bit in the 2nd-level page table before a
+//   write operation to an address mapped by that page table entry.
+//   Dirty bit in directory entries is undefined.
+//
+// A: Accessed bit:
+//   Processor sets the Accessed bits in both levels of page tables before
+//   a read/write operation to a page.
+//
+// PCD: Page level Cache Disable
+//   Controls caching of individual pages or page tables.
+//   This allows a per-page based mechanism to disable caching, for
+//   those pages which contained memory mapped IO, or otherwise
+//   should not be cached.  Processor ignores this flag if paging
+//   is not used (CR0.PG=0) or the cache disable bit is set (CR0.CD=1).
+//   Values:
+//     0: page or page table can be cached
+//     1: page or page table is not cached (prevented)
+//
+// PWT: Page level Write Through
+//   Controls the write-through or write-back caching policy of individual
+//   pages or page tables.  Processor ignores this flag if paging
+//   is not used (CR0.PG=0) or the cache disable bit is set (CR0.CD=1).
+//   Values:
+//     0: write-back caching
+//     1: write-through caching
+//
+// U/S: User/Supervisor level
+//   0: Supervisor level - for the OS, drivers, etc.
+//   1: User level - application code and data
+//
+// R/W: Read/Write access
+//   0: read-only access
+//   1: read/write access
+//
+// P: Present
+//   0: Not present
+//   1: Present
+// ==========================================
+
+
+\f
+// Combined page directory/page table protection:
+// ==============================================
+// There is one column for the combined effect on a 386
+// and one column for the combined effect on a 486+ CPU.
+//
+// +----------------+-----------------+----------------+----------------+
+// |  Page Directory|     Page Table  |   Combined 386 |  Combined 486+ |
+// |Privilege  Type | Privilege  Type | Privilege  Type| Privilege  Type|
+// |----------------+-----------------+----------------+----------------|
+// |User       R    | User       R    | User       R   | User       R   |
+// |User       R    | User       RW   | User       R   | User       R   |
+// |User       RW   | User       R    | User       R   | User       R   |
+// |User       RW   | User       RW   | User       RW  | User       RW  |
+// |User       R    | Supervisor R    | User       R   | Supervisor RW  |
+// |User       R    | Supervisor RW   | User       R   | Supervisor RW  |
+// |User       RW   | Supervisor R    | User       R   | Supervisor RW  |
+// |User       RW   | Supervisor RW   | User       RW  | Supervisor RW  |
+// |Supervisor R    | User       R    | User       R   | Supervisor RW  |
+// |Supervisor R    | User       RW   | User       R   | Supervisor RW  |
+// |Supervisor RW   | User       R    | User       R   | Supervisor RW  |
+// |Supervisor RW   | User       RW   | User       RW  | Supervisor RW  |
+// |Supervisor R    | Supervisor R    | Supervisor RW  | Supervisor RW  |
+// |Supervisor R    | Supervisor RW   | Supervisor RW  | Supervisor RW  |
+// |Supervisor RW   | Supervisor R    | Supervisor RW  | Supervisor RW  |
+// |Supervisor RW   | Supervisor RW   | Supervisor RW  | Supervisor RW  |
+// +----------------+-----------------+----------------+----------------+
+
+// Page Fault Error Code Format:
+// =============================
+//
+// bits 31..4: Reserved
+// bit  3: RSVD (Pentium Pro+)
+//   0: fault caused by reserved bits set to 1 in a page directory
+//      when the PSE or PAE flags in CR4 are set to 1
+//   1: fault was not caused by reserved bit violation
+// bit  2: U/S (386+)
+//   0: fault originated when in supervior mode
+//   1: fault originated when in user mode
+// bit  1: R/W (386+)
+//   0: access causing the fault was a read
+//   1: access causing the fault was a write
+// bit  0: P (386+)
+//   0: fault caused by a nonpresent page
+//   1: fault caused by a page level protection violation
+
+
+// Some paging related notes:
+// ==========================
+//
+// - When the processor is running in supervisor level, all pages are both
+//   readable and writable (write-protect ignored).  When running at user
+//   level, only pages which belong to the user level are accessible;
+//   read/write & read-only are readable, read/write are writable.
+//
+// - If the Present bit is 0 in either level of page table, an
+//   access which uses these entries will generate a page fault.
+//
+// - (A)ccess bit is used to report read or write access to a page
+//   or 2nd level page table.
+//
+// - (D)irty bit is used to report write access to a page.
+//
+// - Processor running at CPL=0,1,2 maps to U/S=0
+//   Processor running at CPL=3     maps to U/S=1
+//
+// - Pentium+ processors have separate TLB's for data and instruction caches
+// - Pentium Pro+ processors maintain separate 4K and 4M TLBs.
+#endif
+
+
+
+
+#if BX_SUPPORT_PAGING
+
+#define BX_INVALID_TLB_ENTRY 0xffffffff
+
+#if BX_CPU_LEVEL >= 4
+#  define BX_PRIV_CHECK_SIZE 32
+#else
+#  define BX_PRIV_CHECK_SIZE 16
+#endif
+
+// The 'priv_check' array is used to decide if the current access
+// has the proper paging permissions.  An index is formed, based
+// on parameters such as the access type and level, the write protect
+// flag and values cached in the TLB.  The format of the index into this
+// array is:
+//
+//   |4 |3 |2 |1 |0 |
+//   |wp|us|us|rw|rw|
+//    |  |  |  |  |
+//    |  |  |  |  +---> r/w of current access
+//    |  |  +--+------> u/s,r/w combined of page dir & table (cached)
+//    |  +------------> u/s of current access
+//    +---------------> Current CR0.wp value
+//
+// The TLB cache holds the following info, from which the above
+// fields can efficiently be extracted to facilitate a privilege check:
+//
+//   |4 |3 |2 |1 |0 |
+//   |  |  |us|rw|D |
+//          |  |  |
+//          |  |  +---> Dirty bit from PTE (not used for privilege check)
+//          +--+------> u/s,r/w combined of page dir & table
+//
+//
+// The rest of the fields are taken from current access parameters
+// and the write-protect field:
+//
+//   |4 |3 |2 |1 |0 |
+//   |wp|us|  |  |rw|
+//    |  |        |
+//    |  |        +---> r/w of current access
+//    |  |
+//    |  +------------> u/s of current access
+//    +---------------> Current CR0.wp value
+
+
+static unsigned priv_check[BX_PRIV_CHECK_SIZE];
+
+
+
+  void
+BX_CPU_C::enable_paging(void)
+{
+  TLB_flush();
+  if (bx_dbg.paging) BX_INFO(("enable_paging():\n"));
+//BX_DEBUG(( "enable_paging():-------------------------\n" ));
+}
+
+  void
+BX_CPU_C::disable_paging(void)
+{
+  TLB_flush();
+  if (bx_dbg.paging) BX_INFO(("disable_paging():\n"));
+}
+
+  void
+BX_CPU_C::CR3_change(Bit32u value32)
+{
+  if (bx_dbg.paging) {
+    BX_INFO(("CR3_change(): flush TLB cache\n"));
+    BX_INFO(("Page Directory Base %08x\n", (unsigned) value32));
+    }
+
+  // flush TLB even if value does not change
+  TLB_flush();
+  BX_CPU_THIS_PTR cr3 = value32;
+}
+
+  void
+BX_CPU_C::TLB_init(void)
+{
+  // Called to initialize the TLB upon startup.
+  // Unconditional initialization of all TLB entries.
+
+#if BX_USE_TLB
+  unsigned i;
+  unsigned wp, us_combined, rw_combined, us_current, rw_current;
+
+  for (i=0; i<BX_TLB_SIZE; i++) {
+    BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+    }
+
+  //
+  // Setup privilege check matrix.
+  //
+
+  for (i=0; i<BX_PRIV_CHECK_SIZE; i++) {
+    wp          = (i & 0x10) >> 4;
+    us_current  = (i & 0x08) >> 3;
+    us_combined = (i & 0x04) >> 2;
+    rw_combined = (i & 0x02) >> 1;
+    rw_current  = (i & 0x01) >> 0;
+    if (wp) { // when write protect on
+      if (us_current > us_combined) // user access, supervisor page
+        priv_check[i] = 0;
+      else if (rw_current > rw_combined) // RW access, RO page
+        priv_check[i] = 0;
+      else
+        priv_check[i] = 1;
+      }
+    else { // when write protect off
+      if (us_current == 0) // Supervisor mode access, anything goes
+        priv_check[i] = 1;
+      else {
+        // user mode access
+        if (us_combined == 0) // user access, supervisor Page
+          priv_check[i] = 0;
+        else if (rw_current > rw_combined) // RW access, RO page
+          priv_check[i] = 0;
+        else
+          priv_check[i] = 1;
+        }
+      }
+    }
+
+#endif  // #if BX_USE_TLB
+}
+
+  void
+BX_CPU_C::TLB_flush(void)
+{
+#if BX_USE_TLB
+  for (unsigned i=0; i<BX_TLB_SIZE; i++) {
+    BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+    }
+#endif  // #if BX_USE_TLB
+
+  invalidate_prefetch_q();
+}
+
+  void
+BX_CPU_C::TLB_clear(void)
+{
+#if BX_USE_TLB
+  for (unsigned i=0; i<BX_TLB_SIZE; i++) {
+    BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+    }
+#endif  // #if BX_USE_TLB
+}
+
+  void
+BX_CPU_C::INVLPG(BxInstruction_t* i)
+{
+#if BX_CPU_LEVEL >= 4
+  invalidate_prefetch_q();
+
+  // Operand must not be a register
+  if (i->mod == 0xc0) {
+    BX_INFO(("INVLPG: op is a register"));
+    UndefinedOpcode(i);
+    }
+  // Can not be executed in v8086 mode
+  if (v8086_mode())
+    exception(BX_GP_EXCEPTION, 0, 0);
+
+  // Protected instruction: CPL0 only
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    if (CPL!=0) {
+      BX_INFO(("INVLPG: CPL!=0\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+
+#if BX_USE_TLB
+  // Just clear the entire TLB, ugh!
+  TLB_clear();
+#endif // BX_USE_TLB
+  BX_INSTR_TLB_CNTRL(BX_INSTR_INVLPG, 0);
+
+#else
+  // not supported on < 486
+  UndefinedOpcode(i);
+#endif
+}
+
+
+// Translate a linear address to a physical address, for
+// a data access (D)
+
+  Bit32u
+BX_CPU_C::dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw)
+{
+  Bit32u   lpf, ppf, poffset, TLB_index, error_code, paddress;
+  Bit32u   pde, pde_addr;
+  Bit32u   pte, pte_addr;
+  unsigned priv_index;
+  Boolean  is_rw;
+  Bit32u   combined_access, new_combined_access;
+
+  lpf       = laddress & 0xfffff000; // linear page frame
+  poffset   = laddress & 0x00000fff; // physical offset
+  TLB_index = BX_TLB_INDEX_OF(lpf);
+
+
+  is_rw = (rw>=BX_WRITE); // write or r-m-w
+
+  if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+    paddress        = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+    combined_access = BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access;
+priv_check:
+    priv_index =
+#if BX_CPU_LEVEL >= 4
+      (BX_CPU_THIS_PTR cr0.wp<<4) |  // bit 4
+#endif
+      (pl<<3) |                      // bit 3
+      (combined_access & 0x06) |     // bit 2,1
+      is_rw;                         // bit 0
+
+    if (priv_check[priv_index]) {
+      // Operation has proper privilege.
+      // See if A/D bits need updating.
+      //BW !! a read access does not do any updates, patched load
+      new_combined_access = combined_access | is_rw;
+      if (new_combined_access == combined_access) {
+        // A/D bits already up-to-date
+        return(paddress);
+        }
+
+      // A/D bits need updating first
+      BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = new_combined_access;
+      pte_addr = BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr;
+      BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte); // get old PTE
+      pte |= 0x20 | (is_rw << 6);
+      BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte); // write updated PTE
+      return(paddress);
+      }
+
+    // Protection violation
+    error_code = 0xfffffff9; // RSVD=1, P=1
+    goto page_fault_check;
+    }
+
+  // Get page dir entry
+  pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+             ((laddress & 0xffc00000) >> 20);
+  BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+  if ( !(pde & 0x01) ) {
+    // Page Directory Entry NOT present
+    error_code = 0xfffffff8; // RSVD=1, P=0
+    goto page_fault_not_present;
+    }
+
+  // Get page table entry
+  pte_addr = (pde & 0xfffff000) |
+             ((laddress & 0x003ff000) >> 10);
+  BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+
+  // update PDE if A bit was not set before
+  if ( !(pde & 0x20) ) {
+    pde |= 0x20;
+    BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
+    }
+
+  if ( !(pte & 0x01) ) {
+    // Page Table Entry NOT present
+    error_code = 0xfffffff8; // RSVD=1, P=0
+    goto page_fault_not_present;
+    }
+
+  //BW added: update PTE if A bit was not set before
+  if ( !(pte & 0x20) ) {
+    pte |= 0x20;
+    BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
+    }
+
+  // 386 and 486+ have different bahaviour for combining
+  // privilege from PDE and PTE.
+#if BX_CPU_LEVEL == 3
+  combined_access  = (pde | pte) & 0x04; // U/S
+  combined_access |= (pde & pte) & 0x02; // R/W
+#else // 486+
+  combined_access  = (pde & pte) & 0x06; // U/S and R/W
+#endif
+
+  ppf = pte & 0xfffff000;
+  paddress = ppf | poffset;
+
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = lpf;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf = ppf;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr = pte_addr;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = combined_access;
+  goto priv_check;
+
+
+page_fault_check:
+// (mch) Define RMW_WRITES for old behavior
+#if !defined(RMW_WRITES)
+  /* (mch) Ok, so we know it's a page fault. It the access is a
+     read-modify-write access we check if the read faults, if it
+     does then we (optionally) do not set the write bit */
+  if (rw == BX_RW) {
+          priv_index =
+#if BX_CPU_LEVEL >= 4
+                  (BX_CPU_THIS_PTR cr0.wp<<4) |               // bit 4
+#endif
+                  (pl<<3) |                   // bit 3
+                  (combined_access & 0x06) |  // bit 2,1
+                  0;                      // bit 0 (read)
+          if (!priv_check[priv_index]) {
+                  // Fault on read
+                  is_rw = 0;
+          }
+  }
+#endif /* RMW_WRITES */
+  goto page_fault_proper;
+
+page_fault_not_present:
+#if !defined(RMW_WRITES)
+  if (rw == BX_RW)
+          is_rw = 0;
+#endif /* RMW_WRITES */
+  goto page_fault_proper;
+
+  page_fault_proper:
+  error_code |= (pl << 2) | (is_rw << 1);
+  BX_CPU_THIS_PTR cr2 = laddress;
+  // invalidate entry - we can get away without maintaining A bit in PTE
+  // if we don't maintain TLB entries without it set.
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
+  exception(BX_PF_EXCEPTION, error_code, 0);
+  return(0); // keep compiler happy
+}
+
+
+// Translate a linear address to a physical address, for
+// an instruction fetch access (I)
+
+  Bit32u
+BX_CPU_C::itranslate_linear(Bit32u laddress, unsigned pl)
+{
+  Bit32u   lpf, ppf, poffset, TLB_index, error_code, paddress;
+  Bit32u   pde, pde_addr;
+  Bit32u   pte, pte_addr;
+  unsigned priv_index;
+  Bit32u   combined_access;
+
+  lpf       = laddress & 0xfffff000; // linear page frame
+  poffset   = laddress & 0x00000fff; // physical offset
+  TLB_index = BX_TLB_INDEX_OF(lpf);
+
+
+  if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+    paddress        = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+    combined_access = BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access;
+priv_check:
+    priv_index =
+#if BX_CPU_LEVEL >= 4
+      (BX_CPU_THIS_PTR cr0.wp<<4) |   // bit 4
+#endif
+      (pl<<3) |                       // bit 3
+      (combined_access & 0x06);       // bit 2,1
+                                      // bit 0 == 0
+
+    if (priv_check[priv_index]) {
+      // Operation has proper privilege.
+      return(paddress);
+      }
+
+    // Protection violation
+    error_code = 0xfffffff9; // RSVD=1, P=1
+    goto page_fault;
+    }
+
+  // Get page dir entry
+  pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+             ((laddress & 0xffc00000) >> 20);
+  BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+  if ( !(pde & 0x01) ) {
+    // Page Directory Entry NOT present
+    error_code = 0xfffffff8; // RSVD=1, P=0
+    goto page_fault;
+    }
+
+  // Get page table entry
+  pte_addr = (pde & 0xfffff000) |
+             ((laddress & 0x003ff000) >> 10);
+  BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+
+  // update PDE if A bit was not set before
+  if ( !(pde & 0x20) ) {
+    pde |= 0x20;
+    BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
+    }
+
+  if ( !(pte & 0x01) ) {
+    // Page Table Entry NOT present
+    error_code = 0xfffffff8; // RSVD=1, P=0
+    goto page_fault;
+    }
+
+  //BW added: update PTE if A bit was not set before
+  if ( !(pte & 0x20) ) {
+    pte |= 0x20;
+    BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
+    }
+
+  // 386 and 486+ have different bahaviour for combining
+  // privilege from PDE and PTE.
+#if BX_CPU_LEVEL == 3
+  combined_access  = (pde | pte) & 0x04; // U/S
+  combined_access |= (pde & pte) & 0x02; // R/W
+#else // 486+
+  combined_access  = (pde & pte) & 0x06; // U/S and R/W
+#endif
+
+  ppf = pte & 0xfffff000;
+  paddress = ppf | poffset;
+
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = lpf;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf = ppf;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr = pte_addr;
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = combined_access;
+  goto priv_check;
+
+
+page_fault:
+  error_code |= (pl << 2);
+  BX_CPU_THIS_PTR cr2 = laddress;
+  // invalidate entry - we can get away without maintaining A bit in PTE
+  // if we don't maintain TLB entries without it set.
+  BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
+  exception(BX_PF_EXCEPTION, error_code, 0);
+  return(0); // keep compiler happy
+}
+
+
+#if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION
+
+  void
+BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddress, Bit32u *phy, Boolean *valid)
+{
+  Bit32u   lpf, ppf, poffset, TLB_index, paddress;
+  Bit32u   pde, pde_addr;
+  Bit32u   pte, pte_addr;
+
+  if (BX_CPU_THIS_PTR cr0.pg == 0) {
+    *phy = laddress;
+    *valid = 1;
+    return;
+    }
+
+  lpf       = laddress & 0xfffff000; // linear page frame
+  poffset   = laddress & 0x00000fff; // physical offset
+  TLB_index = BX_TLB_INDEX_OF(lpf);
+
+  // see if page is in the TLB first
+  if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+    paddress        = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+    *phy = paddress;
+    *valid = 1;
+    return;
+    }
+
+  // Get page dir entry
+  pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+             ((laddress & 0xffc00000) >> 20);
+  BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+  if ( !(pde & 0x01) ) {
+    // Page Directory Entry NOT present
+    goto page_fault;
+    }
+
+  // Get page table entry
+  pte_addr = (pde & 0xfffff000) |
+             ((laddress & 0x003ff000) >> 10);
+  BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+  if ( !(pte & 0x01) ) {
+    // Page Table Entry NOT present
+    goto page_fault;
+    }
+
+  ppf = pte & 0xfffff000;
+  paddress = ppf | poffset;
+
+  *phy = paddress;
+  *valid = 1;
+  return;
+
+page_fault:
+  *phy = 0;
+  *valid = 0;
+  return;
+}
+#endif
+
+
+
+  void
+BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
+    unsigned rw, void *data)
+{
+  Bit32u mod4096;
+  unsigned xlate_rw;
+
+
+#if BX_X86_DEBUGGER
+  if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+    // Only compare debug registers if any breakpoints are enabled
+    Bit32u dr6_bits;
+    unsigned opa, opb;
+    opa = BX_HWDebugMemRW; // Read or Write always compares vs 11b
+    if (rw==BX_READ) // only compares vs 11b
+      opb = opa;
+    else // BX_WRITE or BX_RW; also compare vs 01b
+      opb = BX_HWDebugMemW;
+    dr6_bits = hwdebug_compare(laddress, length, opa, opb);
+    if (dr6_bits) {
+      BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+      BX_CPU_THIS_PTR async_event = 1;
+      }
+    }
+#endif
+
+  if (rw==BX_RW) {
+    xlate_rw = BX_RW;
+    rw = BX_READ;
+    }
+  else {
+    xlate_rw = rw;
+    }
+
+
+  // perhaps put this check before all code which calls this function,
+  // so we don't have to here
+
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    /* check for reference across multiple pages */
+    mod4096 = laddress & 0x00000fff;
+    if ( (mod4096 + length) <= 4096 ) {
+      // Bit32u paddress1;
+
+      /* access within single page */
+      BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
+      BX_CPU_THIS_PTR address_xlation.pages     = 1;
+
+      if (rw == BX_READ) {
+        BX_INSTR_LIN_READ(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
+        BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
+        }
+      else {
+        BX_INSTR_LIN_WRITE(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
+        BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
+        }
+      return;
+      }
+    else {
+      // access across 2 pages
+      BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
+      BX_CPU_THIS_PTR address_xlation.len1      = 4096 - mod4096;
+      BX_CPU_THIS_PTR address_xlation.len2      = length - BX_CPU_THIS_PTR address_xlation.len1;
+      BX_CPU_THIS_PTR address_xlation.pages     = 2;
+
+      BX_CPU_THIS_PTR address_xlation.paddress2 = dtranslate_linear(laddress + BX_CPU_THIS_PTR address_xlation.len1, pl, xlate_rw);
+
+#ifdef BX_LITTLE_ENDIAN
+      if (rw == BX_READ) {
+        BX_INSTR_LIN_READ(laddress,
+                          BX_CPU_THIS_PTR address_xlation.paddress1,
+                          BX_CPU_THIS_PTR address_xlation.len1);
+        BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                             BX_CPU_THIS_PTR address_xlation.len1, data);
+        BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+                          BX_CPU_THIS_PTR address_xlation.paddress2,
+                          BX_CPU_THIS_PTR address_xlation.len2);
+        BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                             BX_CPU_THIS_PTR address_xlation.len2,
+                             ((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
+        }
+      else {
+        BX_INSTR_LIN_WRITE(laddress,
+                           BX_CPU_THIS_PTR address_xlation.paddress1,
+                           BX_CPU_THIS_PTR address_xlation.len1);
+        BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                              BX_CPU_THIS_PTR address_xlation.len1, data);
+        BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+                          BX_CPU_THIS_PTR address_xlation.paddress2,
+                          BX_CPU_THIS_PTR address_xlation.len2);
+        BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                              BX_CPU_THIS_PTR address_xlation.len2,
+                              ((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
+        }
+
+#else // BX_BIG_ENDIAN
+      if (rw == BX_READ) {
+        BX_INSTR_LIN_READ(laddress,
+                          BX_CPU_THIS_PTR address_xlation.paddress1,
+                          BX_CPU_THIS_PTR address_xlation.len1);
+        BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                             BX_CPU_THIS_PTR address_xlation.len1,
+                             ((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
+        BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+                          BX_CPU_THIS_PTR address_xlation.paddress2,
+                          BX_CPU_THIS_PTR address_xlation.len2);
+        BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                             BX_CPU_THIS_PTR address_xlation.len2, data);
+        }
+      else {
+        BX_INSTR_LIN_WRITE(laddress,
+                           BX_CPU_THIS_PTR address_xlation.paddress1,
+                           BX_CPU_THIS_PTR address_xlation.len1);
+        BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+                              BX_CPU_THIS_PTR address_xlation.len1,
+                              ((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
+        BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+                          BX_CPU_THIS_PTR address_xlation.paddress2,
+                          BX_CPU_THIS_PTR address_xlation.len2);
+        BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+                              BX_CPU_THIS_PTR address_xlation.len2, data);
+        }
+#endif
+
+      return;
+      }
+    }
+  else {
+    // paging off, pass linear address thru to physical
+    if (rw == BX_READ) {
+      BX_INSTR_LIN_READ(laddress, laddress, length);
+      BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
+      }
+    else {
+      BX_INSTR_LIN_WRITE(laddress, laddress, length);
+      BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
+      }
+    return;
+    }
+}
+
+
+
+
+
+
+
+
+#else   // BX_SUPPORT_PAGING
+
+// stub functions for non-support of paging
+  void
+BX_CPU_C::enable_paging(void)
+{
+  BX_PANIC(("enable_paging(): not implemented\n"));
+}
+
+  void
+BX_CPU_C::disable_paging(void)
+{
+  BX_PANIC(("disable_paging() called\n"));
+}
+
+  void
+BX_CPU_C::CR3_change(Bit32u value32)
+{
+  BX_INFO(("CR3_change(): flush TLB cache\n"));
+  BX_INFO(("Page Directory Base %08x\n", (unsigned) value32));
+}
+
+
+  void
+BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
+    unsigned rw, void *data)
+{
+  /* perhaps put this check before all code which calls this function,
+   * so we don't have to here
+   */
+  if (BX_CPU_THIS_PTR cr0.pg == 0) {
+    if (rw == BX_READ)
+      BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
+    else
+      BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
+    return;
+    }
+
+  BX_PANIC(("access_linear: paging not supported\n"));
+}
+
+  void
+BX_CPU_C::INVLPG(BxInstruction_t* i)
+{}
+
+#endif  // BX_SUPPORT_PAGING
diff --git a/sid/component/bochs/cpu/proc_ctrl.cc b/sid/component/bochs/cpu/proc_ctrl.cc
new file mode 100644 (file)
index 0000000..aa9d582
--- /dev/null
@@ -0,0 +1,1279 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+  void
+BX_CPU_C::UndefinedOpcode(BxInstruction_t *i)
+{
+  if (i->b1 != 0x63) {
+    // Windows hits the ARPL command a bunch of times.
+    // Too much spew...
+    BX_INFO(("UndefinedOpcode: %02x causes exception 6\n",
+              (unsigned) i->b1));
+    }
+  exception(BX_UD_EXCEPTION, 0, 0);
+}
+
+  void
+BX_CPU_C::NOP(BxInstruction_t *i)
+{
+}
+
+
+  void
+BX_CPU_C::HLT(BxInstruction_t *i)
+{
+  // hack to panic if HLT comes from BIOS
+  if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value == 0xf000 )
+    BX_PANIC(("HALT instruction encountered\n"));
+
+  if (CPL!=0) {
+    BX_INFO(("HLT(): CPL!=0\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  if ( ! BX_CPU_THIS_PTR eflags.if_ ) {
+    BX_INFO(("WARNING: HLT instruction with IF=0!\n"));
+    }
+
+  // stops instruction execution and places the processor in a
+  // HALT state.  An enabled interrupt, NMI, or reset will resume
+  // execution.  If interrupt (including NMI) is used to resume
+  // execution after HLT, the saved CS:eIP points to instruction
+  // following HLT.
+
+  // artificial trap bit, why use another variable.
+  BX_CPU_THIS_PTR debug_trap |= 0x80000000; // artificial trap
+  BX_CPU_THIS_PTR async_event = 1; // so processor knows to check
+  // Execution of this instruction completes.  The processor
+  // will remain in a halt state until one of the above conditions
+  // is met.
+}
+
+
+  void
+BX_CPU_C::CLTS(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("CLTS: not implemented for < 286\n"));
+#else
+
+  if (v8086_mode()) BX_PANIC(("clts: v8086 mode unsupported\n"));
+
+  /* read errata file */
+  // does CLTS also clear NT flag???
+
+  // #GP(0) if CPL is not 0
+  if (CPL!=0) {
+    BX_INFO(("CLTS(): CPL!=0\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  BX_CPU_THIS_PTR cr0.ts = 0;
+  BX_CPU_THIS_PTR cr0.val32 &= ~0x08;
+#endif
+}
+
+  void
+BX_CPU_C::INVD(BxInstruction_t *i)
+{
+  BX_INFO(("---------------\n"));
+  BX_INFO(("- INVD called -\n"));
+  BX_INFO(("---------------\n"));
+
+#if BX_CPU_LEVEL >= 4
+  invalidate_prefetch_q();
+
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    if (CPL!=0) {
+      BX_INFO(("INVD: CPL!=0\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+  BX_INSTR_CACHE_CNTRL(BX_INSTR_INVD);
+#else
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::WBINVD(BxInstruction_t *i)
+{
+  BX_INFO(("WBINVD: (ignoring)\n"));
+
+#if BX_CPU_LEVEL >= 4
+  invalidate_prefetch_q();
+
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    if (CPL!=0) {
+      BX_INFO(("WBINVD: CPL!=0\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      }
+    }
+  BX_INSTR_CACHE_CNTRL(BX_INSTR_WBINVD);
+#else
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::MOV_DdRd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_DdRd: not supported on < 386\n"));
+#else
+  Bit32u val_32;
+
+  if (v8086_mode()) BX_PANIC(("MOV_DdRd: v8086 mode unsupported\n"));
+
+  /* NOTES:
+   *   32bit operands always used
+   *   r/m field specifies general register
+   *   mod field should always be 11 binary
+   *   reg field specifies which special register
+   */
+
+  if (i->mod != 0xc0) {
+    BX_PANIC(("MOV_DdRd(): rm field not a register!\n"));
+    }
+
+  invalidate_prefetch_q();
+
+  if (protected_mode() && CPL!=0) {
+    BX_PANIC(("MOV_DdRd: CPL!=0\n"));
+    /* #GP(0) if CPL is not 0 */
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+  val_32 = BX_READ_32BIT_REG(i->rm);
+#if BX_DEBUGGER
+  if (bx_dbg.dreg)
+    BX_INFO(("MOV_DdRd: DR[%u]=%08xh unhandled\n",
+      (unsigned) i->nnn, (unsigned) val_32));
+#endif
+
+  switch (i->nnn) {
+    case 0: // DR0
+      BX_CPU_THIS_PTR dr0 = val_32;
+      break;
+    case 1: // DR1
+      BX_CPU_THIS_PTR dr1 = val_32;
+      break;
+    case 2: // DR2
+      BX_CPU_THIS_PTR dr2 = val_32;
+      break;
+    case 3: // DR3
+      BX_CPU_THIS_PTR dr3 = val_32;
+      break;
+
+    case 4: // DR4
+    case 6: // DR6
+      // DR4 aliased to DR6 by default.  With Debug Extensions on,
+      // access to DR4 causes #UD
+#if BX_CPU_LEVEL >= 4
+      if ( (i->nnn == 4) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+        // Debug extensions on
+        BX_INFO(("MOV_DdRd: access to DR4 causes #UD\n"));
+        UndefinedOpcode(i);
+        }
+#endif
+#if BX_CPU_LEVEL <= 4
+      // On 386/486 bit12 is settable
+      BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
+                            (val_32 & 0x0000f00f);
+#else
+      // On Pentium+, bit12 is always zero
+      BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
+                            (val_32 & 0x0000e00f);
+#endif
+      break;
+
+    case 5: // DR5
+    case 7: // DR7
+      // Note: 486+ ignore GE and LE flags.  On the 386, exact
+      // data breakpoint matching does not occur unless it is enabled
+      // by setting the LE and/or GE flags.
+
+      // DR5 aliased to DR7 by default.  With Debug Extensions on,
+      // access to DR5 causes #UD
+#if BX_CPU_LEVEL >= 4
+      if ( (i->nnn == 5) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+        // Debug extensions (CR4.DE) on
+        BX_INFO(("MOV_DdRd: access to DR5 causes #UD\n"));
+        UndefinedOpcode(i);
+        }
+#endif
+      // Some sanity checks...
+      if ( val_32 & 0x00002000 ) {
+        BX_PANIC(("MOV_DdRd: GD bit not supported yet\n"));
+        // Note: processor clears GD upon entering debug exception
+        // handler, to allow access to the debug registers
+        }
+      if ( (((val_32>>16) & 3)==2) ||
+           (((val_32>>20) & 3)==2) ||
+           (((val_32>>24) & 3)==2) ||
+           (((val_32>>28) & 3)==2) ) {
+        // IO breakpoints (10b) are not yet supported.
+        BX_PANIC(("MOV_DdRd: write of %08x contains IO breakpoint\n",
+          val_32));
+        }
+      if ( (((val_32>>18) & 3)==2) ||
+           (((val_32>>22) & 3)==2) ||
+           (((val_32>>26) & 3)==2) ||
+           (((val_32>>30) & 3)==2) ) {
+        // LEN0..3 contains undefined length specifier (10b)
+        BX_PANIC(("MOV_DdRd: write of %08x contains undefined LENx\n",
+          val_32));
+        }
+      if ( ((((val_32>>16) & 3)==0) && (((val_32>>18) & 3)!=0)) ||
+           ((((val_32>>20) & 3)==0) && (((val_32>>22) & 3)!=0)) ||
+           ((((val_32>>24) & 3)==0) && (((val_32>>26) & 3)!=0)) ||
+           ((((val_32>>28) & 3)==0) && (((val_32>>30) & 3)!=0)) ) {
+        // Instruction breakpoint with LENx not 00b (1-byte length)
+        BX_PANIC(("MOV_DdRd: write of %08x, R/W=00b LEN!=00b\n",
+          val_32));
+        }
+#if BX_CPU_LEVEL <= 4
+      // 386/486: you can play with all the bits except b10 is always 1
+      BX_CPU_THIS_PTR dr7 = val_32 | 0x00000400;
+#else
+      // Pentium+: bits15,14,12 are hardwired to 0, rest are settable.
+      // Even bits 11,10 are changeable though reserved.
+      BX_CPU_THIS_PTR dr7 = (val_32 & 0xffff2fff) | 0x00000400;
+#endif
+      break;
+    default:
+      BX_PANIC(("MOV_DdRd: control register index out of range\n"));
+      break;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::MOV_RdDd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_RdDd: not supported on < 386\n"));
+#else
+  Bit32u val_32;
+
+  if (v8086_mode()) {
+    BX_INFO(("MOV_RdDd: v8086 mode causes #GP\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+  if (i->mod != 0xc0) {
+    BX_PANIC(("MOV_RdDd(): rm field not a register!\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (protected_mode() && (CPL!=0)) {
+    BX_INFO(("MOV_RdDd: CPL!=0 causes #GP\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+#if BX_DEBUGGER
+  if (bx_dbg.dreg)
+    BX_INFO(("MOV_RdDd: DR%u not implemented yet\n", i->nnn));
+#endif
+  
+  switch (i->nnn) {
+    case 0: // DR0
+      val_32 = BX_CPU_THIS_PTR dr0;
+      break;
+    case 1: // DR1
+      val_32 = BX_CPU_THIS_PTR dr1;
+      break;
+    case 2: // DR2
+      val_32 = BX_CPU_THIS_PTR dr2;
+      break;
+    case 3: // DR3
+      val_32 = BX_CPU_THIS_PTR dr3;
+      break;
+
+    case 4: // DR4
+    case 6: // DR6
+      // DR4 aliased to DR6 by default.  With Debug Extensions on,
+      // access to DR4 causes #UD
+#if BX_CPU_LEVEL >= 4
+      if ( (i->nnn == 4) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+        // Debug extensions on
+        BX_INFO(("MOV_RdDd: access to DR4 causes #UD\n"));
+        UndefinedOpcode(i);
+        }
+#endif
+      val_32 = BX_CPU_THIS_PTR dr6;
+      break;
+
+    case 5: // DR5
+    case 7: // DR7
+      // DR5 aliased to DR7 by default.  With Debug Extensions on,
+      // access to DR5 causes #UD
+#if BX_CPU_LEVEL >= 4
+      if ( (i->nnn == 5) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+        // Debug extensions on
+        BX_INFO(("MOV_RdDd: access to DR5 causes #UD\n"));
+        UndefinedOpcode(i);
+        }
+#endif
+      val_32 = BX_CPU_THIS_PTR dr7;
+      break;
+
+    default:
+      BX_PANIC(("MOV_RdDd: control register index out of range\n"));
+      val_32 = 0;
+    }
+  BX_WRITE_32BIT_REG(i->rm, val_32);
+#endif
+}
+
+
+  void
+BX_CPU_C::LMSW_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LMSW_Ew(): not supported on 8086!\n"));
+#else
+  Bit16u msw;
+  Bit32u cr0;
+
+  if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+  if ( protected_mode() ) {
+    if ( CPL != 0 ) {
+      BX_INFO(("LMSW: CPL != 0, CPL=%u\n", (unsigned) CPL));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  if (i->mod == 0xc0) {
+    msw = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    read_virtual_word(i->seg, i->rm_addr, &msw);
+    }
+
+  // LMSW does not affect PG,CD,NW,AM,WP,NE,ET bits, and cannot clear PE
+
+  // LMSW cannot clear PE
+  if ( ((msw & 0x0001)==0) && BX_CPU_THIS_PTR cr0.pe ) {
+    msw |= 0x0001; // adjust PE bit to current value of 1
+    }
+
+  msw &= 0x000f; // LMSW only affects last 4 flags
+  cr0 = (BX_CPU_THIS_PTR cr0.val32 & 0xfffffff0) | msw;
+  SetCR0(cr0);
+#endif /* BX_CPU_LEVEL < 2 */
+}
+
+  void
+BX_CPU_C::SMSW_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("SMSW_Ew: not supported yet!\n"));
+#else
+  Bit16u msw;
+
+
+#if BX_CPU_LEVEL == 2
+  msw = 0xfff0; /* 80286 init value */
+  msw |= (BX_CPU_THIS_PTR cr0.ts << 3) |
+         (BX_CPU_THIS_PTR cr0.em << 2) |
+         (BX_CPU_THIS_PTR cr0.mp << 1) |
+         BX_CPU_THIS_PTR cr0.pe;
+#else /* 386+ */
+  /* reserved bits 0 ??? */
+  /* should NE bit be included here ??? */
+  // should ET bit be included here (AW)
+  msw =  (BX_CPU_THIS_PTR cr0.ts << 3) |
+         (BX_CPU_THIS_PTR cr0.em << 2) |
+         (BX_CPU_THIS_PTR cr0.mp << 1) |
+         BX_CPU_THIS_PTR cr0.pe;
+#endif
+
+
+  if (i->mod == 0xc0) {
+    if (i->os_32) {
+      BX_WRITE_32BIT_REG(i->rm, msw);  // zeros out high 16bits
+      }
+    else {
+      BX_WRITE_16BIT_REG(i->rm, msw);
+      }
+    }
+  else {
+    write_virtual_word(i->seg, i->rm_addr, &msw);
+    }
+
+#endif
+}
+
+
+  void
+BX_CPU_C::MOV_CdRd(BxInstruction_t *i)
+{
+  // mov general register data to control register
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_CdRd: not supported on < 386\n"));
+#else
+  Bit32u val_32;
+
+
+  if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+  /* NOTES:
+   *   32bit operands always used
+   *   r/m field specifies general register
+   *   mod field should always be 11 binary
+   *   reg field specifies which special register
+   */
+
+  if (i->mod != 0xc0) {
+    BX_PANIC(("MOV_CdRd(): rm field not a register!\n"));
+    }
+
+  invalidate_prefetch_q();
+
+  if (protected_mode() && CPL!=0) {
+    BX_PANIC(("MOV_CdRd: CPL!=0\n"));
+    /* #GP(0) if CPL is not 0 */
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  val_32 = BX_READ_32BIT_REG(i->rm);
+
+  switch (i->nnn) {
+    case 0: // CR0 (MSW)
+      // BX_INFO(("MOV_CdRd:CR0: R32 = %08x\n @CS:EIP %04x:%04x ",
+      //   (unsigned) val_32,
+      //   (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+      //   (unsigned) BX_CPU_THIS_PTR eip));
+      SetCR0(val_32);
+      break;
+
+    case 1: /* CR1 */
+      BX_PANIC(("MOV_CdRd: CR1 not implemented yet\n"));
+      break;
+    case 2: /* CR2 */
+      BX_INFO(("MOV_CdRd: CR2 not implemented yet\n"));
+#if BX_DEBUGGER
+      if (bx_dbg.creg)
+        BX_INFO(("MOV_CdRd: CR2 = reg\n"));
+#endif
+      BX_CPU_THIS_PTR cr2 = val_32;
+      break;
+    case 3: // CR3
+#if BX_DEBUGGER
+      if (bx_dbg.creg)
+        BX_INFO(("MOV_CdRd:CR3 = %08x\n", (unsigned) val_32));
+#endif
+      // Reserved bits take on value of MOV instruction
+      CR3_change(val_32);
+      BX_INSTR_TLB_CNTRL(BX_INSTR_MOV_CR3, val_32);
+      break;
+    case 4: // CR4
+#if BX_CPU_LEVEL == 3
+      BX_PANIC(("MOV_CdRd: write to CR4 of 0x%08x on 386\n",
+        val_32));
+      UndefinedOpcode(i);
+#else
+      //  Protected mode: #GP(0) if attempt to write a 1 to
+      //  any reserved bit of CR4
+
+      BX_INFO(("MOV_CdRd: ignoring write to CR4 of 0x%08x\n",
+        val_32));
+      if (val_32) {
+        BX_INFO(("MOV_CdRd: (CR4) write of 0x%08x not supported!\n",
+          val_32));
+        }
+      // Only allow writes of 0 to CR4 for now.
+      // Writes to bits in CR4 should not be 1s as CPUID
+      // returns not-supported for all of these features.
+      BX_CPU_THIS_PTR cr4 = 0;
+#endif
+      break;
+    default:
+      BX_PANIC(("MOV_CdRd: control register index out of range\n"));
+      break;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::MOV_RdCd(BxInstruction_t *i)
+{
+  // mov control register data to register
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_RdCd: not supported on < 386\n"));
+#else
+  Bit32u val_32;
+
+  if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+  /* NOTES:
+   *   32bit operands always used
+   *   r/m field specifies general register
+   *   mod field should always be 11 binary
+   *   reg field specifies which special register
+   */
+
+  if (i->mod != 0xc0) {
+    BX_PANIC(("MOV_RdCd(): rm field not a register!\n"));
+    }
+
+  if (protected_mode() && CPL!=0) {
+    BX_PANIC(("MOV_RdCd: CPL!=0\n"));
+    /* #GP(0) if CPL is not 0 */
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  switch (i->nnn) {
+    case 0: // CR0 (MSW)
+      val_32 = BX_CPU_THIS_PTR cr0.val32;
+#if 0
+      BX_INFO(("MOV_RdCd:CR0: R32 = %08x\n @CS:EIP %04x:%04x\n",
+        (unsigned) val_32,
+        (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+        (unsigned) BX_CPU_THIS_PTR eip));
+#endif
+      break;
+    case 1: /* CR1 */
+      BX_PANIC(("MOV_RdCd: CR1 not implemented yet\n"));
+      val_32 = 0;
+      break;
+    case 2: /* CR2 */
+#if BX_DEBUGGER
+      if (bx_dbg.creg)
+        BX_INFO(("MOV_RdCd: CR2\n"));
+#endif
+      val_32 = BX_CPU_THIS_PTR cr2;
+      break;
+    case 3: // CR3
+#if BX_DEBUGGER
+      if (bx_dbg.creg)
+        BX_INFO(("MOV_RdCd: reading CR3\n"));
+#endif
+      val_32 = BX_CPU_THIS_PTR cr3;
+      break;
+    case 4: // CR4
+#if BX_CPU_LEVEL == 3
+      val_32 = 0;
+      BX_INFO(("MOV_RdCd: read of CR4 causes #UD\n"));
+      UndefinedOpcode(i);
+#else
+      BX_INFO(("MOV_RdCd: read of CR4\n"));
+      val_32 = BX_CPU_THIS_PTR cr4;
+#endif
+      break;
+    default:
+      BX_PANIC(("MOV_RdCd: control register index out of range\n"));
+      val_32 = 0;
+    }
+  BX_WRITE_32BIT_REG(i->rm, val_32);
+#endif
+}
+
+  void
+BX_CPU_C::MOV_TdRd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_TdRd:\n"));
+#elif BX_CPU_LEVEL <= 4
+  BX_PANIC(("MOV_TdRd:\n"));
+#else
+  // Pentium+ does not have TRx.  They were redesigned using the MSRs.
+  BX_INFO(("MOV_TdRd: causes #UD\n"));
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::MOV_RdTd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("MOV_RdTd:\n"));
+#elif BX_CPU_LEVEL <= 4
+  BX_PANIC(("MOV_RdTd:\n"));
+#else
+  // Pentium+ does not have TRx.  They were redesigned using the MSRs.
+  BX_INFO(("MOV_RdTd: causes #UD\n"));
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::LOADALL(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("undocumented LOADALL instruction not supported on 8086\n"));
+#else
+  Bit16u msw, tr, flags, ip, ldtr;
+  Bit16u ds_raw, ss_raw, cs_raw, es_raw;
+  Bit16u di, si, bp, sp, bx, dx, cx, ax;
+  Bit16u base_15_0, limit;
+  Bit8u  base_23_16, access;
+
+  if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+#if BX_CPU_LEVEL > 2
+  BX_PANIC(("loadall: not implemented for 386\n"));
+  /* ??? need to set G and other bits, and compute .limit_scaled also */
+  /* for all segments CS,DS,SS,... */
+#endif
+
+  if (BX_CPU_THIS_PTR cr0.pe) {
+    BX_PANIC((
+      "LOADALL not yet supported for protected mode\n"));
+    }
+
+BX_PANIC(("LOADALL: handle CR0.val32\n"));
+  /* MSW */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x806, 2, &msw);
+  BX_CPU_THIS_PTR cr0.pe = (msw & 0x01); msw >>= 1;
+  BX_CPU_THIS_PTR cr0.mp = (msw & 0x01); msw >>= 1;
+  BX_CPU_THIS_PTR cr0.em = (msw & 0x01); msw >>= 1;
+  BX_CPU_THIS_PTR cr0.ts = (msw & 0x01);
+
+  //BX_INFO(("LOADALL: pe=%u, mp=%u, em=%u, ts=%u\n",
+  //  (unsigned) BX_CPU_THIS_PTR cr0.pe, (unsigned) BX_CPU_THIS_PTR cr0.mp,
+  //  (unsigned) BX_CPU_THIS_PTR cr0.em, (unsigned) BX_CPU_THIS_PTR cr0.ts));
+
+  if (BX_CPU_THIS_PTR cr0.pe || BX_CPU_THIS_PTR cr0.mp || BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts)
+    BX_PANIC(("LOADALL set PE, MP, EM or TS bits in MSW!\n"));
+
+  /* TR */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x816, 2, &tr);
+  BX_CPU_THIS_PTR tr.selector.value = tr;
+  BX_CPU_THIS_PTR tr.selector.rpl   = (tr & 0x03);  tr >>= 2;
+  BX_CPU_THIS_PTR tr.selector.ti    = (tr & 0x01);  tr >>= 1;
+  BX_CPU_THIS_PTR tr.selector.index = tr;
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x860, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x862, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x863, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x864, 2, &limit);
+
+
+  BX_CPU_THIS_PTR tr.cache.valid =
+  BX_CPU_THIS_PTR tr.cache.p           = (access & 0x80) >> 7;
+  BX_CPU_THIS_PTR tr.cache.dpl         = (access & 0x60) >> 5;
+  BX_CPU_THIS_PTR tr.cache.segment     = (access & 0x10) >> 4;
+  BX_CPU_THIS_PTR tr.cache.type        = (access & 0x0f);
+  BX_CPU_THIS_PTR tr.cache.u.tss286.base  = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR tr.cache.u.tss286.limit = limit;
+
+  if ( (BX_CPU_THIS_PTR tr.selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR tr.cache.valid = 0;
+    }
+  if ( BX_CPU_THIS_PTR tr.cache.valid == 0 ) {
+    }
+  if ( BX_CPU_THIS_PTR tr.cache.u.tss286.limit < 43 ) {
+    BX_CPU_THIS_PTR tr.cache.valid = 0;
+    }
+  if ( BX_CPU_THIS_PTR tr.cache.type != 1 ) {
+    BX_CPU_THIS_PTR tr.cache.valid = 0;
+    }
+  if ( BX_CPU_THIS_PTR tr.cache.segment ) {
+    BX_CPU_THIS_PTR tr.cache.valid = 0;
+    }
+  if (BX_CPU_THIS_PTR tr.cache.valid==0) {
+    BX_CPU_THIS_PTR tr.cache.u.tss286.base   = 0;
+    BX_CPU_THIS_PTR tr.cache.u.tss286.limit  = 0;
+    BX_CPU_THIS_PTR tr.cache.p            = 0;
+    BX_CPU_THIS_PTR tr.selector.value     = 0;
+    BX_CPU_THIS_PTR tr.selector.index     = 0;
+    BX_CPU_THIS_PTR tr.selector.ti        = 0;
+    BX_CPU_THIS_PTR tr.selector.rpl       = 0;
+    }
+
+
+  /* FLAGS */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x818, 2, &flags);
+  write_flags(flags, 1, 1);
+
+  /* IP */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x81a, 2, &ip);
+  IP = ip;
+
+  /* LDTR */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x81c, 2, &ldtr);
+  BX_CPU_THIS_PTR ldtr.selector.value = ldtr;
+  BX_CPU_THIS_PTR ldtr.selector.rpl   = (ldtr & 0x03);  ldtr >>= 2;
+  BX_CPU_THIS_PTR ldtr.selector.ti    = (ldtr & 0x01);  ldtr >>= 1;
+  BX_CPU_THIS_PTR ldtr.selector.index = ldtr;
+  if ( (BX_CPU_THIS_PTR ldtr.selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR ldtr.cache.valid   = 0;
+    BX_CPU_THIS_PTR ldtr.cache.p       = 0;
+    BX_CPU_THIS_PTR ldtr.cache.segment = 0;
+    BX_CPU_THIS_PTR ldtr.cache.type    = 0;
+    BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = 0;
+    BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0;
+    BX_CPU_THIS_PTR ldtr.selector.value = 0;
+    BX_CPU_THIS_PTR ldtr.selector.index = 0;
+    BX_CPU_THIS_PTR ldtr.selector.ti    = 0;
+    }
+  else {
+    BX_CPU_THIS_PTR mem->read_physical(this, 0x854, 2, &base_15_0);
+    BX_CPU_THIS_PTR mem->read_physical(this, 0x856, 1, &base_23_16);
+    BX_CPU_THIS_PTR mem->read_physical(this, 0x857, 1, &access);
+    BX_CPU_THIS_PTR mem->read_physical(this, 0x858, 2, &limit);
+    BX_CPU_THIS_PTR ldtr.cache.valid      =
+    BX_CPU_THIS_PTR ldtr.cache.p          = access >> 7;
+    BX_CPU_THIS_PTR ldtr.cache.dpl        = (access >> 5) & 0x03;
+    BX_CPU_THIS_PTR ldtr.cache.segment    = (access >> 4) & 0x01;
+    BX_CPU_THIS_PTR ldtr.cache.type       = (access & 0x0f);
+    BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (base_23_16 << 16) | base_15_0;
+    BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = limit;
+
+    if (access == 0) {
+      BX_PANIC(("loadall: LDTR case access byte=0.\n"));
+      }
+    if ( BX_CPU_THIS_PTR ldtr.cache.valid==0 ) {
+      BX_PANIC(("loadall: ldtr.valid=0\n"));
+      }
+    if (BX_CPU_THIS_PTR ldtr.cache.segment) { /* not a system segment */
+      BX_INFO(("         AR byte = %02x\n", (unsigned) access));
+      BX_PANIC(("loadall: LDTR descriptor cache loaded with non system segment\n"));
+      }
+    if ( BX_CPU_THIS_PTR ldtr.cache.type != 2 ) {
+      BX_PANIC(("loadall: LDTR.type(%u) != 2\n", (unsigned) (access & 0x0f)));
+      }
+    }
+
+  /* DS */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x81e, 2, &ds_raw);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = ds_raw;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl   = (ds_raw & 0x03);  ds_raw >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti    = (ds_raw & 0x01);  ds_raw >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = ds_raw;
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x848, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x84a, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x84b, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x84c, 2, &limit);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = limit;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a          = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w        = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed       = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment    = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl        = (access & 0x03); access >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid      =
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p          = (access & 0x01);
+
+  if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+    }
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid==0  ||
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment==0) {
+    BX_PANIC(("loadall: DS invalid\n"));
+    }
+
+  /* SS */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x820, 2, &ss_raw);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = ss_raw;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl   = (ss_raw & 0x03); ss_raw >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti    = (ss_raw & 0x01); ss_raw >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = ss_raw;
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x842, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x844, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x845, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x846, 2, &limit);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = limit;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a          = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w        = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed       = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment    = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl        = (access & 0x03); access >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p          = (access & 0x01);
+
+  if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+    }
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0  ||
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment==0) {
+    BX_PANIC(("loadall: SS invalid\n"));
+    }
+
+
+  /* CS */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x822, 2, &cs_raw);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cs_raw;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl   = (cs_raw & 0x03); cs_raw >>= 2;
+
+  //BX_INFO(("LOADALL: setting cs.selector.rpl to %u\n",
+  //  (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl));
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti    = (cs_raw & 0x01); cs_raw >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cs_raw;
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x83c, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x83e, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x83f, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x840, 2, &limit);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = limit;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a          = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w        = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed       = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment    = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl        = (access & 0x03); access >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p          = (access & 0x01);
+
+  if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 0;
+    }
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid==0  ||
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment==0) {
+    BX_PANIC(("loadall: CS invalid\n"));
+    }
+
+  /* ES */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x824, 2, &es_raw);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = es_raw;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl   = (es_raw & 0x03); es_raw >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti    = (es_raw & 0x01); es_raw >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = es_raw;
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x836, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x838, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x839, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x83a, 2, &limit);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = limit;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a          = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w        = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed       = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment    = (access & 0x01); access >>= 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl        = (access & 0x03); access >>= 2;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p          = (access & 0x01);
+
+#if 0
+    BX_INFO(("cs.dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl));
+    BX_INFO(("ss.dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl));
+    BX_INFO(("BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR ds.cache.dpl));
+    BX_INFO(("BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR es.cache.dpl));
+    BX_INFO(("LOADALL: setting cs.selector.rpl to %u\n",
+      (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl));
+    BX_INFO(("LOADALL: setting ss.selector.rpl to %u\n",
+      (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl));
+    BX_INFO(("LOADALL: setting ds.selector.rpl to %u\n",
+      (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl));
+    BX_INFO(("LOADALL: setting es.selector.rpl to %u\n",
+      (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl));
+#endif
+
+  if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value & 0xfffc) == 0 ) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+    }
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid==0  ||
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment==0) {
+    BX_PANIC(("loadall: ES invalid\n"));
+    }
+
+  /* DI */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x826, 2, &di);
+  DI = di;
+
+  /* SI */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x828, 2, &si);
+  SI = si;
+
+  /* BP */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x82a, 2, &bp);
+  BP = bp;
+
+  /* SP */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x82c, 2, &sp);
+  SP = sp;
+
+  /* BX */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x82e, 2, &bx);
+  BX = bx;
+
+  /* DX */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x830, 2, &dx);
+  DX = dx;
+
+  /* CX */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x832, 2, &cx);
+  CX = cx;
+
+  /* AX */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x834, 2, &ax);
+  AX = ax;
+
+  /* GDTR */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x84e, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x850, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x851, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x852, 2, &limit);
+  BX_CPU_THIS_PTR gdtr.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR gdtr.limit = limit;
+
+#if 0
+  if (access)
+      BX_INFO(("LOADALL: GDTR access bits not 0 (%02x).\n",
+        (unsigned) access));
+#endif
+
+  /* IDTR */
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x85a, 2, &base_15_0);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x85c, 1, &base_23_16);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x85d, 1, &access);
+  BX_CPU_THIS_PTR mem->read_physical(this, 0x85e, 2, &limit);
+  BX_CPU_THIS_PTR idtr.base = (base_23_16 << 16) | base_15_0;
+  BX_CPU_THIS_PTR idtr.limit = limit;
+#endif
+}
+
+
+  void
+BX_CPU_C::CPUID(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 4
+  unsigned type, family, model, stepping, features;
+#endif
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 4
+  switch (EAX) {
+    case 0:
+      // EAX: highest input value understood by CPUID
+      // EBX: vendor ID string
+      // EDX: vendor ID string
+      // ECX: vendor ID string
+      EAX = 1; // 486 or pentium
+      EBX = 0x756e6547; // "Genu"
+      EDX = 0x49656e69; // "ineI"
+      ECX = 0x6c65746e; // "ntel"
+      break;
+
+    case 1:
+      // EAX[3:0]   Stepping ID
+      // EAX[7:4]   Model: starts at 1
+      // EAX[11:8]  Family: 4=486, 5=Pentium, 6=PPro
+      // EAX[13:12] Type: 0=OEM,1=overdrive,2=dual cpu,3=reserved
+      // EAX[31:14] Reserved
+      // EBX:       Reserved (0)
+      // ECX:       Reserved (0)
+      // EDX:       Feature Flags
+      //   [0:0]   FPU on chip
+      //   [1:1]   VME: Virtual-8086 Mode enhancements
+      //   [2:2]   DE: Debug Extensions (I/O breakpoints)
+      //   [3:3]   PSE: Page Size Extensions
+      //   [4:4]   TSC: Time Stamp Counter
+      //   [5:5]   MSR: RDMSR and WRMSR support
+      //   [6:6]   PAE: Physical Address Extensions
+      //   [7:7]   MCE: Machine Check Exception
+      //   [8:8]   CXS: CMPXCHG8B instruction
+      //   [9:9]   APIC: APIC on Chip
+      //   [11:10] Reserved
+      //   [12:12] MTRR: Memory Type Range Reg
+      //   [13:13] PGE/PTE Global Bit
+      //   [14:14] MCA: Machine Check Architecture
+      //   [15:15] CMOV: Cond Mov/Cmp Instructions
+      //   [22:16] Reserved
+      //   [23:23] MMX Technology
+      //   [31:24] Reserved
+
+      features = 0; // start with none
+      type = 0; // OEM
+
+#if BX_CPU_LEVEL == 4
+      family = 4;
+#  if BX_SUPPORT_FPU
+      // 486dx
+      model = 1;
+      stepping = 3;
+      features |= 0x01;
+#  else
+      // 486sx
+      model = 2;
+      stepping = 3;
+#  endif
+
+#elif BX_CPU_LEVEL == 5
+      family = 5;
+      model = 1; // Pentium (60,66)
+      stepping = 3; // ???
+      features |= (1<<4);   // implement TSC
+#  if BX_SUPPORT_FPU
+      features |= 0x01;
+#  endif
+
+#elif BX_CPU_LEVEL == 6
+      family = 6;
+      model = 1; // Pentium Pro
+      stepping = 3; // ???
+      features |= (1<<4);   // implement TSC
+#  if BX_SUPPORT_APIC
+      features |= (1<<9);   // APIC on chip
+#  endif
+#  if BX_SUPPORT_FPU
+      features |= 0x01;     // has FPU
+#  endif
+#else
+      BX_PANIC(("CPUID: not implemented for > 6\n"));
+#endif
+
+      EAX = (family <<8) | (model<<4) | stepping;
+      EBX = ECX = 0; // reserved
+      EDX = features;
+      break;
+
+    default:
+      EAX = EBX = ECX = EDX = 0; // Reserved, undefined
+      break;
+    }
+#else
+  BX_PANIC(("CPUID: not available on < late 486\n"));
+#endif
+}
+
+  void
+BX_CPU_C::SetCR0(Bit32u val_32)
+{
+  // from either MOV_CdRd() or debug functions
+  // protection checks made already or forcing from debug
+  Boolean prev_pe, prev_pg;
+
+  prev_pe = BX_CPU_THIS_PTR cr0.pe;
+  prev_pg = BX_CPU_THIS_PTR cr0.pg;
+
+  BX_CPU_THIS_PTR cr0.pe = val_32 & 0x01;
+  BX_CPU_THIS_PTR cr0.mp = (val_32 >> 1) & 0x01;
+  BX_CPU_THIS_PTR cr0.em = (val_32 >> 2) & 0x01;
+  BX_CPU_THIS_PTR cr0.ts = (val_32 >> 3) & 0x01;
+  // cr0.et is hardwired to 1
+#if BX_CPU_LEVEL >= 4
+  BX_CPU_THIS_PTR cr0.ne = (val_32 >> 5)  & 0x01;
+  BX_CPU_THIS_PTR cr0.wp = (val_32 >> 16) & 0x01;
+  BX_CPU_THIS_PTR cr0.am = (val_32 >> 18) & 0x01;
+  BX_CPU_THIS_PTR cr0.nw = (val_32 >> 29) & 0x01;
+  BX_CPU_THIS_PTR cr0.cd = (val_32 >> 30) & 0x01;
+#endif
+  BX_CPU_THIS_PTR cr0.pg = (val_32 >> 31) & 0x01;
+
+  // handle reserved bits behaviour
+#if BX_CPU_LEVEL == 3
+  BX_CPU_THIS_PTR cr0.val32 = val_32 | 0x7ffffff0;
+#elif BX_CPU_LEVEL == 4
+  BX_CPU_THIS_PTR cr0.val32 = val_32 & 0xe005002f;
+#elif BX_CPU_LEVEL == 5
+  BX_CPU_THIS_PTR cr0.val32 = val_32 | 0x00000010;
+#elif BX_CPU_LEVEL == 6
+  BX_CPU_THIS_PTR cr0.val32 = (val_32 | 0x00000010) & 0xe005003f;
+#else
+#error "MOV_CdRd: implement reserved bits behaviour for this CPU_LEVEL"
+#endif
+
+  //if (BX_CPU_THIS_PTR cr0.ts)
+  //  BX_INFO(("MOV_CdRd:CR0.TS set 0x%x\n", (unsigned) val_32));
+
+  if (prev_pe==0 && BX_CPU_THIS_PTR cr0.pe) {
+    enter_protected_mode();
+    }
+  else if (prev_pe==1 && BX_CPU_THIS_PTR cr0.pe==0) {
+    enter_real_mode();
+    }
+
+  if (prev_pg==0 && BX_CPU_THIS_PTR cr0.pg)
+    enable_paging();
+  else if (prev_pg==1 && BX_CPU_THIS_PTR cr0.pg==0)
+    disable_paging();
+}
+
+
+  void
+BX_CPU_C::RSM(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 4
+  invalidate_prefetch_q();
+
+  BX_PANIC(("RSM: System Management Mode not implemented yet\n"));
+#else
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::RDTSC(BxInstruction_t *i)
+{
+#if 0
+#if BX_CPU_LEVEL >= 5
+  Boolean tsd = (BX_CPU_THIS_PTR cr4 & 4)? 1 : 0;
+  Boolean cpl = CPL;
+  if ((tsd==0) || (tsd==1 && cpl==0)) {
+    // return ticks
+    Bit64u ticks = bx_pc_system.time_ticks ();
+    EAX = (Bit32u) (ticks & 0xffffffff);
+    EDX = (Bit32u) ((ticks >> 32) & 0xffffffff);
+    //BX_INFO(("RDTSC: returning EDX:EAX = %08x:%08x\n", EDX, EAX));
+  } else {
+    // not allowed to use RDTSC!
+    exception (BX_GP_EXCEPTION, 0, 0);
+  }
+#else
+  UndefinedOpcode(i);
+#endif
+#endif
+}
+
+  void
+BX_CPU_C::RDMSR(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 5
+  BX_ERROR(("RDMSR: not implemented yet\n"));
+  UndefinedOpcode(i);
+#else
+  UndefinedOpcode(i);
+#endif
+}
+
+  void
+BX_CPU_C::WRMSR(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 5
+  invalidate_prefetch_q();
+
+  BX_PANIC(( "WRMSR: not implemented yet\n"));
+#else
+  UndefinedOpcode(i);
+#endif
+}
+
+#if BX_X86_DEBUGGER
+  Bit32u
+BX_CPU_C::hwdebug_compare(Bit32u laddr_0, unsigned size,
+                          unsigned opa, unsigned opb)
+{
+  // Support x86 hardware debug facilities (DR0..DR7)
+  Bit32u dr7 = BX_CPU_THIS_PTR dr7;
+
+  Boolean ibpoint_found = 0;
+  Bit32u  laddr_n = laddr_0 + (size - 1);
+  Bit32u  dr0, dr1, dr2, dr3;
+  Bit32u  dr0_n, dr1_n, dr2_n, dr3_n;
+  Bit32u  len0, len1, len2, len3;
+  static  unsigned alignment_mask[4] =
+    //    00b=1      01b=2     10b=undef     11b=4
+    { 0xffffffff, 0xfffffffe, 0xffffffff, 0xfffffffc };
+  Bit32u dr0_op, dr1_op, dr2_op, dr3_op;
+
+  len0 = (dr7>>18) & 3;
+  len1 = (dr7>>22) & 3;
+  len2 = (dr7>>26) & 3;
+  len3 = (dr7>>30) & 3;
+
+  dr0 = BX_CPU_THIS_PTR dr0 & alignment_mask[len0];
+  dr1 = BX_CPU_THIS_PTR dr1 & alignment_mask[len1];
+  dr2 = BX_CPU_THIS_PTR dr2 & alignment_mask[len2];
+  dr3 = BX_CPU_THIS_PTR dr3 & alignment_mask[len3];
+
+  dr0_n = dr0 + len0;
+  dr1_n = dr1 + len1;
+  dr2_n = dr2 + len2;
+  dr3_n = dr3 + len3;
+
+  dr0_op = (dr7>>16) & 3;
+  dr1_op = (dr7>>20) & 3;
+  dr2_op = (dr7>>24) & 3;
+  dr3_op = (dr7>>28) & 3;
+
+  // See if this instruction address matches any breakpoints
+  if ( (dr7 & 0x00000003) ) {
+    if ( (dr0_op==opa || dr0_op==opb) &&
+         (laddr_0 <= dr0_n) &&
+         (laddr_n >= dr0) )
+      ibpoint_found = 1;
+    }
+  if ( (dr7 & 0x0000000c) ) {
+    if ( (dr1_op==opa || dr1_op==opb) &&
+         (laddr_0 <= dr1_n) &&
+         (laddr_n >= dr1) )
+      ibpoint_found = 1;
+    }
+  if ( (dr7 & 0x00000030) ) {
+    if ( (dr2_op==opa || dr2_op==opb) &&
+         (laddr_0 <= dr2_n) &&
+         (laddr_n >= dr2) )
+      ibpoint_found = 1;
+    }
+  if ( (dr7 & 0x000000c0) ) {
+    if ( (dr3_op==opa || dr3_op==opb) &&
+         (laddr_0 <= dr3_n) &&
+         (laddr_n >= dr3) )
+      ibpoint_found = 1;
+    }
+
+  // If *any* enabled breakpoints matched, then we need to
+  // set status bits for *all* breakpoints, even disabled ones,
+  // as long as they meet the other breakpoint criteria.
+  // This code is similar to that above, only without the
+  // breakpoint enabled check.  Seems weird to duplicate effort,
+  // but its more efficient to do it this way.
+  if (ibpoint_found) {
+    // dr6_mask is the return value.  These bits represent the bits to
+    // be OR'd into DR6 as a result of the debug event.
+    Bit32u  dr6_mask=0;
+    if ( (dr0_op==opa || dr0_op==opb) &&
+         (laddr_0 <= dr0_n) &&
+         (laddr_n >= dr0) )
+      dr6_mask |= 0x01;
+    if ( (dr1_op==opa || dr1_op==opb) &&
+         (laddr_0 <= dr1_n) &&
+         (laddr_n >= dr1) )
+      dr6_mask |= 0x02;
+    if ( (dr2_op==opa || dr2_op==opb) &&
+         (laddr_0 <= dr2_n) &&
+         (laddr_n >= dr2) )
+      dr6_mask |= 0x04;
+    if ( (dr3_op==opa || dr3_op==opb) &&
+         (laddr_0 <= dr3_n) &&
+         (laddr_n >= dr3) )
+      dr6_mask |= 0x08;
+    return(dr6_mask);
+    }
+  return(0);
+}
+#endif
diff --git a/sid/component/bochs/cpu/protect_ctrl.cc b/sid/component/bochs/cpu/protect_ctrl.cc
new file mode 100644 (file)
index 0000000..f713495
--- /dev/null
@@ -0,0 +1,880 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::ARPL_EwGw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("ARPL_EwRw: not supported on 8086!\n"));
+#else /* 286+ */
+
+  Bit16u op2_16, op1_16;
+
+
+  if (protected_mode()) {
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    if ( (op1_16 & 0x03) < (op2_16 & 0x03) ) {
+      op1_16 = (op1_16 & 0xfffc) | (op2_16 & 0x03);
+      /* now write back to destination */
+      if (i->mod == 0xc0) {
+        if (i->os_32) {
+          // if 32bit opsize, then 0xff3f is or'd into
+          // upper 16bits of register
+          Bit32u op1_32;
+
+          op1_32 = BX_READ_32BIT_REG(i->rm);
+          op1_32 = (op1_32 & 0xffff0000) | op1_16;
+          op1_32 |= 0xff3f0000;
+          BX_WRITE_32BIT_REG(i->rm, op1_32);
+          }
+        else {
+          BX_WRITE_16BIT_REG(i->rm, op1_16);
+          }
+        }
+      else {
+        write_RMW_virtual_word(op1_16);
+        }
+      set_ZF(1);
+      }
+    else {
+      set_ZF(0);
+      }
+    }
+  else {
+    // ARPL not recognized in real or v8086 mode
+    UndefinedOpcode(i);
+    return;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LAR_GvEw(BxInstruction_t *i)
+{
+  /* for 16 bit operand size mode */
+  Bit16u raw_selector;
+  bx_descriptor_t descriptor;
+  bx_selector_t   selector;
+  Bit32u dword1, dword2;
+
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  if (real_mode()) {
+    BX_PANIC(("LAR_GvEw: not recognized in real mode\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+
+  if (i->mod == 0xc0) {
+    raw_selector = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+    }
+
+  /* if selector null, clear ZF and done */
+  if ( (raw_selector & 0xfffc) == 0 ) {
+    set_ZF(0);
+    return;
+    }
+
+  parse_selector(raw_selector, &selector);
+
+  if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+    /* not within descriptor table */
+    set_ZF(0);
+    return;
+    }
+
+  parse_descriptor(dword1, dword2, &descriptor);
+
+  if (descriptor.valid==0) {
+    set_ZF(0);
+    //BX_INFO(("lar(): descriptor valid bit cleared\n"));
+    return;
+    }
+
+  /* if source selector is visible at CPL & RPL,
+   * within the descriptor table, and of type accepted by LAR instruction,
+   * then load register with segment limit and set ZF
+   */
+
+  if ( descriptor.segment ) { /* normal segment */
+    if ( descriptor.u.segment.executable && descriptor.u.segment.c_ed ) {
+      /* ignore DPL for conforming segments */
+      }
+    else {
+      if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+        set_ZF(0);
+        return;
+        }
+      }
+    set_ZF(1);
+    if (i->os_32) {
+      /* masked by 00FxFF00, where x is undefined */
+      BX_WRITE_32BIT_REG(i->nnn, dword2 & 0x00ffff00);
+      }
+    else {
+      BX_WRITE_16BIT_REG(i->nnn, dword2 & 0xff00);
+      }
+    return;
+    }
+  else { /* system or gate segment */
+    switch ( descriptor.type ) {
+      case 1: /* available TSS */
+      case 2: /* LDT */
+      case 3: /* busy TSS */
+      case 4: /* 286 call gate */
+      case 5: /* task gate */
+#if BX_CPU_LEVEL >= 3
+      case 9:  /* available 32bit TSS */
+      case 11: /* busy 32bit TSS */
+      case 12: /* 32bit call gate */
+#endif
+        break;
+      default: /* rest not accepted types to LAR */
+        set_ZF(0);
+        BX_INFO(("lar(): not accepted type\n"));
+        return;
+        break;
+      }
+
+    if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+      set_ZF(0);
+      return;
+      }
+    set_ZF(1);
+    if (i->os_32) {
+      /* masked by 00FxFF00, where x is undefined ??? */
+      BX_WRITE_32BIT_REG(i->nnn, dword2 & 0x00ffff00);
+      }
+    else {
+      BX_WRITE_16BIT_REG(i->nnn, dword2 & 0xff00);
+      }
+    return;
+    }
+}
+
+  void
+BX_CPU_C::LSL_GvEw(BxInstruction_t *i)
+{
+  /* for 16 bit operand size mode */
+  Bit16u raw_selector;
+  Bit32u limit32;
+  //bx_descriptor_t descriptor;
+  bx_selector_t   selector;
+  Bit32u dword1, dword2;
+  Bit32u descriptor_dpl;
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+  if (real_mode()) {
+    BX_PANIC(("LSL_GvEw: not recognized in real mode\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  if (i->mod == 0xc0) {
+    raw_selector = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+    }
+
+
+  /* if selector null, clear ZF and done */
+  if ( (raw_selector & 0xfffc) == 0 ) {
+    set_ZF(0);
+    return;
+    }
+
+  parse_selector(raw_selector, &selector);
+
+  if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+    /* not within descriptor table */
+    set_ZF(0);
+    return;
+    }
+
+  //parse_descriptor(dword1, dword2, &descriptor);
+
+  descriptor_dpl = (dword2 >> 13) & 0x03;
+
+  if ( (dword2 & 0x00001000) == 0 ) { // system segment
+    Bit32u type;
+
+    type = (dword2 >> 8) & 0x0000000f;
+    switch (type) {
+      case 1: // 16bit TSS
+      case 3: // 16bit TSS
+      case 2: // LDT
+      case 9: // 32bit TSS    G00A
+      case 11:// 32bit TSS    G00A
+        limit32 = (dword1 & 0x0000ffff) | (dword2 & 0x000f0000);
+        if ( dword2 & 0x00800000 )
+          limit32 = (limit32 << 12) | 0x00000fff;
+        if ( (descriptor_dpl<CPL) || (descriptor_dpl<selector.rpl) ) {
+          set_ZF(0);
+          return;
+          }
+        goto lsl_ok;
+        break;
+      default:
+        set_ZF(0);
+        return;
+      }
+    }
+  else { // data & code segment
+    limit32 = (dword1 & 0x0000ffff) | (dword2 & 0x000f0000);
+    if ( dword2 & 0x00800000 )
+      limit32 = (limit32 << 12) | 0x00000fff;
+    if ( (dword2 & 0x00000c00) == 0x00000c00 ) {
+      // conforming code segment, no check done
+      goto lsl_ok;
+      }
+
+    if ( (descriptor_dpl<CPL) || (descriptor_dpl<selector.rpl) ) {
+      set_ZF(0);
+      return;
+      }
+    goto lsl_ok;
+    }
+
+lsl_ok:
+  /* all checks pass, limit32 is now byte granular, write to op1 */
+  set_ZF(1);
+
+  if (i->os_32)
+    BX_WRITE_32BIT_REG(i->nnn, limit32)
+  else
+    // chop off upper 16 bits
+    BX_WRITE_16BIT_REG(i->nnn, (Bit16u) limit32)
+}
+
+  void
+BX_CPU_C::SLDT_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("SLDT_Ew: not supported on 8086!\n"));
+#else
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  if (real_mode()) {
+    /* not recognized in real address mode */
+    BX_ERROR(("SLDT_Ew: encountered in real mode.\n"));
+    UndefinedOpcode(i);
+    }
+  else {
+    Bit16u val16;
+
+    val16 = BX_CPU_THIS_PTR ldtr.selector.value;
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, val16);
+      }
+    else {
+      write_virtual_word(i->seg, i->rm_addr, &val16);
+      }
+    }
+#endif
+}
+
+  void
+BX_CPU_C::STR_Ew(BxInstruction_t *i)
+{
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  if (real_mode()) {
+    // not recognized in real address mode
+    BX_PANIC(("STR_Ew: encountered in real mode.\n"));
+    UndefinedOpcode(i);
+    }
+  else {
+    Bit16u val16;
+
+    val16 = BX_CPU_THIS_PTR tr.selector.value;
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, val16);
+      }
+    else {
+      write_virtual_word(i->seg, i->rm_addr, &val16);
+      }
+    }
+}
+
+  void
+BX_CPU_C::LLDT_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LLDT_Ew: not supported on 8086!\n"));
+#else
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  invalidate_prefetch_q();
+
+  if (real_mode()) {
+    BX_PANIC(("lldt: not recognized in real mode\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+  else { /* protected mode */
+    bx_descriptor_t  descriptor;
+    bx_selector_t    selector;
+    Bit16u raw_selector;
+    Bit32u dword1, dword2;
+
+
+    /* #GP(0) if the current privilege level is not 0 */
+    if (CPL != 0) {
+      BX_PANIC(("LLDT: CPL != 0\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+
+    if (i->mod == 0xc0) {
+      raw_selector = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+      }
+
+    /* if selector is NULL, invalidate and done */
+    if ((raw_selector & 0xfffc) == 0) {
+      BX_CPU_THIS_PTR ldtr.selector.value = raw_selector;
+      BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+      return;
+      }
+
+    /* parse fields in selector */
+    parse_selector(raw_selector, &selector);
+
+    // #GP(selector) if the selector operand does not point into GDT
+    if (selector.ti != 0) {
+      BX_INFO(("LLDT: selector.ti != 0\n"));
+      exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+      }
+
+    if ((selector.index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+      BX_PANIC(("lldt: GDT: index > limit\n"));
+      exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+      return;
+      }
+
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8,     4, 0,
+      BX_READ, &dword1);
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 4, 4, 0,
+      BX_READ, &dword2);
+
+    parse_descriptor(dword1, dword2, &descriptor);
+
+    /* if selector doesn't point to an LDT descriptor #GP(selector) */
+    if ( (descriptor.valid==0) ||
+        descriptor.segment  ||
+        (descriptor.type!=2) ) {
+      BX_INFO(("lldt: doesn't point to an LDT descriptor!\n"));
+      exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+      }
+
+    /* #NP(selector) if LDT descriptor is not present */
+    if (descriptor.p==0) {
+      BX_INFO(("lldt: LDT descriptor not present!\n"));
+      exception(BX_NP_EXCEPTION, raw_selector & 0xfffc, 0);
+      }
+
+    if (descriptor.u.ldt.limit < 7) {
+      BX_INFO(("lldt: ldtr.limit < 7\n"));
+      }
+
+    BX_CPU_THIS_PTR ldtr.selector = selector;
+    BX_CPU_THIS_PTR ldtr.cache = descriptor;
+    BX_CPU_THIS_PTR ldtr.cache.valid = 1;
+
+    return;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LTR_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LTR_Ew: not supported on 8086!\n"));
+#else
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+  invalidate_prefetch_q();
+
+  if (protected_mode()) {
+    bx_descriptor_t  descriptor;
+    bx_selector_t    selector;
+    Bit16u raw_selector;
+    Bit32u dword1, dword2;
+
+
+    /* #GP(0) if the current privilege level is not 0 */
+    if (CPL != 0) {
+      BX_PANIC(("LTR: CPL != 0\n"));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+
+    if (i->mod == 0xc0) {
+      raw_selector = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+      }
+
+    /* if selector is NULL, invalidate and done */
+    if ((raw_selector & 0xfffc) == 0) {
+      BX_PANIC(("ltr: loading with NULL selector!\n"));
+      /* if this is OK, then invalidate and load selector & descriptor cache */
+      /* load here */
+      BX_CPU_THIS_PTR tr.selector.value = raw_selector;
+      BX_CPU_THIS_PTR tr.cache.valid = 0;
+      return;
+      }
+
+    /* parse fields in selector, then check for null selector */
+    parse_selector(raw_selector, &selector);
+
+    if (selector.ti) {
+      BX_PANIC(("ltr: selector.ti != 0\n"));
+      return;
+      }
+
+    /* fetch 2 dwords of descriptor; call handles out of limits checks */
+    fetch_raw_descriptor(&selector, &dword1, &dword2, BX_GP_EXCEPTION);
+
+    parse_descriptor(dword1, dword2, &descriptor);
+
+    /* #GP(selector) if object is not a TSS or is already busy */
+    if ( (descriptor.valid==0) || descriptor.segment  ||
+         (descriptor.type!=1 && descriptor.type!=9) ) {
+      BX_PANIC(("ltr: doesn't point to an available TSS descriptor!\n"));
+      exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0); /* 0 ??? */
+      return;
+      }
+
+    /* #NP(selector) if TSS descriptor is not present */
+    if (descriptor.p==0) {
+      BX_PANIC(("ltr: LDT descriptor not present!\n"));
+      exception(BX_NP_EXCEPTION, raw_selector & 0xfffc, 0); /* 0 ??? */
+      return;
+      }
+
+    if (descriptor.type==1 && descriptor.u.tss286.limit<43) {
+      BX_PANIC(("ltr:286TSS: loading tr.limit < 43\n"));
+      }
+    else if (descriptor.type==9 && descriptor.u.tss386.limit_scaled<103) {
+      BX_PANIC(("ltr:386TSS: loading tr.limit < 103\n"));
+      }
+
+    BX_CPU_THIS_PTR tr.selector = selector;
+    BX_CPU_THIS_PTR tr.cache    = descriptor;
+    BX_CPU_THIS_PTR tr.cache.valid = 1;
+
+    /* mark as busy */
+    dword2 |= 0x00000200; /* set busy bit */
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 4, 4, 0,
+      BX_WRITE, &dword2);
+
+    return;
+    }
+  else {
+    BX_PANIC(("ltr_ew: not recognized in real-mode!\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::VERR_Ew(BxInstruction_t *i)
+{
+  /* for 16 bit operand size mode */
+  Bit16u raw_selector;
+  bx_descriptor_t descriptor;
+  bx_selector_t   selector;
+  Bit32u dword1, dword2;
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+  if (real_mode()) {
+    BX_PANIC(("VERR_Ew: not recognized in real mode\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  if (i->mod == 0xc0) {
+    raw_selector = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+    }
+
+  /* if selector null, clear ZF and done */
+  if ( (raw_selector & 0xfffc) == 0 ) {
+    set_ZF(0);
+    BX_INFO(("VERR: null selector\n"));
+    return;
+    }
+
+  /* if source selector is visible at CPL & RPL,
+   * within the descriptor table, and of type accepted by VERR instruction,
+   * then load register with segment limit and set ZF */
+  parse_selector(raw_selector, &selector);
+
+  if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+    /* not within descriptor table */
+    set_ZF(0);
+    BX_INFO(("VERR: not in table\n"));
+    return;
+    }
+
+  parse_descriptor(dword1, dword2, &descriptor);
+
+  if ( descriptor.segment==0 ) { /* system or gate descriptor */
+    set_ZF(0); /* inaccessible */
+    BX_INFO(("VERR: system descriptor\n"));
+    return;
+    }
+
+  if ( descriptor.valid==0 ) {
+    set_ZF(0);
+    BX_INFO(("VERR: valid bit cleared\n"));
+    return;
+    }
+
+  /* normal data/code segment */
+  if ( descriptor.u.segment.executable ) { /* code segment */
+    /* ignore DPL for readable conforming segments */
+    if ( descriptor.u.segment.c_ed &&
+         descriptor.u.segment.r_w) {
+      set_ZF(1); /* accessible */
+      BX_INFO(("VERR: conforming code, OK\n"));
+      return;
+      }
+    if ( descriptor.u.segment.r_w==0 ) {
+      set_ZF(0); /* inaccessible */
+      BX_INFO(("VERR: code not readable\n"));
+      return;
+      }
+    /* readable, non-conforming code segment */
+    if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+      set_ZF(0); /* inaccessible */
+      BX_INFO(("VERR: non-coforming code not withing priv level\n"));
+      return;
+      }
+    set_ZF(1); /* accessible */
+    BX_INFO(("VERR: code seg readable\n"));
+    return;
+    }
+  else { /* data segment */
+    if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+      set_ZF(0); /* not accessible */
+      BX_INFO(("VERR: data seg not withing priv level\n"));
+      return;
+      }
+    set_ZF(1); /* accessible */
+    BX_INFO(("VERR: data segment OK\n"));
+    return;
+    }
+}
+
+  void
+BX_CPU_C::VERW_Ew(BxInstruction_t *i)
+{
+  /* for 16 bit operand size mode */
+  Bit16u raw_selector;
+  bx_descriptor_t descriptor;
+  bx_selector_t   selector;
+  Bit32u dword1, dword2;
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+  if (real_mode()) {
+    BX_PANIC(("VERW_Ew: not recognized in real mode\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  if (i->mod == 0xc0) {
+    raw_selector = BX_READ_16BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+    }
+
+  /* if selector null, clear ZF and done */
+  if ( (raw_selector & 0xfffc) == 0 ) {
+    set_ZF(0);
+    BX_INFO(("VERW: null selector\n"));
+    return;
+    }
+
+  /* if source selector is visible at CPL & RPL,
+   * within the descriptor table, and of type accepted by VERW instruction,
+   * then load register with segment limit and set ZF */
+  parse_selector(raw_selector, &selector);
+
+  if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+    /* not within descriptor table */
+    set_ZF(0);
+    BX_INFO(("VERW: not in table\n"));
+    return;
+    }
+
+  parse_descriptor(dword1, dword2, &descriptor);
+
+  /* rule out system segments & code segments */
+  if ( descriptor.segment==0 || descriptor.u.segment.executable ) {
+    set_ZF(0);
+    BX_INFO(("VERW: system seg or code\n"));
+    return;
+    }
+
+  if ( descriptor.valid==0 ) {
+    set_ZF(0);
+    BX_INFO(("VERW: valid bit cleared\n"));
+    return;
+    }
+
+  /* data segment */
+  if ( descriptor.u.segment.r_w ) { /* writable */
+    if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+      set_ZF(0); /* not accessible */
+      BX_INFO(("VERW: writable data seg not within priv level\n"));
+      return;
+      }
+    set_ZF(1); /* accessible */
+    BX_INFO(("VERW: data seg writable\n"));
+    return;
+    }
+
+  set_ZF(0); /* not accessible */
+  BX_INFO(("VERW: data seg not writable\n"));
+  return;
+}
+
+  void
+BX_CPU_C::SGDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("SGDT_Ms: not supported on 8086!\n"));
+#else
+  Bit16u limit_16;
+  Bit32u base_32;
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    /* undefined opcode exception */
+    BX_PANIC(("SGDT_Ms: use of register is undefined opcode.\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  limit_16 = BX_CPU_THIS_PTR gdtr.limit;
+  base_32  = BX_CPU_THIS_PTR gdtr.base;
+#if BX_CPU_LEVEL == 2
+  base_32 |= 0xff000000; /* ??? */
+#else /* 386+ */
+  /* 32bit processors always write 32bits of base */
+#endif
+  write_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+  write_virtual_dword(i->seg, i->rm_addr+2, &base_32);
+
+#endif
+}
+
+  void
+BX_CPU_C::SIDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("SIDT_Ms: not supported on 8086!\n"));
+#else
+  Bit16u limit_16;
+  Bit32u base_32;
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    /* undefined opcode exception */
+    BX_PANIC(("SIDT: use of register is undefined opcode.\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  limit_16 = BX_CPU_THIS_PTR idtr.limit;
+  base_32  = BX_CPU_THIS_PTR idtr.base;
+
+#if BX_CPU_LEVEL == 2
+  base_32 |= 0xff000000;
+#else /* 386+ */
+  /* ??? regardless of operand size, all 32bits of base are stored */
+#endif
+
+  write_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+  write_virtual_dword(i->seg, i->rm_addr+2, &base_32);
+
+#endif
+}
+
+  void
+BX_CPU_C::LGDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LGDT_Ms: not supported on 8086!\n"));
+#else
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  invalidate_prefetch_q();
+
+  if (protected_mode() && (CPL!=0)) {
+    BX_PANIC(("LGDT: protected mode: CPL!=0\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    return;
+    }
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    BX_PANIC(("LGDT generating exception 6\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->os_32) {
+    Bit16u limit_16;
+    Bit32u base0_31;
+
+    read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+    read_virtual_dword(i->seg, i->rm_addr + 2, &base0_31);
+
+    BX_CPU_THIS_PTR gdtr.limit = limit_16;
+    BX_CPU_THIS_PTR gdtr.base = base0_31;
+    }
+  else
+#endif
+    {
+    Bit16u limit_16, base0_15;
+    Bit8u base16_23;
+
+    read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+    read_virtual_word(i->seg, i->rm_addr + 2, &base0_15);
+
+    read_virtual_byte(i->seg, i->rm_addr + 4, &base16_23);
+
+    /* ignore high 8 bits */
+
+    BX_CPU_THIS_PTR gdtr.limit = limit_16;
+    BX_CPU_THIS_PTR gdtr.base = (base16_23 << 16) | base0_15;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LIDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LIDT_Ms: not supported on 8086!\n"));
+#else
+  Bit16u limit_16;
+  Bit32u base_32;
+
+
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+  invalidate_prefetch_q();
+
+  if (protected_mode()) {
+    if (CPL != 0) {
+      BX_PANIC(("LIDT(): CPL(%u) != 0\n", (unsigned) CPL));
+      exception(BX_GP_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    /* undefined opcode exception */
+    BX_PANIC(("LIDT generating exception 6\n"));
+    UndefinedOpcode(i);
+    return;
+    }
+
+  read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+  read_virtual_dword(i->seg, i->rm_addr + 2, &base_32);
+
+  BX_CPU_THIS_PTR idtr.limit = limit_16;
+
+#if BX_CPU_LEVEL >= 3
+  if (i->os_32)
+    BX_CPU_THIS_PTR idtr.base = base_32;
+  else
+#endif
+    BX_CPU_THIS_PTR idtr.base = base_32 & 0x00ffffff; /* ignore upper 8 bits */
+
+#endif
+}
diff --git a/sid/component/bochs/cpu/protect_ctrl_pro.cc b/sid/component/bochs/cpu/protect_ctrl_pro.cc
new file mode 100644 (file)
index 0000000..8febdd5
--- /dev/null
@@ -0,0 +1,68 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::enter_protected_mode(void)
+{
+// BX_INFO(("processor switching into PROTECTED mode!!!\n"));
+// debug(BX_CPU_THIS_PTR prev_eip);
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+#if BX_DEBUGGER
+  if (bx_dbg.reset)
+    BX_INFO(("processor switching into PROTECTED mode!!!\n"));
+#endif
+
+if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl!=0 || BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl!=0 )
+  BX_PANIC(("enter_protected_mode: CS or SS rpl != 0\n"));
+}
+
+
+  void
+BX_CPU_C::enter_real_mode(void)
+{
+// ???
+// BX_INFO(("processor switching into REAL mode!!!\n"));
+// debug(BX_CPU_THIS_PTR prev_eip);
+  if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+#if BX_DEBUGGER
+  if (bx_dbg.reset)
+    BX_INFO(("processor switching into REAL mode!!!\n"));
+#endif
+
+if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl!=0 || BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl!=0 )
+  BX_PANIC(("enter_real_mode: CS or SS rpl != 0\n"));
+}
diff --git a/sid/component/bochs/cpu/resolve16.cc b/sid/component/bochs/cpu/resolve16.cc
new file mode 100644 (file)
index 0000000..e67c04e
--- /dev/null
@@ -0,0 +1,109 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::Resolve16Mod0Rm0(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BX + SI);
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm1(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BX + DI);
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm2(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BP + SI);
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm3(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BP + DI);
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm4(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) SI;
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm5(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) DI;
+}
+  void
+BX_CPU_C::Resolve16Mod0Rm7(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) BX;
+}
+
+  void
+BX_CPU_C::Resolve16Mod1or2Rm0(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BX + SI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm1(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BX + DI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm2(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BP + SI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm3(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BP + DI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm4(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (SI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm5(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (DI + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm6(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BP + (Bit16s) i->displ16u);
+}
+  void
+BX_CPU_C::Resolve16Mod1or2Rm7(BxInstruction_t *i)
+{
+  i->rm_addr = (Bit16u) (BX + (Bit16s) i->displ16u);
+}
diff --git a/sid/component/bochs/cpu/resolve32.cc b/sid/component/bochs/cpu/resolve32.cc
new file mode 100644 (file)
index 0000000..fa8c417
--- /dev/null
@@ -0,0 +1,282 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::Resolve32Mod0Rm0(BxInstruction_t *i)
+{
+  i->rm_addr = EAX;
+}
+  void
+BX_CPU_C::Resolve32Mod0Rm1(BxInstruction_t *i)
+{
+  i->rm_addr = ECX;
+}
+  void
+BX_CPU_C::Resolve32Mod0Rm2(BxInstruction_t *i)
+{
+  i->rm_addr = EDX;
+}
+  void
+BX_CPU_C::Resolve32Mod0Rm3(BxInstruction_t *i)
+{
+  i->rm_addr = EBX;
+}
+  void
+BX_CPU_C::Resolve32Mod0Rm6(BxInstruction_t *i)
+{
+  i->rm_addr = ESI;
+}
+  void
+BX_CPU_C::Resolve32Mod0Rm7(BxInstruction_t *i)
+{
+  i->rm_addr = EDI;
+}
+
+
+  void
+BX_CPU_C::Resolve32Mod1or2Rm0(BxInstruction_t *i)
+{
+  i->rm_addr = EAX + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm1(BxInstruction_t *i)
+{
+  i->rm_addr = ECX + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm2(BxInstruction_t *i)
+{
+  i->rm_addr = EDX + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm3(BxInstruction_t *i)
+{
+  i->rm_addr = EBX + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm5(BxInstruction_t *i)
+{
+  i->rm_addr = EBP + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm6(BxInstruction_t *i)
+{
+  i->rm_addr = ESI + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Rm7(BxInstruction_t *i)
+{
+  i->rm_addr = EDI + i->displ32u;
+}
+
+
+  void
+BX_CPU_C::Resolve32Mod0Base0(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EAX + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base1(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ECX + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base2(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EDX + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base3(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EBX + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base4(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ESP + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base5(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = i->displ32u + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base6(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ESI + scaled_index;
+}
+  void
+BX_CPU_C::Resolve32Mod0Base7(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EDI + scaled_index;
+}
+
+
+
+
+  void
+BX_CPU_C::Resolve32Mod1or2Base0(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EAX + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base1(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ECX + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base2(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EDX + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base3(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EBX + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base4(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ESP + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base5(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EBP + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base6(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = ESI + scaled_index + i->displ32u;
+}
+  void
+BX_CPU_C::Resolve32Mod1or2Base7(BxInstruction_t *i)
+{
+  Bit32u scaled_index;
+
+  if (i->index != 4)
+    scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+  else
+    scaled_index = 0;
+  i->rm_addr = EDI + scaled_index + i->displ32u;
+}
diff --git a/sid/component/bochs/cpu/segment_ctrl.cc b/sid/component/bochs/cpu/segment_ctrl.cc
new file mode 100644 (file)
index 0000000..c216694
--- /dev/null
@@ -0,0 +1,218 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+  void
+BX_CPU_C::LES_GvMp(BxInstruction_t *i)
+{
+  if (i->mod == 0xc0) {
+    // (BW) NT seems to use this when booting.
+    BX_INFO(("invalid use of LES, must use memory reference!\n"));
+    UndefinedOpcode(i);
+    }
+
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    Bit16u es;
+    Bit32u reg_32;
+
+    read_virtual_dword(i->seg, i->rm_addr, &reg_32);
+    read_virtual_word(i->seg, i->rm_addr + 4, &es);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+
+    BX_WRITE_32BIT_REG(i->nnn, reg_32);
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    { /* 16 bit mode */
+    Bit16u reg_16, es;
+
+    read_virtual_word(i->seg, i->rm_addr, &reg_16);
+    read_virtual_word(i->seg, i->rm_addr + 2, &es);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+
+    BX_WRITE_16BIT_REG(i->nnn, reg_16);
+    }
+}
+
+  void
+BX_CPU_C::LDS_GvMp(BxInstruction_t *i)
+{
+  if (i->mod == 0xc0) {
+    BX_PANIC(("invalid use of LDS, must use memory reference!\n"));
+    UndefinedOpcode(i);
+    }
+
+#if BX_CPU_LEVEL > 2
+  if (i->os_32) {
+    Bit16u ds;
+    Bit32u reg_32;
+
+    read_virtual_dword(i->seg, i->rm_addr, &reg_32);
+    read_virtual_word(i->seg, i->rm_addr + 4, &ds);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+
+    BX_WRITE_32BIT_REG(i->nnn, reg_32);
+    }
+  else
+#endif /* BX_CPU_LEVEL > 2 */
+    { /* 16 bit mode */
+    Bit16u reg_16, ds;
+
+    read_virtual_word(i->seg, i->rm_addr, &reg_16);
+    read_virtual_word(i->seg, i->rm_addr + 2, &ds);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+
+    BX_WRITE_16BIT_REG(i->nnn, reg_16);
+    }
+}
+
+  void
+BX_CPU_C::LFS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("lfs_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+  if (i->mod == 0xc0) {
+    BX_PANIC(("invalid use of LFS, must use memory reference!\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (i->os_32) {
+    Bit32u reg_32;
+    Bit16u fs;
+
+    read_virtual_dword(i->seg, i->rm_addr, &reg_32);
+    read_virtual_word(i->seg, i->rm_addr + 4, &fs);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+
+    BX_WRITE_32BIT_REG(i->nnn, reg_32);
+    }
+  else { /* 16 bit operand size */
+    Bit16u reg_16;
+    Bit16u fs;
+
+    read_virtual_word(i->seg, i->rm_addr, &reg_16);
+    read_virtual_word(i->seg, i->rm_addr + 2, &fs);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+
+    BX_WRITE_16BIT_REG(i->nnn, reg_16);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LGS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("lgs_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+  if (i->mod == 0xc0) {
+    BX_PANIC(("invalid use of LGS, must use memory reference!\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (i->os_32) {
+    Bit32u reg_32;
+    Bit16u gs;
+
+    read_virtual_dword(i->seg, i->rm_addr, &reg_32);
+    read_virtual_word(i->seg, i->rm_addr + 4, &gs);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+
+    BX_WRITE_32BIT_REG(i->nnn, reg_32);
+    }
+  else { /* 16 bit operand size */
+    Bit16u reg_16;
+    Bit16u gs;
+
+    read_virtual_word(i->seg, i->rm_addr, &reg_16);
+    read_virtual_word(i->seg, i->rm_addr + 2, &gs);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+
+    BX_WRITE_16BIT_REG(i->nnn, reg_16);
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LSS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("lss_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+  if (i->mod == 0xc0) {
+    BX_PANIC(("invalid use of LSS, must use memory reference!\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (i->os_32) {
+    Bit32u reg_32;
+    Bit16u ss_raw;
+
+    read_virtual_dword(i->seg, i->rm_addr, &reg_32);
+    read_virtual_word(i->seg, i->rm_addr + 4, &ss_raw);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss_raw);
+
+    BX_WRITE_32BIT_REG(i->nnn, reg_32);
+    }
+  else { /* 16 bit operand size */
+    Bit16u reg_16;
+    Bit16u ss_raw;
+
+    read_virtual_word(i->seg, i->rm_addr, &reg_16);
+    read_virtual_word(i->seg, i->rm_addr + 2, &ss_raw);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss_raw);
+
+    BX_WRITE_16BIT_REG(i->nnn, reg_16);
+    }
+#endif
+}
diff --git a/sid/component/bochs/cpu/segment_ctrl_pro.cc b/sid/component/bochs/cpu/segment_ctrl_pro.cc
new file mode 100644 (file)
index 0000000..654aa52
--- /dev/null
@@ -0,0 +1,578 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
+{
+#if BX_CPU_LEVEL >= 3
+  if (v8086_mode()) {
+    /* ??? don't need to set all these fields */
+    seg->selector.value = new_value;
+    seg->selector.rpl = 3;
+    seg->cache.valid = 1;
+    seg->cache.p = 1;
+    seg->cache.dpl = 3;
+    seg->cache.segment = 1; /* regular segment */
+    if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_CS])
+      seg->cache.u.segment.executable = 1; /* code segment */
+    else
+      seg->cache.u.segment.executable = 0; /* data segment */
+    seg->cache.u.segment.c_ed = 0; /* expand up */
+    seg->cache.u.segment.r_w = 1; /* writeable */
+    seg->cache.u.segment.a = 1; /* accessed */
+    seg->cache.u.segment.base = new_value << 4;
+    seg->cache.u.segment.limit        = 0xffff;
+    seg->cache.u.segment.limit_scaled = 0xffff;
+    seg->cache.u.segment.g     = 0; /* byte granular */
+    seg->cache.u.segment.d_b   = 0; /* default 16bit size */
+    seg->cache.u.segment.avl   = 0;
+
+    return;
+    }
+#endif
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_SS]) {
+      Bit16u index;
+      Bit8u ti;
+      Bit8u rpl;
+      bx_descriptor_t descriptor;
+      Bit32u dword1, dword2;
+
+      if ((new_value & 0xfffc) == 0) { /* null selector */
+        BX_PANIC(("load_seg_reg: SS: new_value == 0\n"));
+        exception(BX_GP_EXCEPTION, 0, 0);
+        return;
+        }
+
+      index = new_value >> 3;
+      ti = (new_value >> 2) & 0x01;
+      rpl = (new_value & 0x03);
+
+      /* examine AR byte of destination selector for legal values: */
+
+      if (ti == 0) { /* GDT */
+        if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+          BX_PANIC(("load_seg_reg: GDT: %s: index(%04x) > limit(%06x)\n",
+            BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8,     4, 0,
+          BX_READ, &dword1);
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+          BX_READ, &dword2);
+        }
+      else { /* LDT */
+        if (BX_CPU_THIS_PTR ldtr.cache.valid==0) { /* ??? */
+          BX_INFO(("load_seg_reg: LDT invalid\n"));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+          BX_INFO(("load_seg_reg ss: LDT: index > limit\n"));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8,     4, 0,
+          BX_READ, &dword1);
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+          BX_READ, &dword2);
+        }
+
+      /* selector's RPL must = CPL, else #GP(selector) */
+      if (rpl != CPL) {
+        BX_INFO(("load_seg_reg(): rpl != CPL\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        return;
+        }
+
+      parse_descriptor(dword1, dword2, &descriptor);
+
+      if (descriptor.valid==0) {
+        BX_INFO(("load_seg_reg(): valid bit cleared\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        return;
+        }
+
+      /* AR byte must indicate a writable data segment else #GP(selector) */
+      if ( (descriptor.segment==0) ||
+           descriptor.u.segment.executable ||
+           descriptor.u.segment.r_w==0 ) {
+        BX_INFO(("load_seg_reg(): not writable data segment\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        }
+
+      /* DPL in the AR byte must equal CPL else #GP(selector) */
+      if (descriptor.dpl != CPL) {
+        BX_INFO(("load_seg_reg(): dpl != CPL\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        }
+
+      /* segment must be marked PRESENT else #SS(selector) */
+      if (descriptor.p == 0) {
+        BX_INFO(("load_seg_reg(): not present\n"));
+        exception(BX_SS_EXCEPTION, new_value & 0xfffc, 0);
+        }
+
+      /* load SS with selector, load SS cache with descriptor */
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value        = new_value;
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index        = index;
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti           = ti;
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl          = rpl;
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = descriptor;
+      BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid             = 1;
+
+      /* now set accessed bit in descriptor */
+      dword2 |= 0x0100;
+      if (ti == 0) { /* GDT */
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+          BX_WRITE, &dword2);
+        }
+      else { /* LDT */
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+          BX_WRITE, &dword2);
+        }
+
+      return;
+      }
+    else if ( (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_DS]) ||
+              (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_ES])
+#if BX_CPU_LEVEL >= 3
+           || (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_FS]) ||
+              (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_GS])
+#endif
+            ) {
+      Bit16u index;
+      Bit8u ti;
+      Bit8u rpl;
+      bx_descriptor_t descriptor;
+      Bit32u dword1, dword2;
+
+
+      if ((new_value & 0xfffc) == 0) { /* null selector */
+        seg->selector.index = 0;
+        seg->selector.ti = 0;
+        seg->selector.rpl = 0;
+        seg->selector.value = 0;
+        seg->cache.valid = 0; /* invalidate null selector */
+        return;
+        }
+
+      index = new_value >> 3;
+      ti = (new_value >> 2) & 0x01;
+      rpl = (new_value & 0x03);
+
+      /* selector index must be within descriptor limits, else #GP(selector) */
+
+      if (ti == 0) { /* GDT */
+        if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+          BX_INFO(("load_seg_reg: GDT: %s: index(%04x) > limit(%06x)\n",
+            BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8,     4, 0,
+          BX_READ, &dword1);
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+          BX_READ, &dword2);
+        }
+      else { /* LDT */
+        if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
+          BX_INFO(("load_seg_reg: LDT invalid\n"));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+          BX_INFO(("load_seg_reg ds,es: LDT: index > limit\n"));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8,     4, 0,
+          BX_READ, &dword1);
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+          BX_READ, &dword2);
+        }
+
+      parse_descriptor(dword1, dword2, &descriptor);
+
+      if (descriptor.valid==0) {
+        BX_INFO(("load_seg_reg(): valid bit cleared\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        return;
+        }
+
+      /* AR byte must indicate data or readable code segment else #GP(selector) */
+      if ( descriptor.segment==0 ||
+           (descriptor.u.segment.executable==1 &&
+            descriptor.u.segment.r_w==0) ) {
+        BX_INFO(("load_seg_reg(): not data or readable code\n"));
+        exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+        return;
+        }
+
+      /* If data or non-conforming code, then both the RPL and the CPL
+       * must be less than or equal to DPL in AR byte else #GP(selector) */
+      if ( descriptor.u.segment.executable==0 ||
+           descriptor.u.segment.c_ed==0 ) {
+        if ((rpl > descriptor.dpl) || (CPL > descriptor.dpl)) {
+          BX_INFO(("load_seg_reg: RPL & CPL must be <= DPL\n"));
+          exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+          return;
+          }
+        }
+
+      /* segment must be marked PRESENT else #NP(selector) */
+      if (descriptor.p == 0) {
+        BX_INFO(("load_seg_reg: segment not present\n"));
+        exception(BX_NP_EXCEPTION, new_value & 0xfffc, 0);
+        return;
+        }
+
+      /* load segment register with selector */
+      /* load segment register-cache with descriptor */
+      seg->selector.value        = new_value;
+      seg->selector.index        = index;
+      seg->selector.ti           = ti;
+      seg->selector.rpl          = rpl;
+      seg->cache = descriptor;
+      seg->cache.valid             = 1;
+
+      /* now set accessed bit in descriptor */
+      dword2 |= 0x0100;
+      if (ti == 0) { /* GDT */
+        access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+          BX_WRITE, &dword2);
+        }
+      else { /* LDT */
+        access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+          BX_WRITE, &dword2);
+        }
+      return;
+      }
+    else {
+      BX_PANIC(("load_seg_reg(): invalid segment register passed!\n"));
+      return;
+      }
+    }
+
+  /* real mode */
+  /* seg->limit = ; ??? different behaviours depening on seg reg. */
+  /* something about honoring previous values */
+
+  /* ??? */
+  if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_CS]) {
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = new_value;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* regular segment */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* code segment */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* expand up */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = new_value << 4;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit        = 0xffff;
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffff;
+#if BX_CPU_LEVEL >= 3
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g     = 0; /* byte granular */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b   = 0; /* default 16bit size */
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl   = 0;
+#endif
+    }
+  else { /* SS, DS, ES, FS, GS */
+    seg->selector.value = new_value;
+    seg->cache.valid = 1;
+    seg->cache.p = 1; // set this???
+    seg->cache.u.segment.base = new_value << 4;
+    seg->cache.segment = 1; /* regular segment */
+    seg->cache.u.segment.a = 1; /* accessed */
+    /* set G, D_B, AVL bits here ??? */
+    }
+#else /* 8086 */
+
+  seg->selector.value = new_value;
+  seg->cache.u.segment.base = new_value << 4;
+#endif
+}
+
+
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::parse_selector(Bit16u raw_selector, bx_selector_t *selector)
+{
+  selector->value  = raw_selector;
+  selector->index  = raw_selector >> 3;
+  selector->ti     = (raw_selector >> 2) & 0x01;
+  selector->rpl    = raw_selector & 0x03;
+}
+#endif
+
+  void
+BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
+{
+  Bit8u AR_byte;
+
+  AR_byte        = dword2 >> 8;
+  temp->p        = (AR_byte >> 7) & 0x01;
+  temp->dpl      = (AR_byte >> 5) & 0x03;
+  temp->segment  = (AR_byte >> 4) & 0x01;
+  temp->type     = (AR_byte & 0x0f);
+  temp->valid    = 0; /* start out invalid */
+
+
+  if (temp->segment) { /* data/code segment descriptors */
+    temp->u.segment.executable = (AR_byte >> 3) & 0x01;
+    temp->u.segment.c_ed       = (AR_byte >> 2) & 0x01;
+    temp->u.segment.r_w        = (AR_byte >> 1) & 0x01;
+    temp->u.segment.a          = (AR_byte >> 0) & 0x01;
+
+    temp->u.segment.limit      = (dword1 & 0xffff);
+    temp->u.segment.base       = (dword1 >> 16) |
+                                 ((dword2 & 0xFF) << 16);
+
+#if BX_CPU_LEVEL >= 3
+    temp->u.segment.limit        |= (dword2 & 0x000F0000);
+    temp->u.segment.g            =  (dword2 & 0x00800000) > 0;
+    temp->u.segment.d_b          =  (dword2 & 0x00400000) > 0;
+    temp->u.segment.avl          =  (dword2 & 0x00100000) > 0;
+    temp->u.segment.base         |= (dword2 & 0xFF000000);
+    if (temp->u.segment.g) {
+      if ( (temp->u.segment.executable==0) && (temp->u.segment.c_ed) )
+        temp->u.segment.limit_scaled = (temp->u.segment.limit << 12);
+      else
+        temp->u.segment.limit_scaled = (temp->u.segment.limit << 12) | 0x0fff;
+      }
+    else
+#endif
+      temp->u.segment.limit_scaled = temp->u.segment.limit;
+
+    temp->valid    = 1;
+    }
+  else { // system & gate segment descriptors
+    switch ( temp->type ) {
+      case  0: // reserved
+      case  8: // reserved
+      case 10: // reserved
+      case 13: // reserved
+        temp->valid    = 0;
+        break;
+      case 1: // 286 TSS (available)
+      case 3: // 286 TSS (busy)
+        temp->u.tss286.base  = (dword1 >> 16) |
+                               ((dword2 & 0xff) << 16);
+        temp->u.tss286.limit = (dword1 & 0xffff);
+        temp->valid    = 1;
+        break;
+      case 2: // LDT descriptor
+        temp->u.ldt.base = (dword1 >> 16) |
+                           ((dword2 & 0xFF) << 16);
+#if BX_CPU_LEVEL >= 3
+        temp->u.ldt.base |= (dword2 & 0xff000000);
+#endif
+        temp->u.ldt.limit = (dword1 & 0xffff);
+        temp->valid    = 1;
+        break;
+      case 4: // 286 call gate
+      case 6: // 286 interrupt gate
+      case 7: // 286 trap gate
+        /* word count only used for call gate */
+        temp->u.gate286.word_count = dword2 & 0x1f;
+        temp->u.gate286.dest_selector = dword1 >> 16;;
+        temp->u.gate286.dest_offset   = dword1 & 0xffff;
+        temp->valid = 1;
+        break;
+      case 5: // 286/386 task gate
+        temp->u.taskgate.tss_selector = dword1 >> 16;;
+        temp->valid = 1;
+        break;
+
+#if BX_CPU_LEVEL >= 3
+      case 9:  // 386 TSS (available)
+      case 11: // 386 TSS (busy)
+        temp->u.tss386.base  = (dword1 >> 16) |
+                               ((dword2 & 0xff) << 16) |
+                               (dword2 & 0xff000000);
+        temp->u.tss386.limit = (dword1 & 0x0000ffff) |
+                               (dword2 & 0x000f0000);
+        temp->u.tss386.g     = (dword2 & 0x00800000) > 0;
+        temp->u.tss386.avl   = (dword2 & 0x00100000) > 0;
+        if (temp->u.tss386.g)
+          temp->u.tss386.limit_scaled = (temp->u.tss386.limit << 12) | 0x0fff;
+        else
+          temp->u.tss386.limit_scaled = temp->u.tss386.limit;
+        temp->valid = 1;
+        break;
+
+      case 12: // 386 call gate
+      case 14: // 386 interrupt gate
+      case 15: // 386 trap gate
+        // word count only used for call gate
+        temp->u.gate386.dword_count   = dword2 & 0x1f;
+        temp->u.gate386.dest_selector = dword1 >> 16;;
+        temp->u.gate386.dest_offset   = (dword2 & 0xffff0000) |
+                                        (dword1 & 0x0000ffff);
+        temp->valid = 1;
+        break;
+#endif
+      default: BX_PANIC(("parse_descriptor(): case %d unfinished\n",
+                 (unsigned) temp->type));
+        temp->valid    = 0;
+      }
+    }
+}
+
+  void
+BX_CPU_C::load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor)
+{
+  /* check for null selector, if so invalidate LDTR */
+  if ( (selector->value & 0xfffc)==0 ) {
+    BX_CPU_THIS_PTR ldtr.selector = *selector;
+    BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+    return;
+    }
+
+  if (!descriptor)
+    BX_PANIC(("load_ldtr(): descriptor == NULL!\n"));
+
+  BX_CPU_THIS_PTR ldtr.cache = *descriptor; /* whole structure copy */
+  BX_CPU_THIS_PTR ldtr.selector = *selector;
+
+  if (BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit < 7) {
+    BX_PANIC(("load_ldtr(): ldtr.limit < 7\n"));
+    }
+
+  BX_CPU_THIS_PTR ldtr.cache.valid = 1;
+}
+
+  void
+BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor,
+           Bit8u cpl)
+{
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector     = *selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache        = *descriptor;
+
+  /* caller may request different CPL then in selector */
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpl;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; /* ??? */
+  // (BW) Added cpl to the selector value.
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value =
+    (0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl;
+}
+
+  void
+BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl)
+{
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector = *selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl;
+
+  if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value & 0xfffc) == 0 )
+    BX_PANIC(("load_ss(): null selector passed\n"));
+
+  if ( !BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid ) {
+    BX_PANIC(("load_ss(): invalid selector/descriptor passed.\n"));
+    }
+}
+
+
+
+#if BX_CPU_LEVEL >= 2
+  void
+BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
+                        Bit32u *dword1, Bit32u *dword2, Bit8u exception_no)
+{
+  if (selector->ti == 0) { /* GDT */
+    if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+BX_INFO(("-----------------------------------\n"));
+BX_INFO(("selector->index*8 + 7 = %u\n", (unsigned) selector->index*8 + 7));
+BX_INFO(("gdtr.limit = %u\n", (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+      BX_INFO(("fetch_raw_descriptor: GDT: index > limit\n"));
+debug(BX_CPU_THIS_PTR prev_eip);
+BX_INFO(("-----------------------------------\n"));
+      exception(exception_no, selector->value & 0xfffc, 0);
+      return;
+      }
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8,     4, 0,
+      BX_READ, dword1);
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
+      BX_READ, dword2);
+    }
+  else { /* LDT */
+    if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
+      BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0\n"));
+      }
+    if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+      BX_PANIC(("fetch_raw_descriptor: LDT: index > limit\n"));
+      exception(exception_no, selector->value & 0xfffc, 0);
+      return;
+      }
+    access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8,     4, 0,
+      BX_READ, dword1);
+    access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
+      BX_READ, dword2);
+    }
+}
+#endif
+
+
+
+
+
+  Boolean
+BX_CPU_C::fetch_raw_descriptor2(bx_selector_t *selector,
+                        Bit32u *dword1, Bit32u *dword2)
+{
+  if (selector->ti == 0) { /* GDT */
+    if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit)
+      return(0);
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8,     4, 0,
+      BX_READ, dword1);
+    access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
+      BX_READ, dword2);
+    return(1);
+    }
+  else { /* LDT */
+    if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)
+      return(0);
+    access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8,     4, 0,
+      BX_READ, dword1);
+    access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
+      BX_READ, dword2);
+    return(1);
+    }
+}
diff --git a/sid/component/bochs/cpu/shift16.cc b/sid/component/bochs/cpu/shift16.cc
new file mode 100644 (file)
index 0000000..f39d32a
--- /dev/null
@@ -0,0 +1,520 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+  void
+BX_CPU_C::SHLD_EwGw(BxInstruction_t *i)
+{
+  Bit16u op1_16, op2_16, result_16;
+  Bit32u temp_32, result_32;
+  unsigned count;
+
+  /* op1:op2 << count.  result stored in op1 */
+  if (i->b1 == 0x1a4)
+    count = i->Ib;
+  else // 0x1a5
+    count = CL;
+
+  count &= 0x1f; // use only 5 LSB's
+
+
+    if (!count) return; /* NOP */
+    // count is 1..31
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    temp_32 = (op1_16 << 16) | (op2_16); // double formed by op1:op2
+    result_32 = temp_32 << count;
+    if (count > 16) {
+      // hack to act like x86 SHLD when count > 16
+      // actually shifting op1:op2:op2 << count
+      result_32 |= (op2_16 << (count - 16));
+      }
+    result_16 = result_32 >> 16;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    /* set eflags:
+     * SHLD count affects the following flags: S,Z,P,C,O
+     */
+    set_CF( (temp_32 >> (32 - count)) & 0x01 );
+    if (count == 1)
+      set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+    set_ZF(result_16 == 0);
+    set_SF(result_16 >> 15);
+    set_PF_base((Bit8u) result_16);
+}
+
+
+  void
+BX_CPU_C::SHRD_EwGw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("shrd_evgvib: not supported on < 386\n"));
+#else
+  Bit16u op1_16, op2_16, result_16;
+  Bit32u temp_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0x1ac)
+    count = i->Ib;
+  else // 0x1ad
+    count = CL;
+  count &= 0x1F; /* use only 5 LSB's */
+
+  if (!count) return; /* NOP */
+
+    // count is 1..31
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+    op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+    temp_32 = (op2_16 << 16) | op1_16; // double formed by op2:op1
+    result_32 = temp_32 >> count;
+    if (count > 16) {
+      // hack to act like x86 SHLD when count > 16
+      // actually shifting op2:op2:op1 >> count
+      result_32 |= (op2_16 << (32 - count));
+      }
+    result_16 = result_32;
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    /* set eflags:
+     * SHRD count affects the following flags: S,Z,P,C,O
+     */
+
+    set_CF((temp_32 >> (count - 1)) & 0x01);
+    set_ZF(result_16 == 0);
+    set_SF(result_16 >> 15);
+    /* for shift of 1, OF set if sign change occurred. */
+    if (count == 1)
+      set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+    set_PF_base((Bit8u) result_16);
+#endif /* BX_CPU_LEVEL >= 3 */
+}
+
+
+
+  void
+BX_CPU_C::ROL_Ew(BxInstruction_t *i)
+{
+
+    Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+    count &= 0x0f; // only use bottom 4 bits
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    if (count) {
+      result_16 = (op1_16 << count) | (op1_16 >> (16 - count));
+
+      /* now write result back to destination */
+      if (i->mod == 0xc0) {
+        BX_WRITE_16BIT_REG(i->rm, result_16);
+        }
+      else {
+        write_RMW_virtual_word(result_16);
+        }
+
+      /* set eflags:
+       * ROL count affects the following flags: C
+       */
+
+      set_CF(result_16 & 0x01);
+      if (count == 1)
+        set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+      }
+}
+
+
+
+
+  void
+BX_CPU_C::ROR_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16, result_16, result_b15;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+    count &= 0x0f;  // use only 4 LSB's
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    if (count) {
+      result_16 = (op1_16 >> count) | (op1_16 << (16 - count));
+
+      /* now write result back to destination */
+      if (i->mod == 0xc0) {
+        BX_WRITE_16BIT_REG(i->rm, result_16);
+        }
+      else {
+        write_RMW_virtual_word(result_16);
+        }
+
+      /* set eflags:
+       * ROR count affects the following flags: C
+       */
+      result_b15 = result_16 & 0x8000;
+
+      set_CF(result_b15 != 0);
+      if (count == 1)
+        set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+      }
+}
+
+
+
+  void
+BX_CPU_C::RCL_Ew(BxInstruction_t *i)
+{
+  Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+  count &= 0x1F;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    count %= 17;
+
+    if (!count) return;
+
+    if (count==1) {
+      result_16 = (op1_16 << 1) | get_CF();
+      }
+    else if (count==16) {
+      result_16 = (get_CF() << 15) |
+                  (op1_16 >> 1);
+      }
+    else { // 2..15
+      result_16 = (op1_16 << count) |
+                  (get_CF() << (count - 1)) |
+                  (op1_16 >> (17 - count));
+      }
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    /* set eflags:
+     * RCL count affects the following flags: C
+     */
+
+    if (count == 1)
+      set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+    set_CF((op1_16 >> (16 - count)) & 0x01);
+}
+
+
+
+  void
+BX_CPU_C::RCR_Ew(BxInstruction_t *i)
+{
+  Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+  count = count & 0x1F;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    count %= 17;
+    if (count) {
+      result_16 = (op1_16 >> count) |
+               (get_CF() << (16 - count)) |
+               (op1_16 << (17 - count));
+
+      /* now write result back to destination */
+      if (i->mod == 0xc0) {
+       BX_WRITE_16BIT_REG(i->rm, result_16);
+       }
+      else {
+       write_RMW_virtual_word(result_16);
+        }
+
+      /* set eflags:
+       * RCR count affects the following flags: C
+       */
+
+      set_CF((op1_16 >> (count - 1)) & 0x01);
+      if (count == 1)
+        set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+      }
+}
+
+
+
+
+  void
+BX_CPU_C::SHL_Ew(BxInstruction_t *i)
+{
+  Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+  count &= 0x1F; /* use only 5 LSB's */
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    if (!count) return;
+
+    result_16 = (op1_16 << count);
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHL16);
+}
+
+
+
+
+  void
+BX_CPU_C::SHR_Ew(BxInstruction_t *i)
+{
+  Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+  count &= 0x1F; /* use only 5 LSB's */
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    if (!count) return;
+
+    result_16 = (op1_16 >> count);
+
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHR16);
+}
+
+
+
+  void
+BX_CPU_C::SAR_Ew(BxInstruction_t *i)
+{
+  Bit16u op1_16, result_16;
+  unsigned count;
+
+  if ( i->b1 == 0xc1 )
+    count = i->Ib;
+  else if ( i->b1 == 0xd1 )
+    count = 1;
+  else // 0xd3
+    count = CL;
+
+  count &= 0x1F;  /* use only 5 LSB's */
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    if (!count) return;
+
+    if (count < 16) {
+      if (op1_16 & 0x8000) {
+       result_16 = (op1_16 >> count) | (0xffff << (16 - count));
+       }
+      else {
+       result_16 = (op1_16 >> count);
+       }
+      }
+    else {
+      if (op1_16 & 0x8000) {
+       result_16 = 0xffff;
+       }
+      else {
+       result_16 = 0;
+       }
+      }
+
+
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_16BIT_REG(i->rm, result_16);
+      }
+    else {
+      write_RMW_virtual_word(result_16);
+      }
+
+    /* set eflags:
+     * SAR count affects the following flags: S,Z,P,C
+     */
+    if (count < 16) {
+      set_CF((op1_16 >> (count - 1)) & 0x01);
+      }
+    else {
+      if (op1_16 & 0x8000) {
+       set_CF(1);
+       }
+      else {
+       set_CF(0);
+       }
+      }
+
+    set_ZF(result_16 == 0);
+    set_SF(result_16 >> 15);
+    if (count == 1)
+      set_OF(0);
+    set_PF_base((Bit8u) result_16);
+}
diff --git a/sid/component/bochs/cpu/shift32.cc b/sid/component/bochs/cpu/shift32.cc
new file mode 100644 (file)
index 0000000..12cfc18
--- /dev/null
@@ -0,0 +1,461 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::SHLD_EdGd(BxInstruction_t *i)
+{
+  Bit32u op1_32, op2_32, result_32;
+  unsigned count;
+
+  /* op1:op2 << count.  result stored in op1 */
+
+  if (i->b1 == 0x1a4)
+    count = i->Ib & 0x1f;
+  else // 0x1a5
+    count = CL & 0x1f;
+
+    if (!count) return; /* NOP */
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    result_32 = (op1_32 << count) | (op2_32 >> (32 - count));
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    /* set eflags:
+     * SHLD count affects the following flags: S,Z,P,C,O
+     */
+    set_CF((op1_32 >> (32 - count)) & 0x01);
+    if (count == 1)
+      set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+    set_ZF(result_32 == 0);
+    set_PF_base(result_32);
+    set_SF(result_32 >> 31);
+}
+
+
+  void
+BX_CPU_C::SHRD_EdGd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  BX_PANIC(("shrd_evgvib: not supported on < 386\n"));
+#else
+  Bit32u op1_32, op2_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0x1ac)
+    count = i->Ib & 0x1f;
+  else // 0x1ad
+    count = CL & 0x1f;
+
+  if (!count) return; /* NOP */
+
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+    op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+    result_32 = (op2_32 << (32 - count)) | (op1_32 >> count);
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    /* set eflags:
+     * SHRD count affects the following flags: S,Z,P,C,O
+     */
+
+    set_CF((op1_32 >> (count - 1)) & 0x01);
+    set_ZF(result_32 == 0);
+    set_SF(result_32 >> 31);
+    /* for shift of 1, OF set if sign change occurred. */
+    if (count == 1)
+      set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+    set_PF_base(result_32);
+#endif /* BX_CPU_LEVEL >= 3 */
+}
+
+
+
+  void
+BX_CPU_C::ROL_Ed(BxInstruction_t *i)
+{
+
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (count) {
+      result_32 = (op1_32 << count) | (op1_32 >> (32 - count));
+
+      /* now write result back to destination */
+      if (i->mod == 0xc0) {
+        BX_WRITE_32BIT_REG(i->rm, result_32);
+        }
+      else {
+        write_RMW_virtual_dword(result_32);
+        }
+
+      /* set eflags:
+       * ROL count affects the following flags: C
+       */
+
+      set_CF(result_32 & 0x01);
+      if (count == 1)
+        set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+      }
+}
+
+
+
+
+  void
+BX_CPU_C::ROR_Ed(BxInstruction_t *i)
+{
+    Bit32u op1_32, result_32, result_b31;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (count) {
+      result_32 = (op1_32 >> count) | (op1_32 << (32 - count));
+
+      /* now write result back to destination */
+      if (i->mod == 0xc0) {
+        BX_WRITE_32BIT_REG(i->rm, result_32);
+        }
+      else {
+        write_RMW_virtual_dword(result_32);
+        }
+
+      /* set eflags:
+       * ROR count affects the following flags: C
+       */
+      result_b31 = result_32 & 0x80000000;
+
+      set_CF(result_b31 != 0);
+      if (count == 1)
+        set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+      }
+}
+
+
+
+  void
+BX_CPU_C::RCL_Ed(BxInstruction_t *i)
+{
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (!count) return;
+
+    if (count==1) {
+      result_32 = (op1_32 << 1) | get_CF();
+      }
+    else {
+      result_32 = (op1_32 << count) |
+                (get_CF() << (count - 1)) |
+                (op1_32 >> (33 - count));
+      }
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    /* set eflags:
+     * RCL count affects the following flags: C
+     */
+    if (count == 1)
+      set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+    set_CF((op1_32 >> (32 - count)) & 0x01);
+}
+
+
+
+  void
+BX_CPU_C::RCR_Ed(BxInstruction_t *i)
+{
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (!count) return;
+
+    if (count==1) {
+      result_32 = (op1_32 >> 1) | (get_CF() << 31);
+      }
+    else {
+      result_32 = (op1_32 >> count) |
+                (get_CF() << (32 - count)) |
+                (op1_32 << (33 - count));
+      }
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    /* set eflags:
+     * RCR count affects the following flags: C
+     */
+
+    set_CF((op1_32 >> (count - 1)) & 0x01);
+    if (count == 1)
+      set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+}
+
+
+
+
+  void
+BX_CPU_C::SHL_Ed(BxInstruction_t *i)
+{
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (!count) return;
+
+    result_32 = (op1_32 << count);
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
+}
+
+
+
+
+  void
+BX_CPU_C::SHR_Ed(BxInstruction_t *i)
+{
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (!count) return;
+
+    result_32 = (op1_32 >> count);
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHR32);
+}
+
+
+
+  void
+BX_CPU_C::SAR_Ed(BxInstruction_t *i)
+{
+  Bit32u op1_32, result_32;
+  unsigned count;
+
+  if (i->b1 == 0xc1)
+    count = i->Ib & 0x1f;
+  else if (i->b1 == 0xd1)
+    count = 1;
+  else // (i->b1 == 0xd3)
+    count = CL & 0x1f;
+
+    /* op1 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    if (!count) return;
+
+    /* count < 32, since only lower 5 bits used */
+    if (op1_32 & 0x80000000) {
+      result_32 = (op1_32 >> count) | (0xffffffff << (32 - count));
+      }
+    else {
+      result_32 = (op1_32 >> count);
+      }
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_32BIT_REG(i->rm, result_32);
+      }
+    else {
+      write_RMW_virtual_dword(result_32);
+      }
+
+    /* set eflags:
+     * SAR count affects the following flags: S,Z,P,C
+     */
+
+    set_CF((op1_32 >> (count - 1)) & 0x01);
+    set_ZF(result_32 == 0);
+    set_SF(result_32 >> 31);
+    if (count == 1)
+      set_OF(0);
+    set_PF_base(result_32);
+}
diff --git a/sid/component/bochs/cpu/shift8.cc b/sid/component/bochs/cpu/shift8.cc
new file mode 100644 (file)
index 0000000..638070e
--- /dev/null
@@ -0,0 +1,388 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::ROL_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count &= 0x07; // use only lowest 3 bits
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (count) {
+    result_8 = (op1_8 << count) | (op1_8 >> (8 - count));
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_8BIT_REG(i->rm, result_8);
+      }
+    else {
+      write_RMW_virtual_byte(result_8);
+      }
+
+    /* set eflags:
+     * ROL count affects the following flags: C
+     */
+
+    set_CF(result_8 & 0x01);
+    if (count == 1)
+      set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+    }
+}
+
+
+
+
+  void
+BX_CPU_C::ROR_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  Bit8u result_b7;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+
+  count &= 0x07; /* use only bottom 3 bits */
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (count) {
+    result_8 = (op1_8 >> count) | (op1_8 << (8 - count));
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_8BIT_REG(i->rm, result_8);
+      }
+    else {
+      write_RMW_virtual_byte(result_8);
+      }
+
+    /* set eflags:
+     * ROR count affects the following flags: C
+     */
+    result_b7 = result_8 & 0x80;
+
+    set_CF(result_b7 != 0);
+    if (count == 1)
+      set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+    }
+}
+
+
+
+  void
+BX_CPU_C::RCL_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count = (count & 0x1F) % 9;
+
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (count) {
+    result_8 = (op1_8 << count) |
+             (get_CF() << (count - 1)) |
+             (op1_8 >> (9 - count));
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_8BIT_REG(i->rm, result_8);
+      }
+    else {
+      write_RMW_virtual_byte(result_8);
+      }
+
+    /* set eflags:
+     * RCL count affects the following flags: C
+     */
+    if (count == 1)
+      set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+    set_CF((op1_8 >> (8 - count)) & 0x01);
+    }
+}
+
+
+
+  void
+BX_CPU_C::RCR_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count = ( count & 0x1F ) % 9;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (count) {
+    result_8 = (op1_8 >> count) |
+             (get_CF() << (8 - count)) |
+             (op1_8 << (9 - count));
+
+    /* now write result back to destination */
+    if (i->mod == 0xc0) {
+      BX_WRITE_8BIT_REG(i->rm, result_8);
+      }
+    else {
+      write_RMW_virtual_byte(result_8);
+      }
+
+    /* set eflags:
+     * RCR count affects the following flags: C
+     */
+
+    set_CF((op1_8 >> (count - 1)) & 0x01);
+    if (count == 1)
+      set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+    }
+}
+
+
+
+
+  void
+BX_CPU_C::SHL_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count &= 0x1F;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (!count) return;
+
+  result_8 = (op1_8 << count);
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_RMW_virtual_byte(result_8);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHL8);
+}
+
+
+
+  void
+BX_CPU_C::SHR_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count &= 0x1F;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (!count) return;
+
+  result_8 = (op1_8 >> count);
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_RMW_virtual_byte(result_8);
+    }
+
+  SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHR8);
+}
+
+
+
+
+  void
+BX_CPU_C::SAR_Eb(BxInstruction_t *i)
+{
+  Bit8u op1_8, result_8;
+  unsigned count;
+
+  if (i->b1 == 0xc0)
+    count = i->Ib;
+  else if (i->b1 == 0xd0)
+    count = 1;
+  else // 0xd2
+    count = CL;
+
+  count &= 0x1F;
+
+  /* op1 is a register or memory reference */
+  if (i->mod == 0xc0) {
+    op1_8 = BX_READ_8BIT_REG(i->rm);
+    }
+  else {
+    /* pointer, segment address pair */
+    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+    }
+
+  if (!count) return;
+
+  if (count < 8) {
+    if (op1_8 & 0x80) {
+      result_8 = (op1_8 >> count) | (0xff << (8 - count));
+      }
+    else {
+      result_8 = (op1_8 >> count);
+      }
+    }
+  else {
+    if (op1_8 & 0x80) {
+      result_8 = 0xff;
+      }
+    else {
+      result_8 = 0;
+      }
+    }
+
+  /* now write result back to destination */
+  if (i->mod == 0xc0) {
+    BX_WRITE_8BIT_REG(i->rm, result_8);
+    }
+  else {
+    write_RMW_virtual_byte(result_8);
+    }
+
+  /* set eflags:
+   * SAR count affects the following flags: S,Z,P,C
+   */
+
+  if (count < 8) {
+    set_CF((op1_8 >> (count - 1)) & 0x01);
+    }
+  else {
+    if (op1_8 & 0x80) {
+      set_CF(1);
+      }
+    else {
+      set_CF(0);
+      }
+    }
+
+  set_ZF(result_8 == 0);
+  set_SF(result_8 >> 7);
+  if (count == 1)
+    set_OF(0);
+  set_PF_base(result_8);
+}
diff --git a/sid/component/bochs/cpu/soft_int-sid.cc b/sid/component/bochs/cpu/soft_int-sid.cc
new file mode 100644 (file)
index 0000000..89a3f0a
--- /dev/null
@@ -0,0 +1,166 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+#if 0
+  void
+BX_CPU_C::BOUND_GvMa(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("BOUND_GvMa: not supported on 8086!\n"));
+#else
+
+  if (i->mod == 0xc0) {
+    /* undefined opcode exception */
+    BX_PANIC(("bound: op2 must be mem ref\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (i->os_32) {
+    Bit32s bound_min, bound_max;
+    Bit32s op1_32;
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &bound_min);
+    read_virtual_dword(i->seg, i->rm_addr+4, (Bit32u *) &bound_max);
+
+    /* ??? */
+    if ( (op1_32 < bound_min) || (op1_32 > bound_max) ) {
+      BX_INFO(("BOUND: fails bounds test\n"));
+      exception(5, 0, 0);
+      }
+    }
+  else {
+    Bit16s bound_min, bound_max;
+    Bit16s op1_16;
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &bound_min);
+    read_virtual_word(i->seg, i->rm_addr+2, (Bit16u *) &bound_max);
+
+    /* ??? */
+    if ( (op1_16 < bound_min) || (op1_16 > bound_max) ) {
+      BX_INFO(("BOUND: fails bounds test\n"));
+      exception(5, 0, 0);
+      }
+    }
+
+#endif
+}
+
+  void
+BX_CPU_C::INT1(BxInstruction_t *i)
+{
+  // This is an undocumented instrucion (opcode 0xf1)
+  // which is useful for an ICE system.
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  interrupt(1, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+#endif
+
+  void
+sid_cpu_c::INT3(BxInstruction_t *i)
+{
+  // INT 3 is not IOPL sensitive
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+//BX_PANIC(("INT3: bailing\n"));
+  interrupt(3, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+
+
+  void
+sid_cpu_c::INT_Ib(BxInstruction_t *i)
+{
+  Bit8u imm8;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  imm8 = i->Ib;
+
+  if (v8086_mode() && (IOPL<3)) {
+    //BX_INFO(("int_ib: v8086: IOPL<3\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+#ifdef SHOW_EXIT_STATUS
+if ( (imm8 == 0x21) && (AH == 0x4c) ) {
+  BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x\n", (unsigned) AL, (unsigned) BX));
+  }
+#endif
+
+  interrupt(imm8, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+#if 0
+
+  void
+BX_CPU_C::INTO(BxInstruction_t *i)
+{
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  /* ??? is this IOPL sensitive ? */
+  if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported\n"));
+
+  if (get_OF()) {
+    interrupt(4, 1, 0, 0);
+    BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                        BX_CPU_THIS_PTR eip);
+    }
+}
+#endif
diff --git a/sid/component/bochs/cpu/soft_int.cc b/sid/component/bochs/cpu/soft_int.cc
new file mode 100644 (file)
index 0000000..02e5ee2
--- /dev/null
@@ -0,0 +1,164 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+  void
+BX_CPU_C::BOUND_GvMa(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("BOUND_GvMa: not supported on 8086!\n"));
+#else
+
+  if (i->mod == 0xc0) {
+    /* undefined opcode exception */
+    BX_PANIC(("bound: op2 must be mem ref\n"));
+    UndefinedOpcode(i);
+    }
+
+  if (i->os_32) {
+    Bit32s bound_min, bound_max;
+    Bit32s op1_32;
+
+    op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+    read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &bound_min);
+    read_virtual_dword(i->seg, i->rm_addr+4, (Bit32u *) &bound_max);
+
+    /* ??? */
+    if ( (op1_32 < bound_min) || (op1_32 > bound_max) ) {
+      BX_INFO(("BOUND: fails bounds test\n"));
+      exception(5, 0, 0);
+      }
+    }
+  else {
+    Bit16s bound_min, bound_max;
+    Bit16s op1_16;
+
+    op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+    read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &bound_min);
+    read_virtual_word(i->seg, i->rm_addr+2, (Bit16u *) &bound_max);
+
+    /* ??? */
+    if ( (op1_16 < bound_min) || (op1_16 > bound_max) ) {
+      BX_INFO(("BOUND: fails bounds test\n"));
+      exception(5, 0, 0);
+      }
+    }
+
+#endif
+}
+
+  void
+BX_CPU_C::INT1(BxInstruction_t *i)
+{
+  // This is an undocumented instrucion (opcode 0xf1)
+  // which is useful for an ICE system.
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  interrupt(1, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+
+  void
+BX_CPU_C::INT3(BxInstruction_t *i)
+{
+  // INT 3 is not IOPL sensitive
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+//BX_PANIC(("INT3: bailing\n"));
+  interrupt(3, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+
+
+  void
+BX_CPU_C::INT_Ib(BxInstruction_t *i)
+{
+  Bit8u imm8;
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  imm8 = i->Ib;
+
+  if (v8086_mode() && (IOPL<3)) {
+    //BX_INFO(("int_ib: v8086: IOPL<3\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+#ifdef SHOW_EXIT_STATUS
+if ( (imm8 == 0x21) && (AH == 0x4c) ) {
+  BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x\n", (unsigned) AL, (unsigned) BX));
+  }
+#endif
+
+  interrupt(imm8, 1, 0, 0);
+  BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                      BX_CPU_THIS_PTR eip);
+}
+
+
+  void
+BX_CPU_C::INTO(BxInstruction_t *i)
+{
+
+#if BX_DEBUGGER
+  BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+  /* ??? is this IOPL sensitive ? */
+  if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported\n"));
+
+  if (get_OF()) {
+    interrupt(4, 1, 0, 0);
+    BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+                        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+                        BX_CPU_THIS_PTR eip);
+    }
+}
diff --git a/sid/component/bochs/cpu/stack16.cc b/sid/component/bochs/cpu/stack16.cc
new file mode 100644 (file)
index 0000000..4d95bce
--- /dev/null
@@ -0,0 +1,183 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+  void
+BX_CPU_C::PUSH_RX(BxInstruction_t *i)
+{
+  push_16( BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx );
+}
+
+  void
+BX_CPU_C::POP_RX(BxInstruction_t *i)
+{
+  Bit16u rx;
+
+  pop_16(&rx);
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = rx;
+}
+
+  void
+BX_CPU_C::POP_Ew(BxInstruction_t *i)
+{
+  Bit16u val16;
+
+  pop_16(&val16);
+
+  if (i->mod == 0xc0) {
+    BX_WRITE_16BIT_REG(i->rm, val16);
+    }
+  else {
+    // Note: there is one little weirdism here.  When 32bit addressing
+    // is used, it is possible to use ESP in the modrm addressing.
+    // If used, the value of ESP after the pop is used to calculate
+    // the address.
+    if (i->as_32 && (i->mod!=0xc0) && (i->rm==4) && (i->base==4)) {
+      BX_CPU_CALL_METHOD (i->ResolveModrm, (i));
+      }
+    write_virtual_word(i->seg, i->rm_addr, &val16);
+    }
+}
+
+  void
+BX_CPU_C::PUSHAD16(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("PUSHAD: not supported on an 8086\n"));
+#else
+  Bit32u temp_ESP;
+  Bit16u sp;
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+#if BX_CPU_LEVEL >= 2
+    if (protected_mode()) {
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 16) ) {
+        BX_PANIC(("PUSHA(): stack doesn't have enough room!\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+    else
+#endif
+      {
+      if (temp_ESP < 16)
+        BX_PANIC(("pushad: eSP < 16\n"));
+      }
+
+    sp = SP;
+
+    /* ??? optimize this by using virtual write, all checks passed */
+    push_16(AX);
+    push_16(CX);
+    push_16(DX);
+    push_16(BX);
+    push_16(sp);
+    push_16(BP);
+    push_16(SI);
+    push_16(DI);
+#endif
+}
+
+  void
+BX_CPU_C::POPAD16(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("POPAD not supported on an 8086\n"));
+#else /* 286+ */
+
+    Bit16u di, si, bp, tmp, bx, dx, cx, ax;
+
+    if (protected_mode()) {
+      if ( !can_pop(16) ) {
+        BX_PANIC(("pop_a: not enough bytes on stack\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+
+    /* ??? optimize this */
+    pop_16(&di);
+    pop_16(&si);
+    pop_16(&bp);
+    pop_16(&tmp); /* value for SP discarded */
+    pop_16(&bx);
+    pop_16(&dx);
+    pop_16(&cx);
+    pop_16(&ax);
+
+    DI = di;
+    SI = si;
+    BP = bp;
+    BX = bx;
+    DX = dx;
+    CX = cx;
+    AX = ax;
+#endif
+}
+
+  void
+BX_CPU_C::PUSH_Iw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("PUSH_Iv: not supported on 8086!\n"));
+#else
+
+    Bit16u imm16;
+
+    imm16 = i->Iw;
+
+    push_16(imm16);
+#endif
+}
+
+  void
+BX_CPU_C::PUSH_Ew(BxInstruction_t *i)
+{
+    Bit16u op1_16;
+
+    /* op1_16 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_16 = BX_READ_16BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_word(i->seg, i->rm_addr, &op1_16);
+      }
+
+    push_16(op1_16);
+}
diff --git a/sid/component/bochs/cpu/stack32.cc b/sid/component/bochs/cpu/stack32.cc
new file mode 100644 (file)
index 0000000..6acbae8
--- /dev/null
@@ -0,0 +1,510 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+  void
+BX_CPU_C::POP_Ed(BxInstruction_t *i)
+{
+  Bit32u val32;
+
+  pop_32(&val32);
+
+  if (i->mod == 0xc0) {
+    BX_WRITE_32BIT_REG(i->rm, val32);
+    }
+  else {
+    // Note: there is one little weirdism here.  When 32bit addressing
+    // is used, it is possible to use ESP in the modrm addressing.
+    // If used, the value of ESP after the pop is used to calculate
+    // the address.
+    if (i->as_32 && (i->mod!=0xc0) && (i->rm==4) && (i->base==4)) {
+      // call method on BX_CPU_C object
+      BX_CPU_CALL_METHOD (i->ResolveModrm, (i));
+      }
+    write_virtual_dword(i->seg, i->rm_addr, &val32);
+    }
+}
+
+  void
+BX_CPU_C::PUSH_ERX(BxInstruction_t *i)
+{
+  push_32(BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx);
+}
+
+  void
+BX_CPU_C::POP_ERX(BxInstruction_t *i)
+{
+  Bit32u erx;
+
+  pop_32(&erx);
+  BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = erx;
+}
+
+
+  void
+BX_CPU_C::PUSH_CS(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+}
+  void
+BX_CPU_C::PUSH_DS(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+}
+  void
+BX_CPU_C::PUSH_ES(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+}
+  void
+BX_CPU_C::PUSH_FS(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+}
+  void
+BX_CPU_C::PUSH_GS(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+}
+  void
+BX_CPU_C::PUSH_SS(BxInstruction_t *i)
+{
+  if (i->os_32)
+    push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+  else
+    push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+}
+
+
+  void
+BX_CPU_C::POP_DS(BxInstruction_t *i)
+{
+  if (i->os_32) {
+    Bit32u ds;
+    pop_32(&ds);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], (Bit16u) ds);
+    }
+  else {
+    Bit16u ds;
+    pop_16(&ds);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+    }
+}
+  void
+BX_CPU_C::POP_ES(BxInstruction_t *i)
+{
+  if (i->os_32) {
+    Bit32u es;
+    pop_32(&es);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], (Bit16u) es);
+    }
+  else {
+    Bit16u es;
+    pop_16(&es);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+    }
+}
+  void
+BX_CPU_C::POP_FS(BxInstruction_t *i)
+{
+  if (i->os_32) {
+    Bit32u fs;
+    pop_32(&fs);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
+    }
+  else {
+    Bit16u fs;
+    pop_16(&fs);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+    }
+}
+  void
+BX_CPU_C::POP_GS(BxInstruction_t *i)
+{
+  if (i->os_32) {
+    Bit32u gs;
+    pop_32(&gs);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
+    }
+  else {
+    Bit16u gs;
+    pop_16(&gs);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+    }
+}
+  void
+BX_CPU_C::POP_SS(BxInstruction_t *i)
+{
+  if (i->os_32) {
+    Bit32u ss;
+    pop_32(&ss);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], (Bit16u) ss);
+    }
+  else {
+    Bit16u ss;
+    pop_16(&ss);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss);
+    }
+
+  // POP SS inhibits interrupts, debug exceptions and single-step
+  // trap exceptions until the execution boundary following the
+  // next instruction is reached.
+  // Same code as MOV_SwEw()
+  BX_CPU_THIS_PTR inhibit_mask |=
+    BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG;
+  BX_CPU_THIS_PTR async_event = 1;
+}
+
+
+  void
+BX_CPU_C::PUSHAD32(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("PUSHAD: not supported on an 8086\n"));
+#else
+  Bit32u temp_ESP;
+  Bit32u esp;
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+
+    if (protected_mode()) {
+      if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 32) ) {
+        BX_PANIC(("PUSHAD(): stack doesn't have enough room!\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+    else {
+      if (temp_ESP < 32)
+        BX_PANIC(("pushad: eSP < 32\n"));
+      }
+
+    esp = ESP;
+
+    /* ??? optimize this by using virtual write, all checks passed */
+    push_32(EAX);
+    push_32(ECX);
+    push_32(EDX);
+    push_32(EBX);
+    push_32(esp);
+    push_32(EBP);
+    push_32(ESI);
+    push_32(EDI);
+#endif
+}
+
+  void
+BX_CPU_C::POPAD32(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("POPAD not supported on an 8086\n"));
+#else /* 286+ */
+    Bit32u edi, esi, ebp, etmp, ebx, edx, ecx, eax;
+
+    if (protected_mode()) {
+      if ( !can_pop(32) ) {
+        BX_PANIC(("pop_ad: not enough bytes on stack\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+
+    /* ??? optimize this */
+    pop_32(&edi);
+    pop_32(&esi);
+    pop_32(&ebp);
+    pop_32(&etmp); /* value for ESP discarded */
+    pop_32(&ebx);
+    pop_32(&edx);
+    pop_32(&ecx);
+    pop_32(&eax);
+
+    EDI = edi;
+    ESI = esi;
+    EBP = ebp;
+    EBX = ebx;
+    EDX = edx;
+    ECX = ecx;
+    EAX = eax;
+#endif
+}
+
+  void
+BX_CPU_C::PUSH_Id(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("PUSH_Iv: not supported on 8086!\n"));
+#else
+
+    Bit32u imm32;
+
+    imm32 = i->Id;
+
+    push_32(imm32);
+#endif
+}
+
+  void
+BX_CPU_C::PUSH_Ed(BxInstruction_t *i)
+{
+    Bit32u op1_32;
+
+    /* op1_32 is a register or memory reference */
+    if (i->mod == 0xc0) {
+      op1_32 = BX_READ_32BIT_REG(i->rm);
+      }
+    else {
+      /* pointer, segment address pair */
+      read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+      }
+
+    push_32(op1_32);
+}
+
+
+  void
+BX_CPU_C::ENTER_IwIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("ENTER_IwIb: not supported by 8086!\n"));
+#else
+  Bit32u frame_ptr32;
+  Bit16u frame_ptr16;
+  Bit8u level;
+
+  level = i->Ib2;
+
+  invalidate_prefetch_q();
+
+  level %= 32;
+/* ??? */
+if (level) BX_PANIC(("enter(): level > 0\n"));
+//if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b && i->os_32==0) {
+//  BX_INFO(("enter(): stacksize!=opsize: I'm unsure of the code for this\n"));
+//  BX_PANIC(("         The Intel manuals are a mess on this one!\n"));
+//  }
+
+  if ( protected_mode() ) {
+    Bit32u bytes_to_push, temp_ESP;
+
+    if (level == 0) {
+      if (i->os_32)
+        bytes_to_push = 4 + i->Iw;
+      else
+        bytes_to_push = 2 + i->Iw;
+      }
+    else { /* level > 0 */
+      if (i->os_32)
+        bytes_to_push = 4 + (level-1)*4 + 4 + i->Iw;
+      else
+        bytes_to_push = 2 + (level-1)*2 + 2 + i->Iw;
+      }
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      temp_ESP = ESP;
+    else
+      temp_ESP = SP;
+    if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, bytes_to_push) ) {
+      BX_PANIC(("ENTER: not enough room on stack!\n"));
+      exception(BX_SS_EXCEPTION, 0, 0);
+      }
+    }
+
+  if (i->os_32)
+    push_32(EBP);
+  else
+    push_16(BP);
+
+  // can just do frame_ptr32 = ESP for either case ???
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    frame_ptr32 = ESP;
+  else
+    frame_ptr32 = SP;
+
+  if (level > 0) {
+    /* do level-1 times */
+    while (--level) {
+      if (i->os_32) {
+        Bit32u temp32;
+
+        if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+          EBP -= 4;
+          read_virtual_dword(BX_SEG_REG_SS, EBP, &temp32);
+          ESP -= 4;
+          write_virtual_dword(BX_SEG_REG_SS, ESP, &temp32);
+          }
+        else { /* 16bit stacksize */
+          BP -= 4;
+          read_virtual_dword(BX_SEG_REG_SS, BP, &temp32);
+          SP -= 4;
+          write_virtual_dword(BX_SEG_REG_SS, SP, &temp32);
+          }
+        }
+      else { /* 16bit opsize */
+        Bit16u temp16;
+
+        if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+          EBP -= 2;
+          read_virtual_word(BX_SEG_REG_SS, EBP, &temp16);
+          ESP -= 2;
+          write_virtual_word(BX_SEG_REG_SS, ESP, &temp16);
+          }
+        else { /* 16bit stacksize */
+          BP -= 2;
+          read_virtual_word(BX_SEG_REG_SS, BP, &temp16);
+          SP -= 2;
+          write_virtual_word(BX_SEG_REG_SS, SP, &temp16);
+          }
+        }
+      } /* while (--level) */
+
+    /* push(frame pointer) */
+    if (i->os_32) {
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+        ESP -= 4;
+        write_virtual_dword(BX_SEG_REG_SS, ESP, &frame_ptr32);
+        }
+      else {
+        SP -= 4;
+        write_virtual_dword(BX_SEG_REG_SS, SP, &frame_ptr32);
+        }
+      }
+    else { /* 16bit opsize */
+      if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+        frame_ptr16 = frame_ptr32;
+        ESP -= 2;
+        write_virtual_word(BX_SEG_REG_SS, ESP, &frame_ptr16);
+        }
+      else {
+        frame_ptr16 = frame_ptr32;
+        SP -= 2;
+        write_virtual_word(BX_SEG_REG_SS, SP, &frame_ptr16);
+        }
+      }
+    } /* if (level > 0) ... */
+
+  if (i->os_32)
+    EBP = frame_ptr32;
+  else
+    BP = frame_ptr32;
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+    ESP = ESP - i->Iw;
+    }
+  else { /* 16bit stack */
+    SP = SP - i->Iw;
+    }
+#endif
+}
+
+  void
+BX_CPU_C::LEAVE(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+  BX_PANIC(("LEAVE: not supported by 8086!\n"));
+#else
+  Bit32u temp_EBP;
+
+
+  invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_EBP = EBP;
+  else
+#endif
+    temp_EBP = BP;
+
+  if ( protected_mode() ) {
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed) { /* expand up */
+      if (temp_EBP <= BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("LEAVE: BP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].limit\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+    else { /* normal */
+      if (temp_EBP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
+        BX_PANIC(("LEAVE: BP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].limit\n"));
+        exception(BX_SS_EXCEPTION, 0, 0);
+        return;
+        }
+      }
+    }
+
+
+  // delete frame
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    ESP = EBP;
+  else
+#endif
+    SP = BP;
+
+  // restore frame pointer
+#if BX_CPU_LEVEL >= 3
+  if (i->os_32) {
+    Bit32u temp32;
+
+    pop_32(&temp32);
+    EBP = temp32;
+    }
+  else
+#endif
+    {
+    Bit16u temp16;
+
+    pop_16(&temp16);
+    BP = temp16;
+    }
+#endif
+}
diff --git a/sid/component/bochs/cpu/stack_pro.cc b/sid/component/bochs/cpu/stack_pro.cc
new file mode 100644 (file)
index 0000000..a2b0b28
--- /dev/null
@@ -0,0 +1,335 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+  void
+BX_CPU_C::push_16(Bit16u value16)
+{
+  Bit32u temp_ESP;
+
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+#if BX_CPU_LEVEL >= 3
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      temp_ESP = ESP;
+    else
+#endif
+      temp_ESP = SP;
+    if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 2)) {
+      BX_PANIC(("push_16(): can't push on stack\n"));
+      exception(BX_SS_EXCEPTION, 0, 0);
+      return;
+      }
+
+    /* access within limits */
+    write_virtual_word(BX_SEG_REG_SS, temp_ESP - 2, &value16);
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+      ESP -= 2;
+    else
+      SP -= 2;
+    return;
+    }
+  else
+#endif
+    { /* real mode */
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
+      if (ESP == 1)
+        BX_PANIC(("CPU shutting down due to lack of stack space, ESP==1\n"));
+      ESP -= 2;
+      temp_ESP = ESP;
+      }
+    else {
+      if (SP == 1)
+        BX_PANIC(("CPU shutting down due to lack of stack space, SP==1\n"));
+      SP -= 2;
+      temp_ESP = SP;
+      }
+
+    write_virtual_word(BX_SEG_REG_SS, temp_ESP, &value16);
+    return;
+    }
+}
+
+#if BX_CPU_LEVEL >= 3
+  /* push 32 bit operand size */
+  void
+BX_CPU_C::push_32(Bit32u value32)
+{
+  /* must use StackAddrSize, and either ESP or SP accordingly */
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
+    /* 32bit stack size: pushes use SS:ESP  */
+    if (protected_mode()) {
+      if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, ESP, 4)) {
+        BX_PANIC(("push_32(): push outside stack limits\n"));
+        /* #SS(0) */
+        }
+      }
+    else { /* real mode */
+      if ((ESP>=1) && (ESP<=3)) {
+        BX_PANIC(("push_32: ESP=%08x\n", (unsigned) ESP));
+        }
+      }
+
+    write_virtual_dword(BX_SEG_REG_SS, ESP-4, &value32);
+    ESP -= 4;
+    /* will return after error anyway */
+    return;
+    }
+  else { /* 16bit stack size: pushes use SS:SP  */
+    if (protected_mode()) {
+      if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, SP, 4)) {
+        BX_PANIC(("push_32(): push outside stack limits\n"));
+        /* #SS(0) */
+        }
+      }
+    else { /* real mode */
+      if ((SP>=1) && (SP<=3)) {
+        BX_PANIC(("push_32: SP=%08x\n", (unsigned) SP));
+        }
+      }
+
+    write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (SP-4), &value32);
+    SP -= 4;
+    /* will return after error anyway */
+    return;
+    }
+}
+#endif /* BX_CPU_LEVEL >= 3 */
+
+  void
+BX_CPU_C::pop_16(Bit16u *value16_ptr)
+{
+  Bit32u temp_ESP;
+
+#if BX_CPU_LEVEL >= 3
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+#endif
+    temp_ESP = SP;
+
+#if BX_CPU_LEVEL >= 2
+  if (protected_mode()) {
+    if ( !can_pop(2) ) {
+      BX_INFO(("pop_16(): can't pop from stack\n"));
+      exception(BX_SS_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+#endif
+
+
+  /* access within limits */
+  read_virtual_word(BX_SEG_REG_SS, temp_ESP, value16_ptr);
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    ESP += 2;
+  else
+    SP += 2;
+}
+
+#if BX_CPU_LEVEL >= 3
+  void
+BX_CPU_C::pop_32(Bit32u *value32_ptr)
+{
+  Bit32u temp_ESP;
+
+  /* 32 bit stack mode: use SS:ESP */
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+  /* 16 bit stack mode: use SS:SP */
+  if (protected_mode()) {
+    if ( !can_pop(4) ) {
+      BX_PANIC(("pop_32(): can't pop from stack\n"));
+      exception(BX_SS_EXCEPTION, 0, 0);
+      return;
+      }
+    }
+
+  /* access within limits */
+  read_virtual_dword(BX_SEG_REG_SS, temp_ESP, value32_ptr);
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b==1)
+    ESP += 4;
+  else
+    SP += 4;
+}
+#endif
+
+
+
+#if BX_CPU_LEVEL >= 2
+  Boolean
+BX_CPU_C::can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes)
+{
+  if ( real_mode() ) { /* code not needed ??? */
+    BX_PANIC(("can_push(): called in real mode\n"));
+    return(0); /* never gets here */
+    }
+
+  // small stack compares against 16-bit SP
+  if (!descriptor->u.segment.d_b)
+    esp &= 0x0000ffff;
+
+
+  if (descriptor->valid==0) {
+    BX_PANIC(("can_push(): SS invalidated.\n"));
+    return(0);
+    }
+
+  if (descriptor->p==0) {
+    BX_PANIC(("can_push(): not present\n"));
+    return(0);
+    }
+
+
+  if (descriptor->u.segment.c_ed) { /* expand down segment */
+    Bit32u expand_down_limit;
+
+    if (descriptor->u.segment.d_b)
+      expand_down_limit = 0xffffffff;
+    else
+      expand_down_limit = 0x0000ffff;
+
+    if (esp==0) {
+      BX_PANIC(("can_push(): esp=0, wraparound?\n"));
+      return(0);
+      }
+
+    if (esp < bytes) {
+      BX_PANIC(("can_push(): expand-down: esp < N\n"));
+      return(0);
+      }
+    if ( (esp - bytes) <= descriptor->u.segment.limit_scaled ) {
+      BX_PANIC(("can_push(): expand-down: esp-N < limit\n"));
+      return(0);
+      }
+    if ( esp > expand_down_limit ) {
+      BX_PANIC(("can_push(): esp > expand-down-limit\n"));
+      return(0);
+      }
+    return(1);
+    }
+  else { /* normal (expand-up) segment */
+    if (descriptor->u.segment.limit_scaled==0) {
+      BX_PANIC(("can_push(): found limit of 0\n"));
+      return(0);
+      }
+
+    // Look at case where esp==0.  Possibly, it's an intentional wraparound
+    // If so, limit must be the maximum for the given stack size
+    if (esp==0) {
+      if (descriptor->u.segment.d_b && (descriptor->u.segment.limit_scaled==0xffffffff))
+        return(1);
+      if ((descriptor->u.segment.d_b==0) && (descriptor->u.segment.limit_scaled>=0xffff))
+        return(1);
+      BX_PANIC(("can_push(): esp=0, normal, wraparound? limit=%08x\n",
+        descriptor->u.segment.limit_scaled));
+      return(0);
+      }
+
+    if (esp < bytes) {
+      BX_INFO(("can_push(): expand-up: esp < N\n"));
+      return(0);
+      }
+    if ((esp-1) > descriptor->u.segment.limit_scaled) {
+      BX_INFO(("can_push(): expand-up: SP > limit\n"));
+      return(0);
+      }
+    /* all checks pass */
+    return(1);
+    }
+}
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+  Boolean
+BX_CPU_C::can_pop(Bit32u bytes)
+{
+  Bit32u temp_ESP, expand_down_limit;
+
+  /* ??? */
+  if (real_mode()) BX_PANIC(("can_pop(): called in real mode?\n"));
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* Big bit set: use ESP */
+    temp_ESP = ESP;
+    expand_down_limit = 0xFFFFFFFF;
+    }
+  else { /* Big bit clear: use SP */
+    temp_ESP = SP;
+    expand_down_limit = 0xFFFF;
+    }
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0) {
+    BX_PANIC(("can_pop(): SS invalidated.\n"));
+    return(0); /* never gets here */
+    }
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p==0) { /* ??? */
+    BX_PANIC(("can_pop(): SS.p = 0\n"));
+    return(0);
+    }
+
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed) { /* expand down segment */
+    if ( temp_ESP == expand_down_limit ) {
+      BX_PANIC(("can_pop(): found SP=ffff\n"));
+      return(0);
+      }
+    if ( ((expand_down_limit - temp_ESP) + 1) >= bytes )
+      return(1);
+    return(0);
+    }
+  else { /* normal (expand-up) segment */
+    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled==0) {
+      BX_PANIC(("can_pop(): SS.limit = 0\n"));
+      }
+    if ( temp_ESP == expand_down_limit ) {
+      BX_PANIC(("can_pop(): found SP=ffff\n"));
+      return(0);
+      }
+    if ( temp_ESP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled ) {
+      BX_PANIC(("can_pop(): eSP > SS.limit\n"));
+      return(0);
+      }
+    if ( ((BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled - temp_ESP) + 1) >= bytes )
+      return(1);
+    return(0);
+    }
+}
+#endif
diff --git a/sid/component/bochs/cpu/state_file.h b/sid/component/bochs/cpu/state_file.h
new file mode 100644 (file)
index 0000000..66bfda0
--- /dev/null
@@ -0,0 +1,57 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+// Classes for helping to make checkpoints of the emulator state.
+
+#ifndef _STATE_FILE_H
+#define _STATE_FILE_H
+#include <stdio.h>
+#include <stddef.h>
+
+
+class state_file {
+  void init(void);
+public:
+  FILE *file;
+  class logfunctions *log;
+
+  FILE *get_handle();
+  void write(Bit8u);
+  void write(Bit16u);
+  void write(Bit32u);
+  void write(Bit64u);
+  void write(const void*, size_t);
+  void read(Bit8u &);
+  void read(Bit16u &);
+  void read(Bit32u &);
+  void read(Bit64u &);
+  void read(void *, size_t);
+  void write_check(const char *);
+  void read_check (const char *);
+
+  state_file (const char *name, const char *options);
+  state_file (FILE *f);
+  ~state_file();
+};
+
+#endif  // #ifndef _STATE_FILE_H
diff --git a/sid/component/bochs/cpu/string.cc b/sid/component/bochs/cpu/string.cc
new file mode 100644 (file)
index 0000000..2b4b203
--- /dev/null
@@ -0,0 +1,874 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+/* MOVSB ES:[EDI], DS:[ESI]   DS may be overridden
+ *   mov string from DS:[ESI] into ES:[EDI]
+ */
+
+  void
+BX_CPU_C::MOVSB_XbYb(BxInstruction_t *i)
+{
+  unsigned seg;
+  Bit8u temp8;
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u esi, edi;
+
+    esi = ESI;
+    edi = EDI;
+
+    read_virtual_byte(seg, esi, &temp8);
+
+    write_virtual_byte(BX_SEG_REG_ES, edi, &temp8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI, EDI */
+      esi--;
+      edi--;
+      }
+    else {
+      /* increment ESI, EDI */
+      esi++;
+      edi++;
+      }
+
+    ESI = esi;
+    EDI = edi;
+    }
+
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16 bit address mode */
+    Bit16u si, di;
+
+    si = SI;
+    di = DI;
+
+    read_virtual_byte(seg, si, &temp8);
+
+    write_virtual_byte(BX_SEG_REG_ES, di, &temp8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement SI, DI */
+      si--;
+      di--;
+      }
+    else {
+      /* increment SI, DI */
+      si++;
+      di++;
+      }
+
+    SI = si;
+    DI = di;
+    }
+}
+
+  void
+BX_CPU_C::MOVSW_XvYv(BxInstruction_t *i)
+{
+  unsigned seg;
+
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u  temp32;
+
+    Bit32u esi, edi;
+
+    esi = ESI;
+    edi = EDI;
+
+    if (i->os_32) {
+      read_virtual_dword(seg, esi, &temp32);
+
+      write_virtual_dword(BX_SEG_REG_ES, edi, &temp32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 4;
+        edi -= 4;
+        }
+      else {
+        /* increment ESI */
+        esi += 4;
+        edi += 4;
+        }
+      } /* if (i->os_32) ... */
+    else { /* 16 bit opsize mode */
+      Bit16u  temp16;
+
+      read_virtual_word(seg, esi, &temp16);
+
+      write_virtual_word(BX_SEG_REG_ES, edi, &temp16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 2;
+        edi -= 2;
+        }
+      else {
+        /* increment ESI */
+        esi += 2;
+        edi += 2;
+        }
+      }
+
+    ESI = esi;
+    EDI = edi;
+    }
+
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u si, di;
+
+    si = SI;
+    di = DI;
+
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+      Bit32u temp32;
+
+      read_virtual_dword(seg, si, &temp32);
+
+      write_virtual_dword(BX_SEG_REG_ES, di, &temp32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        si -= 4;
+        di -= 4;
+        }
+      else {
+        /* increment ESI */
+        si += 4;
+        di += 4;
+        }
+      } /* if (i->os_32) ... */
+    else
+#endif /* BX_CPU_LEVEL >= 3 */
+      { /* 16 bit opsize mode */
+      Bit16u  temp16;
+
+      read_virtual_word(seg, si, &temp16);
+
+      write_virtual_word(BX_SEG_REG_ES, di, &temp16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement SI, DI */
+        si -= 2;
+        di -= 2;
+        }
+      else {
+        /* increment SI, DI */
+        si += 2;
+        di += 2;
+        }
+      }
+
+    SI = si;
+    DI = di;
+    }
+}
+
+  void
+BX_CPU_C::CMPSB_XbYb(BxInstruction_t *i)
+{
+  unsigned seg;
+  Bit8u op1_8, op2_8, diff_8;
+
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u esi, edi;
+
+    esi = ESI;
+    edi = EDI;
+
+    read_virtual_byte(seg, esi, &op1_8);
+
+    read_virtual_byte(BX_SEG_REG_ES, edi, &op2_8);
+
+    diff_8 = op1_8 - op2_8;
+
+    SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMPS8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      esi--;
+      edi--;
+      }
+    else {
+      /* increment ESI */
+      esi++;
+      edi++;
+      }
+
+    EDI = edi;
+    ESI = esi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u si, di;
+
+    si = SI;
+    di = DI;
+
+    read_virtual_byte(seg, si, &op1_8);
+
+    read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+
+    diff_8 = op1_8 - op2_8;
+
+    SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMPS8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      si--;
+      di--;
+      }
+    else {
+      /* increment ESI */
+      si++;
+      di++;
+      }
+
+    DI = di;
+    SI = si;
+    }
+}
+
+  void
+BX_CPU_C::CMPSW_XvYv(BxInstruction_t *i)
+{
+  unsigned seg;
+
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u op1_32, op2_32, diff_32;
+    Bit32u esi, edi;
+
+    esi = ESI;
+    edi = EDI;
+
+
+    if (i->os_32) {
+      read_virtual_dword(seg, esi, &op1_32);
+
+      read_virtual_dword(BX_SEG_REG_ES, edi, &op2_32);
+
+      diff_32 = op1_32 - op2_32;
+
+      SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMPS32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 4;
+        edi -= 4;
+        }
+      else {
+        /* increment ESI */
+        esi += 4;
+        edi += 4;
+        }
+      }
+    else { /* 16 bit opsize */
+      Bit16u op1_16, op2_16, diff_16;
+
+      read_virtual_word(seg, esi, &op1_16);
+
+      read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+
+      diff_16 = op1_16 - op2_16;
+
+      SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 2;
+        edi -= 2;
+        }
+      else {
+        /* increment ESI */
+        esi += 2;
+        edi += 2;
+        }
+      }
+
+
+    EDI = edi;
+    ESI = esi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16 bit address mode */
+    Bit16u si, di;
+
+    si = SI;
+    di = DI;
+
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+      Bit32u op1_32, op2_32, diff_32;
+
+      read_virtual_dword(seg, si, &op1_32);
+
+      read_virtual_dword(BX_SEG_REG_ES, di, &op2_32);
+
+      diff_32 = op1_32 - op2_32;
+
+      SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMPS32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        si -= 4;
+        di -= 4;
+        }
+      else {
+        /* increment ESI */
+        si += 4;
+        di += 4;
+        }
+      }
+    else
+#endif /* BX_CPU_LEVEL >= 3 */
+      { /* 16 bit opsize */
+      Bit16u op1_16, op2_16, diff_16;
+
+      read_virtual_word(seg, si, &op1_16);
+
+      read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+
+      diff_16 = op1_16 - op2_16;
+
+      SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        si -= 2;
+        di -= 2;
+        }
+      else {
+        /* increment ESI */
+        si += 2;
+        di += 2;
+        }
+      }
+
+
+    DI = di;
+    SI = si;
+    }
+}
+
+  void
+BX_CPU_C::SCASB_ALXb(BxInstruction_t *i)
+{
+  Bit8u op1_8, op2_8, diff_8;
+
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u edi;
+
+    edi = EDI;
+
+    op1_8 = AL;
+
+    read_virtual_byte(BX_SEG_REG_ES, edi, &op2_8);
+
+    diff_8 = op1_8 - op2_8;
+
+    SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
+
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      edi--;
+      }
+    else {
+      /* increment ESI */
+      edi++;
+      }
+
+    EDI = edi;
+    }
+
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u di;
+
+    di = DI;
+
+    op1_8 = AL;
+
+    read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+
+    diff_8 = op1_8 - op2_8;
+
+    SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      di--;
+      }
+    else {
+      /* increment ESI */
+      di++;
+      }
+
+    DI = di;
+    }
+}
+
+  void
+BX_CPU_C::SCASW_eAXXv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u edi;
+
+    edi = EDI;
+
+    if (i->os_32) {
+      Bit32u op1_32, op2_32, diff_32;
+
+      op1_32 = EAX;
+      read_virtual_dword(BX_SEG_REG_ES, edi, &op2_32);
+
+      diff_32 = op1_32 - op2_32;
+
+      SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SCAS32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        edi -= 4;
+        }
+      else {
+        /* increment ESI */
+        edi += 4;
+        }
+      }
+    else { /* 16 bit opsize */
+      Bit16u op1_16, op2_16, diff_16;
+
+      op1_16 = AX;
+      read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+
+      diff_16 = op1_16 - op2_16;
+
+      SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        edi -= 2;
+        }
+      else {
+        /* increment ESI */
+        edi += 2;
+        }
+      }
+
+    EDI = edi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u di;
+
+    di = DI;
+
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+      Bit32u op1_32, op2_32, diff_32;
+
+      op1_32 = EAX;
+      read_virtual_dword(BX_SEG_REG_ES, di, &op2_32);
+
+      diff_32 = op1_32 - op2_32;
+
+      SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SCAS32);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        di -= 4;
+        }
+      else {
+        /* increment ESI */
+        di += 4;
+        }
+      }
+    else
+#endif /* BX_CPU_LEVEL >= 3 */
+      { /* 16 bit opsize */
+      Bit16u op1_16, op2_16, diff_16;
+
+      op1_16 = AX;
+      read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+
+      diff_16 = op1_16 - op2_16;
+
+      SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        di -= 2;
+        }
+      else {
+        /* increment ESI */
+        di += 2;
+        }
+      }
+
+    DI = di;
+    }
+}
+
+  void
+BX_CPU_C::STOSB_YbAL(BxInstruction_t *i)
+{
+  Bit8u al;
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u edi;
+
+    edi = EDI;
+
+    al = AL;
+    write_virtual_byte(BX_SEG_REG_ES, edi, &al);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement EDI */
+      edi--;
+      }
+    else {
+      /* increment EDI */
+      edi++;
+      }
+
+    EDI = edi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address size */
+    Bit16u di;
+
+    di = DI;
+
+    al = AL;
+    write_virtual_byte(BX_SEG_REG_ES, di, &al);
+
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement EDI */
+      di--;
+      }
+    else {
+      /* increment EDI */
+      di++;
+      }
+
+    DI = di;
+    }
+}
+
+  void
+BX_CPU_C::STOSW_YveAX(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u edi;
+
+    edi = EDI;
+
+    if (i->os_32) {
+        Bit32u eax;
+
+        eax = EAX;
+        write_virtual_dword(BX_SEG_REG_ES, edi, &eax);
+
+        if (BX_CPU_THIS_PTR eflags.df) {
+          /* decrement EDI */
+          edi -= 4;
+          }
+        else {
+          /* increment EDI */
+          edi += 4;
+          }
+      } /* if (i->os_32) ... */
+    else { /* 16 bit opsize mode */
+        Bit16u ax;
+
+        ax = AX;
+        write_virtual_word(BX_SEG_REG_ES, edi, &ax);
+
+        if (BX_CPU_THIS_PTR eflags.df) {
+          /* decrement EDI */
+          edi -= 2;
+          }
+        else {
+          /* increment EDI */
+          edi += 2;
+          }
+      }
+
+    EDI = edi;
+    }
+
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address size */
+    Bit16u di;
+
+    di = DI;
+
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+        Bit32u eax;
+
+        eax = EAX;
+        write_virtual_dword(BX_SEG_REG_ES, di, &eax);
+
+        if (BX_CPU_THIS_PTR eflags.df) {
+          /* decrement EDI */
+          di -= 4;
+          }
+        else {
+          /* increment EDI */
+          di += 4;
+          }
+      } /* if (i->os_32) ... */
+    else
+#endif /* BX_CPU_LEVEL >= 3 */
+      { /* 16 bit opsize mode */
+        Bit16u ax;
+
+        ax = AX;
+        write_virtual_word(BX_SEG_REG_ES, di, &ax);
+
+        if (BX_CPU_THIS_PTR eflags.df) {
+          /* decrement EDI */
+          di -= 2;
+          }
+        else {
+          /* increment EDI */
+          di += 2;
+          }
+      }
+
+    DI = di;
+    }
+}
+
+
+  void
+BX_CPU_C::LODSB_ALXb(BxInstruction_t *i)
+{
+  unsigned seg;
+  Bit8u al;
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u esi;
+
+    esi = ESI;
+
+    read_virtual_byte(seg, esi, &al);
+
+    AL = al;
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      esi--;
+      }
+    else {
+      /* increment ESI */
+      esi++;
+      }
+
+    ESI = esi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u si;
+
+    si = SI;
+
+    read_virtual_byte(seg, si, &al);
+
+    AL = al;
+    if (BX_CPU_THIS_PTR eflags.df) {
+      /* decrement ESI */
+      si--;
+      }
+    else {
+      /* increment ESI */
+      si++;
+      }
+
+    SI = si;
+    }
+}
+
+  void
+BX_CPU_C::LODSW_eAXXv(BxInstruction_t *i)
+{
+  unsigned seg;
+
+  if (!BX_NULL_SEG_REG(i->seg)) {
+    seg = i->seg;
+    }
+  else {
+    seg = BX_SEG_REG_DS;
+    }
+
+#if BX_CPU_LEVEL >= 3
+  if (i->as_32) {
+    Bit32u esi;
+
+    esi = ESI;
+
+    if (i->os_32) {
+      Bit32u eax;
+
+      read_virtual_dword(seg, esi, &eax);
+
+      EAX = eax;
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 4;
+        }
+      else {
+        /* increment ESI */
+        esi += 4;
+        }
+      } /* if (i->os_32) ... */
+    else { /* 16 bit opsize mode */
+      Bit16u ax;
+      read_virtual_word(seg, esi, &ax);
+
+      AX = ax;
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        esi -= 2;
+        }
+      else {
+        /* increment ESI */
+        esi += 2;
+        }
+      }
+
+    ESI = esi;
+    }
+  else
+#endif /* BX_CPU_LEVEL >= 3 */
+    { /* 16bit address mode */
+    Bit16u si;
+
+    si = SI;
+
+#if BX_CPU_LEVEL >= 3
+    if (i->os_32) {
+      Bit32u eax;
+
+      read_virtual_dword(seg, si, &eax);
+
+      EAX = eax;
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        si -= 4;
+        }
+      else {
+        /* increment ESI */
+        si += 4;
+        }
+      }
+    else
+#endif /* BX_CPU_LEVEL >= 3 */
+      { /* 16 bit opsize mode */
+      Bit16u ax;
+
+      read_virtual_word(seg, si, &ax);
+
+      AX = ax;
+      if (BX_CPU_THIS_PTR eflags.df) {
+        /* decrement ESI */
+        si -= 2;
+        }
+      else {
+        /* increment ESI */
+        si += 2;
+        }
+      }
+
+    SI = si;
+    }
+}
diff --git a/sid/component/bochs/cpu/tasking.cc b/sid/component/bochs/cpu/tasking.cc
new file mode 100644 (file)
index 0000000..2bb59ba
--- /dev/null
@@ -0,0 +1,979 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if BX_SUPPORT_TASKING
+
+#if BX_CPU_LEVEL >= 2
+
+// Notes:
+// ======
+// Step 2: TSS descriptor is not busy TS (for IRET); GP (for JMP, CALL, INT)
+//   returns error code (Task's backlink TSS)???
+
+// *   TSS selector must map to GDT
+// *   TSS is stored in linear address space
+// * what to do with I/O Map Base
+// * what to do with T flag
+// * where to set CR3 and flush paging cache
+// * what happens when fault occurs, with some seg regs having valid bit cleared?
+// * should check validity of current TR(TSS) before writing into it
+//
+
+  // ======================
+  // 286 Task State Segment
+  // ======================
+  // dynamic item                      | hex  dec  offset
+  // 0       task LDT selector         | 2a   42
+  // 1       DS selector               | 28   40
+  // 1       SS selector               | 26   38
+  // 1       CS selector               | 24   36
+  // 1       ES selector               | 22   34
+  // 1       DI                        | 20   32
+  // 1       SI                        | 1e   30
+  // 1       BP                        | 1c   28
+  // 1       SP                        | 1a   26
+  // 1       BX                        | 18   24
+  // 1       DX                        | 16   22
+  // 1       CX                        | 14   20
+  // 1       AX                        | 12   18
+  // 1       flag word                 | 10   16
+  // 1       IP (entry point)          | 0e   14
+  // 0       SS for CPL 2              | 0c   12
+  // 0       SP for CPL 2              | 0a   10
+  // 0       SS for CPL 1              | 08   08
+  // 0       SP for CPL 1              | 06   06
+  // 0       SS for CPL 0              | 04   04
+  // 0       SP for CPL 0              | 02   02
+  //         back link selector to TSS | 00   00
+
+
+  // ======================
+  // 386 Task State Segment
+  // ======================
+  // |31            16|15                    0|
+  // |I/O Map Base    |000000000000000000000|T| 64  static
+  // |0000000000000000| LDT                   | 60  static
+  // |0000000000000000| GS selector           | 5c  dynamic
+  // |0000000000000000| FS selector           | 58  dynamic
+  // |0000000000000000| DS selector           | 54  dynamic
+  // |0000000000000000| SS selector           | 50  dynamic
+  // |0000000000000000| CS selector           | 4c  dynamic
+  // |0000000000000000| ES selector           | 48  dynamic
+  // |                EDI                     | 44  dynamic
+  // |                ESI                     | 40  dynamic
+  // |                EBP                     | 3c  dynamic
+  // |                ESP                     | 38  dynamic
+  // |                EBX                     | 34  dynamic
+  // |                EDX                     | 30  dynamic
+  // |                ECX                     | 2c  dynamic
+  // |                EAX                     | 28  dynamic
+  // |                EFLAGS                  | 24  dynamic
+  // |                EIP (entry point)       | 20  dynamic
+  // |           CR3 (PDPR)                   | 1c  static
+  // |000000000000000 | SS for CPL 2          | 18  static
+  // |           ESP for CPL 2                | 14  static
+  // |000000000000000 | SS for CPL 1          | 10  static
+  // |           ESP for CPL 1                | 0c  static
+  // |000000000000000 | SS for CPL 0          | 08  static
+  // |           ESP for CPL 0                | 04  static
+  // |000000000000000 | back link to prev TSS | 00  dynamic (updated only when return expected)
+
+
+  // ==================================================
+  // Effect of task switch on Busy, NT, and Link Fields
+  // ==================================================
+
+  // Field         jump        call/interrupt     iret
+  // ------------------------------------------------------
+  // new busy bit  Set         Set                No change
+  // old busy bit  Cleared     No change          Cleared
+  // new NT flag   No change   Set                No change
+  // old NT flag   No change   No change          Cleared
+  // new link      No change   old TSS selector   No change
+  // old link      No change   No change          No change
+  // CR0.TS        Set         Set                Set
+
+  // Note: I checked 386, 486, and Pentium, and they all exhibited
+  //       exactly the same behaviour as above.  There seems to
+  //       be some misprints in the Intel docs.
+
+
+  void
+BX_CPU_C::task_switch(bx_selector_t *tss_selector,
+                 bx_descriptor_t *tss_descriptor, unsigned source,
+                 Bit32u dword1, Bit32u dword2)
+{
+  Bit32u obase32; // base address of old TSS
+  Bit32u nbase32; // base address of new TSS
+  Bit32u temp32, newCR3;
+  Bit16u raw_cs_selector, raw_ss_selector, raw_ds_selector, raw_es_selector,
+         raw_fs_selector, raw_gs_selector, raw_ldt_selector;
+  Bit16u temp16, trap_word;
+  bx_selector_t cs_selector, ss_selector, ds_selector, es_selector,
+                fs_selector, gs_selector, ldt_selector;
+  bx_descriptor_t cs_descriptor, ss_descriptor, ds_descriptor, es_descriptor,
+                  fs_descriptor, gs_descriptor, ldt_descriptor;
+  Bit32u old_TSS_max, new_TSS_max, old_TSS_limit, new_TSS_limit;
+  Bit32u newEAX, newECX, newEDX, newEBX;
+  Bit32u newESP, newEBP, newESI, newEDI;
+  Bit32u newEFLAGS, oldEFLAGS, newEIP;
+  unsigned exception_no;
+  Bit16u error_code;
+
+//BX_DEBUG(( "TASKING: ENTER\n" ));
+
+  invalidate_prefetch_q();
+
+  // Discard any traps and inhibits for new context; traps will
+  // resume upon return.
+  BX_CPU_THIS_PTR debug_trap = 0;
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+
+
+  // The following checks are made before calling task_switch(), for
+  // JMP & CALL only.  These checks are NOT made for exceptions, interrupts, & IRET
+  //
+  //   1) TSS DPL must be >= CPL
+  //   2) TSS DPL must be >= TSS selector RPL
+  //   3) TSS descriptor is not busy.  TS(for IRET); GP(for JMP, CALL, INT)
+
+  // Privilege and busy checks done in CALL, JUMP, INT, IRET
+
+  exception_no = 256; // no exception
+  error_code   = 0;
+  oldEFLAGS = read_eflags();
+
+  // Gather info about old TSS
+  if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
+    obase32 = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
+    old_TSS_max   = 43;
+    old_TSS_limit = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
+    }
+  else {
+    obase32 = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
+    old_TSS_max   = 103;
+    old_TSS_limit = BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled;
+    }
+
+  // Gather info about new TSS
+  if (tss_descriptor->type <= 3) { // {1,3}
+    nbase32 = tss_descriptor->u.tss286.base; // new TSS.base
+    new_TSS_max   = 43;
+    new_TSS_limit = tss_descriptor->u.tss286.limit;
+    }
+  else { // tss_descriptor->type = {9,11}
+    nbase32 = tss_descriptor->u.tss386.base; // new TSS.base
+    new_TSS_max   = 103;
+    new_TSS_limit = tss_descriptor->u.tss386.limit_scaled;
+    }
+
+  // Task State Seg must be present, else #NP(TSS selector)
+  if (tss_descriptor->p==0) {
+    BX_INFO(("task_switch: TSS.p == 0\n"));
+    exception(BX_NP_EXCEPTION, tss_selector->value & 0xfffc, 0);
+    }
+
+  // TSS must have valid limit, else #TS(TSS selector)
+  if (tss_selector->ti ||
+      tss_descriptor->valid==0 ||
+      new_TSS_limit < new_TSS_max) {
+    BX_PANIC(("task_switch(): TR not valid\n"));
+    exception(BX_TS_EXCEPTION, tss_selector->value & 0xfffc, 0);
+    }
+
+  // Check that old TSS, new TSS, and all segment descriptors
+  // used in the task switch are paged in.
+  if (BX_CPU_THIS_PTR cr0.pg) {
+    //BX_RW, BX_READ, BX_WRITE
+    // Old TSS
+    (void) dtranslate_linear(nbase32, 0, /*rw*/ BX_WRITE);
+    (void) dtranslate_linear(nbase32+old_TSS_max, 0, /*rw*/ BX_WRITE);
+
+    // New TSS
+    (void) dtranslate_linear(nbase32, 0, /*rw*/ 0);
+    (void) dtranslate_linear(nbase32+new_TSS_max, 0, /*rw*/ 0);
+
+    // ??? fix RW above
+    // ??? touch old/new TSS descriptors here when necessary.
+    }
+
+  // Need to fetch all new registers and temporarily store them.
+
+  if (tss_descriptor->type <= 3) {
+    access_linear(nbase32 + 14, 2, 0, BX_READ, &temp16);
+      newEIP = temp16; // zero out upper word
+    access_linear(nbase32 + 16, 2, 0, BX_READ, &temp16);
+      newEFLAGS = temp16;
+
+    // incoming TSS is 16bit:
+    //   - upper word of general registers is set to 0xFFFF
+    //   - upper word of eflags is zero'd
+    //   - FS, GS are zero'd
+    //   - upper word of eIP is zero'd
+    access_linear(nbase32 + 18, 2, 0, BX_READ, &temp16);
+      newEAX = 0xffff0000 | temp16;
+    access_linear(nbase32 + 20, 2, 0, BX_READ, &temp16);
+      newECX = 0xffff0000 | temp16;
+    access_linear(nbase32 + 22, 2, 0, BX_READ, &temp16);
+      newEDX = 0xffff0000 | temp16;
+    access_linear(nbase32 + 24, 2, 0, BX_READ, &temp16);
+      newEBX = 0xffff0000 | temp16;
+    access_linear(nbase32 + 26, 2, 0, BX_READ, &temp16);
+      newESP = 0xffff0000 | temp16;
+    access_linear(nbase32 + 28, 2, 0, BX_READ, &temp16);
+      newEBP = 0xffff0000 | temp16;
+    access_linear(nbase32 + 30, 2, 0, BX_READ, &temp16);
+      newESI = 0xffff0000 | temp16;
+    access_linear(nbase32 + 32, 2, 0, BX_READ, &temp16);
+      newEDI = 0xffff0000 | temp16;
+
+    access_linear(nbase32 + 34, 2, 0, BX_READ, &raw_es_selector);
+    access_linear(nbase32 + 36, 2, 0, BX_READ, &raw_cs_selector);
+    access_linear(nbase32 + 38, 2, 0, BX_READ, &raw_ss_selector);
+    access_linear(nbase32 + 40, 2, 0, BX_READ, &raw_ds_selector);
+    access_linear(nbase32 + 42, 2, 0, BX_READ, &raw_ldt_selector);
+
+    raw_fs_selector = 0; // use a NULL selector
+    raw_gs_selector = 0; // use a NULL selector
+    // No CR3 change for 286 task switch
+    newCR3 = 0;   // keep compiler happy (not used)
+    trap_word = 0; // keep compiler happy (not used)
+    }
+  else {
+    access_linear(nbase32 + 0x1c, 4, 0, BX_READ, &newCR3);
+    access_linear(nbase32 + 0x20, 4, 0, BX_READ, &newEIP);
+    access_linear(nbase32 + 0x24, 4, 0, BX_READ, &newEFLAGS);
+    access_linear(nbase32 + 0x28, 4, 0, BX_READ, &newEAX);
+    access_linear(nbase32 + 0x2c, 4, 0, BX_READ, &newECX);
+    access_linear(nbase32 + 0x30, 4, 0, BX_READ, &newEDX);
+    access_linear(nbase32 + 0x34, 4, 0, BX_READ, &newEBX);
+    access_linear(nbase32 + 0x38, 4, 0, BX_READ, &newESP);
+    access_linear(nbase32 + 0x3c, 4, 0, BX_READ, &newEBP);
+    access_linear(nbase32 + 0x40, 4, 0, BX_READ, &newESI);
+    access_linear(nbase32 + 0x44, 4, 0, BX_READ, &newEDI);
+    access_linear(nbase32 + 0x48, 2, 0, BX_READ, &raw_es_selector);
+    access_linear(nbase32 + 0x4c, 2, 0, BX_READ, &raw_cs_selector);
+    access_linear(nbase32 + 0x50, 2, 0, BX_READ, &raw_ss_selector);
+    access_linear(nbase32 + 0x54, 2, 0, BX_READ, &raw_ds_selector);
+    access_linear(nbase32 + 0x58, 2, 0, BX_READ, &raw_fs_selector);
+    access_linear(nbase32 + 0x5c, 2, 0, BX_READ, &raw_gs_selector);
+    access_linear(nbase32 + 0x60, 2, 0, BX_READ, &raw_ldt_selector);
+    access_linear(nbase32 + 0x64, 2, 0, BX_READ, &trap_word);
+    // I/O Map Base Address ???
+    }
+
+#if 0
+if (ss_descriptor.u.segment.d_b && (tss_descriptor->type<9)) {
+  BX_DEBUG(( "++++++++++++++++++++++++++\n" ));
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+  exception(BX_SS_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+  //exception(BX_TS_EXCEPTION, tss_selector->value & 0xfffc, 0);
+  }
+#endif
+
+
+  //
+  // Step 6: If JMP or IRET, clear busy bit in old task TSS descriptor,
+  //         otherwise leave set.
+  //
+
+  // effect on Busy bit of old task
+  if ( (source==BX_TASK_FROM_JUMP) || (source==BX_TASK_FROM_IRET) ) {
+    // Bit is cleared
+    access_linear(BX_CPU_THIS_PTR gdtr.base +
+                  BX_CPU_THIS_PTR tr.selector.index*8 + 4,
+                  4, 0, BX_READ, &temp32);
+    temp32 &= ~0x00000200;
+    access_linear(BX_CPU_THIS_PTR gdtr.base +
+                  BX_CPU_THIS_PTR tr.selector.index*8 + 4,
+                  4, 0, BX_WRITE, &temp32);
+    }
+
+
+  //
+  // Step 7: If IRET, clear NT flag in temp image of EFLAGS, otherwise
+  //         leave alone.
+  //
+
+  if (source == BX_TASK_FROM_IRET) {
+    // NT flags in old task is cleared with an IRET
+    oldEFLAGS &= ~0x00004000;
+    }
+
+
+  //
+  // Step 8: Save dynamic state of old task.
+  //
+
+  if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
+    temp16 = IP; access_linear(obase32 + 14, 2, 0, BX_WRITE, &temp16);
+    temp16 = oldEFLAGS; access_linear(obase32 + 16, 2, 0, BX_WRITE, &temp16);
+    temp16 = AX; access_linear(obase32 + 18, 2, 0, BX_WRITE, &temp16);
+    temp16 = CX; access_linear(obase32 + 20, 2, 0, BX_WRITE, &temp16);
+    temp16 = DX; access_linear(obase32 + 22, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX; access_linear(obase32 + 24, 2, 0, BX_WRITE, &temp16);
+    temp16 = SP; access_linear(obase32 + 26, 2, 0, BX_WRITE, &temp16);
+    temp16 = BP; access_linear(obase32 + 28, 2, 0, BX_WRITE, &temp16);
+    temp16 = SI; access_linear(obase32 + 30, 2, 0, BX_WRITE, &temp16);
+    temp16 = DI; access_linear(obase32 + 32, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+                 access_linear(obase32 + 34, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+                 access_linear(obase32 + 36, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+                 access_linear(obase32 + 38, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+                 access_linear(obase32 + 40, 2, 0, BX_WRITE, &temp16);
+    }
+  else {
+    temp32 = EIP; access_linear(obase32 + 0x20, 4, 0, BX_WRITE, &temp32);
+    temp32 = oldEFLAGS; access_linear(obase32 + 0x24, 4, 0, BX_WRITE, &temp32);
+    temp32 = EAX; access_linear(obase32 + 0x28, 4, 0, BX_WRITE, &temp32);
+    temp32 = ECX; access_linear(obase32 + 0x2c, 4, 0, BX_WRITE, &temp32);
+    temp32 = EDX; access_linear(obase32 + 0x30, 4, 0, BX_WRITE, &temp32);
+    temp32 = EBX; access_linear(obase32 + 0x34, 4, 0, BX_WRITE, &temp32);
+    temp32 = ESP; access_linear(obase32 + 0x38, 4, 0, BX_WRITE, &temp32);
+    temp32 = EBP; access_linear(obase32 + 0x3c, 4, 0, BX_WRITE, &temp32);
+    temp32 = ESI; access_linear(obase32 + 0x40, 4, 0, BX_WRITE, &temp32);
+    temp32 = EDI; access_linear(obase32 + 0x44, 4, 0, BX_WRITE, &temp32);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+                  access_linear(obase32 + 0x48, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+                  access_linear(obase32 + 0x4c, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+                  access_linear(obase32 + 0x50, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+                  access_linear(obase32 + 0x54, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+                  access_linear(obase32 + 0x58, 2, 0, BX_WRITE, &temp16);
+    temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+                  access_linear(obase32 + 0x5c, 2, 0, BX_WRITE, &temp16);
+    }
+
+
+
+  //
+  // Commit point.  At this point, we commit to the new
+  // context.  If an unrecoverable error occurs in further
+  // processing, we complete the task switch without performing
+  // additional access and segment availablility checks and
+  // generate the appropriate exception prior to beginning
+  // execution of the new task.
+  //
+
+
+  // Task switch clears LE/L3/L2/L1/L0 in DR7
+  BX_CPU_THIS_PTR dr7 &= ~0x00000155;
+
+
+// effect on link field of new task
+if ( source==BX_TASK_FROM_CALL_OR_INT ) {
+  // set to selector of old task's TSS
+  temp16 = BX_CPU_THIS_PTR tr.selector.value;
+  access_linear(nbase32 + 0, 2, 0, BX_WRITE, &temp16);
+  }
+
+
+
+  //
+  // Step 9: If call or interrupt, set the NT flag in the eflags
+  //         image stored in new task's TSS.  If IRET or JMP,
+  //         NT is restored from new TSS eflags image. (no change)
+  //
+
+  // effect on NT flag of new task
+  if ( source==BX_TASK_FROM_CALL_OR_INT ) {
+    newEFLAGS |= 0x4000; // flag is set
+    }
+
+
+  //
+  // Step 10: If CALL, interrupt, or JMP, set busy flag in new task's
+  //          TSS descriptor.  If IRET, leave set.
+  //
+
+  if ( (source==BX_TASK_FROM_JUMP) || (source==BX_TASK_FROM_CALL_OR_INT) ) {
+    // set the new task's busy bit
+    access_linear(BX_CPU_THIS_PTR gdtr.base + tss_selector->index*8 + 4,
+                  4, 0, BX_READ, &dword2);
+    dword2 |= 0x00000200;
+    access_linear(BX_CPU_THIS_PTR gdtr.base + tss_selector->index*8 + 4,
+                  4, 0, BX_WRITE, &dword2);
+    }
+
+
+  //
+  // Step 11: Set TS flag in the CR0 image stored in the new task TSS.
+  //
+
+  // set TS bit in CR0 register
+  BX_CPU_THIS_PTR cr0.ts = 1;
+  BX_CPU_THIS_PTR cr0.val32 |= 0x00000008;
+
+
+  //
+  // Step 12: Load the task register with the segment selector and
+  //          descriptor for the new task TSS.
+  //
+
+  BX_CPU_THIS_PTR tr.selector = *tss_selector;
+  BX_CPU_THIS_PTR tr.cache    = *tss_descriptor;
+
+
+  //
+  // Step 13: Load the new task (dynamic) state from new TSS.
+  //          Any errors associated with loading and qualification of
+  //          segment descriptors in this step occur in the new task's
+  //          context.  State loaded here includes LDTR, CR3,
+  //          EFLAGS, EIP, general purpose registers, and segment
+  //          descriptor parts of the segment registers.
+  //
+
+  if (tss_descriptor->type >= 9) {
+    CR3_change(newCR3); // Tell paging unit about new cr3 value
+    BX_INSTR_TLB_CNTRL(BX_INSTR_TASKSWITCH, newCR3);
+    }
+
+  BX_CPU_THIS_PTR prev_eip = EIP = newEIP;
+  write_eflags(newEFLAGS, 1,1,1,1);
+  EAX = newEAX;
+  ECX = newECX;
+  EDX = newEDX;
+  EBX = newEBX;
+  ESP = newESP;
+  EBP = newEBP;
+  ESI = newESI;
+  EDI = newEDI;
+
+  // Fill in selectors for all segment registers.  If errors
+  // occur later, the selectors will at least be loaded.
+  parse_selector(raw_es_selector, &es_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector = es_selector;
+  parse_selector(raw_cs_selector, &cs_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector = cs_selector;
+  parse_selector(raw_ss_selector, &ss_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector = ss_selector;
+  parse_selector(raw_ds_selector, &ds_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector = ds_selector;
+  parse_selector(raw_fs_selector, &fs_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector = fs_selector;
+  parse_selector(raw_gs_selector, &gs_selector);
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector = gs_selector;
+  parse_selector(raw_ldt_selector, &ldt_selector);
+  BX_CPU_THIS_PTR ldtr.selector                 = ldt_selector;
+
+  // Start out with invalid descriptor caches, fill in
+  // with values only as they are validated.
+  BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+
+
+// need to test valid bit in fetch_raw_descriptor?()
+// or set limit to 0 instead when LDT is loaded with
+// null. ??? +++
+BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0;
+
+  // LDTR
+  if (ldt_selector.ti) {
+    // LDT selector must be in GDT
+    BX_INFO(("task_switch: bad LDT selector TI=1\n"));
+    exception_no = BX_TS_EXCEPTION;
+    error_code   = raw_ldt_selector & 0xfffc;
+    goto post_exception;
+    }
+
+// ??? is LDT loaded in v8086 mode
+  if ( (raw_ldt_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&ldt_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad LDT fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ldt_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &ldt_descriptor);
+
+    // LDT selector of new task is valid, else #TS(new task's LDT)
+    if (ldt_descriptor.valid==0 ||
+        ldt_descriptor.type!=2 ||
+        ldt_descriptor.segment ||
+        ldt_descriptor.u.ldt.limit<7) {
+      BX_INFO(("task_switch: bad LDT segment\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ldt_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    // LDT of new task is present in memory, else #TS(new tasks's LDT)
+    else if (ldt_descriptor.p==0) {
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ldt_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in LDTR shadow cache
+    BX_CPU_THIS_PTR ldtr.cache = ldt_descriptor;
+    }
+  else {
+    // NULL LDT selector is OK, leave cache invalid
+    }
+
+  if (v8086_mode()) {
+    // load seg regs as 8086 registers
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], raw_cs_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], raw_ss_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], raw_ds_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], raw_es_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], raw_fs_selector);
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], raw_gs_selector);
+    }
+  else {
+
+  // CS
+  if ( (raw_cs_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&cs_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad CS fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_cs_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &cs_descriptor);
+
+    // CS descriptor AR byte must indicate code segment else #TS(CS)
+    if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
+        cs_descriptor.u.segment.executable==0) {
+      BX_PANIC(("task_switch: CS not valid executable seg\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_cs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if non-conforming then DPL must equal selector RPL else #TS(CS)
+    else if (cs_descriptor.u.segment.c_ed==0 &&
+        cs_descriptor.dpl!=cs_selector.rpl) {
+      BX_INFO(("task_switch: non-conforming: CS.dpl!=CS.RPL\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_cs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if conforming then DPL must be <= selector RPL else #TS(CS)
+    else if (cs_descriptor.u.segment.c_ed &&
+        cs_descriptor.dpl>cs_selector.rpl) {
+      BX_INFO(("task_switch: conforming: CS.dpl>RPL\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_cs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // Code segment is present in memory, else #NP(new code segment)
+    else if (cs_descriptor.p==0) {
+      BX_PANIC(("task_switch: CS.p==0\n"));
+      exception_no = BX_NP_EXCEPTION;
+      error_code   = raw_cs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache    = cs_descriptor;
+    }
+  else {
+    // If new cs selector is null #TS(CS)
+    BX_PANIC(("task_switch: CS NULL\n"));
+    exception_no = BX_TS_EXCEPTION;
+    error_code   = raw_cs_selector & 0xfffc;
+    goto post_exception;
+    }
+
+
+  // SS
+  if ( (raw_ss_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&ss_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad SS fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &ss_descriptor);
+    // SS selector must be within its descriptor table limits else #TS(SS)
+    // SS descriptor AR byte must must indicate writable data segment,
+    // else #TS(SS)
+    if (ss_descriptor.valid==0 ||
+        ss_descriptor.segment==0 ||
+        ss_descriptor.u.segment.executable ||
+        ss_descriptor.u.segment.r_w==0) {
+      BX_INFO(("task_switch: SS not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    //
+    // Stack segment is present in memory, else #SF(new stack segment)
+    //
+    else if (ss_descriptor.p==0) {
+      BX_PANIC(("task_switch: SS not present\n"));
+      exception_no = BX_SS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    // Stack segment DPL matches CS.RPL, else #TS(new stack segment)
+    else if (ss_descriptor.dpl != cs_selector.rpl) {
+      BX_PANIC(("task_switch: SS.rpl != CS.RPL\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    // Stack segment DPL matches selector RPL, else #TS(new stack segment)
+    else if (ss_descriptor.dpl != ss_selector.rpl) {
+      BX_PANIC(("task_switch: SS.dpl != SS.rpl\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+
+#if 0
+    // +++
+    else if (ss_descriptor.u.segment.d_b && (tss_descriptor->type<9)) {
+      BX_DEBUG(( "++++++++++++++++++++++++++\n" ));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ss_selector & 0xfffc;
+      goto post_exception;
+      }
+#endif
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache    = ss_descriptor;
+    }
+  else {
+    // SS selector is valid, else #TS(new stack segment)
+    BX_PANIC(("task_switch: SS NULL\n"));
+    exception_no = BX_TS_EXCEPTION;
+    error_code   = raw_ss_selector & 0xfffc;
+    goto post_exception;
+    }
+
+
+  //   if new selector is not null then perform following checks:
+  //     index must be within its descriptor table limits else #TS(selector)
+  //     AR byte must indicate data or readable code else #TS(selector)
+  //     if data or non-conforming code then:
+  //       DPL must be >= CPL else #TS(selector)
+  //       DPL must be >= RPL else #TS(selector)
+  //     AR byte must indicate PRESENT else #NP(selector)
+  //     load cache with new segment descriptor and set valid bit
+
+
+
+  // DS
+  if ( (raw_ds_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&ds_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad DS fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ds_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &ds_descriptor);
+    if (ds_descriptor.valid==0 || ds_descriptor.segment==0 ||
+        (ds_descriptor.u.segment.executable &&
+         ds_descriptor.u.segment.r_w==0)) {
+      BX_PANIC(("task_switch: DS not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ds_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if data or non-conforming code
+    else if (ds_descriptor.type<12 &&
+        (ds_descriptor.dpl<cs_selector.rpl ||
+         ds_descriptor.dpl<ds_selector.rpl)) {
+      BX_PANIC(("task_switch: DS.dpl not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_ds_selector & 0xfffc;
+      goto post_exception;
+      }
+    else if (ds_descriptor.p==0) {
+      BX_PANIC(("task_switch: DS.p==0\n"));
+      exception_no = BX_NP_EXCEPTION;
+      error_code   = raw_ds_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache    = ds_descriptor;
+    }
+  else {
+    // NULL DS selector is OK, leave cache invalid
+    }
+
+  // ES
+  if ( (raw_es_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&es_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad ES fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_es_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &es_descriptor);
+    if (es_descriptor.valid==0 || es_descriptor.segment==0 ||
+        (es_descriptor.u.segment.executable &&
+         es_descriptor.u.segment.r_w==0)) {
+      BX_PANIC(("task_switch: ES not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_es_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if data or non-conforming code
+    else if (es_descriptor.type<12 &&
+        (es_descriptor.dpl<cs_selector.rpl ||
+         es_descriptor.dpl<es_selector.rpl)) {
+      BX_PANIC(("task_switch: ES.dpl not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_es_selector & 0xfffc;
+      goto post_exception;
+      }
+    else if (es_descriptor.p==0) {
+      BX_PANIC(("task_switch: ES.p==0\n"));
+      exception_no = BX_NP_EXCEPTION;
+      error_code   = raw_es_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache    = es_descriptor;
+    }
+  else {
+    // NULL ES selector is OK, leave cache invalid
+    }
+
+
+  // FS
+  if ( (raw_fs_selector & 0xfffc) != 0 ) { // not NULL
+    Boolean good;
+    good = fetch_raw_descriptor2(&fs_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad FS fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_fs_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &fs_descriptor);
+    if (fs_descriptor.valid==0 || fs_descriptor.segment==0 ||
+        (fs_descriptor.u.segment.executable &&
+         fs_descriptor.u.segment.r_w==0)) {
+      BX_PANIC(("task_switch: FS not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_fs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if data or non-conforming code
+    else if (fs_descriptor.type<12 &&
+        (fs_descriptor.dpl<cs_selector.rpl ||
+         fs_descriptor.dpl<fs_selector.rpl)) {
+      BX_PANIC(("task_switch: FS.dpl not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_fs_selector & 0xfffc;
+      goto post_exception;
+      }
+    else if (fs_descriptor.p==0) {
+      BX_PANIC(("task_switch: FS.p==0\n"));
+      exception_no = BX_NP_EXCEPTION;
+      error_code   = raw_fs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache    = fs_descriptor;
+    }
+  else {
+    // NULL FS selector is OK, leave cache invalid
+    }
+
+  // GS
+  if ( (raw_gs_selector & 0xfffc) != 0 ) {
+    Boolean good;
+    good = fetch_raw_descriptor2(&gs_selector, &dword1, &dword2);
+    if (!good) {
+      BX_INFO(("task_switch: bad GS fetch\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_gs_selector & 0xfffc;
+      goto post_exception;
+      }
+
+    parse_descriptor(dword1, dword2, &gs_descriptor);
+    if (gs_descriptor.valid==0 || gs_descriptor.segment==0 ||
+        (gs_descriptor.u.segment.executable &&
+         gs_descriptor.u.segment.r_w==0)) {
+      BX_PANIC(("task_switch: GS not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_gs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // if data or non-conforming code
+    else if (gs_descriptor.type<12 &&
+        (gs_descriptor.dpl<cs_selector.rpl ||
+         gs_descriptor.dpl<gs_selector.rpl)) {
+      BX_PANIC(("task_switch: GS.dpl not valid\n"));
+      exception_no = BX_TS_EXCEPTION;
+      error_code   = raw_gs_selector & 0xfffc;
+      goto post_exception;
+      }
+    else if (gs_descriptor.p==0) {
+      BX_PANIC(("task_switch: GS.p==0\n"));
+      //exception(BX_NP_EXCEPTION, raw_gs_selector & 0xfffc, 0);
+      exception_no = BX_NP_EXCEPTION;
+      error_code   = raw_gs_selector & 0xfffc;
+      goto post_exception;
+      }
+    // All checks pass, fill in shadow cache
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache    = gs_descriptor;
+    }
+  else {
+    // NULL GS selector is OK, leave cache invalid
+    }
+
+    }
+
+
+  if ((tss_descriptor->type>=9) && (trap_word & 0x0001)) {
+    BX_CPU_THIS_PTR debug_trap |= 0x00008000; // BT flag in DR6
+    BX_CPU_THIS_PTR async_event = 1; // so processor knows to check
+    BX_INFO(("task_switch: T bit set in new TSS.\n"));
+    }
+
+
+
+  //
+  // Step 14: Begin execution of new task.
+  //
+//BX_DEBUG(( "TASKING: LEAVE\n" ));
+  return;
+
+post_exception:
+  BX_CPU_THIS_PTR debug_trap = 0;
+  BX_CPU_THIS_PTR inhibit_mask = 0;
+  BX_INFO(("task switch: posting exception %u after commit point\n",
+    exception_no));
+  exception(exception_no, error_code, 0);
+  return;
+}
+
+
+  void
+BX_CPU_C::get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp)
+{
+  if (BX_CPU_THIS_PTR tr.cache.valid==0)
+    BX_PANIC(("get_SS_ESP_from_TSS: TR.cache invalid\n"));
+
+  if (BX_CPU_THIS_PTR tr.cache.type==9) {
+    // 32-bit TSS
+    Bit32u TSSstackaddr;
+
+    TSSstackaddr = 8*pl + 4;
+    if ( (TSSstackaddr+7) >
+         BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled )
+      exception(BX_TS_EXCEPTION,
+                BX_CPU_THIS_PTR tr.selector.value & 0xfffc, 0);
+
+    access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base +
+      TSSstackaddr+4, 2, 0, BX_READ, ss);
+    access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base +
+      TSSstackaddr,   4, 0, BX_READ, esp);
+    }
+  else if (BX_CPU_THIS_PTR tr.cache.type==1) {
+    // 16-bit TSS
+    Bit16u temp16;
+    Bit32u TSSstackaddr;
+
+    TSSstackaddr = 4*pl + 2;
+    if ( (TSSstackaddr+4) > BX_CPU_THIS_PTR tr.cache.u.tss286.limit )
+      exception(BX_TS_EXCEPTION,
+                BX_CPU_THIS_PTR tr.selector.value & 0xfffc, 0);
+
+    access_linear(BX_CPU_THIS_PTR tr.cache.u.tss286.base +
+      TSSstackaddr+2, 2, 0, BX_READ, ss);
+    access_linear(BX_CPU_THIS_PTR tr.cache.u.tss286.base +
+      TSSstackaddr,   2, 0, BX_READ, &temp16);
+    *esp = temp16; // truncate
+    }
+  else {
+    BX_PANIC(("get_SS_ESP_from_TSS: TR is bogus type (%u)\n",
+             (unsigned) BX_CPU_THIS_PTR tr.cache.type));
+    }
+}
+#endif
+
+
+
+#else  // BX_SUPPORT_TASKING
+
+
+// for non-support of hardware tasking
+
+#if BX_CPU_LEVEL >= 2
+  /* corresponds to SWITCH_TASKS algorithm in Intel documentation */
+  void
+BX_CPU_C::task_switch(bx_selector_t *selector,
+                 bx_descriptor_t *descriptor, unsigned source,
+                 Bit32u dword1, Bit32u dword2)
+{
+  UNUSED(selector);
+  UNUSED(descriptor);
+  UNUSED(source);
+  UNUSED(dword1);
+  UNUSED(dword2);
+
+  BX_INFO(("task_switch(): not complete\n"));
+}
+
+  void
+BX_CPU_C::get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp)
+{
+}
+#endif
+
+
+#endif // BX_SUPPORT_TASKING
diff --git a/sid/component/bochs/cpu/vm8086.cc b/sid/component/bochs/cpu/vm8086.cc
new file mode 100644 (file)
index 0000000..71f4fc4
--- /dev/null
@@ -0,0 +1,301 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+// Notes:
+//
+// The high bits of the 32bit eip image are ignored by
+// the IRET to VM.  The high bits of the 32bit esp image
+// are loaded into ESP.  A subsequent push uses
+// only the low 16bits since it's in VM.  In neither case
+// did a protection fault occur during actual tests.  This
+// is contrary to the Intel docs which claim a #GP for
+// eIP out of code limits.
+//
+// IRET to VM does affect IOPL, IF, VM, and RF
+
+
+#if BX_SUPPORT_V8086_MODE
+
+
+#if BX_CPU_LEVEL >= 3
+
+
+  void
+BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
+                              Bit32u flags32)
+{
+  Bit32u temp_ESP, new_esp, esp_laddr;
+  Bit16u raw_es_selector, raw_ds_selector, raw_fs_selector,
+         raw_gs_selector, raw_ss_selector;
+
+
+  // Must be 32bit effective opsize, VM is in upper 16bits of eFLAGS
+  // CPL = 0 to get here
+
+  // ----------------
+  // |     | OLD GS | eSP+32
+  // |     | OLD FS | eSP+28
+  // |     | OLD DS | eSP+24
+  // |     | OLD ES | eSP+20
+  // |     | OLD SS | eSP+16
+  // |  OLD ESP     | eSP+12
+  // | OLD EFLAGS   | eSP+8
+  // |     | OLD CS | eSP+4
+  // |  OLD EIP     | eSP+0
+  // ----------------
+
+  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+    temp_ESP = ESP;
+  else
+    temp_ESP = SP;
+
+  // top 36 bytes of stack must be within stack limits, else #GP(0)
+  if ( !can_pop(36) ) {
+    BX_PANIC(("iret: VM: top 36 bytes not within limits\n"));
+    exception(BX_SS_EXCEPTION, 0, 0);
+    return;
+    }
+
+  if ( new_eip & 0xffff0000 ) {
+    BX_INFO(("IRET to V86-mode: ignoring upper 16-bits\n"));
+    new_eip = new_eip & 0xffff;
+    }
+
+  esp_laddr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base +
+              temp_ESP;
+
+  // load SS:ESP from stack
+  access_linear(esp_laddr + 12, 4, 0, BX_READ, &new_esp);
+  access_linear(esp_laddr + 16, 2, 0, BX_READ, &raw_ss_selector);
+
+  // load ES,DS,FS,GS from stack
+  access_linear(esp_laddr + 20, 2, 0, BX_READ, &raw_es_selector);
+  access_linear(esp_laddr + 24, 2, 0, BX_READ, &raw_ds_selector);
+  access_linear(esp_laddr + 28, 2, 0, BX_READ, &raw_fs_selector);
+  access_linear(esp_laddr + 32, 2, 0, BX_READ, &raw_gs_selector);
+
+  write_eflags(flags32, /*change IOPL*/ 1, /*change IF*/ 1,
+                  /*change VM*/ 1, /*change RF*/ 1);
+
+  // load CS:EIP from stack; already read and passed as args
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = raw_cs_selector;
+  EIP = new_eip;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = raw_es_selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = raw_ds_selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = raw_fs_selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = raw_gs_selector;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = raw_ss_selector;
+  ESP = new_esp; // Full 32bits are loaded.
+
+  init_v8086_mode();
+}
+
+
+  void
+BX_CPU_C::stack_return_from_v86(BxInstruction_t *i)
+{
+  //BX_INFO(("stack_return_from_v86:\n"));
+  exception(BX_GP_EXCEPTION, 0, 0);
+
+#if 0
+  if (IOPL != 3) {
+    // trap to virtual 8086 monitor
+    BX_INFO(("stack_return_from_v86: IOPL != 3\n"));
+    exception(BX_GP_EXCEPTION, 0, 0);
+    }
+
+  if (i->os_32) {
+    Bit32u eip, ecs_raw, eflags;
+
+// ??? should be some stack checks here
+    pop_32(&eip);
+    pop_32(&ecs_raw);
+    pop_32(&eflags);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+    BX_CPU_THIS_PTR eip = eip;
+    write_eflags(eflags, /*IOPL*/ CPL==0, /*IF*/ 1, /*VM*/ 0, /*RF*/ 1);
+    }
+  else {
+    Bit16u ip, cs_raw, flags;
+
+// ??? should be some stack checks here
+    pop_16(&ip);
+    pop_16(&cs_raw);
+    pop_16(&flags);
+
+    load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+    BX_CPU_THIS_PTR eip = (Bit32u) ip;
+    write_flags(flags, /*IOPL*/ CPL==0, /*IF*/ 1);
+    }
+#endif
+}
+
+
+  void
+BX_CPU_C::init_v8086_mode(void)
+{
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable   = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl                 = 3;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable   = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl                 = 3;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable   = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl                 = 3;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable   = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl                 = 3;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable   = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl                 = 3;
+
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid                  = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p                      = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl                    = 3;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment                = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable   = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed         = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w          = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a            = 1;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base         =
+    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value << 4;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit        = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled = 0xffff;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g            = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl          = 0;
+  BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl                 = 3;
+}
+
+
+#endif /* BX_CPU_LEVEL >= 3 */
+
+
+
+
+
+#else  // BX_SUPPORT_V8086_MODE
+
+// non-support of v8086 mode
+
+  void
+BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32)
+{
+  BX_INFO(("stack_return_to_v86: VM bit set in EFLAGS stack image\n"));
+  v8086_message();
+}
+
+  void
+BX_CPU_C::stack_return_from_v86(BxInstruction_t *i)
+{
+  BX_INFO(("stack_return_from_v86:\n"));
+  v8086_message();
+}
+
+  void
+BX_CPU_C::v8086_message(void)
+{
+  BX_INFO(("Program compiled with BX_SUPPORT_V8086_MODE = 0\n"));
+  BX_INFO(("You need to rerun the configure script and recompile\n"));
+  BX_INFO(("  to use virtual-8086 mode features.\n"));
+  BX_PANIC(("Bummer!\n"));
+}
+#endif // BX_SUPPORT_V8086_MODE
diff --git a/sid/component/bochs/cpu/x86-memory-modes.cc b/sid/component/bochs/cpu/x86-memory-modes.cc
new file mode 100644 (file)
index 0000000..96a7cc6
--- /dev/null
@@ -0,0 +1,407 @@
+//  x86-memory-modes.cc - set up protected mode. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#include "x86.h"
+
+void x86_cpu::enter_protected_mode()
+{
+  if (memory_mode == "default")
+  {
+    // This mode sets all segment bases to 0x0, and sets all
+    //   limits to 0xfffff
+    // create a global descriptor table in memory:
+    // null descriptor:
+    for(int i = 0; i < 16; i += 4)
+      write_data_memory_4(0x0, i, 0x0);
+    
+    // CS descriptor:
+    write_data_memory_4(0x0, 0x0010, 0xffff0000);
+    write_data_memory_4(0x0, 0x0014, 0x009b4f00);
+    
+    // DS descriptor:
+    write_data_memory_4(0x0, 0x0018, 0xffff0000);
+    write_data_memory_4(0x0, 0x001c, 0x00934f00);
+
+        // CS (Code Segment) selector and descriptor in bochs representation:
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.value =     0x0010;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.index =     0x0002;
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.executable   = 1; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit        =     0xfffff;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =     0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.g   = 0; /* byte granular */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+        // DS (Data Segment) selector and descriptor in bochs representation:
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.index =     0x0003;
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.executable   = 0; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit        =     0xfffff; // 2000
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =     0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.g   = 0; /* byte granular */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+      /* ES (Extra Segment) and descriptor cache */
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =     0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.g   = 0; /* byte granular */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+    /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.value =     0x0018;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.g   = 0; /* byte granular */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.value =     0x0018;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.g   = 0; /* byte granular */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+      /* SS (Stack Segment) and descriptor cache */
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.index =     0x0003;
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.executable   = 0; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit        =     0xfffff;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =     0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.g   = 0; /* byte granular */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+        /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.gdtr.base         = 0x00000000;  
+    bx_cpu.gdtr.limit        =     0x001f;  
+#endif
+        // set PE bit in CR0 so that protected mode is enabled
+    bx_cpu.SetCR0(0x01);
+
+  }
+  else if (memory_mode == "cygmon")
+  {
+    // support for initial cygmon memory layout
+
+    // this section simulates the Cygmon rom monitor startup code 
+    
+    // create a global descriptor table in memory:
+    // null descriptor:
+    for(int i = 0; i < 16; i += 4)
+      write_data_memory_4(0x0, i, 0x0);
+
+       // CS descriptor:
+    write_data_memory_4(0x0, 0x10, 0xffff0000);
+    write_data_memory_4(0x0, 0x14, 0x009bcf00);
+
+        // DS descriptor:
+    write_data_memory_4(0x0, 0x18, 0xffff0000);
+    write_data_memory_4(0x0, 0x1c, 0x0093cf00);
+
+    // CS (Code Segment) selector and descriptor in bochs representation:
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.value =     0x0010;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.index =     0x0002;
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.executable   = 1; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit        =     0xfffff;
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =     0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.g   = 1; /* 4Kb granular */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+        // DS (Data Segment) selector and descriptor in bochs representation:
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.index =     0x0003;
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.executable   = 0; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit        =     0xfffff; // 2000
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =     0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.g   = 1; /* 4Kb granular */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+      /* ES (Extra Segment) and descriptor cache */
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =     0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.g   = 1; /* 4Kb granular */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+    /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.value =     0x0018;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =     0xffffffff;
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.g   = 1; /* 4Kb granular */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+  /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.value =     0x0018;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.index =     0x0003;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.ti = 0;
+  bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.valid =     1;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.p = 1;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.dpl = 0;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.executable   = 0; /* data/stack segment */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.c_ed         = 0; /* normal expand up */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.r_w          = 1; /* writeable */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.a            = 1; /* accessed */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.base         = 0x00000000;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit        =     0xfffff;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =     0xffffffff;
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.g   = 1; /* 4Kb granular */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 1; /* 32bit default size */
+  bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+      /* SS (Stack Segment) and descriptor cache */
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.value =     0x0018;
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.index =     0x0003;
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.ti = 0;
+    bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl = 0;
+    
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.valid =     1;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.p = 1;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.dpl = 0;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+    
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.executable   = 0; /* data/stack segment */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.c_ed         = 0; /* normal expand up */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.r_w          = 1; /* writeable */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.a            = 1; /* accessed */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.base         = 0x00000000;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit        =     0xfffff;
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =     0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.g   = 1; /* 4Kb granular */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32bit default size */
+    bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+    // 
+        /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+    bx_cpu.gdtr.base         = 0x00000000;  
+    bx_cpu.gdtr.limit        =     0x001f;  
+#endif
+        // set PE bit in CR0 so that protected mode is enabled
+    bx_cpu.SetCR0(0x01);
+  }
+  else
+  {
+    cerr << "hw-cpu-x86: unsupported memory mode" << endl;
+  }
+}
diff --git a/sid/component/bochs/cpu/x86.cc b/sid/component/bochs/cpu/x86.cc
new file mode 100644 (file)
index 0000000..edecc7b
--- /dev/null
@@ -0,0 +1,176 @@
+//  x86.cc - member function implementations for the x86 sid component. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#include "x86.h"
+
+x86_cpu::x86_cpu () :
+    memory_mode("default"),
+    blocking_on_syscall(false),
+    verbose_p(false)
+{
+  bx_mem.sid_cpu = this;
+  bx_cpu.sid_cpu = this;
+  
+  bx_cpu.init(&bx_mem);
+
+  // set up registers for use by gloss component.
+  // see libgloss/i386/* for calling conventions
+  // and exception-sid.cc for handling of int 0x80
+  this->add_watchable_register (string("syscall-arg0"), &bx_cpu.gen_reg[0].erx);
+  this->add_watchable_register (string("syscall-arg1"), &bx_cpu.gen_reg[3].erx);
+  this->add_watchable_register (string("syscall-arg2"), &bx_cpu.gen_reg[1].erx);
+  this->add_watchable_register (string("syscall-arg3"), &bx_cpu.gen_reg[2].erx);
+  this->add_watchable_register (string("syscall-result"), &bx_cpu.gen_reg[0].erx);
+  
+  this->add_watchable_register (string("syscall-trap"), &bx_cpu.gen_reg[0].erx);    
+  this->add_watchable_register (string("syscall-error"), &syscall_error);
+
+  // set up debugging interface
+  // there are 16 integer registers
+  create_gdb_register_attrs (16, "4;5;8;9", & this->bx_cpu.eip);
+  
+  this->add_attribute ("enable-warnings?", & warnings_enabled, "setting");
+  this->add_attribute ("memory-mode", & memory_mode, "setting");
+  this->add_attribute("verbose?", &this->verbose_p, "setting");
+}
+
+void x86_cpu::do_syscall()
+{
+    sid::host_int_4 tempAX = bx_cpu.gen_reg[0].erx;
+    sid::host_int_4 tempBX = bx_cpu.gen_reg[3].erx;
+    sid::host_int_4 tempCX = bx_cpu.gen_reg[1].erx;
+    sid::host_int_4 tempDX = bx_cpu.gen_reg[2].erx;
+        
+    sidutil::cpu_trap_disposition whatnext = signal_trap(sidutil::cpu_trap_software, bx_cpu.gen_reg[0].erx);
+
+    switch (whatnext)
+    {
+      case sidutil::cpu_trap_unhandled:
+          cerr << "hw-cpu-x86: cpu syscall trap unhandled" << endl;
+          this->blocking_on_syscall = false;
+          return;
+      case sidutil::cpu_trap_reissue:
+          bx_cpu.gen_reg[0].erx = tempAX;
+          bx_cpu.gen_reg[3].erx = tempBX;
+          bx_cpu.gen_reg[1].erx = tempCX;
+          bx_cpu.gen_reg[2].erx = tempDX;
+          this->blocking_on_syscall = true;
+          return;
+      case sidutil::cpu_trap_skip:
+          /* fall-through */
+      case sidutil::cpu_trap_handled:
+          this->blocking_on_syscall = false;
+          return;
+      default:
+          abort ();
+    }
+    this->yield();
+    throw sidutil::cpu_exception();
+}
+
+void x86_cpu::do_breakpoint()
+{
+    sidutil::cpu_trap_disposition whatnext = signal_trap(sidutil::cpu_trap_breakpoint, 0);
+
+    switch (whatnext)
+    {
+      case sidutil::cpu_trap_unhandled:
+          cerr << "hw-cpu-x86: cpu breakpoint trap unhandled" << endl;
+          break;
+
+      case sidutil::cpu_trap_skip:
+      case sidutil::cpu_trap_handled:
+      case sidutil::cpu_trap_reissue:
+          break;
+
+      default:
+          abort();
+    }
+    this->yield();
+    throw sidutil::cpu_exception();
+}
+
+void x86_cpu::step_insns () {
+    try {
+        if (!this->blocking_on_syscall)
+            bx_cpu.cpu_loop(1);
+        else
+            do_syscall();
+    }
+    catch (sidutil::cpu_exception& t)
+    {
+        this->yield();
+    }
+
+    if (this->enable_step_trap_p) 
+        this->signal_trap (sidutil::cpu_trap_stepped);
+}
+
+void x86_cpu::reset () {
+    bx_cpu.reset(BX_RESET_HARDWARE);
+
+    enter_protected_mode();
+}
+
+void x86_cpu::flush_icache () {
+    bx_cpu.invalidate_prefetch_q();
+}
+
+void x86_cpu::set_pc (sid::host_int_4 value) {
+        // FIXME: this should check if we're using the extended (32-bit)
+        // instruction pointer or the 16-bit one
+    bx_cpu.eip = value - bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base;
+}
+
+string x86_cpu::dbg_get_reg(unsigned int reg)
+{
+    string attr;
+    sid::host_int_4 val;
+    val = bx_cpu.dbg_get_reg(reg + 10);
+
+    // Change to "target endian".
+    sid::little_int_4 v = val;
+    for (unsigned i = 0; i < 4; i++)
+        attr += v.read_byte (i);
+
+    if (verbose_p)
+        cerr << "dbg_get_reg: reg = " << reg << endl;
+    
+    return attr;
+}
+
+sid::component::status x86_cpu::dbg_set_reg(unsigned int reg, const string &attr)
+{
+    // change from "target endian"
+    sid::little_int_4 v;
+    for (unsigned i = 0; i < 4; i++)
+        v.write_byte (i, attr[i]);
+    sid::host_int_4 val = v;
+
+    if (verbose_p)
+    {
+        cerr << "dbg_set_reg: reg = " << reg;
+        fprintf(stderr, " val = %p\n", val);
+    }
+    
+    if(bx_cpu.dbg_set_reg(reg + 10, val))
+        return sid::component::ok;
+    else
+        return sid::component::bad_value;
+}
+
diff --git a/sid/component/bochs/cpu/x86.h b/sid/component/bochs/cpu/x86.h
new file mode 100644 (file)
index 0000000..8f991f2
--- /dev/null
@@ -0,0 +1,60 @@
+//  x86.h - x86_cpu class declaration for the x86 sid component. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#ifndef __X86_H__
+#define __X86_H__ 1
+#include "sidcomp.h"
+#include "sidcpuutil.h"
+#include "bochs.h"
+#include "memory-sid.h"
+#include "cpu-sid.h"
+
+#define X86_CPU_DEBUG 0
+
+class x86_cpu : public sidutil::basic_bi_endian_cpu {
+    friend void sid_mem_c::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+    friend void sid_mem_c::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+  public:
+    sid_cpu_c bx_cpu;
+    sid_mem_c bx_mem;
+
+    sid::host_int_4 syscall_error;
+
+    bool warnings_enabled;
+    bool blocking_on_syscall;
+    bool verbose_p;
+    
+    x86_cpu ();
+
+    void do_syscall();
+    void do_breakpoint();
+
+    void step_insns ();
+    void reset ();
+    void flush_icache ();
+    void set_pc (sid::host_int_4 value);
+    string dbg_get_reg(unsigned int);
+    sid::component::status dbg_set_reg(unsigned int, const string &);
+  private:
+    string memory_mode;
+    
+    void enter_protected_mode();
+    
+};
+
+#endif // __X86_H__
diff --git a/sid/component/bochs/debug/debug.h b/sid/component/bochs/debug/debug.h
new file mode 100644 (file)
index 0000000..c612621
--- /dev/null
@@ -0,0 +1,413 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+// if including from C parser, need basic types etc
+#include "config.h"
+#if BX_DEBUGGER
+#include "osdep.h"
+#endif
+#if BX_USE_LOADER
+#include "loader_misc.h"
+void bx_dbg_loader(char *path, bx_loader_misc_t *misc_ptr);
+#endif
+
+#if BX_DBG_ICOUNT_SIZE == 32
+  typedef Bit32u bx_dbg_icount_t;
+#elif BX_DBG_ICOUNT_SIZE == 64
+  typedef Bit64u bx_dbg_icount_t;
+#else
+#  error "BX_DBG_ICOUNT_SIZE incorrect."
+#endif
+
+
+#define BX_DBG_NO_HANDLE 1000
+
+extern Bit32u dbg_cpu;
+
+unsigned long crc32(unsigned char *buf, int len);
+
+#if BX_DEBUGGER
+
+// some strict C declarations needed by the parser/lexer
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Flex defs
+extern int bxlex(void);
+extern char *bxtext;  // Using the pointer option rather than array
+extern int bxwrap(void);
+void bx_add_lex_input(char *buf);
+
+// Yacc defs
+extern int bxparse(void);
+extern void bxerror(char *s);
+
+typedef struct {
+  Bit64s from;
+  Bit64s to;
+} bx_num_range;
+#define EMPTY_ARG (-1)
+
+bx_num_range make_num_range (Bit64s from, Bit64s to);
+char* bx_dbg_symbolic_address(Bit32u context, Bit32u eip, Bit32u base);
+void bx_dbg_symbol_command(char* filename, Boolean global, Bit32u offset);
+void bx_dbg_trace_on_command(void);
+void bx_dbg_trace_off_command(void);
+void bx_dbg_ptime_command(void);
+void bx_dbg_timebp_command(Boolean absolute, Bit64u time);
+void bx_dbg_diff_memory(void);
+void bx_dbg_always_check(Bit32u page_start, Boolean on);
+void bx_dbg_sync_memory(Boolean set);
+void bx_dbg_sync_cpu(Boolean set);
+void bx_dbg_fast_forward(Bit32u num);
+void bx_dbg_info_address(Bit32u seg_reg_num, Bit32u offset);
+#define MAX_CONCURRENT_BPS 5
+extern int timebp_timer;
+extern Bit64u timebp_queue[MAX_CONCURRENT_BPS];
+extern int timebp_queue_size;
+void bx_dbg_record_command(char*);
+void bx_dbg_playback_command(char*);
+void bx_dbg_modebp_command(char*); /* BW */
+void bx_dbg_where_command(void);
+void bx_dbg_print_string_command(Bit32u addr);
+void bx_dbg_show_command(char*); /* BW */
+void enter_playback_entry();
+void bx_dbg_print_stack_command(int nwords);
+void bx_dbg_watch(int read, Bit32u address);
+void bx_dbg_unwatch(int read, Bit32u address);
+void bx_dbg_continue_command(void);
+void bx_dbg_stepN_command(bx_dbg_icount_t count);
+void bx_dbg_set_command(char *p1, char *p2, char *p3);
+void bx_dbg_del_breakpoint_command(unsigned handle);
+void bx_dbg_vbreakpoint_command(Boolean specific, Bit32u cs, Bit32u eip);
+void bx_dbg_lbreakpoint_command(Boolean specific, Bit32u laddress);
+void bx_dbg_pbreakpoint_command(Boolean specific, Bit32u paddress);
+void bx_dbg_info_bpoints_command(void);
+void bx_dbg_quit_command(void);
+void bx_dbg_info_program_command(void);
+void bx_dbg_info_registers_command(void);
+void bx_dbg_info_dirty_command(void);
+void bx_dbg_info_idt_command(bx_num_range);
+void bx_dbg_info_gdt_command(bx_num_range);
+void bx_dbg_info_ldt_command(bx_num_range);
+void bx_dbg_info_tss_command(bx_num_range);
+void bx_dbg_info_control_regs_command(void);
+void bx_dbg_info_linux_command(void);
+void bx_dbg_examine_command(char *command, char *format, Boolean format_passed,
+                    Bit32u addr, Boolean addr_passed, int simulator);
+void bx_dbg_setpmem_command(Bit32u addr, unsigned len, Bit32u val);
+void bx_dbg_set_symbol_command(char *symbol, Bit32u val);
+void bx_dbg_query_command(char *);
+void bx_dbg_take_command(char *, unsigned n);
+void bx_dbg_dump_cpu_command(void);
+void bx_dbg_set_cpu_command(void);
+void bx_dbg_disassemble_command(bx_num_range);
+void bx_dbg_instrument_command(char *);
+void bx_dbg_loader_command(char *);
+void bx_dbg_doit_command(unsigned);
+void bx_dbg_crc_command(Bit32u addr1, Bit32u addr2);
+void bx_dbg_maths_command(char *command, int data1, int data2);
+void bx_dbg_maths_expression_command(char *expr);
+void bx_dbg_v2l_command(unsigned seg_no, Bit32u offset);
+extern Boolean watchpoint_continue;
+void bx_dbg_linux_syscall ();
+
+#ifdef __cplusplus
+}
+#endif
+
+// the rest for C++
+#ifdef __cplusplus
+
+// (mch) Read/write watchpoint hack
+#define MAX_WRITE_WATCHPOINTS 16
+#define MAX_READ_WATCHPOINTS 16
+extern int num_write_watchpoints;
+extern Bit32u write_watchpoint[MAX_WRITE_WATCHPOINTS];
+extern int num_read_watchpoints;
+extern Bit32u read_watchpoint[MAX_READ_WATCHPOINTS];
+
+typedef enum {
+      STOP_NO_REASON = 0, STOP_TIME_BREAK_POINT, STOP_READ_WATCH_POINT, STOP_WRITE_WATCH_POINT, STOP_MAGIC_BREAK_POINT, STOP_TRACE, STOP_MODE_BREAK_POINT, STOP_CPU_HALTED
+} stop_reason_t;
+
+typedef enum {
+      BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
+} break_point_t;
+#endif // __cplusplus
+#endif // BX_DEBUGGER
+#ifdef __cplusplus
+#define BX_DBG_REG_EAX          10
+#define BX_DBG_REG_ECX          11
+#define BX_DBG_REG_EDX          12
+#define BX_DBG_REG_EBX          13
+#define BX_DBG_REG_ESP          14
+#define BX_DBG_REG_EBP          15
+#define BX_DBG_REG_ESI          16
+#define BX_DBG_REG_EDI          17
+#define BX_DBG_REG_EIP          18
+#define BX_DBG_REG_EFLAGS       19
+#define BX_DBG_REG_CS           20
+#define BX_DBG_REG_SS           21
+#define BX_DBG_REG_DS           22
+#define BX_DBG_REG_ES           23
+#define BX_DBG_REG_FS           24
+#define BX_DBG_REG_GS           25
+#endif // __cplusplus
+#if BX_DEBUGGER
+#ifdef __cplusplus
+#define BX_DBG_PENDING_DMA 1
+#define BX_DBG_PENDING_IRQ 2
+
+
+
+
+void bx_dbg_exit(int code);
+#if BX_DBG_EXTENSIONS
+  int bx_dbg_extensions(char *command);
+#else
+#define bx_dbg_extensions(command) 0
+#endif
+
+
+//
+// code for guards...
+//
+
+#define BX_DBG_GUARD_INSTR_BEGIN   0x0001
+#define BX_DBG_GUARD_INSTR_END     0x0002
+#define BX_DBG_GUARD_EXCEP_BEGIN   0x0004
+#define BX_DBG_GUARD_EXCEP_END     0x0008
+#define BX_DBG_GUARD_INTER_BEGIN   0x0010
+#define BX_DBG_GUARD_INTER_END     0x0020
+#define BX_DBG_GUARD_INSTR_MAP     0x0040
+
+// following 3 go along with BX_DBG_GUARD_INSTR_BEGIN
+// to provide breakpointing
+#define BX_DBG_GUARD_IADDR_VIR     0x0080
+#define BX_DBG_GUARD_IADDR_LIN     0x0100
+#define BX_DBG_GUARD_IADDR_PHY     0x0200
+#define BX_DBG_GUARD_IADDR_ALL (BX_DBG_GUARD_IADDR_VIR | \
+                                BX_DBG_GUARD_IADDR_LIN | \
+                                BX_DBG_GUARD_IADDR_PHY)
+
+#define BX_DBG_GUARD_ICOUNT        0x0400
+#define BX_DBG_GUARD_CTRL_C        0x0800
+
+
+typedef struct {
+  unsigned long guard_for;
+
+  // instruction address breakpoints
+  struct {
+#if BX_DBG_SUPPORT_VIR_BPOINT
+    unsigned num_virtual;
+    struct {
+      Bit32u cs;  // only use 16 bits
+      Bit32u eip;
+      unsigned bpoint_id;
+      } vir[BX_DBG_MAX_VIR_BPOINTS];
+#endif
+
+#if BX_DBG_SUPPORT_LIN_BPOINT
+    unsigned num_linear;
+    struct {
+      Bit32u addr;
+      unsigned bpoint_id;
+      } lin[BX_DBG_MAX_LIN_BPOINTS];
+#endif
+
+#if BX_DBG_SUPPORT_PHY_BPOINT
+    unsigned num_physical;
+    struct {
+      Bit32u addr;
+      unsigned bpoint_id;
+      } phy[BX_DBG_MAX_PHY_BPOINTS];
+#endif
+    } iaddr;
+
+  bx_dbg_icount_t icount; // stop after completing this many instructions
+
+  // user typed Ctrl-C, requesting simulator stop at next convient spot
+  volatile Boolean interrupt_requested;
+
+  // booleans to control whether simulator should report events
+  // to debug controller
+  struct {
+   Boolean irq;
+   Boolean a20;
+   Boolean io;
+   Boolean ucmem;
+   Boolean dma;
+   } report;
+
+  struct {
+    Boolean irq;  // should process IRQs asynchronously
+    Boolean dma;  // should process DMAs asynchronously
+    } async;
+
+#define BX_DBG_ASYNC_PENDING_A20   0x01
+#define BX_DBG_ASYNC_PENDING_RESET 0x02
+#define BX_DBG_ASYNC_PENDING_NMI   0x04
+
+  // Asynchronous changes which are pending.  These are Q'd by
+  // the debugger, as the master simulator is notified of a pending
+  // async change.  At the simulator's next point, where it checks for
+  // such events, it notifies the debugger with acknowlegement.  This
+  // field contains a logically or'd list of all events which should
+  // be checked, and ack'd.
+  struct {
+    unsigned which; // logical OR of above constants
+    Boolean a20;
+    Boolean reset;
+    Boolean nmi;
+    } async_changes_pending;
+  } bx_guard_t;
+
+// working information for each simulator to update when a guard
+// is reached (found)
+typedef struct bx_guard_found_t {
+  unsigned long guard_found;
+  unsigned iaddr_index;
+  bx_dbg_icount_t icount; // number of completed instructions
+  Bit32u   cs;     // cs:eip and linear addr of instruction at guard point
+  Bit32u   eip;
+  Bit32u   laddr;
+  Boolean  is_32bit_code; // CS seg size at guard point
+  Boolean  ctrl_c; // simulator stopped due to Ctrl-C request
+  } bx_guard_found_t;
+
+extern bx_guard_t        bx_guard;
+
+
+
+
+
+int  bx_dbg_main(int argc, char *argv[]);
+void bx_dbg_user_input_loop(void);
+
+
+typedef struct {
+  Bit16u sel;
+  Bit32u des_l, des_h, valid;
+  } bx_dbg_sreg_t;
+
+typedef struct {
+    Bit32u eax;
+    Bit32u ebx;
+    Bit32u ecx;
+    Bit32u edx;
+    Bit32u ebp;
+    Bit32u esi;
+    Bit32u edi;
+    Bit32u esp;
+    Bit32u eflags;
+    Bit32u eip;
+    bx_dbg_sreg_t cs;
+    bx_dbg_sreg_t ss;
+    bx_dbg_sreg_t ds;
+    bx_dbg_sreg_t es;
+    bx_dbg_sreg_t fs;
+    bx_dbg_sreg_t gs;
+    bx_dbg_sreg_t ldtr;
+    bx_dbg_sreg_t tr;
+    struct { Bit32u base, limit; } gdtr;
+    struct { Bit32u base, limit; } idtr;
+    Bit32u dr0, dr1, dr2, dr3, dr6, dr7;
+    Bit32u tr3, tr4, tr5, tr6, tr7;
+    Bit32u cr0, cr1, cr2, cr3, cr4;
+    unsigned inhibit_mask;
+    } bx_dbg_cpu_t;
+
+
+
+
+typedef struct {
+  // call back functions specific to each simulator
+  Boolean (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);
+  Boolean (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);
+  void    (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, Boolean *valid);
+  Boolean (*set_reg)(unsigned reg, Bit32u val);
+  Bit32u  (*get_reg)(unsigned reg);
+  Boolean (*get_sreg)(bx_dbg_sreg_t *sreg, unsigned sreg_no);
+  Boolean (*set_cpu)(bx_dbg_cpu_t *cpu);
+  Boolean (*get_cpu)(bx_dbg_cpu_t *cpu);
+  unsigned       dirty_page_tbl_size;
+  unsigned char *dirty_page_tbl;
+  void    (*atexit)(void);
+  unsigned (*query_pending)(void);
+  void     (*execute)(void);
+  void     (*take_irq)(void);
+  void     (*take_dma)(void);
+  void     (*reset_cpu)(unsigned source);
+  void     (*init_mem)(int size_in_bytes);
+  void     (*load_ROM)(const char *path, Bit32u romaddress);
+
+  // for asynchronous environment handling
+  void     (*set_A20)(unsigned val);
+  void     (*set_NMI)(unsigned val);
+  void     (*set_RESET)(unsigned val);
+  void     (*set_INTR)(unsigned val);
+  void     (*force_interrupt)(unsigned vector);
+
+#if BX_INSTRUMENTATION
+  void    (*instr_start)(void);
+  void    (*instr_stop)(void);
+  void    (*instr_reset)(void);
+  void    (*instr_print)(void);
+#endif
+#if BX_USE_LOADER
+  void    (*loader)(char *path, bx_loader_misc_t *misc_ptr);
+#endif
+  Boolean (*crc32)(unsigned long (*f)(unsigned char *buf, int len),
+                   Bit32u addr1, Bit32u addr2, Bit32u *crc);
+  } bx_dbg_callback_t;
+
+extern bx_dbg_callback_t bx_dbg_callback[BX_NUM_SIMULATORS];
+
+void BX_SIM1_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
+#ifdef BX_SIM2_INIT
+void BX_SIM2_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
+#endif
+
+
+void bx_dbg_dma_report(Bit32u addr, unsigned len, unsigned what, Bit32u val);
+void bx_dbg_iac_report(unsigned vector, unsigned irq);
+void bx_dbg_a20_report(unsigned val);
+void bx_dbg_io_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
+void bx_dbg_ucmem_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
+
+Bit8u   bx_dbg_ucmem_read(Bit32u addr);
+void    bx_dbg_ucmem_write(Bit32u addr, Bit8u value);
+void    bx_dbg_async_pin_request(unsigned what, Boolean val);
+void    bx_dbg_async_pin_ack(unsigned what, Boolean val);
+Bit32u  bx_dbg_inp(Bit16u addr, unsigned len);
+void    bx_dbg_outp(Bit16u addr, Bit32u value, unsigned len);
+void    bx_dbg_raise_HLDA(void);
+Bit8u   bx_dbg_IAC(void);
+void    bx_dbg_set_INTR(Boolean b);
+
+int bx_dbg_symbolic_output(void); /* BW */
+#endif // #ifdef __cplusplus
+#endif // #if BX_DEBUGGER
diff --git a/sid/component/bochs/fpu/Makefile.am b/sid/component/bochs/fpu/Makefile.am
new file mode 100644 (file)
index 0000000..bf5e020
--- /dev/null
@@ -0,0 +1,13 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+##         component/bochs bochs/fpu   bochs/fpu/stubs
+INCLUDES = -I$(srcdir)/..  -I$(srcdir) -I$(srcdir)/stubs -DUSE_WITH_CPU_SIM -DPARANOID -DNO_ASSEMBLER
+
+noinst_LTLIBRARIES = libfpu.la
+
+libfpu_la_SOURCES = fpu.cc wmFPUemu_glue.cc fpu_entry.c errors.c reg_ld_str.c load_store.c fpu_arith.c fpu_aux.c fpu_etc.c fpu_tags.c fpu_trig.c poly_atan.c poly_l2.c poly_2xm1.c poly_sin.c poly_tan.c reg_add_sub.c reg_compare.c reg_constant.c reg_convert.c reg_divide.c reg_mul.c reg_u_add.c reg_u_div.c reg_u_mul.c reg_u_sub.c div_small.c reg_norm.c reg_round.c wm_shrx.c wm_sqrt.c div_Xsig.c polynom_Xsig.c round_Xsig.c shr_Xsig.c mul_Xsig.c 
+
+
+libfpu_la_LDFLAGS = -no-undefined
diff --git a/sid/component/bochs/fpu/Makefile.in b/sid/component/bochs/fpu/Makefile.in
new file mode 100644 (file)
index 0000000..2d4e54b
--- /dev/null
@@ -0,0 +1,428 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(srcdir)/..  -I$(srcdir) -I$(srcdir)/stubs -DUSE_WITH_CPU_SIM -DPARANOID -DNO_ASSEMBLER
+
+noinst_LTLIBRARIES = libfpu.la
+
+libfpu_la_SOURCES = fpu.cc wmFPUemu_glue.cc fpu_entry.c errors.c reg_ld_str.c load_store.c fpu_arith.c fpu_aux.c fpu_etc.c fpu_tags.c fpu_trig.c poly_atan.c poly_l2.c poly_2xm1.c poly_sin.c poly_tan.c reg_add_sub.c reg_compare.c reg_constant.c reg_convert.c reg_divide.c reg_mul.c reg_u_add.c reg_u_div.c reg_u_mul.c reg_u_sub.c div_small.c reg_norm.c reg_round.c wm_shrx.c wm_sqrt.c div_Xsig.c polynom_Xsig.c round_Xsig.c shr_Xsig.c mul_Xsig.c 
+
+libfpu_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libfpu_la_LIBADD = 
+libfpu_la_OBJECTS =  fpu.lo wmFPUemu_glue.lo fpu_entry.lo errors.lo \
+reg_ld_str.lo load_store.lo fpu_arith.lo fpu_aux.lo fpu_etc.lo \
+fpu_tags.lo fpu_trig.lo poly_atan.lo poly_l2.lo poly_2xm1.lo \
+poly_sin.lo poly_tan.lo reg_add_sub.lo reg_compare.lo reg_constant.lo \
+reg_convert.lo reg_divide.lo reg_mul.lo reg_u_add.lo reg_u_div.lo \
+reg_u_mul.lo reg_u_sub.lo div_small.lo reg_norm.lo reg_round.lo \
+wm_shrx.lo wm_sqrt.lo div_Xsig.lo polynom_Xsig.lo round_Xsig.lo \
+shr_Xsig.lo mul_Xsig.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON =  README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES =  .deps/div_Xsig.P .deps/div_small.P .deps/errors.P \
+.deps/fpu.P .deps/fpu_arith.P .deps/fpu_aux.P .deps/fpu_entry.P \
+.deps/fpu_etc.P .deps/fpu_tags.P .deps/fpu_trig.P .deps/load_store.P \
+.deps/mul_Xsig.P .deps/poly_2xm1.P .deps/poly_atan.P .deps/poly_l2.P \
+.deps/poly_sin.P .deps/poly_tan.P .deps/polynom_Xsig.P \
+.deps/reg_add_sub.P .deps/reg_compare.P .deps/reg_constant.P \
+.deps/reg_convert.P .deps/reg_divide.P .deps/reg_ld_str.P \
+.deps/reg_mul.P .deps/reg_norm.P .deps/reg_round.P .deps/reg_u_add.P \
+.deps/reg_u_div.P .deps/reg_u_mul.P .deps/reg_u_sub.P \
+.deps/round_Xsig.P .deps/shr_Xsig.P .deps/wmFPUemu_glue.P \
+.deps/wm_shrx.P .deps/wm_sqrt.P
+SOURCES = $(libfpu_la_SOURCES)
+OBJECTS = $(libfpu_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign fpu/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libfpu.la: $(libfpu_la_OBJECTS) $(libfpu_la_DEPENDENCIES)
+       $(CXXLINK)  $(libfpu_la_LDFLAGS) $(libfpu_la_OBJECTS) $(libfpu_la_LIBADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = fpu
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign fpu/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstLTLIBRARIES clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstLTLIBRARIES distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstLTLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sid/component/bochs/fpu/PORTING b/sid/component/bochs/fpu/PORTING
new file mode 100644 (file)
index 0000000..532972d
--- /dev/null
@@ -0,0 +1,13 @@
+Portable i387 emulator
+
+22 Nov 99  Version 2.02:
+
+First pseudo-portable version for little-endian machines.
+
+Beginning of big-endian support provided through the pre-processor
+symbol BIG_ENDIAN.
+
+Some of the code in fpu_entry.c and get_address.c is still in a
+non-portable form and these two files still contain assembler code.
+
+
diff --git a/sid/component/bochs/fpu/README b/sid/component/bochs/fpu/README
new file mode 100644 (file)
index 0000000..d13efbc
--- /dev/null
@@ -0,0 +1,427 @@
+ +---------------------------------------------------------------------------+
+ |  wm-FPU-emu   an FPU emulator for 80386 and 80486SX microprocessors.      |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1996,1997,1999                          |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ |    This program is free software; you can redistribute it and/or modify   |
+ |    it under the terms of the GNU General Public License version 2 as      |
+ |    published by the Free Software Foundation.                             |
+ |                                                                           |
+ |    This program is distributed in the hope that it will be useful,        |
+ |    but WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          |
+ |    GNU General Public License for more details.                           |
+ |                                                                           |
+ |    You should have received a copy of the GNU General Public License      |
+ |    along with this program; if not, write to the Free Software            |
+ |    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              |
+ |                                                                           |
+ +---------------------------------------------------------------------------+
+
+
+
+wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387
+which was my 80387 emulator for early versions of djgpp (gcc under
+msdos); wm-emu387 was in turn based upon emu387 which was written by
+DJ Delorie for djgpp.  The interface to the Linux kernel is based upon
+the original Linux math emulator by Linus Torvalds.
+
+My target FPU for wm-FPU-emu is that described in the Intel486
+Programmer's Reference Manual (1992 edition). Unfortunately, numerous
+facets of the functioning of the FPU are not well covered in the
+Reference Manual. The information in the manual has been supplemented
+with measurements on real 80486's. Unfortunately, it is simply not
+possible to be sure that all of the peculiarities of the 80486 have
+been discovered, so there is always likely to be obscure differences
+in the detailed behaviour of the emulator and a real 80486.
+
+wm-FPU-emu does not implement all of the behaviour of the 80486 FPU,
+but is very close.  See "Limitations" later in this file for a list of
+some differences.
+
+Please report bugs, etc to me at:
+       billm@melbpc.org.au
+or     b.metzenthen@medoto.unimelb.edu.au
+
+For more information on the emulator and on floating point topics, see
+my web pages, currently at  http://www.suburbia.net/~billm/
+
+
+--Bill Metzenthen
+  December 1999
+
+
+----------------------- Internals of wm-FPU-emu -----------------------
+
+Numeric algorithms:
+(1) Add, subtract, and multiply. Nothing remarkable in these.
+(2) Divide has been tuned to get reasonable performance. The algorithm
+    is not the obvious one which most people seem to use, but is designed
+    to take advantage of the characteristics of the 80386. I expect that
+    it has been invented many times before I discovered it, but I have not
+    seen it. It is based upon one of those ideas which one carries around
+    for years without ever bothering to check it out.
+(3) The sqrt function has been tuned to get good performance. It is based
+    upon Newton's classic method. Performance was improved by capitalizing
+    upon the properties of Newton's method, and the code is once again
+    structured taking account of the 80386 characteristics.
+(4) The trig, log, and exp functions are based in each case upon quasi-
+    "optimal" polynomial approximations. My definition of "optimal" was
+    based upon getting good accuracy with reasonable speed.
+(5) The argument reducing code for the trig function effectively uses
+    a value of pi which is accurate to more than 128 bits. As a consequence,
+    the reduced argument is accurate to more than 64 bits for arguments up
+    to a few pi, and accurate to more than 64 bits for most arguments,
+    even for arguments approaching 2^63. This is far superior to an
+    80486, which uses a value of pi which is accurate to 66 bits.
+
+The code of the emulator is complicated slightly by the need to
+account for a limited form of re-entrancy. Normally, the emulator will
+emulate each FPU instruction to completion without interruption.
+However, it may happen that when the emulator is accessing the user
+memory space, swapping may be needed. In this case the emulator may be
+temporarily suspended while disk i/o takes place. During this time
+another process may use the emulator, thereby perhaps changing static
+variables. The code which accesses user memory is confined to five
+files:
+    fpu_entry.c
+    reg_ld_str.c
+    load_store.c
+    get_address.c
+    errors.c
+As from version 1.12 of the emulator, no static variables are used
+(apart from those in the kernel's per-process tables). The emulator is
+therefore now fully re-entrant, rather than having just the restricted
+form of re-entrancy which is required by the Linux kernel.
+
+----------------------- Limitations of wm-FPU-emu -----------------------
+
+There are a number of differences between the current wm-FPU-emu
+(version 2.05) and the 80486 FPU (apart from bugs).  The differences
+are fewer than those which applied to the 1.xx series of the emulator.
+Some of the more important differences are listed below:
+
+The Roundup flag does not have much meaning for the transcendental
+functions and its 80486 value with these functions is likely to differ
+from its emulator value.
+
+In a few rare cases the Underflow flag obtained with the emulator will
+be different from that obtained with an 80486. This occurs when the
+following conditions apply simultaneously:
+(a) the operands have a higher precision than the current setting of the
+    precision control (PC) flags.
+(b) the underflow exception is masked.
+(c) the magnitude of the exact result (before rounding) is less than 2^-16382.
+(d) the magnitude of the final result (after rounding) is exactly 2^-16382.
+(e) the magnitude of the exact result would be exactly 2^-16382 if the
+    operands were rounded to the current precision before the arithmetic
+    operation was performed.
+If all of these apply, the emulator will set the Underflow flag but a real
+80486 will not.
+
+NOTE: Certain formats of Extended Real are UNSUPPORTED. They are
+unsupported by the 80486. They are the Pseudo-NaNs, Pseudoinfinities,
+and Unnormals. None of these will be generated by an 80486 or by the
+emulator. Do not use them. The emulator treats them differently in
+detail from the way an 80486 does.
+
+Self modifying code can cause the emulator to fail. An example of such
+code is:
+          movl %esp,[%ebx]
+         fld1
+The FPU instruction may be (usually will be) loaded into the pre-fetch
+queue of the CPU before the mov instruction is executed. If the
+destination of the 'movl' overlaps the FPU instruction then the bytes
+in the prefetch queue and memory will be inconsistent when the FPU
+instruction is executed. The emulator will be invoked but will not be
+able to find the instruction which caused the device-not-present
+exception. For this case, the emulator cannot emulate the behaviour of
+an 80486DX.
+
+Handling of the address size override prefix byte (0x67) has not been
+extensively tested yet. A major problem exists because using it in
+vm86 mode can cause a general protection fault. Address offsets
+greater than 0xffff appear to be illegal in vm86 mode but are quite
+acceptable (and work) in real mode. A small test program developed to
+check the addressing, and which runs successfully in real mode,
+crashes dosemu under Linux and also brings Windows down with a general
+protection fault message when run under the MS-DOS prompt of Windows
+3.1. (The program simply reads data from a valid address).
+
+The emulator supports 16-bit protected mode, with one difference from
+an 80486DX.  A 80486DX will allow some floating point instructions to
+write a few bytes below the lowest address of the stack.  The emulator
+will not allow this in 16-bit protected mode: no instructions are
+allowed to write outside the bounds set by the protection.
+
+----------------------- Performance of wm-FPU-emu -----------------------
+
+Speed.
+-----
+
+The speed of floating point computation with the emulator will depend
+upon instruction mix. Relative performance is best for the instructions
+which require most computation. The simple instructions are adversely
+affected by the FPU instruction trap overhead.
+
+
+Timing: Some simple timing tests have been made on the emulator functions.
+The times include load/store instructions. All times are in microseconds
+measured on a 33MHz 386 with 64k cache. The Turbo C tests were under
+ms-dos, the next two columns are for emulators running with the djgpp
+ms-dos extender. The final column is for wm-FPU-emu in Linux 0.97,
+using libm4.0 (hard).
+
+function      Turbo C        djgpp 1.06        WM-emu387     wm-FPU-emu
+
+   +          60.5           154.8              76.5          139.4
+   -          61.1-65.5      157.3-160.8        76.2-79.5     142.9-144.7
+   *          71.0           190.8              79.6          146.6
+   /          61.2-75.0      261.4-266.9        75.3-91.6     142.2-158.1
+
+ sin()        310.8          4692.0            319.0          398.5
+ cos()        284.4          4855.2            308.0          388.7
+ tan()        495.0          8807.1            394.9          504.7
+ atan()       328.9          4866.4            601.1          419.5-491.9
+
+ sqrt()       128.7          crashed           145.2          227.0
+ log()        413.1-419.1    5103.4-5354.21    254.7-282.2    409.4-437.1
+ exp()        479.1          6619.2            469.1          850.8
+
+
+The performance under Linux is improved by the use of look-ahead code.
+The following results show the improvement which is obtained under
+Linux due to the look-ahead code. Also given are the times for the
+original Linux emulator with the 4.1 'soft' lib.
+
+ [ Linus' note: I changed look-ahead to be the default under linux, as
+   there was no reason not to use it after I had edited it to be
+   disabled during tracing ]
+
+            wm-FPU-emu w     original w
+            look-ahead       'soft' lib
+   +         106.4             190.2
+   -         108.6-111.6      192.4-216.2
+   *         113.4             193.1
+   /         108.8-124.4      700.1-706.2
+
+ sin()       390.5            2642.0
+ cos()       381.5            2767.4
+ tan()       496.5            3153.3
+ atan()      367.2-435.5     2439.4-3396.8
+
+ sqrt()      195.1            4732.5
+ log()       358.0-387.5     3359.2-3390.3
+ exp()       619.3            4046.4
+
+
+These figures are now somewhat out-of-date. The emulator has become
+progressively slower for most functions as more of the 80486 features
+have been implemented.
+
+
+----------------------- Accuracy of wm-FPU-emu -----------------------
+
+
+The accuracy of the emulator is in almost all cases equal to or better
+than that of an Intel 80486 FPU.
+
+The results of the basic arithmetic functions (+,-,*,/), and fsqrt
+match those of an 80486 FPU. They are the best possible; the error for
+these never exceeds 1/2 an lsb. The fprem and fprem1 instructions
+return exact results; they have no error.
+
+
+The following table compares the emulator accuracy for the sqrt(),
+trig and log functions against the Turbo C "emulator". For this table,
+each function was tested at about 400 points. Ideal worst-case results
+would be 64 bits. The reduced Turbo C accuracy of cos() and tan() for
+arguments greater than pi/4 can be thought of as being related to the
+precision of the argument x; e.g. an argument of pi/2-(1e-10) which is
+accurate to 64 bits can result in a relative accuracy in cos() of
+about 64 + log2(cos(x)) = 31 bits.
+
+
+Function      Tested x range            Worst result                Turbo C
+                                        (relative bits)
+
+sqrt(x)       1 .. 2                    64.1                         63.2
+atan(x)       1e-10 .. 200              64.2                         62.8
+cos(x)        0 .. pi/2-(1e-10)         64.4 (x <= pi/4)             62.4
+                                        64.1 (x = pi/2-(1e-10))      31.9
+sin(x)        1e-10 .. pi/2             64.0                         62.8
+tan(x)        1e-10 .. pi/2-(1e-10)     64.0 (x <= pi/4)             62.1
+                                        64.1 (x = pi/2-(1e-10))      31.9
+exp(x)        0 .. 1                    63.1 **                      62.9
+log(x)        1+1e-6 .. 2               63.8 **                      62.1
+
+** The accuracy for exp() and log() is low because the FPU (emulator)
+does not compute them directly; two operations are required.
+
+
+The emulator passes the "paranoia" tests (compiled with gcc 2.3.3 or
+later) for 'float' variables (24 bit precision numbers) when precision
+control is set to 24, 53 or 64 bits, and for 'double' variables (53
+bit precision numbers) when precision control is set to 53 bits (a
+properly performing FPU cannot pass the 'paranoia' tests for 'double'
+variables when precision control is set to 64 bits).
+
+The code for reducing the argument for the trig functions (fsin, fcos,
+fptan and fsincos) has been improved and now effectively uses a value
+for pi which is accurate to more than 128 bits precision. As a
+consequence, the accuracy of these functions for large arguments has
+been dramatically improved (and is now very much better than an 80486
+FPU). There is also now no degradation of accuracy for fcos and fptan
+for operands close to pi/2. Measured results are (note that the
+definition of accuracy has changed slightly from that used for the
+above table):
+
+Function      Tested x range          Worst result
+                                     (absolute bits)
+
+cos(x)        0 .. 9.22e+18              62.0
+sin(x)        1e-16 .. 9.22e+18          62.1
+tan(x)        1e-16 .. 9.22e+18          61.8
+
+It is possible with some effort to find very large arguments which
+give much degraded precision. For example, the integer number
+           8227740058411162616.0
+is within about 10e-7 of a multiple of pi. To find the tan (for
+example) of this number to 64 bits precision it would be necessary to
+have a value of pi which had about 150 bits precision. The FPU
+emulator computes the result to about 42.6 bits precision (the correct
+result is about -9.739715e-8). On the other hand, an 80486 FPU returns
+0.01059, which in relative terms is hopelessly inaccurate.
+
+For arguments close to critical angles (which occur at multiples of
+pi/2) the emulator is more accurate than an 80486 FPU. For very large
+arguments, the emulator is far more accurate.
+
+
+Prior to version 1.20 of the emulator, the accuracy of the results for
+the transcendental functions (in their principal range) was not as
+good as the results from an 80486 FPU. From version 1.20, the accuracy
+has been considerably improved and these functions now give measured
+worst-case results which are better than the worst-case results given
+by an 80486 FPU.
+
+The following table gives the measured results for the emulator. The
+number of randomly selected arguments in each case is about half a
+million.  The group of three columns gives the frequency of the given
+accuracy in number of times per million, thus the second of these
+columns shows that an accuracy of between 63.80 and 63.89 bits was
+found at a rate of 133 times per one million measurements for fsin.
+The results show that the fsin, fcos and fptan instructions return
+results which are in error (i.e. less accurate than the best possible
+result (which is 64 bits)) for about one per cent of all arguments
+between -pi/2 and +pi/2.  The other instructions have a lower
+frequency of results which are in error.  The last two columns give
+the worst accuracy which was found (in bits) and the approximate value
+of the argument which produced it.
+
+                                frequency (per M)
+                               -------------------   ---------------
+instr   arg range    # tests   63.7   63.8    63.9   worst   at arg
+                               bits   bits    bits    bits
+-----  ------------  -------   ----   ----   -----   -----  --------
+fsin     (0,pi/2)     547756      0    133   10673   63.89  0.451317
+fcos     (0,pi/2)     547563      0    126   10532   63.85  0.700801
+fptan    (0,pi/2)     536274     11    267   10059   63.74  0.784876
+fpatan  4 quadrants   517087      0      8    1855   63.88  0.435121 (4q)
+fyl2x     (0,20)      541861      0      0    1323   63.94  1.40923  (x)
+fyl2xp1 (-.293,.414)  520256      0      0    5678   63.93  0.408542 (x)
+f2xm1     (-1,1)      538847      4    481    6488   63.79  0.167709
+
+
+Tests performed on an 80486 FPU showed results of lower accuracy. The
+following table gives the results which were obtained with an AMD
+486DX2/66 (other tests indicate that an Intel 486DX produces
+identical results).  The tests were basically the same as those used
+to measure the emulator (the values, being random, were in general not
+the same).  The total number of tests for each instruction are given
+at the end of the table, in case each about 100k tests were performed.
+Another line of figures at the end of the table shows that most of the
+instructions return results which are in error for more than 10
+percent of the arguments tested.
+
+The numbers in the body of the table give the approx number of times a
+result of the given accuracy in bits (given in the left-most column)
+was obtained per one million arguments. For three of the instructions,
+two columns of results are given: * The second column for f2xm1 gives
+the number cases where the results of the first column were for a
+positive argument, this shows that this instruction gives better
+results for positive arguments than it does for negative.  * In the
+cases of fcos and fptan, the first column gives the results when all
+cases where arguments greater than 1.5 were removed from the results
+given in the second column. Unlike the emulator, an 80486 FPU returns
+results of relatively poor accuracy for these instructions when the
+argument approaches pi/2. The table does not show those cases when the
+accuracy of the results were less than 62 bits, which occurs quite
+often for fsin and fptan when the argument approaches pi/2. This poor
+accuracy is discussed above in relation to the Turbo C "emulator", and
+the accuracy of the value of pi.
+
+
+bits   f2xm1  f2xm1 fpatan   fcos   fcos  fyl2x fyl2xp1  fsin  fptan  fptan
+62.0       0      0      0      0    437      0      0      0      0    925
+62.1       0      0     10      0    894      0      0      0      0   1023
+62.2      14      0      0      0   1033      0      0      0      0    945
+62.3      57      0      0      0   1202      0      0      0      0   1023
+62.4     385      0      0     10   1292      0     23      0      0   1178
+62.5    1140      0      0    119   1649      0     39      0      0   1149
+62.6    2037      0      0    189   1620      0     16      0      0   1169
+62.7    5086     14      0    646   2315     10    101     35     39   1402
+62.8    8818     86      0    984   3050     59    287    131    224   2036
+62.9   11340   1355      0   2126   4153     79    605    357    321   1948
+63.0   15557   4750      0   3319   5376    246   1281    862    808   2688
+63.1   20016   8288      0   4620   6628    511   2569   1723   1510   3302
+63.2   24945  11127     10   6588   8098   1120   4470   2968   2990   4724
+63.3   25686  12382     69   8774  10682   1906   6775   4482   5474   7236
+63.4   29219  14722     79  11109  12311   3094   9414   7259   8912  10587
+63.5   30458  14936    393  13802  15014   5874  12666   9609  13762  15262
+63.6   32439  16448   1277  17945  19028  10226  15537  14657  19158  20346
+63.7   35031  16805   4067  23003  23947  18910  20116  21333  25001  26209
+63.8   33251  15820   7673  24781  25675  24617  25354  24440  29433  30329
+63.9   33293  16833  18529  28318  29233  31267  31470  27748  29676  30601
+
+Per cent with error:
+        30.9           3.2          18.5    9.8   13.1   11.6          17.4
+Total arguments tested:
+       70194  70099 101784 100641 100641 101799 128853 114893 102675 102675
+
+
+------------------------- Contributors -------------------------------
+
+A number of people have contributed to the development of the
+emulator, often by just reporting bugs, sometimes with suggested
+fixes, and a few kind people have provided me with access in one way
+or another to an 80486 machine. Contributors include (to those people
+who I may have forgotten, please forgive me):
+
+Linus Torvalds
+Tommy.Thorn@daimi.aau.dk
+Andrew.Tridgell@anu.edu.au
+Nick Holloway, alfie@dcs.warwick.ac.uk
+Hermano Moura, moura@dcs.gla.ac.uk
+Jon Jagger, J.Jagger@scp.ac.uk
+Lennart Benschop
+Brian Gallew, geek+@CMU.EDU
+Thomas Staniszewski, ts3v+@andrew.cmu.edu
+Martin Howell, mph@plasma.apana.org.au
+M Saggaf, alsaggaf@athena.mit.edu
+Peter Barker, PETER@socpsy.sci.fau.edu
+tom@vlsivie.tuwien.ac.at
+Dan Russel, russed@rpi.edu
+Daniel Carosone, danielce@ee.mu.oz.au
+cae@jpmorgan.com
+Hamish Coleman, t933093@minyos.xx.rmit.oz.au
+Bruce Evans, bde@kralizec.zeta.org.au
+Timo Korvola, Timo.Korvola@hut.fi
+Rick Lyons, rick@razorback.brisnet.org.au
+Rick, jrs@world.std.com
+...and numerous others who responded to my request for help with
+a real 80486.
+
diff --git a/sid/component/bochs/fpu/control_w.h b/sid/component/bochs/fpu/control_w.h
new file mode 100644 (file)
index 0000000..ae2274d
--- /dev/null
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------+
+ |  control_w.h                                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1993                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _CONTROLW_H_
+#define _CONTROLW_H_
+
+#ifdef __ASSEMBLY__
+#define        _Const_(x)      $##x
+#else
+#define        _Const_(x)      x
+#endif
+
+#define CW_RC          _Const_(0x0C00) /* rounding control */
+#define CW_PC          _Const_(0x0300) /* precision control */
+
+#define CW_Precision   Const_(0x0020)  /* loss of precision mask */
+#define CW_Underflow   Const_(0x0010)  /* underflow mask */
+#define CW_Overflow    Const_(0x0008)  /* overflow mask */
+#define CW_ZeroDiv     Const_(0x0004)  /* divide by zero mask */
+#define CW_Denormal    Const_(0x0002)  /* denormalized operand mask */
+#define CW_Invalid     Const_(0x0001)  /* invalid operation mask */
+
+#define CW_Exceptions          _Const_(0x003f) /* all masks */
+
+#define RC_RND         _Const_(0x0000)
+#define RC_DOWN                _Const_(0x0400)
+#define RC_UP          _Const_(0x0800)
+#define RC_CHOP                _Const_(0x0C00)
+
+/* p 15-5: Precision control bits affect only the following:
+   ADD, SUB(R), MUL, DIV(R), and SQRT */
+#define PR_24_BITS        _Const_(0x000)
+#define PR_53_BITS        _Const_(0x200)
+#define PR_64_BITS        _Const_(0x300)
+#define PR_RESERVED_BITS  _Const_(0x100)
+/* FULL_PRECISION simulates all exceptions masked */
+#define FULL_PRECISION  (PR_64_BITS | RC_RND | 0x3f)
+
+#endif /* _CONTROLW_H_ */
diff --git a/sid/component/bochs/fpu/div_Xsig.S b/sid/component/bochs/fpu/div_Xsig.S
new file mode 100644 (file)
index 0000000..d94d85e
--- /dev/null
@@ -0,0 +1,365 @@
+       .file   "div_Xsig.S"
+/*---------------------------------------------------------------------------+
+ |  div_Xsig.S                                                               |
+ |                                                                           |
+ | Division subroutine for 96 bit quantities                                 |
+ |                                                                           |
+ | Copyright (C) 1994,1995                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Divide the 96 bit quantity pointed to by a, by that pointed to by b, and  |
+ | put the 96 bit result at the location d.                                  |
+ |                                                                           |
+ | The result may not be accurate to 96 bits. It is intended for use where   |
+ | a result better than 64 bits is required. The result should usually be    |
+ | good to at least 94 bits.                                                 |
+ | The returned result is actually divided by one half. This is done to      |
+ | prevent overflow.                                                         |
+ |                                                                           |
+ |  .aaaaaaaaaaaaaa / .bbbbbbbbbbbbb  ->  .dddddddddddd                      |
+ |                                                                           |
+ |  void div_Xsig(Xsig *a, Xsig *b, Xsig *dest)                              |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#define        XsigLL(x)       (x)
+#define        XsigL(x)        4(x)
+#define        XsigH(x)        8(x)
+
+
+#ifndef NON_REENTRANT_FPU
+/*
+       Local storage on the stack:
+       Accumulator:    FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ */
+#define FPU_accum_3    -4(%ebp)
+#define FPU_accum_2    -8(%ebp)
+#define FPU_accum_1    -12(%ebp)
+#define FPU_accum_0    -16(%ebp)
+#define FPU_result_3   -20(%ebp)
+#define FPU_result_2   -24(%ebp)
+#define FPU_result_1   -28(%ebp)
+
+#else
+.data
+/*
+       Local storage in a static area:
+       Accumulator:    FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ */
+       .align 4,0
+FPU_accum_3:
+       .long   0
+FPU_accum_2:
+       .long   0
+FPU_accum_1:
+       .long   0
+FPU_accum_0:
+       .long   0
+FPU_result_3:
+       .long   0
+FPU_result_2:
+       .long   0
+FPU_result_1:
+       .long   0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(div_Xsig)
+       pushl   %ebp
+       movl    %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+       subl    $28,%esp
+#endif /* NON_REENTRANT_FPU */
+
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%esi     /* pointer to num */
+       movl    PARAM2,%ebx     /* pointer to denom */
+
+#ifdef PARANOID
+       testl   $0x80000000, XsigH(%ebx)        /* Divisor */
+       je      L_bugged
+#endif /* PARANOID */
+
+
+/*---------------------------------------------------------------------------+
+ |  Divide:   Return  arg1/arg2 to arg3.                                     |
+ |                                                                           |
+ |  The maximum returned value is (ignoring exponents)                       |
+ |               .ffffffff ffffffff                                          |
+ |               ------------------  =  1.ffffffff fffffffe                  |
+ |               .80000000 00000000                                          |
+ | and the minimum is                                                        |
+ |               .80000000 00000000                                          |
+ |               ------------------  =  .80000000 00000001   (rounded)       |
+ |               .ffffffff ffffffff                                          |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+       /* Save extended dividend in local register */
+
+       /* Divide by 2 to prevent overflow */
+       clc
+       movl    XsigH(%esi),%eax
+       rcrl    %eax
+       movl    %eax,FPU_accum_3
+       movl    XsigL(%esi),%eax
+       rcrl    %eax
+       movl    %eax,FPU_accum_2
+       movl    XsigLL(%esi),%eax
+       rcrl    %eax
+       movl    %eax,FPU_accum_1
+       movl    $0,%eax
+       rcrl    %eax
+       movl    %eax,FPU_accum_0
+
+       movl    FPU_accum_2,%eax        /* Get the current num */
+       movl    FPU_accum_3,%edx
+
+/*----------------------------------------------------------------------*/
+/* Initialization done.
+   Do the first 32 bits. */
+
+       /* We will divide by a number which is too large */
+       movl    XsigH(%ebx),%ecx
+       addl    $1,%ecx
+       jnc     LFirst_div_not_1
+
+       /* here we need to divide by 100000000h,
+          i.e., no division at all.. */
+       mov     %edx,%eax
+       jmp     LFirst_div_done
+
+LFirst_div_not_1:
+       divl    %ecx            /* Divide the numerator by the augmented
+                                  denom ms dw */
+
+LFirst_div_done:
+       movl    %eax,FPU_result_3       /* Put the result in the answer */
+
+       mull    XsigH(%ebx)     /* mul by the ms dw of the denom */
+
+       subl    %eax,FPU_accum_2        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_3
+
+       movl    FPU_result_3,%eax       /* Get the result back */
+       mull    XsigL(%ebx)     /* now mul the ls dw of the denom */
+
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+       sbbl    $0,FPU_accum_3
+       je      LDo_2nd_32_bits         /* Must check for non-zero result here */
+
+#ifdef PARANOID
+       jb      L_bugged_1
+#endif /* PARANOID */
+
+       /* need to subtract another once of the denom */
+       incl    FPU_result_3    /* Correct the answer */
+
+       movl    XsigL(%ebx),%eax
+       movl    XsigH(%ebx),%edx
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+
+#ifdef PARANOID
+       sbbl    $0,FPU_accum_3
+       jne     L_bugged_1      /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* Half of the main problem is done, there is just a reduced numerator
+   to handle now.
+   Work with the second 32 bits, FPU_accum_0 not used from now on */
+LDo_2nd_32_bits:
+       movl    FPU_accum_2,%edx        /* get the reduced num */
+       movl    FPU_accum_1,%eax
+
+       /* need to check for possible subsequent overflow */
+       cmpl    XsigH(%ebx),%edx
+       jb      LDo_2nd_div
+       ja      LPrevent_2nd_overflow
+
+       cmpl    XsigL(%ebx),%eax
+       jb      LDo_2nd_div
+
+LPrevent_2nd_overflow:
+/* The numerator is greater or equal, would cause overflow */
+       /* prevent overflow */
+       subl    XsigL(%ebx),%eax
+       sbbl    XsigH(%ebx),%edx
+       movl    %edx,FPU_accum_2
+       movl    %eax,FPU_accum_1
+
+       incl    FPU_result_3    /* Reflect the subtraction in the answer */
+
+#ifdef PARANOID
+       je      L_bugged_2      /* Can't bump the result to 1.0 */
+#endif /* PARANOID */
+
+LDo_2nd_div:
+       cmpl    $0,%ecx         /* augmented denom msw */
+       jnz     LSecond_div_not_1
+
+       /* %ecx == 0, we are dividing by 1.0 */
+       mov     %edx,%eax
+       jmp     LSecond_div_done
+
+LSecond_div_not_1:
+       divl    %ecx            /* Divide the numerator by the denom ms dw */
+
+LSecond_div_done:
+       movl    %eax,FPU_result_2       /* Put the result in the answer */
+
+       mull    XsigH(%ebx)     /* mul by the ms dw of the denom */
+
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+#endif /* PARANOID */
+
+       movl    FPU_result_2,%eax       /* Get the result back */
+       mull    XsigL(%ebx)     /* now mul the ls dw of the denom */
+
+       subl    %eax,FPU_accum_0        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    $0,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+#endif /* PARANOID */
+
+       jz      LDo_3rd_32_bits
+
+#ifdef PARANOID
+       cmpl    $1,FPU_accum_2
+       jne     L_bugged_2
+#endif /* PARANOID */
+
+       /* need to subtract another once of the denom */
+       movl    XsigL(%ebx),%eax
+       movl    XsigH(%ebx),%edx
+       subl    %eax,FPU_accum_0        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_1
+       sbbl    $0,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+       jne     L_bugged_2
+#endif /* PARANOID */
+
+       addl    $1,FPU_result_2 /* Correct the answer */
+       adcl    $0,FPU_result_3
+
+#ifdef PARANOID
+       jc      L_bugged_2      /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* The division is essentially finished here, we just need to perform
+   tidying operations.
+   Deal with the 3rd 32 bits */
+LDo_3rd_32_bits:
+       /* We use an approximation for the third 32 bits.
+       To take account of the 3rd 32 bits of the divisor
+       (call them del), we subtract  del * (a/b) */
+
+       movl    FPU_result_3,%eax       /* a/b */
+       mull    XsigLL(%ebx)            /* del */
+
+       subl    %edx,FPU_accum_1
+
+       /* A borrow indicates that the result is negative */
+       jnb     LTest_over
+
+       movl    XsigH(%ebx),%edx
+       addl    %edx,FPU_accum_1
+
+       subl    $1,FPU_result_2         /* Adjust the answer */
+       sbbl    $0,FPU_result_3
+
+       /* The above addition might not have been enough, check again. */
+       movl    FPU_accum_1,%edx        /* get the reduced num */
+       cmpl    XsigH(%ebx),%edx        /* denom */
+       jb      LDo_3rd_div
+
+       movl    XsigH(%ebx),%edx
+       addl    %edx,FPU_accum_1
+
+       subl    $1,FPU_result_2         /* Adjust the answer */
+       sbbl    $0,FPU_result_3
+       jmp     LDo_3rd_div
+
+LTest_over:
+       movl    FPU_accum_1,%edx        /* get the reduced num */
+
+       /* need to check for possible subsequent overflow */
+       cmpl    XsigH(%ebx),%edx        /* denom */
+       jb      LDo_3rd_div
+
+       /* prevent overflow */
+       subl    XsigH(%ebx),%edx
+       movl    %edx,FPU_accum_1
+
+       addl    $1,FPU_result_2 /* Reflect the subtraction in the answer */
+       adcl    $0,FPU_result_3
+
+LDo_3rd_div:
+       movl    FPU_accum_0,%eax
+       movl    FPU_accum_1,%edx
+       divl    XsigH(%ebx)
+
+       movl    %eax,FPU_result_1       /* Rough estimate of third word */
+
+       movl    PARAM3,%esi             /* pointer to answer */
+
+       movl    FPU_result_1,%eax
+       movl    %eax,XsigLL(%esi)
+       movl    FPU_result_2,%eax
+       movl    %eax,XsigL(%esi)
+       movl    FPU_result_3,%eax
+       movl    %eax,XsigH(%esi)
+
+L_exit:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+
+       leave
+       ret
+
+
+#ifdef PARANOID
+/* The logic is wrong if we got here */
+L_bugged:
+       pushl   EX_INTERNAL|0x240
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_bugged_1:
+       pushl   EX_INTERNAL|0x241
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_bugged_2:
+       pushl   EX_INTERNAL|0x242
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+#endif /* PARANOID */
diff --git a/sid/component/bochs/fpu/div_Xsig.c b/sid/component/bochs/fpu/div_Xsig.c
new file mode 100644 (file)
index 0000000..36e7c2a
--- /dev/null
@@ -0,0 +1,185 @@
+/*---------------------------------------------------------------------------+
+ |  div_Xsig.S                                                               |
+ |                                                                           |
+ | Division subroutine for 96 bit quantities                                 |
+ |                                                                           |
+ | Copyright (C) 1994,1995,1999                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Divide the 96 bit quantity pointed to by a, by that pointed to by b, and  |
+ | put the 96 bit result at the location d.                                  |
+ |                                                                           |
+ | The result may not be accurate to 96 bits. It is intended for use where   |
+ | a result better than 64 bits is required. The result should usually be    |
+ | good to at least 94 bits.                                                 |
+ | The returned result is actually divided by one half. This is done to      |
+ | prevent overflow.                                                         |
+ |                                                                           |
+ |  .aaaaaaaaaaaaaa / .bbbbbbbbbbbbb  ->  .dddddddddddd                      |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void div_Xsig(const Xsig *aa, const Xsig *b, Xsig *dest)
+{
+  Xsig a = *aa, xpr, result;
+  u32  prodh, prodl, den, wd;
+  u64  num, prod;
+
+#ifdef PARANOID
+  if ( (b->msw & 0x80000000) == 0 )
+    {
+      EXCEPTION(EX_INTERNAL|0x240);
+      return;
+    }
+#endif
+
+  /* Shift a right */
+  a.lsw >>= 1;
+  if ( a.midw & 1 )
+    a.lsw |= 0x80000000;
+  a.midw >>= 1;
+  if ( a.msw & 1 )
+    a.midw |= 0x80000000;
+  a.msw >>= 1;
+
+  num = a.msw;
+  num <<= 32;
+  num |= a.midw;
+
+  den = b->msw + 1;
+  if ( den )
+    {
+      result.msw = num / den;
+    }
+  else
+    result.msw = a.msw;
+
+  xpr = *b;
+  mul32_Xsig(&xpr, result.msw);
+  a.msw -= xpr.msw;
+  wd = a.midw;
+  a.midw -= xpr.midw;
+  if ( a.midw > wd )
+    a.msw --;
+  wd = a.lsw;
+  a.lsw -= xpr.lsw;
+  if ( a.lsw > wd )
+    {
+      a.midw --;
+      if ( a.midw == 0xffffffff )
+       a.msw --;
+    }
+
+#ifdef PARANOID
+      if ( a.msw > 1 )
+       {
+         EXCEPTION(EX_INTERNAL|0x241);
+       }
+#endif
+
+  while ( (a.msw != 0) || (a.midw > b->msw) )
+    {
+      wd = a.midw;
+      a.midw -= b->msw;
+      if ( a.midw > wd )
+       a.msw --;
+      wd = a.lsw;
+      a.lsw -= b->midw;
+      if ( a.lsw > wd )
+       {
+         a.midw --;
+         if ( a.midw == 0xffffffff )
+           a.msw --;
+       }
+      result.msw ++;
+    }
+
+  /* Whew! result.msw is now done. */
+
+  num = a.midw;
+  num <<= 32;
+  num |= a.lsw;
+
+  if ( den )
+    {
+      result.midw = num / den;
+    }
+  else
+    result.midw = a.midw;
+
+  prod = result.midw;
+  prod *= b->msw;
+  a.midw -= prod >> 32;
+  prodl = prod;
+  wd = a.lsw;
+  a.lsw -= prodl;
+  if ( a.lsw > wd )
+    a.midw --;
+
+  prod = result.midw;
+  prod *= b->midw;
+  prodh = prod >> 32;
+  wd = a.lsw;
+  a.lsw -= prodh;
+  if ( a.lsw > wd )
+    a.midw --;
+
+#ifdef PARANOID
+      if ( a.midw > 1 )
+       {
+          EXCEPTION(EX_INTERNAL|0x242);
+       }
+#endif
+
+  while ( (a.midw != 0) || (a.lsw > b->msw) )
+    {
+      wd = a.lsw;
+      a.lsw -= b->msw;
+      if ( a.lsw > wd )
+       a.midw --;
+      result.midw ++;
+    }
+
+
+  /* Now result.msw is done, the lsw is next... */
+
+  num = a.lsw;
+  num <<= 32;
+
+  if ( den )
+    {
+      result.lsw = num / den;
+    }
+  else
+    result.lsw = a.lsw;
+
+  prod = result.lsw;
+  prod *= b->msw;
+  a.lsw -= prod >> 32;
+
+#ifdef PARANOID
+  if ( a.lsw > 2 )
+    {
+      EXCEPTION(EX_INTERNAL|0x243);
+    }
+#endif
+
+  result.lsw -= a.lsw;
+
+  /* Hey! we're done. */
+
+  *dest = result;
+
+}
+
diff --git a/sid/component/bochs/fpu/div_small.S b/sid/component/bochs/fpu/div_small.S
new file mode 100644 (file)
index 0000000..4709962
--- /dev/null
@@ -0,0 +1,47 @@
+       .file   "div_small.S"
+/*---------------------------------------------------------------------------+
+ |  div_small.S                                                              |
+ |                                                                           |
+ | Divide a 64 bit integer by a 32 bit integer & return remainder.           |
+ |                                                                           |
+ | Copyright (C) 1992,1995                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |    unsigned long FPU_div_small(unsigned long long *x, unsigned long y)    |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(FPU_div_small)
+       pushl   %ebp
+       movl    %esp,%ebp
+
+       pushl   %esi
+
+       movl    PARAM1,%esi     /* pointer to num */
+       movl    PARAM2,%ecx     /* The denominator */
+
+       movl    4(%esi),%eax    /* Get the current num msw */
+       xorl    %edx,%edx
+       divl    %ecx
+
+       movl    %eax,4(%esi)
+
+       movl    (%esi),%eax     /* Get the num lsw */
+       divl    %ecx
+
+       movl    %eax,(%esi)
+
+       movl    %edx,%eax       /* Return the remainder in eax */
+
+       popl    %esi
+
+       leave
+       ret
+
diff --git a/sid/component/bochs/fpu/div_small.c b/sid/component/bochs/fpu/div_small.c
new file mode 100644 (file)
index 0000000..9559a15
--- /dev/null
@@ -0,0 +1,26 @@
+/*---------------------------------------------------------------------------+
+ |  div_small.S                                                              |
+ |                                                                           |
+ | Divide a 64 bit integer by a 32 bit integer & return remainder.           |
+ |                                                                           |
+ | Copyright (C) 1992,1995,1999                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+
+u32 FPU_div_small(u64 *x, u32 y)
+{
+  u32 retval;
+
+  retval = *x % y;
+
+  *x /= y;
+
+  return retval;
+}
+
diff --git a/sid/component/bochs/fpu/errors.c b/sid/component/bochs/fpu/errors.c
new file mode 100644 (file)
index 0000000..fd9a4e4
--- /dev/null
@@ -0,0 +1,799 @@
+/*---------------------------------------------------------------------------+
+ |  errors.c                                                                 |
+ |                                                                           |
+ |  The error handling functions for wm-FPU-emu                              |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1996                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@jacobi.maths.monash.edu.au                |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
+#include <linux/signal.h>
+#include <asm/uaccess.h>
+#include <stdio.h>
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "reg_constant.h"
+#include "version.h"
+
+/* */
+#undef PRINT_MESSAGES
+/* */
+
+
+#ifndef USE_WITH_CPU_SIM
+void Un_impl(void)
+{
+  u_char byte1, FPU_modrm;
+  u32 address = FPU_ORIG_EIP;
+
+  RE_ENTRANT_CHECK_OFF;
+  /* No need to verify_area(), we have previously fetched these bytes. */
+  printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
+  if ( FPU_CS == __USER_CS )
+    {
+      while ( 1 )
+       {
+         FPU_get_user(byte1, (u_char *) address);
+         if ( (byte1 & 0xf8) == 0xd8 ) break;
+         printk("[%02x]", byte1);
+         address++;
+       }
+      printk("%02x ", byte1);
+      FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+      
+      if (FPU_modrm >= 0300)
+       printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+      else
+       printk("/%d\n", (FPU_modrm >> 3) & 7);
+    }
+  else
+    {
+      printk("cs selector = %04x\n", FPU_CS);
+    }
+
+  RE_ENTRANT_CHECK_ON;
+
+  EXCEPTION(EX_Invalid);
+
+}
+#endif
+
+
+/*
+   Called for opcodes which are illegal and which are known to result in a
+   SIGILL with a real 80486.
+   */
+void FPU_illegal(void)
+{
+  math_abort(FPU_info,SIGILL);
+}
+
+
+
+#ifndef USE_WITH_CPU_SIM
+void FPU_printall(void)
+{
+  int i;
+  static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty",
+                              "DeNorm", "Inf", "NaN" };
+  u_char byte1, FPU_modrm;
+  u32 address = FPU_ORIG_EIP;
+
+  RE_ENTRANT_CHECK_OFF;
+  /* No need to verify_area(), we have previously fetched these bytes. */
+  printk("At %p:", (void *) address);
+  if ( FPU_CS == __USER_CS )
+    {
+#define MAX_PRINTED_BYTES 20
+      for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
+       {
+         FPU_get_user(byte1, (u_char *) address);
+         if ( (byte1 & 0xf8) == 0xd8 )
+           {
+             printk(" %02x", byte1);
+             break;
+           }
+         printk(" [%02x]", byte1);
+         address++;
+       }
+      if ( i == MAX_PRINTED_BYTES )
+       printk(" [more..]\n");
+      else
+       {
+         FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+         
+         if (FPU_modrm >= 0300)
+           printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+         else
+           printk(" /%d, mod=%d rm=%d\n",
+                  (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
+       }
+    }
+  else
+    {
+      printk("%04x\n", FPU_CS);
+    }
+
+  partial_status = status_word();
+
+
+  printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n",
+        partial_status & 0x8000 ? 1 : 0,   /* busy */
+        (partial_status & 0x3800) >> 11,   /* stack top pointer */
+        partial_status & 0x80 ? 1 : 0,     /* Error summary status */
+        partial_status & 0x40 ? 1 : 0,     /* Stack flag */
+        partial_status & SW_C3?1:0, partial_status & SW_C2?1:0, /* cc */
+        partial_status & SW_C1?1:0, partial_status & SW_C0?1:0, /* cc */
+        partial_status & SW_Precision?1:0, partial_status & SW_Underflow?1:0,
+        partial_status & SW_Overflow?1:0, partial_status & SW_Zero_Div?1:0,
+        partial_status & SW_Denorm_Op?1:0, partial_status & SW_Invalid?1:0);
+  
+printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d     ef=%d%d%d%d%d%d\n",
+        control_word & 0x1000 ? 1 : 0,
+        (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
+        (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
+        control_word & 0x80 ? 1 : 0,
+        control_word & SW_Precision?1:0, control_word & SW_Underflow?1:0,
+        control_word & SW_Overflow?1:0, control_word & SW_Zero_Div?1:0,
+        control_word & SW_Denorm_Op?1:0, control_word & SW_Invalid?1:0);
+
+  for ( i = 0; i < 8; i++ )
+    {
+      FPU_REG *r = &st(i);
+      u_char tagi = FPU_gettagi(i);
+      switch (tagi)
+       {
+       case TAG_Empty:
+         continue;
+         break;
+       case TAG_Zero:
+       case TAG_Special:
+         tagi = FPU_Special(r);
+       case TAG_Valid:
+         printk("st(%d)  %c .%04lx %04lx %04lx %04lx e%+-6d ", i,
+                getsign(r) ? '-' : '+',
+                (s32)(r->sigh >> 16),
+                (s32)(r->sigh & 0xFFFF),
+                (s32)(r->sigl >> 16),
+                (s32)(r->sigl & 0xFFFF),
+                exponent(r) - EXP_BIAS + 1);
+         break;
+       default:
+         printk("Whoops! Error in errors.c: tag%d is %d ", i, tagi);
+         continue;
+         break;
+       }
+      printk("%s\n", tag_desc[(int) (unsigned) tagi]);
+    }
+
+  RE_ENTRANT_CHECK_ON;
+
+}
+#endif
+
+static struct {
+  int type;
+  const char *name;
+} exception_names[] = {
+  { EX_StackOver, "stack overflow" },
+  { EX_StackUnder, "stack underflow" },
+  { EX_Precision, "loss of precision" },
+  { EX_Underflow, "underflow" },
+  { EX_Overflow, "overflow" },
+  { EX_ZeroDiv, "divide by zero" },
+  { EX_Denormal, "denormalized operand" },
+  { EX_Invalid, "invalid operation" },
+  { EX_INTERNAL, "INTERNAL BUG in "FPU_VERSION },
+  { 0, NULL }
+};
+
+/*
+ EX_INTERNAL is always given with a code which indicates where the
+ error was detected.
+
+ Internal error types:
+       0x14   in fpu_etc.c
+       0x1nn  in a *.c file:
+              0x101  in reg_add_sub.c
+              0x102  in reg_mul.c
+              0x104  in poly_atan.c
+              0x105  in reg_mul.c
+              0x107  in fpu_trig.c
+             0x108  in reg_compare.c
+             0x109  in reg_compare.c
+             0x110  in reg_add_sub.c
+             0x111  in fpe_entry.c
+             0x112  in fpu_trig.c
+             0x113  in errors.c
+             0x115  in fpu_trig.c
+             0x116  in fpu_trig.c
+             0x117  in fpu_trig.c
+             0x118  in fpu_trig.c
+             0x119  in fpu_trig.c
+             0x120  in poly_atan.c
+             0x121  in reg_compare.c
+             0x122  in reg_compare.c
+             0x123  in reg_compare.c
+             0x125  in fpu_trig.c
+             0x126  in fpu_entry.c
+             0x127  in poly_2xm1.c
+             0x128  in fpu_entry.c
+             0x129  in fpu_entry.c
+             0x130  in get_address.c
+             0x131  in get_address.c
+             0x132  in get_address.c
+             0x133  in get_address.c
+             0x140  in load_store.c
+             0x141  in load_store.c
+              0x150  in poly_sin.c
+              0x151  in poly_sin.c
+             0x160  in reg_ld_str.c
+             0x161  in reg_ld_str.c
+             0x162  in reg_ld_str.c
+             0x163  in reg_ld_str.c
+             0x164  in reg_ld_str.c
+             0x170  in fpu_tags.c
+             0x171  in fpu_tags.c
+             0x172  in fpu_tags.c
+             0x180  in reg_convert.c
+       0x2nn  in an *.S file:
+              0x201  in reg_u_add.S
+              0x202  in reg_u_div.S
+              0x203  in reg_u_div.S
+              0x204  in reg_u_div.S
+              0x205  in reg_u_mul.S
+              0x206  in reg_u_sub.S
+              0x207  in wm_sqrt.S
+             0x208  in reg_div.S
+              0x209  in reg_u_sub.S
+              0x210  in reg_u_sub.S
+              0x211  in reg_u_sub.S
+              0x212  in reg_u_sub.S
+             0x213  in wm_sqrt.S
+             0x214  in wm_sqrt.S
+             0x215  in wm_sqrt.S
+             0x220  in reg_norm.S
+             0x221  in reg_norm.S
+             0x230  in reg_round.S
+             0x231  in reg_round.S
+             0x232  in reg_round.S
+             0x233  in reg_round.S
+             0x234  in reg_round.S
+             0x235  in reg_round.S
+             0x236  in reg_round.S
+             0x240  in div_Xsig.S
+             0x241  in div_Xsig.S
+             0x242  in div_Xsig.S
+ */
+
+void FPU_exception(int n)
+{
+  int i, int_type;
+
+  int_type = 0;         /* Needed only to stop compiler warnings */
+  if ( n & EX_INTERNAL )
+    {
+      int_type = n - EX_INTERNAL;
+      n = EX_INTERNAL;
+      /* Set lots of exception bits! */
+      partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward);
+    }
+  else
+    {
+      /* Extract only the bits which we use to set the status word */
+      n &= (SW_Exc_Mask);
+      /* Set the corresponding exception bit */
+      partial_status |= n;
+      /* Set summary bits iff exception isn't masked */
+      if ( partial_status & ~control_word & CW_Exceptions )
+       partial_status |= (SW_Summary | SW_Backward);
+      if ( n & (SW_Stack_Fault | EX_Precision) )
+       {
+         if ( !(n & SW_C1) )
+           /* This bit distinguishes over- from underflow for a stack fault,
+              and roundup from round-down for precision loss. */
+           partial_status &= ~SW_C1;
+       }
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  if ( (~control_word & n & CW_Exceptions) || (n == EX_INTERNAL) )
+    {
+#ifdef PRINT_MESSAGES
+      /* My message from the sponsor */
+      printk(FPU_VERSION" "__DATE__" (C) W. Metzenthen.\n");
+#endif /* PRINT_MESSAGES */
+      
+      /* Get a name string for error reporting */
+      for (i=0; exception_names[i].type; i++)
+       if ( (exception_names[i].type & n) == exception_names[i].type )
+         break;
+      
+      if (exception_names[i].type)
+       {
+#ifdef PRINT_MESSAGES
+         printk("FP Exception: %s!\n", exception_names[i].name);
+#endif /* PRINT_MESSAGES */
+       }
+      else
+       printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
+      
+      if ( n == EX_INTERNAL )
+       {
+         printk("FPU emulator: Internal error type 0x%04x\n", int_type);
+         FPU_printall();
+       }
+#ifdef PRINT_MESSAGES
+      else
+       FPU_printall();
+#endif /* PRINT_MESSAGES */
+
+      /*
+       * The 80486 generates an interrupt on the next non-control FPU
+       * instruction. So we need some means of flagging it.
+       * We use the ES (Error Summary) bit for this.
+       */
+    }
+  RE_ENTRANT_CHECK_ON;
+
+
+}
+
+
+/* Real operation attempted on a NaN. */
+/* Returns < 0 if the exception is unmasked */
+int real_1op_NaN(FPU_REG *a)
+{
+  int signalling, isNaN;
+
+  isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);
+
+  /* The default result for the case of two "equal" NaNs (signs may
+     differ) is chosen to reproduce 80486 behaviour */
+  signalling = isNaN && !(a->sigh & 0x40000000);
+
+  if ( !signalling )
+    {
+      if ( !isNaN )  /* pseudo-NaN, or other unsupported? */
+       {
+         if ( control_word & CW_Invalid )
+           {
+             /* Masked response */
+             reg_copy(&CONST_QNaN, a);
+           }
+         EXCEPTION(EX_Invalid);
+         return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+       }
+      return TAG_Special;
+    }
+
+  if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      if ( !(a->sigh & 0x80000000) )  /* pseudo-NaN ? */
+       {
+         reg_copy(&CONST_QNaN, a);
+       }
+      /* ensure a Quiet NaN */
+      a->sigh |= 0x40000000;
+    }
+
+  EXCEPTION(EX_Invalid);
+
+  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+}
+
+
+/* Real operation attempted on two operands, one a NaN. */
+/* Returns < 0 if the exception is unmasked */
+int real_2op_NaN(FPU_REG const *b, u_char tagb,
+                int deststnr,
+                FPU_REG const *defaultNaN)
+{
+  FPU_REG *dest = &st(deststnr);
+  FPU_REG const *a = dest;
+  u_char taga = FPU_gettagi(deststnr);
+  FPU_REG const *x;
+  int signalling, unsupported;
+
+  if ( taga == TAG_Special )
+    taga = FPU_Special(a);
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+
+  /* TW_NaN is also used for unsupported data types. */
+  unsupported = ((taga == TW_NaN)
+                && !((exponent(a) == EXP_OVER) && (a->sigh & 0x80000000)))
+    || ((tagb == TW_NaN)
+       && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));
+  if ( unsupported )
+    {
+      if ( control_word & CW_Invalid )
+       {
+         /* Masked response */
+         FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+       }
+      EXCEPTION(EX_Invalid);
+      return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+    }
+
+  if (taga == TW_NaN)
+    {
+      x = a;
+      if (tagb == TW_NaN)
+       {
+         signalling = !(a->sigh & b->sigh & 0x40000000);
+         if ( significand(b) > significand(a) )
+           x = b;
+         else if ( significand(b) == significand(a) )
+           {
+             /* The default result for the case of two "equal" NaNs (signs may
+                differ) is chosen to reproduce 80486 behaviour */
+             x = defaultNaN;
+           }
+       }
+      else
+       {
+         /* return the quiet version of the NaN in a */
+         signalling = !(a->sigh & 0x40000000);
+       }
+    }
+  else
+#ifdef PARANOID
+    if (tagb == TW_NaN)
+#endif /* PARANOID */
+    {
+      signalling = !(b->sigh & 0x40000000);
+      x = b;
+    }
+#ifdef PARANOID
+  else
+    {
+      signalling = 0;
+      EXCEPTION(EX_INTERNAL|0x113);
+      x = &CONST_QNaN;
+    }
+#endif /* PARANOID */
+
+  if ( (!signalling) || (control_word & CW_Invalid) )
+    {
+      if ( ! x )
+       x = b;
+
+      if ( !(x->sigh & 0x80000000) )  /* pseudo-NaN ? */
+       x = &CONST_QNaN;
+
+      FPU_copy_to_regi(x, TAG_Special, deststnr);
+
+      if ( !signalling )
+       return TAG_Special;
+
+      /* ensure a Quiet NaN */
+      dest->sigh |= 0x40000000;
+    }
+
+  EXCEPTION(EX_Invalid);
+
+  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+}
+
+
+/* Invalid arith operation on Valid registers */
+/* Returns < 0 if the exception is unmasked */
+asmlinkage int arith_invalid(int deststnr)
+{
+
+  EXCEPTION(EX_Invalid);
+  
+  if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+    }
+  
+  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
+
+}
+
+
+/* Divide a finite number by zero */
+asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign)
+{
+  FPU_REG *dest = &st(deststnr);
+  int tag = TAG_Valid;
+
+  if ( control_word & CW_ZeroDiv )
+    {
+      /* The masked response */
+      FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
+      setsign(dest, sign);
+      tag = TAG_Special;
+    }
+  EXCEPTION(EX_ZeroDiv);
+
+  return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;
+
+}
+
+
+/* This may be called often, so keep it lean */
+int set_precision_flag(int flags)
+{
+  if ( control_word & CW_Precision )
+    {
+      partial_status &= ~(SW_C1 & flags);
+      partial_status |= flags;   /* The masked response */
+      return 0;
+    }
+  else
+    {
+      EXCEPTION(flags);
+      return 1;
+    }
+}
+
+
+/* This may be called often, so keep it lean */
+asmlinkage void set_precision_flag_up(void)
+{
+  if ( control_word & CW_Precision )
+    partial_status |= (SW_Precision | SW_C1);   /* The masked response */
+  else
+    EXCEPTION(EX_Precision | SW_C1);
+}
+
+
+/* This may be called often, so keep it lean */
+asmlinkage void set_precision_flag_down(void)
+{
+  if ( control_word & CW_Precision )
+    {   /* The masked response */
+      partial_status &= ~SW_C1;
+      partial_status |= SW_Precision;
+    }
+  else
+    EXCEPTION(EX_Precision);
+}
+
+
+asmlinkage int denormal_operand(void)
+{
+  if ( control_word & CW_Denormal )
+    {   /* The masked response */
+      partial_status |= SW_Denorm_Op;
+      return TAG_Special;
+    }
+  else
+    {
+      EXCEPTION(EX_Denormal);
+      return TAG_Special | FPU_Exception;
+    }
+}
+
+
+asmlinkage int arith_overflow(FPU_REG *dest)
+{
+  int tag = TAG_Valid;
+
+  if ( control_word & CW_Overflow )
+    {
+      /* The masked response */
+      reg_copy(&CONST_INF, dest);
+      tag = TAG_Special;
+    }
+  else
+    {
+      /* Subtract the magic number from the exponent */
+      addexponent(dest, (-3 * (1 << 13)));
+    }
+
+  EXCEPTION(EX_Overflow);
+  if ( control_word & CW_Overflow )
+    {
+      /* The overflow exception is masked. */
+      /* By definition, precision is lost.
+        The roundup bit (C1) is also set because we have
+        "rounded" upwards to Infinity. */
+      EXCEPTION(EX_Precision | SW_C1);
+      return tag;
+    }
+
+  return tag;
+
+}
+
+
+asmlinkage int arith_round_overflow(FPU_REG *dest, u8 sign)
+{
+  int tag = TAG_Valid;
+  int largest;
+
+  if ( control_word & CW_Overflow )
+    {
+      /* The masked response */
+      /* The response here depends upon the rounding mode */
+      switch ( control_word & CW_RC )
+       {
+       case RC_CHOP:           /* Truncate */
+         largest = 1;
+         break;
+       case RC_UP:             /* Towards +infinity */
+         largest = (sign == SIGN_NEG);
+         break;
+       case RC_DOWN:           /* Towards -infinity */
+         largest = (sign == SIGN_POS);
+         break;
+       default:
+         largest = 0;
+         break;
+       }
+      if ( ! largest )
+       {
+         reg_copy(&CONST_INF, dest);
+         tag = TAG_Special;
+       }
+      else
+       {
+         dest->exp = EXTENDED_Ebias+EXP_OVER-1;
+         switch ( control_word & CW_PC )
+           {
+           case 01:
+           case PR_64_BITS:
+             significand(dest) = BX_CONST64(0xffffffffffffffff);
+             break;
+           case PR_53_BITS:
+             significand(dest) = BX_CONST64(0xfffffffffffff800);
+             break;
+           case PR_24_BITS:
+             significand(dest) = BX_CONST64(0xffffff0000000000);
+             break;
+           }
+       }
+    }
+  else
+    {
+      /* Subtract the magic number from the exponent */
+      addexponent(dest, (-3 * (1 << 13)));
+      largest = 0;
+    }
+
+  EXCEPTION(EX_Overflow);
+  if ( control_word & CW_Overflow )
+    {
+      /* The overflow exception is masked. */
+      if ( largest )
+       {
+         EXCEPTION(EX_Precision);
+       }
+      else
+       {
+         /* By definition, precision is lost.
+            The roundup bit (C1) is also set because we have
+            "rounded" upwards to Infinity. */
+         EXCEPTION(EX_Precision | SW_C1);
+       }
+      return tag;
+    }
+
+  return tag;
+
+}
+
+
+asmlinkage int arith_underflow(FPU_REG *dest)
+{
+  int tag = TAG_Valid;
+
+  if ( control_word & CW_Underflow )
+    {
+      /* The masked response */
+      if ( exponent16(dest) <= EXP_UNDER - 63 )
+       {
+         reg_copy(&CONST_Z, dest);
+         partial_status &= ~SW_C1;       /* Round down. */
+         tag = TAG_Zero;
+       }
+      else
+       {
+         stdexp(dest);
+       }
+    }
+  else
+    {
+      /* Add the magic number to the exponent. */
+      addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
+    }
+
+  EXCEPTION(EX_Underflow);
+  if ( control_word & CW_Underflow )
+    {
+      /* The underflow exception is masked. */
+      EXCEPTION(EX_Precision);
+      return tag;
+    }
+
+  return tag;
+
+}
+
+
+void FPU_stack_overflow(void)
+{
+
+ if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      top--;
+      FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+    }
+
+  EXCEPTION(EX_StackOver);
+
+  return;
+
+}
+
+
+void FPU_stack_underflow(void)
+{
+
+ if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+    }
+
+  EXCEPTION(EX_StackUnder);
+
+  return;
+
+}
+
+
+void FPU_stack_underflow_i(int i)
+{
+
+ if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+    }
+
+  EXCEPTION(EX_StackUnder);
+
+  return;
+
+}
+
+
+void FPU_stack_underflow_pop(int i)
+{
+
+ if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+      FPU_pop();
+    }
+
+  EXCEPTION(EX_StackUnder);
+
+  return;
+
+}
+
diff --git a/sid/component/bochs/fpu/exception.h b/sid/component/bochs/fpu/exception.h
new file mode 100644 (file)
index 0000000..2b9b3ce
--- /dev/null
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------+
+ |  exception.h                                                              |
+ |                                                                           |
+ | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+
+#ifdef __ASSEMBLY__
+#define        Const_(x)       $##x
+#else
+#define        Const_(x)       x
+#endif
+
+#ifndef SW_C1
+#include "fpu_emu.h"
+#endif /* SW_C1 */
+
+#define FPU_BUSY        Const_(0x8000)   /* FPU busy bit (8087 compatibility) */
+#define EX_ErrorSummary Const_(0x0080)   /* Error summary status */
+/* Special exceptions: */
+#define        EX_INTERNAL     Const_(0x8000)  /* Internal error in wm-FPU-emu */
+#define EX_StackOver   Const_(0x0041|SW_C1)    /* stack overflow */
+#define EX_StackUnder  Const_(0x0041)  /* stack underflow */
+/* Exception flags: */
+#define EX_Precision   Const_(0x0020)  /* loss of precision */
+#define EX_Underflow   Const_(0x0010)  /* underflow */
+#define EX_Overflow    Const_(0x0008)  /* overflow */
+#define EX_ZeroDiv     Const_(0x0004)  /* divide by zero */
+#define EX_Denormal    Const_(0x0002)  /* denormalized operand */
+#define EX_Invalid     Const_(0x0001)  /* invalid operation */
+
+
+#define PRECISION_LOST_UP    Const_((EX_Precision | SW_C1))
+#define PRECISION_LOST_DOWN  Const_(EX_Precision)
+
+
+#ifndef __ASSEMBLY__
+
+#define        EXCEPTION(x)    FPU_exception(x)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _EXCEPTION_H_ */
diff --git a/sid/component/bochs/fpu/fpu.cc b/sid/component/bochs/fpu/fpu.cc
new file mode 100644 (file)
index 0000000..9178389
--- /dev/null
@@ -0,0 +1,179 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+#include "bochs.h"
+
+#define LOG_THIS genlog->
+
+// Nomenclature used to signify argument types
+//
+// Es = single real
+// El = double real
+// Ea = 14/28 bytes    98/108b bytes (FRSTOR,FSAVE)???
+// Ew = word integer (2 bytes)
+// Ed = dword integer (4 bytes) (short int)
+// Et = extended real
+// Eb = packed BCD
+// Eq = quadword integer (8 bytes) (long integer)
+
+
+
+  void
+BX_CPU_C::ESC0(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC0 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC1(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC1 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC2(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC2 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC3(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+
+//BX_DEBUG(( "CS:EIP = %04x:%08x\n",
+//  BX_CPU.sregs[BX_SEG_REG_CS].selector.value, BX_CPU.prev_eip));
+
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC3 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC4(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC4 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC5(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC5 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC6(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC6 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::ESC7(BxInstruction_t *i)
+{
+  if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+    exception(BX_NM_EXCEPTION, 0, 0);
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("ESC7 not implemented\n"));
+#endif
+}
+
+  void
+BX_CPU_C::FWAIT(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+  // WAIT doesn't generate single steps on 8086.
+  // The same goes for prefix instructions, and instructions which
+  // modify segment registers. (pg4-16)
+  // single_step_event = 0;
+  BX_PANIC(("WAIT: not implemented for < 386\n"));
+#else // BX_CPU_LEVEL >= 3
+
+  if ( BX_CPU_THIS_PTR cr0.ts && BX_CPU_THIS_PTR cr0.mp ) {
+    exception(BX_NM_EXCEPTION, 0, 0); // no error
+    }
+#if BX_SUPPORT_FPU
+  fpu_execute(i);
+#else
+  BX_INFO(("FWAIT: no FPU\n"));
+#endif
+
+#endif
+}
+
+
+#if BX_SUPPORT_FPU==0
+  // if supporting FPU, this function in glue logic file
+  void
+BX_CPU_C::fpu_init(void)
+{
+}
+#endif
diff --git a/sid/component/bochs/fpu/fpu_arith.c b/sid/component/bochs/fpu/fpu_arith.c
new file mode 100644 (file)
index 0000000..f012174
--- /dev/null
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_arith.c                                                              |
+ |                                                                           |
+ | Code to implement the FPU register/register arithmetic instructions       |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1997                                              |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+void fadd__()
+{
+  /* fadd st,st(i) */
+  int i = FPU_rm;
+  clear_C1();
+  FPU_add(&st(i), FPU_gettagi(i), 0, control_word);
+}
+
+
+void fmul__()
+{
+  /* fmul st,st(i) */
+  int i = FPU_rm;
+  clear_C1();
+  FPU_mul(&st(i), FPU_gettagi(i), 0, control_word);
+}
+
+
+
+void fsub__()
+{
+  /* fsub st,st(i) */
+  clear_C1();
+  FPU_sub(0, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fsubr_()
+{
+  /* fsubr st,st(i) */
+  clear_C1();
+  FPU_sub(REV, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdiv__()
+{
+  /* fdiv st,st(i) */
+  clear_C1();
+  FPU_div(0, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdivr_()
+{
+  /* fdivr st,st(i) */
+  clear_C1();
+  FPU_div(REV, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+
+void fadd_i()
+{
+  /* fadd st(i),st */
+  int i = FPU_rm;
+  clear_C1();
+  FPU_add(&st(i), FPU_gettagi(i), i, control_word);
+}
+
+
+void fmul_i()
+{
+  /* fmul st(i),st */
+  clear_C1();
+  FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word);
+}
+
+
+void fsubri()
+{
+  /* fsubr st(i),st */
+  clear_C1();
+  FPU_sub(DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fsub_i()
+{
+  /* fsub st(i),st */
+  clear_C1();
+  FPU_sub(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdivri()
+{
+  /* fdivr st(i),st */
+  clear_C1();
+  FPU_div(DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdiv_i()
+{
+  /* fdiv st(i),st */
+  clear_C1();
+  FPU_div(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+
+void faddp_()
+{
+  /* faddp st(i),st */
+  int i = FPU_rm;
+  clear_C1();
+  if ( FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0 )
+    FPU_pop();
+}
+
+
+void fmulp_()
+{
+  /* fmulp st(i),st */
+  clear_C1();
+  if ( FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0 )
+    FPU_pop();
+}
+
+
+
+void fsubrp()
+{
+  /* fsubrp st(i),st */
+  clear_C1();
+  if ( FPU_sub(DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+    FPU_pop();
+}
+
+
+void fsubp_()
+{
+  /* fsubp st(i),st */
+  clear_C1();
+  if ( FPU_sub(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+    FPU_pop();
+}
+
+
+void fdivrp()
+{
+  /* fdivrp st(i),st */
+  clear_C1();
+  if ( FPU_div(DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+    FPU_pop();
+}
+
+
+void fdivp_()
+{
+  /* fdivp st(i),st */
+  clear_C1();
+  if ( FPU_div(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+    FPU_pop();
+}
diff --git a/sid/component/bochs/fpu/fpu_asm.h b/sid/component/bochs/fpu/fpu_asm.h
new file mode 100644 (file)
index 0000000..5665f09
--- /dev/null
@@ -0,0 +1,32 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_asm.h                                                                |
+ |                                                                           |
+ | Copyright (C) 1992,1995,1997                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@suburbia.net               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _FPU_ASM_H_
+#define _FPU_ASM_H_
+
+#include <linux/linkage.h>
+
+#define        EXCEPTION       SYMBOL_NAME(FPU_exception)
+
+
+#define PARAM1 8(%ebp)
+#define        PARAM2  12(%ebp)
+#define        PARAM3  16(%ebp)
+#define        PARAM4  20(%ebp)
+#define        PARAM5  24(%ebp)
+#define        PARAM6  28(%ebp)
+#define        PARAM7  32(%ebp)
+
+#define SIGL_OFFSET 0
+#define        EXP(x)  8(x)
+#define SIG(x) SIGL_OFFSET##(x)
+#define        SIGL(x) SIGL_OFFSET##(x)
+#define        SIGH(x) 4(x)
+
+#endif /* _FPU_ASM_H_ */
diff --git a/sid/component/bochs/fpu/fpu_aux.c b/sid/component/bochs/fpu/fpu_aux.c
new file mode 100644 (file)
index 0000000..a2cea50
--- /dev/null
@@ -0,0 +1,204 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_aux.c                                                                |
+ |                                                                           |
+ | Code to implement some of the FPU auxiliary instructions.                 |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+
+
+static void fnop(void)
+{
+}
+
+void fclex(void)
+{
+  partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
+                  SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
+                  SW_Invalid);
+  no_ip_update = 1;
+}
+
+/* Needs to be externally visible */
+void finit()
+{
+  control_word = 0x037f;
+  partial_status = 0;
+  top = 0;            /* We don't keep top in the status word internally. */
+  fpu_tag_word = 0xffff;
+  /* The behaviour is different from that detailed in
+     Section 15.1.6 of the Intel manual */
+  operand_address.offset = 0;
+  operand_address.selector = 0;
+  instruction_address.offset = 0;
+  instruction_address.selector = 0;
+  instruction_address.opcode = 0;
+  no_ip_update = 1;
+}
+
+/*
+ * These are nops on the i387..
+ */
+#define feni fnop
+#define fdisi fnop
+#define fsetpm fnop
+
+static FUNC const finit_table[] = {
+  feni, fdisi, fclex, finit,
+  fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void finit_()
+{
+  (finit_table[FPU_rm])();
+}
+
+
+static void fstsw_ax(void)
+{
+  SET_AX(status_word()); // KPL
+  no_ip_update = 1;
+}
+
+static FUNC const fstsw_table[] = {
+  fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
+  FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void fstsw_()
+{
+  (fstsw_table[FPU_rm])();
+}
+
+
+static FUNC const fp_nop_table[] = {
+  fnop, FPU_illegal, FPU_illegal, FPU_illegal,
+  FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void fp_nop()
+{
+  (fp_nop_table[FPU_rm])();
+}
+
+
+void fld_i_()
+{
+  FPU_REG *st_new_ptr;
+  int i;
+  u_char tag;
+
+  if ( STACK_OVERFLOW )
+    { FPU_stack_overflow(); return; }
+
+  /* fld st(i) */
+  i = FPU_rm;
+  if ( NOT_EMPTY(i) )
+    {
+      reg_copy(&st(i), st_new_ptr);
+      tag = FPU_gettagi(i);
+      push();
+      FPU_settag0(tag);
+    }
+  else
+    {
+      if ( control_word & CW_Invalid )
+       {
+         /* The masked response */
+         FPU_stack_underflow();
+       }
+      else
+       EXCEPTION(EX_StackUnder);
+    }
+
+}
+
+
+void fxch_i()
+{
+  /* fxch st(i) */
+  FPU_REG t;
+  int i = FPU_rm;
+  FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
+  s32 tag_word = fpu_tag_word;
+  int regnr = top & 7, regnri = ((regnr + i) & 7);
+  u_char st0_tag = (tag_word >> (regnr*2)) & 3;
+  u_char sti_tag = (tag_word >> (regnri*2)) & 3;
+
+  if ( st0_tag == TAG_Empty )
+    {
+      if ( sti_tag == TAG_Empty )
+       {
+         FPU_stack_underflow();
+         FPU_stack_underflow_i(i);
+         return;
+       }
+      if ( control_word & CW_Invalid )
+       {
+         /* Masked response */
+         FPU_copy_to_reg0(sti_ptr, sti_tag);
+       }
+      FPU_stack_underflow_i(i);
+      return;
+    }
+  if ( sti_tag == TAG_Empty )
+    {
+      if ( control_word & CW_Invalid )
+       {
+         /* Masked response */
+         FPU_copy_to_regi(st0_ptr, st0_tag, i);
+       }
+      FPU_stack_underflow();
+      return;
+    }
+  clear_C1();
+
+  reg_copy(st0_ptr, &t);
+  reg_copy(sti_ptr, st0_ptr);
+  reg_copy(&t, sti_ptr);
+
+  tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
+  tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
+  fpu_tag_word = tag_word;
+}
+
+
+void ffree_()
+{
+  /* ffree st(i) */
+  FPU_settagi(FPU_rm, TAG_Empty);
+}
+
+
+void ffreep()
+{
+  /* ffree st(i) + pop - unofficial code */
+  FPU_settagi(FPU_rm, TAG_Empty);
+  FPU_pop();
+}
+
+
+void fst_i_()
+{
+  /* fst st(i) */
+  FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+}
+
+
+void fstp_i()
+{
+  /* fstp st(i) */
+  FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+  FPU_pop();
+}
+
diff --git a/sid/component/bochs/fpu/fpu_emu.h b/sid/component/bochs/fpu/fpu_emu.h
new file mode 100644 (file)
index 0000000..2e9d4bd
--- /dev/null
@@ -0,0 +1,251 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_emu.h                                                                |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@suburbia.net             |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+#ifndef _FPU_EMU_H_
+#define _FPU_EMU_H_
+
+/*
+ * Define PECULIAR_486 to get a closer approximation to 80486 behaviour,
+ * rather than behaviour which appears to be cleaner.
+ * This is a matter of opinion: for all I know, the 80486 may simply
+ * be complying with the IEEE spec. Maybe one day I'll get to see the
+ * spec...
+ */
+#define PECULIAR_486
+
+// change a pointer to an int, with type conversions that make it legal.
+// On machines with 64-bit pointers, compilers complain when you typecast
+// a 64-bit pointer into a 32-bit integer.
+#define PTR2INT(x) ((bx_ptr_equiv_t)(void *)(x))
+
+#ifdef __ASSEMBLY__
+#include "fpu_asm.h"
+#define        Const(x)        $##x
+#else
+#include <asm/types.h>
+#define        Const(x)        x
+#endif
+
+#define EXP_BIAS       Const(0)
+#define EXP_OVER       Const(0x4000)    /* smallest invalid large exponent */
+#define        EXP_UNDER       Const(-0x3fff)   /* largest invalid small exponent */
+#define EXP_WAY_UNDER   Const(-0x6000)   /* Below the smallest denormal, but
+                                           still a 16 bit nr. */
+#define EXP_Infinity    EXP_OVER
+#define EXP_NaN         EXP_OVER
+
+#define EXTENDED_Ebias Const(0x3fff)
+#define EXTENDED_Emin (-0x3ffe)  /* smallest valid exponent */
+
+#define SIGN_POS       Const(0)
+#define SIGN_NEG       Const(0x80)
+
+#define SIGN_Positive  Const(0)
+#define SIGN_Negative  Const(0x8000)
+
+
+/* Keep the order TAG_Valid, TAG_Zero, TW_Denormal */
+/* The following fold to 2 (Special) in the Tag Word */
+#define TW_Denormal     Const(4)        /* De-normal */
+#define TW_Infinity    Const(5)        /* + or - infinity */
+#define        TW_NaN          Const(6)        /* Not a Number */
+#define        TW_Unsupported  Const(7)        /* Not supported by an 80486 */
+
+#define TAG_Valid      Const(0)        /* valid */
+#define TAG_Zero       Const(1)        /* zero */
+#define TAG_Special    Const(2)        /* De-normal, + or - infinity,
+                                          or Not a Number */
+#define TAG_Empty      Const(3)        /* empty */
+
+#define LOADED_DATA    Const(10101)    /* Special st() number to identify
+                                          loaded data (not on stack). */
+
+/* A few flags (must be >= 0x10). */
+#define REV             0x10
+#define DEST_RM         0x20
+#define LOADED          0x40
+
+#define FPU_Exception   Const(0x80000000)   /* Added to tag returns. */
+
+
+#ifndef __ASSEMBLY__
+
+#include "fpu_system.h"
+
+#include <asm/sigcontext.h>   /* for struct _fpstate */
+#include <asm/math_emu.h>
+#include <linux/linkage.h>
+
+/*
+#define RE_ENTRANT_CHECKING
+ */
+
+#ifdef RE_ENTRANT_CHECKING
+extern u_char emulating;
+#  define RE_ENTRANT_CHECK_OFF emulating = 0
+#  define RE_ENTRANT_CHECK_ON emulating = 1
+#else
+#  define RE_ENTRANT_CHECK_OFF
+#  define RE_ENTRANT_CHECK_ON
+#endif /* ifdef RE_ENTRANT_CHECKING */
+
+#define FWAIT_OPCODE 0x9b
+#define OP_SIZE_PREFIX 0x66
+#define ADDR_SIZE_PREFIX 0x67
+#define PREFIX_CS 0x2e
+#define PREFIX_DS 0x3e
+#define PREFIX_ES 0x26
+#define PREFIX_SS 0x36
+#define PREFIX_FS 0x64
+#define PREFIX_GS 0x65
+#define PREFIX_REPE 0xf3
+#define PREFIX_REPNE 0xf2
+#define PREFIX_LOCK 0xf0
+#define PREFIX_CS_ 1
+#define PREFIX_DS_ 2
+#define PREFIX_ES_ 3
+#define PREFIX_FS_ 4
+#define PREFIX_GS_ 5
+#define PREFIX_SS_ 6
+#define PREFIX_DEFAULT 7
+
+struct address {
+  u32 offset;
+#ifdef EMU_BIG_ENDIAN
+  u32 empty:5;
+  u32 opcode:11;
+  u32 selector:16;
+#else
+  u32 selector:16;
+  u32 opcode:11;
+  u32 empty:5;
+#endif
+} GCC_ATTRIBUTE((packed));
+
+struct fpu__reg {
+#ifdef EMU_BIG_ENDIAN
+  u32 sigh;
+  u32 sigl;
+  s16 exp;   /* Signed quantity used in internal arithmetic. */
+#else
+  u32 sigl;
+  u32 sigh;
+  s16 exp;   /* Signed quantity used in internal arithmetic. */
+#endif
+} GCC_ATTRIBUTE((aligned(16), packed));
+
+#ifdef EMU_BIG_ENDIAN
+#define MAKE_REG(s,e,l,h) { h, l, \
+                           ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
+#else
+#define MAKE_REG(s,e,l,h) { l, h, \
+                           ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
+#endif
+
+typedef void (*FUNC)(void);
+typedef struct fpu__reg FPU_REG;
+typedef void (*FUNC_ST0)(FPU_REG *st0_ptr, u_char st0_tag);
+typedef struct { u_char address_size, operand_size, segment; }
+        GCC_ATTRIBUTE((packed)) overrides;
+/* This structure is 32 bits: */
+typedef struct { overrides override;
+                u_char default_mode; } 
+    GCC_ATTRIBUTE((packed)) fpu_addr_modes;
+/* PROTECTED has a restricted meaning in the emulator; it is used
+   to signal that the emulator needs to do special things to ensure
+   that protection is respected in a segmented model. */
+#define PROTECTED 4
+#define SIXTEEN   1         /* We rely upon this being 1 (true) */
+#define VM86      SIXTEEN
+#define PM16      (SIXTEEN | PROTECTED)
+#define SEG32     PROTECTED
+extern u_char const data_sizes_16[32];
+
+#define register_base ((u_char *) registers )
+#define fpu_register(x)  ( * ((FPU_REG *)( register_base + sizeof(FPU_REG) * (x & 7) )) )
+#define        st(x)      ( * ((FPU_REG *)( register_base + sizeof(FPU_REG) * ((top+x) & 7) )) )
+
+#define        STACK_OVERFLOW  (FPU_stackoverflow(&st_new_ptr))
+#define        NOT_EMPTY(i)    (!FPU_empty_i(i))
+
+#define        NOT_EMPTY_ST0   (st0_tag ^ TAG_Empty)
+
+#define poppop() { FPU_pop(); FPU_pop(); }
+
+/* push() does not affect the tags */
+#define push() { top--; }
+
+#ifdef EMU_BIG_ENDIAN
+#define signbyte(a) (((u_char *)(a))[8])
+#else
+#define signbyte(a) (((u_char *)(a))[9])
+#endif
+#define getsign(a) (signbyte(a) & 0x80)
+#define setsign(a,b) { if (b) signbyte(a) |= 0x80; else signbyte(a) &= 0x7f; }
+#define copysign(a,b) { if (getsign(a)) signbyte(b) |= 0x80; \
+                        else signbyte(b) &= 0x7f; }
+#define changesign(a) { signbyte(a) ^= 0x80; }
+#define setpositive(a) { signbyte(a) &= 0x7f; }
+#define setnegative(a) { signbyte(a) |= 0x80; }
+#define signpositive(a) ( (signbyte(a) & 0x80) == 0 )
+#define signnegative(a) (signbyte(a) & 0x80)
+
+#ifdef EMU_BIG_ENDIAN
+#define significand(x) ( ((u64 *)&((x)->sigh))[0] )
+#else
+#define significand(x) ( ((u64 *)&((x)->sigl))[0] )
+#endif
+
+BX_C_INLINE
+void reg_copy(FPU_REG const *x, FPU_REG *y)
+{
+  y->exp = x->exp;
+  significand(y) = significand(x);
+}
+
+#define exponent(x)  (((x)->exp & 0x7fff) - EXTENDED_Ebias)
+#define setexponentpos(x,y) { (x)->exp = ((y) + EXTENDED_Ebias) & 0x7fff; }
+#define exponent16(x)         (x)->exp
+#define setexponent16(x,y)  { (x)->exp = (y); }
+#define addexponent(x,y)    { (x)->exp += (y); }
+#define stdexp(x)           { (x)->exp += EXTENDED_Ebias; }
+
+#define isdenormal(ptr)   (exponent(ptr) == EXP_BIAS+EXP_UNDER)
+
+/*----- Prototypes for functions written in assembler -----*/
+/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
+
+asmlinkage int FPU_normalize_nuo(FPU_REG *x, int bias);
+asmlinkage int FPU_u_sub(FPU_REG const *arg1, FPU_REG const *arg2,
+                        FPU_REG *answ, u16 control_w, u_char sign,
+                        s32 expa, s32 expb);
+asmlinkage int FPU_u_mul(FPU_REG const *arg1, FPU_REG const *arg2,
+                        FPU_REG *answ, u16 control_w, u_char sign,
+                        s32 expon);
+asmlinkage int FPU_u_div(FPU_REG const *arg1, FPU_REG const *arg2,
+                        FPU_REG *answ, u16 control_w, u_char sign);
+asmlinkage int FPU_u_add(FPU_REG const *arg1, FPU_REG const *arg2,
+                        FPU_REG *answ, u16 control_w, u_char sign,
+                        s32 expa, s32 expb);
+asmlinkage int wm_sqrt(FPU_REG *n, int dummy1, int dummy2,
+                      u16 control_w, u_char sign);
+asmlinkage u32 FPU_shrx(void *l, u32 x);
+asmlinkage u32 FPU_shrxs(void *v, u32 x);
+asmlinkage u32 FPU_div_small(u64 *x, u32 y);
+asmlinkage int FPU_round(FPU_REG *arg, u32 extent, int dummy,
+                        u16 control_w, u_char sign);
+
+#ifndef MAKING_PROTO
+#include "fpu_proto.h"
+#endif
+
+#endif /* defined __ASSEMBLY__ */
+
+#endif /* !defined _FPU_EMU_H_ */
diff --git a/sid/component/bochs/fpu/fpu_entry.c b/sid/component/bochs/fpu/fpu_entry.c
new file mode 100644 (file)
index 0000000..567c87a
--- /dev/null
@@ -0,0 +1,1074 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_entry.c                                                              |
+ |                                                                           |
+ | The entry functions for wm-FPU-emu                                        |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1996,1997                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ | See the files "README" and "COPYING" for further copyright and warranty   |
+ | information.                                                              |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | math_emulate(), restore_i387_soft() and save_i387_soft() are the only     |
+ | entry points for wm-FPU-emu.                                              |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+#include "status_w.h"
+
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+
+#define __BAD__ FPU_illegal   /* Illegal on an 80486, causes SIGILL */
+
+#ifndef NO_UNDOC_CODE    /* Un-documented FPU op-codes supported by default. */
+
+/* WARNING: These codes are not documented by Intel in their 80486 manual
+   and may not work on FPU clones or later Intel FPUs. */
+
+/* Changes to support the un-doc codes provided by Linus Torvalds. */
+
+#define _d9_d8_ fstp_i    /* unofficial code (19) */
+#define _dc_d0_ fcom_st   /* unofficial code (14) */
+#define _dc_d8_ fcompst   /* unofficial code (1c) */
+#define _dd_c8_ fxch_i    /* unofficial code (0d) */
+#define _de_d0_ fcompst   /* unofficial code (16) */
+#define _df_c0_ ffreep    /* unofficial code (07) ffree + pop */
+#define _df_c8_ fxch_i    /* unofficial code (0f) */
+#define _df_d0_ fstp_i    /* unofficial code (17) */
+#define _df_d8_ fstp_i    /* unofficial code (1f) */
+
+static FUNC const st_instr_table[64] = {
+  fadd__,   fld_i_,     __BAD__, __BAD__, fadd_i,  ffree_,  faddp_,  _df_c0_,
+  fmul__,   fxch_i,     __BAD__, __BAD__, fmul_i,  _dd_c8_, fmulp_,  _df_c8_,
+  fcom_st,  fp_nop,     __BAD__, __BAD__, _dc_d0_, fst_i_,  _de_d0_, _df_d0_,
+  fcompst,  _d9_d8_,    __BAD__, __BAD__, _dc_d8_, fstp_i,  fcompp,  _df_d8_,
+  fsub__,   FPU_etc,    __BAD__, finit_,  fsubri,  fucom_,  fsubrp,  fstsw_,
+  fsubr_,   fconst,     fucompp, __BAD__, fsub_i,  fucomp,  fsubp_,  __BAD__,
+  fdiv__,   FPU_triga,  __BAD__, __BAD__, fdivri,  __BAD__, fdivrp,  __BAD__,
+  fdivr_,   FPU_trigb,  __BAD__, __BAD__, fdiv_i,  __BAD__, fdivp_,  __BAD__,
+};
+
+#else     /* Support only documented FPU op-codes */
+
+static FUNC const st_instr_table[64] = {
+  fadd__,   fld_i_,     __BAD__, __BAD__, fadd_i,  ffree_,  faddp_,  __BAD__,
+  fmul__,   fxch_i,     __BAD__, __BAD__, fmul_i,  __BAD__, fmulp_,  __BAD__,
+  fcom_st,  fp_nop,     __BAD__, __BAD__, __BAD__, fst_i_,  __BAD__, __BAD__,
+  fcompst,  __BAD__,    __BAD__, __BAD__, __BAD__, fstp_i,  fcompp,  __BAD__,
+  fsub__,   FPU_etc,    __BAD__, finit_,  fsubri,  fucom_,  fsubrp,  fstsw_,
+  fsubr_,   fconst,     fucompp, __BAD__, fsub_i,  fucomp,  fsubp_,  __BAD__,
+  fdiv__,   FPU_triga,  __BAD__, __BAD__, fdivri,  __BAD__, fdivrp,  __BAD__,
+  fdivr_,   FPU_trigb,  __BAD__, __BAD__, fdiv_i,  __BAD__, fdivp_,  __BAD__,
+};
+
+#endif /* NO_UNDOC_CODE */
+
+
+#define _NONE_ 0   /* Take no special action */
+#define _REG0_ 1   /* Need to check for not empty st(0) */
+#define _REGI_ 2   /* Need to check for not empty st(0) and st(rm) */
+#define _REGi_ 0   /* Uses st(rm) */
+#define _PUSH_ 3   /* Need to check for space to push onto stack */
+#define _null_ 4   /* Function illegal or not implemented */
+#define _REGIi 5   /* Uses st(0) and st(rm), result to st(rm) */
+#define _REGIp 6   /* Uses st(0) and st(rm), result to st(rm) then pop */
+#define _REGIc 0   /* Compare st(0) and st(rm) */
+#define _REGIn 0   /* Uses st(0) and st(rm), but handle checks later */
+
+#ifndef NO_UNDOC_CODE
+
+/* Un-documented FPU op-codes supported by default. (see above) */
+
+static u_char const type_table[64] = {
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
+  _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
+  _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+  _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+  _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+  _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+
+#else     /* Support only documented FPU op-codes */
+
+static u_char const type_table[64] = {
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
+  _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+  _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
+  _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
+  _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+  _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+  _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+
+#endif /* NO_UNDOC_CODE */
+
+
+#ifndef USE_WITH_CPU_SIM
+
+
+#ifdef RE_ENTRANT_CHECKING
+u_char emulating=0;
+#endif /* RE_ENTRANT_CHECKING */
+
+static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+                       overrides *override);
+
+asmlinkage void math_emulate(long arg)
+{
+  u_char  FPU_modrm, byte1;
+  unsigned short code;
+  fpu_addr_modes addr_modes;
+  int unmasked;
+  FPU_REG loaded_data;
+  FPU_REG *st0_ptr;
+  u_char         loaded_tag, st0_tag;
+  void *data_address;
+  struct address data_sel_off;
+  struct address entry_sel_off;
+  u32 code_base = 0;
+  u32 code_limit = 0;  /* Initialized to stop compiler warnings */
+  struct desc_struct code_descriptor;
+
+#ifdef RE_ENTRANT_CHECKING
+  if ( emulating )
+    {
+      printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
+    }
+  RE_ENTRANT_CHECK_ON;
+#endif /* RE_ENTRANT_CHECKING */
+
+  if (!current->used_math)
+    {
+      finit();
+      current->used_math = 1;
+    }
+
+  SETUP_DATA_AREA(arg);
+
+  FPU_ORIG_EIP = FPU_EIP;
+
+  if ( (FPU_EFLAGS & 0x00020000) != 0 )
+    {
+      /* Virtual 8086 mode */
+      addr_modes.default_mode = VM86;
+      FPU_EIP += code_base = FPU_CS << 4;
+      code_limit = code_base + 0xffff;  /* Assumes code_base <= 0xffff0000 */
+    }
+  else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
+    {
+      addr_modes.default_mode = 0;
+    }
+  else if ( FPU_CS == __KERNEL_CS )
+    {
+      printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
+      panic("Math emulation needed in kernel");
+    }
+  else
+    {
+
+      if ( (FPU_CS & 4) != 4 )   /* Must be in the LDT */
+       {
+         /* Can only handle segmented addressing via the LDT
+            for now, and it must be 16 bit */
+         printk("FPU emulator: Unsupported addressing mode\n");
+         math_abort(FPU_info, SIGILL);
+       }
+
+      if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) )
+       {
+         /* The above test may be wrong, the book is not clear */
+         /* Segmented 32 bit protected mode */
+         addr_modes.default_mode = SEG32;
+       }
+      else
+       {
+         /* 16 bit protected mode */
+         addr_modes.default_mode = PM16;
+       }
+      FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
+      code_limit = code_base
+       + (SEG_LIMIT(code_descriptor)+1) * SEG_GRANULARITY(code_descriptor)
+         - 1;
+      if ( code_limit < code_base ) code_limit = 0xffffffff;
+    }
+
+  FPU_lookahead = 1;
+  if (current->flags & PF_PTRACED)
+    FPU_lookahead = 0;
+
+  if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
+                    &addr_modes.override) )
+    {
+      RE_ENTRANT_CHECK_OFF;
+      printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
+            "FPU emulator: self-modifying code! (emulation impossible)\n",
+            byte1);
+      RE_ENTRANT_CHECK_ON;
+      EXCEPTION(EX_INTERNAL|0x126);
+      math_abort(FPU_info,SIGILL);
+    }
+
+do_another_FPU_instruction:
+
+  no_ip_update = 0;
+
+  FPU_EIP++;  /* We have fetched the prefix and first code bytes. */
+
+  if ( addr_modes.default_mode )
+    {
+      /* This checks for the minimum instruction bytes.
+        We also need to check any extra (address mode) code access. */
+      if ( FPU_EIP > code_limit )
+       math_abort(FPU_info,SIGSEGV);
+    }
+
+  if ( (byte1 & 0xf8) != 0xd8 )
+    {
+      if ( byte1 == FWAIT_OPCODE )
+       {
+         if (partial_status & SW_Summary)
+           goto do_the_FPU_interrupt;
+         else
+           goto FPU_fwait_done;
+       }
+#ifdef PARANOID
+      EXCEPTION(EX_INTERNAL|0x128);
+      math_abort(FPU_info,SIGILL);
+#endif /* PARANOID */
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_code_verify_area(1);
+  FPU_get_user(FPU_modrm, (u_char *) FPU_EIP);
+  RE_ENTRANT_CHECK_ON;
+  FPU_EIP++;
+
+  if (partial_status & SW_Summary)
+    {
+      /* Ignore the error for now if the current instruction is a no-wait
+        control instruction */
+      /* The 80486 manual contradicts itself on this topic,
+        but a real 80486 uses the following instructions:
+        fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
+       */
+      code = (FPU_modrm << 8) | byte1;
+      if ( ! ( (((code & 0xf803) == 0xe003) ||    /* fnclex, fninit, fnstsw */
+               (((code & 0x3003) == 0x3001) &&   /* fnsave, fnstcw, fnstenv,
+                                                    fnstsw */
+                ((code & 0xc000) != 0xc000))) ) )
+       {
+         /*
+          *  We need to simulate the action of the kernel to FPU
+          *  interrupts here.
+          */
+       do_the_FPU_interrupt:
+
+         FPU_EIP = FPU_ORIG_EIP;       /* Point to current FPU instruction. */
+
+         RE_ENTRANT_CHECK_OFF;
+         current->tss.trap_no = 16;
+         current->tss.error_code = 0;
+         send_sig(SIGFPE, current, 1);
+         return;
+       }
+    }
+
+  entry_sel_off.offset = FPU_ORIG_EIP;
+  entry_sel_off.selector = FPU_CS;
+  entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
+
+  FPU_rm = FPU_modrm & 7;
+
+  if ( FPU_modrm < 0300 )
+    {
+      /* All of these instructions use the mod/rm byte to get a data address */
+
+      if ( (addr_modes.default_mode & SIXTEEN)
+         ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
+       data_address = FPU_get_address_16(FPU_modrm, (u32 *)&FPU_EIP, &data_sel_off,
+                                         addr_modes);
+      else
+       data_address = FPU_get_address(FPU_modrm, (u32 *)&FPU_EIP, &data_sel_off,
+                                      addr_modes);
+
+      if ( addr_modes.default_mode )
+       {
+         if ( FPU_EIP-1 > code_limit )
+           math_abort(FPU_info,SIGSEGV);
+       }
+
+      if ( !(byte1 & 1) )
+       {
+         unsigned short status1 = partial_status;
+
+         st0_ptr = &st(0);
+         st0_tag = FPU_gettag0();
+
+         /* Stack underflow has priority */
+         if ( NOT_EMPTY_ST0 )
+           {
+             if ( addr_modes.default_mode & PROTECTED )
+               {
+                 /* This table works for 16 and 32 bit protected mode */
+                 if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
+                   math_abort(FPU_info,SIGSEGV);
+               }
+
+             unmasked = 0;  /* Do this here to stop compiler warnings. */
+             switch ( (byte1 >> 1) & 3 )
+               {
+               case 0:
+                 unmasked = FPU_load_single((float *)data_address,
+                                            &loaded_data);
+                 loaded_tag = unmasked & 0xff;
+                 unmasked &= ~0xff;
+                 break;
+               case 1:
+                 loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data); // bbd: was (u32*)
+                 break;
+               case 2:
+                 unmasked = FPU_load_double((double *)data_address,
+                                            &loaded_data);
+                 loaded_tag = unmasked & 0xff;
+                 unmasked &= ~0xff;
+                 break;
+               case 3:
+               default:  /* Used here to suppress gcc warnings. */
+                 loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+                 break;
+               }
+
+             /* No more access to user memory, it is safe
+                to use static data now */
+
+             /* NaN operands have the next priority. */
+             /* We have to delay looking at st(0) until after
+                loading the data, because that data might contain an SNaN */
+             if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
+                 ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
+               {
+                 /* Restore the status word; we might have loaded a
+                    denormal. */
+                 partial_status = status1;
+                 if ( (FPU_modrm & 0x30) == 0x10 )
+                   {
+                     /* fcom or fcomp */
+                     EXCEPTION(EX_Invalid);
+                     setcc(SW_C3 | SW_C2 | SW_C0);
+                     if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+                       FPU_pop();             /* fcomp, masked, so we pop. */
+                   }
+                 else
+                   {
+                     if ( loaded_tag == TAG_Special )
+                       loaded_tag = FPU_Special(&loaded_data);
+#ifdef PECULIAR_486
+                     /* This is not really needed, but gives behaviour
+                        identical to an 80486 */
+                     if ( (FPU_modrm & 0x28) == 0x20 )
+                       /* fdiv or fsub */
+                       real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
+                     else
+#endif /* PECULIAR_486 */
+                       /* fadd, fdivr, fmul, or fsubr */
+                       real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
+                   }
+                 goto reg_mem_instr_done;
+               }
+
+             if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
+               {
+                 /* Is not a comparison instruction. */
+                 if ( (FPU_modrm & 0x38) == 0x38 )
+                   {
+                     /* fdivr */
+                     if ( (st0_tag == TAG_Zero) &&
+                          ((loaded_tag == TAG_Valid)
+                           || (loaded_tag == TAG_Special
+                               && isdenormal(&loaded_data))) )
+                       {
+                         if ( FPU_divide_by_zero(0, getsign(&loaded_data))
+                              < 0 )
+                           {
+                             /* We use the fact here that the unmasked
+                                exception in the loaded data was for a
+                                denormal operand */
+                             /* Restore the state of the denormal op bit */
+                             partial_status &= ~SW_Denorm_Op;
+                             partial_status |= status1 & SW_Denorm_Op;
+                           }
+                         else
+                           setsign(st0_ptr, getsign(&loaded_data));
+                       }
+                   }
+                 goto reg_mem_instr_done;
+               }
+
+             switch ( (FPU_modrm >> 3) & 7 )
+               {
+               case 0:         /* fadd */
+                 clear_C1();
+                 FPU_add(&loaded_data, loaded_tag, 0, control_word);
+                 break;
+               case 1:         /* fmul */
+                 clear_C1();
+                 FPU_mul(&loaded_data, loaded_tag, 0, control_word);
+                 break;
+               case 2:         /* fcom */
+                 FPU_compare_st_data(&loaded_data, loaded_tag);
+                 break;
+               case 3:         /* fcomp */
+                 if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
+                      && !unmasked )
+                   FPU_pop();
+                 break;
+               case 4:         /* fsub */
+                 clear_C1();
+                 // bbd: loaded_data used to be typecast to an int, but 
+                 // this corrupted the pointer on 64-bit machines.
+                 // Now FPU_sub and similar take a FPU_REG* here instead. 
+                 FPU_sub(LOADED|loaded_tag, &loaded_data, control_word);
+                 break;
+               case 5:         /* fsubr */
+                 clear_C1();
+                 FPU_sub(REV|LOADED|loaded_tag, &loaded_data, control_word);
+                 break;
+               case 6:         /* fdiv */
+                 clear_C1();
+                 FPU_div(LOADED|loaded_tag, &loaded_data, control_word);
+                 break;
+               case 7:         /* fdivr */
+                 clear_C1();
+                 if ( st0_tag == TAG_Zero )
+                   partial_status = status1;  /* Undo any denorm tag,
+                                                 zero-divide has priority. */
+                 FPU_div(REV|LOADED|loaded_tag, &loaded_data, control_word);
+                 break;
+               }
+           }
+         else
+           {
+             if ( (FPU_modrm & 0x30) == 0x10 )
+               {
+                 /* The instruction is fcom or fcomp */
+                 EXCEPTION(EX_StackUnder);
+                 setcc(SW_C3 | SW_C2 | SW_C0);
+                 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+                   FPU_pop();             /* fcomp */
+               }
+             else
+               FPU_stack_underflow();
+           }
+       reg_mem_instr_done:
+         operand_address = data_sel_off;
+       }
+      else
+       {
+         if ( !(no_ip_update =
+                FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
+                               addr_modes, data_address)) )
+           {
+             operand_address = data_sel_off;
+           }
+       }
+
+    }
+  else
+    {
+      /* None of these instructions access user memory */
+      u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
+
+#ifdef PECULIAR_486
+      /* This is supposed to be undefined, but a real 80486 seems
+        to do this: */
+      operand_address.offset = 0;
+      operand_address.selector = FPU_DS;
+#endif /* PECULIAR_486 */
+
+      st0_ptr = &st(0);
+      st0_tag = FPU_gettag0();
+      switch ( type_table[(int) instr_index] )
+       {
+       case _NONE_:   /* also _REGIc: _REGIn */
+         break;
+       case _REG0_:
+         if ( !NOT_EMPTY_ST0 )
+           {
+             FPU_stack_underflow();
+             goto FPU_instruction_done;
+           }
+         break;
+       case _REGIi:
+         if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+           {
+             FPU_stack_underflow_i(FPU_rm);
+             goto FPU_instruction_done;
+           }
+         break;
+       case _REGIp:
+         if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+           {
+             FPU_stack_underflow_pop(FPU_rm);
+             goto FPU_instruction_done;
+           }
+         break;
+       case _REGI_:
+         if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+           {
+             FPU_stack_underflow();
+             goto FPU_instruction_done;
+           }
+         break;
+       case _PUSH_:     /* Only used by the fld st(i) instruction */
+         break;
+       case _null_:
+         FPU_illegal();
+         goto FPU_instruction_done;
+       default:
+         EXCEPTION(EX_INTERNAL|0x111);
+         goto FPU_instruction_done;
+       }
+      (*st_instr_table[(int) instr_index])();
+
+FPU_instruction_done:
+      ;
+    }
+
+  if ( ! no_ip_update )
+    instruction_address = entry_sel_off;
+
+FPU_fwait_done:
+
+  if (FPU_lookahead && !current->need_resched)
+    {
+      FPU_ORIG_EIP = FPU_EIP - code_base;
+      if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
+                       &addr_modes.override) )
+       goto do_another_FPU_instruction;
+    }
+
+  if ( addr_modes.default_mode )
+    FPU_EIP -= code_base;
+
+  RE_ENTRANT_CHECK_OFF;
+}
+
+
+/* Support for prefix bytes is not yet complete. To properly handle
+   all prefix bytes, further changes are needed in the emulator code
+   which accesses user address space. Access to separate segments is
+   important for msdos emulation. */
+static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+                       overrides *override)
+{
+  u_char byte;
+  u_char *ip = *fpu_eip;
+
+  *override = (overrides) { 0, 0, PREFIX_DEFAULT };       /* defaults */
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_code_verify_area(1);
+  FPU_get_user(byte, ip);
+  RE_ENTRANT_CHECK_ON;
+
+  while ( 1 )
+    {
+      switch ( byte )
+       {
+       case ADDR_SIZE_PREFIX:
+         override->address_size = ADDR_SIZE_PREFIX;
+         goto do_next_byte;
+
+       case OP_SIZE_PREFIX:
+         override->operand_size = OP_SIZE_PREFIX;
+         goto do_next_byte;
+
+       case PREFIX_CS:
+         override->segment = PREFIX_CS_;
+         goto do_next_byte;
+       case PREFIX_ES:
+         override->segment = PREFIX_ES_;
+         goto do_next_byte;
+       case PREFIX_SS:
+         override->segment = PREFIX_SS_;
+         goto do_next_byte;
+       case PREFIX_FS:
+         override->segment = PREFIX_FS_;
+         goto do_next_byte;
+       case PREFIX_GS:
+         override->segment = PREFIX_GS_;
+         goto do_next_byte;
+       case PREFIX_DS:
+         override->segment = PREFIX_DS_;
+         goto do_next_byte;
+
+/* lock is not a valid prefix for FPU instructions,
+   let the cpu handle it to generate a SIGILL. */
+/*     case PREFIX_LOCK: */
+
+         /* rep.. prefixes have no meaning for FPU instructions */
+       case PREFIX_REPE:
+       case PREFIX_REPNE:
+
+       do_next_byte:
+         ip++;
+         RE_ENTRANT_CHECK_OFF;
+         FPU_code_verify_area(1);
+         FPU_get_user(byte, ip);
+         RE_ENTRANT_CHECK_ON;
+         break;
+       case FWAIT_OPCODE:
+         *Byte = byte;
+         return 1;
+       default:
+         if ( (byte & 0xf8) == 0xd8 )
+           {
+             *Byte = byte;
+             *fpu_eip = ip;
+             return 1;
+           }
+         else
+           {
+             /* Not a valid sequence of prefix bytes followed by
+                an FPU instruction. */
+             *Byte = byte;  /* Needed for error message. */
+             return 0;
+           }
+       }
+    }
+}
+
+
+void math_abort(struct info * info, unsigned int signal)
+{
+       FPU_EIP = FPU_ORIG_EIP;
+       current->tss.trap_no = 16;
+       current->tss.error_code = 0;
+       send_sig(signal,current,1);
+       RE_ENTRANT_CHECK_OFF;
+       __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
+#ifdef PARANOID
+      printk("ERROR: wm-FPU-emu math_abort failed!\n");
+#endif /* PARANOID */
+}
+
+
+
+#define S387 ((struct i387_soft_struct *)s387)
+#define sstatus_word() \
+  ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
+
+int restore_i387_soft(void *s387, struct _fpstate *buf)
+{
+  u_char *d = (u_char *)buf;
+  int offset, other, i, tags, regnr, tag, newtop;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, d, 7*4 + 8*10);
+  if (__copy_from_user(&S387->cwd, d, 7*4))
+    return -1;
+  RE_ENTRANT_CHECK_ON;
+
+  d += 7*4;
+
+  S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
+  offset = (S387->ftop & 7) * 10;
+  other = 80 - offset;
+
+  RE_ENTRANT_CHECK_OFF;
+  /* Copy all registers in stack order. */
+  if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other))
+    return -1;
+  if ( offset )
+    if (__copy_from_user((u_char *)&S387->st_space, d+other, offset))
+      return -1;
+  RE_ENTRANT_CHECK_ON;
+
+  /* The tags may need to be corrected now. */
+  tags = S387->twd;
+  newtop = S387->ftop;
+  for ( i = 0; i < 8; i++ )
+    {
+      regnr = (i+newtop) & 7;
+      if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty )
+       {
+         /* The loaded data over-rides all other cases. */
+         tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr));
+         tags &= ~(3 << (regnr*2));
+         tags |= (tag & 3) << (regnr*2);
+       }
+    }
+  S387->twd = tags;
+
+  return 0;
+}
+
+
+int save_i387_soft(void *s387, struct _fpstate * buf)
+{
+  u_char *d = (u_char *)buf;
+  int offset = (S387->ftop & 7) * 10, other = 80 - offset;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE, d, 7*4 + 8*10);
+#ifdef PECULIAR_486
+  S387->cwd &= ~0xe080;
+  /* An 80486 sets nearly all of the reserved bits to 1. */
+  S387->cwd |= 0xffff0040;
+  S387->swd = sstatus_word() | 0xffff0000;
+  S387->twd |= 0xffff0000;
+  S387->fcs &= ~0xf8000000;
+  S387->fos |= 0xffff0000;
+#endif /* PECULIAR_486 */
+  __copy_to_user(d, &S387->cwd, 7*4);
+  RE_ENTRANT_CHECK_ON;
+
+  d += 7*4;
+
+  RE_ENTRANT_CHECK_OFF;
+  /* Copy all registers in stack order. */
+  if (__copy_to_user(d, ((u_char *)&S387->st_space)+offset, other))
+    return -1;
+  if ( offset )
+    if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset))
+      return -1
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+#else  /* #ifndef USE_WITH_CPU_SIM */
+
+
+/* Note, this is a version of fpu_entry.c, modified to interface
+ * to a CPU simulator, rather than a kernel.
+ *
+ * Ported by Kevin Lawton Sep 20, 1999
+ */
+
+
+  asmlinkage void
+math_emulate2(fpu_addr_modes addr_modes,
+              u_char  FPU_modrm,
+              u_char byte1,
+              void *data_address,
+              struct address data_sel_off,
+              struct address entry_sel_off)
+{
+  u16 code;
+  int unmasked;
+  FPU_REG loaded_data;
+  FPU_REG *st0_ptr;
+  u_char    loaded_tag, st0_tag;
+
+
+  // assuming byte is 0xd8..0xdf or 0xdb==FWAIT
+
+  // lock is not a valid prefix for FPU instructions, +++
+  // let the cpu handle it to generate a SIGILL.
+
+
+  no_ip_update = 0;
+
+  if ( byte1 == FWAIT_OPCODE ) {
+    if (partial_status & SW_Summary)
+      goto do_the_FPU_interrupt;
+    else
+      goto FPU_fwait_done;
+    }
+
+  if (partial_status & SW_Summary) {
+    /* Ignore the error for now if the current instruction is a no-wait
+       control instruction */
+    /* The 80486 manual contradicts itself on this topic,
+       but a real 80486 uses the following instructions:
+       fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
+       */
+    code = (FPU_modrm << 8) | byte1;
+    if ( ! ( (((code & 0xf803) == 0xe003) ||    /* fnclex, fninit, fnstsw */
+              (((code & 0x3003) == 0x3001) &&   /* fnsave, fnstcw, fnstenv,
+                                                   fnstsw */
+               ((code & 0xc000) != 0xc000))) ) ) {
+      /*
+       *  We need to simulate the action of the kernel to FPU
+       *  interrupts here.
+       */
+do_the_FPU_interrupt:
+
+      math_abort(FPU_info, SIGFPE);
+      }
+    }
+
+  entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
+
+  FPU_rm = FPU_modrm & 7;
+
+  if ( FPU_modrm < 0300 ) {
+      /* All of these instructions use the mod/rm byte to get a data address */
+
+      if ( !(byte1 & 1) ) {
+          u16 status1 = partial_status;
+
+          st0_ptr = &st(0);
+          st0_tag = FPU_gettag0();
+
+          /* Stack underflow has priority */
+          if ( NOT_EMPTY_ST0 ) {
+              if ( addr_modes.default_mode & PROTECTED )
+                {
+                  /* This table works for 16 and 32 bit protected mode */
+                  if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
+                    math_abort(FPU_info, SIGSEGV);
+                }
+
+              unmasked = 0;  /* Do this here to stop compiler warnings. */
+              switch ( (byte1 >> 1) & 3 )
+                {
+                case 0:
+                  unmasked = FPU_load_single((float *)data_address,
+                                             &loaded_data);
+                  loaded_tag = unmasked & 0xff;
+                  unmasked &= ~0xff;
+                  break;
+                case 1:
+                  loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data);  // bbd: was (u32 *)
+                  break;
+                case 2:
+                  unmasked = FPU_load_double((double *)data_address,
+                                             &loaded_data);
+                  loaded_tag = unmasked & 0xff;
+                  unmasked &= ~0xff;
+                  break;
+                case 3:
+                default:  /* Used here to suppress gcc warnings. */
+                  loaded_tag = FPU_load_int16((s16 *)data_address, &loaded_data);
+                  break;
+                }
+
+              /* No more access to user memory, it is safe
+                 to use static data now */
+
+              /* NaN operands have the next priority. */
+              /* We have to delay looking at st(0) until after
+                 loading the data, because that data might contain an SNaN */
+              if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
+                  ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
+                {
+                  /* Restore the status word; we might have loaded a
+                     denormal. */
+                  partial_status = status1;
+                  if ( (FPU_modrm & 0x30) == 0x10 )
+                    {
+                      /* fcom or fcomp */
+                      EXCEPTION(EX_Invalid);
+                      setcc(SW_C3 | SW_C2 | SW_C0);
+                      if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+                        FPU_pop();             /* fcomp, masked, so we pop. */
+                    }
+                  else
+                    {
+                      if ( loaded_tag == TAG_Special )
+                        loaded_tag = FPU_Special(&loaded_data);
+#ifdef PECULIAR_486
+                      /* This is not really needed, but gives behaviour
+                         identical to an 80486 */
+                      if ( (FPU_modrm & 0x28) == 0x20 )
+                        /* fdiv or fsub */
+                        real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
+                      else
+#endif /* PECULIAR_486 */
+                        /* fadd, fdivr, fmul, or fsubr */
+                        real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
+                    }
+                  goto reg_mem_instr_done;
+                }
+
+              if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
+                {
+                  /* Is not a comparison instruction. */
+                  if ( (FPU_modrm & 0x38) == 0x38 )
+                    {
+                      /* fdivr */
+                      if ( (st0_tag == TAG_Zero) &&
+                           ((loaded_tag == TAG_Valid)
+                            || (loaded_tag == TAG_Special
+                                && isdenormal(&loaded_data))) )
+                        {
+                          if ( FPU_divide_by_zero(0, getsign(&loaded_data))
+                               < 0 )
+                            {
+                              /* We use the fact here that the unmasked
+                                 exception in the loaded data was for a
+                                 denormal operand */
+                              /* Restore the state of the denormal op bit */
+                              partial_status &= ~SW_Denorm_Op;
+                              partial_status |= status1 & SW_Denorm_Op;
+                            }
+                          else
+                            setsign(st0_ptr, getsign(&loaded_data));
+                        }
+                    }
+                  goto reg_mem_instr_done;
+                }
+
+              switch ( (FPU_modrm >> 3) & 7 )
+                {
+                case 0:         /* fadd */
+                  clear_C1();
+                  FPU_add(&loaded_data, loaded_tag, 0, control_word);
+                  break;
+                case 1:         /* fmul */
+                  clear_C1();
+                  FPU_mul(&loaded_data, loaded_tag, 0, control_word);
+                  break;
+                case 2:         /* fcom */
+                  FPU_compare_st_data(&loaded_data, loaded_tag);
+                  break;
+                case 3:         /* fcomp */
+                 // bbd: used to typecase to int first, but this corrupted the
+                 // pointer on 64 bit machines.
+                  if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
+                       && !unmasked )
+                    FPU_pop();
+                  break;
+                case 4:         /* fsub */
+                  clear_C1();
+                  FPU_sub(LOADED|loaded_tag, &loaded_data, control_word);
+                  break;
+                case 5:         /* fsubr */
+                  clear_C1();
+                  FPU_sub(REV|LOADED|loaded_tag, &loaded_data, control_word);
+                  break;
+                case 6:         /* fdiv */
+                  clear_C1();
+                  FPU_div(LOADED|loaded_tag, &loaded_data, control_word);
+                  break;
+                case 7:         /* fdivr */
+                  clear_C1();
+                  if ( st0_tag == TAG_Zero )
+                    partial_status = status1;  /* Undo any denorm tag,
+                                                  zero-divide has priority. */
+                  FPU_div(REV|LOADED|loaded_tag, &loaded_data, control_word);
+                  break;
+                }
+            }
+          else
+            {
+              if ( (FPU_modrm & 0x30) == 0x10 )
+                {
+                  /* The instruction is fcom or fcomp */
+                  EXCEPTION(EX_StackUnder);
+                  setcc(SW_C3 | SW_C2 | SW_C0);
+                  if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+                    FPU_pop();             /* fcomp */
+                }
+              else
+                FPU_stack_underflow();
+            }
+        reg_mem_instr_done:
+          operand_address = data_sel_off;
+        }
+      else {
+          if ( !(no_ip_update =
+                 FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
+                                addr_modes, data_address)) )
+            {
+              operand_address = data_sel_off;
+            }
+        }
+    }
+  else {
+      /* None of these instructions access user memory */
+      u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
+
+#ifdef PECULIAR_486
+      /* This is supposed to be undefined, but a real 80486 seems
+         to do this: */
+      operand_address.offset = 0;
+      operand_address.selector = FPU_DS;
+#endif /* PECULIAR_486 */
+
+      st0_ptr = &st(0);
+      st0_tag = FPU_gettag0();
+      switch ( type_table[(int) instr_index] )
+        {
+        case _NONE_:   /* also _REGIc: _REGIn */
+          break;
+        case _REG0_:
+          if ( !NOT_EMPTY_ST0 )
+            {
+              FPU_stack_underflow();
+              goto FPU_instruction_done;
+            }
+          break;
+        case _REGIi:
+          if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+            {
+              FPU_stack_underflow_i(FPU_rm);
+              goto FPU_instruction_done;
+            }
+          break;
+        case _REGIp:
+          if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+            {
+              FPU_stack_underflow_pop(FPU_rm);
+              goto FPU_instruction_done;
+            }
+          break;
+        case _REGI_:
+          if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+            {
+              FPU_stack_underflow();
+              goto FPU_instruction_done;
+            }
+          break;
+        case _PUSH_:     /* Only used by the fld st(i) instruction */
+          break;
+        case _null_:
+          FPU_illegal();
+          goto FPU_instruction_done;
+        default:
+          EXCEPTION(EX_INTERNAL|0x111);
+          goto FPU_instruction_done;
+        }
+      (*st_instr_table[(int) instr_index])();
+
+FPU_instruction_done:
+      ;
+    }
+
+  if ( ! no_ip_update )
+    instruction_address = entry_sel_off;
+
+FPU_fwait_done:
+
+#ifdef DEBUG
+  FPU_printall();
+#endif /* DEBUG */
+#ifdef BX_NO_BLANK_LABELS
+  if(0);
+#endif
+}
+
+#endif  /* #ifndef USE_WITH_CPU_SIM */
diff --git a/sid/component/bochs/fpu/fpu_etc.c b/sid/component/bochs/fpu/fpu_etc.c
new file mode 100644 (file)
index 0000000..b7d288d
--- /dev/null
@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_etc.c                                                                |
+ |                                                                           |
+ | Implement a few FPU instructions.                                         |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@suburbia.net             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "reg_constant.h"
+
+
+static void fchs(FPU_REG *st0_ptr, u_char st0tag)
+{
+  if ( st0tag ^ TAG_Empty )
+    {
+      signbyte(st0_ptr) ^= SIGN_NEG;
+      clear_C1();
+    }
+  else
+    FPU_stack_underflow();
+}
+
+
+static void fpu_fabs(FPU_REG *st0_ptr, u_char st0tag)
+{
+  if ( st0tag ^ TAG_Empty )
+    {
+      setpositive(st0_ptr);
+      clear_C1();
+    }
+  else
+    FPU_stack_underflow();
+}
+
+
+static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
+{
+  switch (st0tag)
+    {
+    case TAG_Zero:
+      setcc(SW_C3);
+      break;
+    case TAG_Valid:
+      if (getsign(st0_ptr) == SIGN_POS)
+        setcc(0);
+      else
+        setcc(SW_C0);
+      break;
+    case TAG_Special:
+      switch ( FPU_Special(st0_ptr) )
+       {
+       case TW_Denormal:
+         if (getsign(st0_ptr) == SIGN_POS)
+           setcc(0);
+         else
+           setcc(SW_C0);
+         if ( denormal_operand() < 0 )
+           {
+#ifdef PECULIAR_486
+             /* This is weird! */
+             if (getsign(st0_ptr) == SIGN_POS)
+               setcc(SW_C3);
+#endif /* PECULIAR_486 */
+             return;
+           }
+         break;
+       case TW_NaN:
+         setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
+         EXCEPTION(EX_Invalid);
+         break;
+       case TW_Infinity:
+         if (getsign(st0_ptr) == SIGN_POS)
+           setcc(0);
+         else
+           setcc(SW_C0);
+         break;
+       default:
+         setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
+         EXCEPTION(EX_INTERNAL|0x14);
+         break;
+       }
+      break;
+    case TAG_Empty:
+      setcc(SW_C0|SW_C2|SW_C3);
+      EXCEPTION(EX_StackUnder);
+      break;
+    }
+}
+
+
+static void fxam(FPU_REG *st0_ptr, u_char st0tag)
+{
+  int c = 0;
+  switch (st0tag)
+    {
+    case TAG_Empty:
+      c = SW_C3|SW_C0;
+      break;
+    case TAG_Zero:
+      c = SW_C3;
+      break;
+    case TAG_Valid:
+      c = SW_C2;
+      break;
+    case TAG_Special:
+      switch ( FPU_Special(st0_ptr) )
+       {
+       case TW_Denormal:
+         c = SW_C2|SW_C3;  /* Denormal */
+         break;
+       case TW_NaN:
+         /* We also use NaN for unsupported types. */
+         if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) )
+           c = SW_C0;
+         break;
+       case TW_Infinity:
+         c = SW_C2|SW_C0;
+         break;
+       }
+    }
+  if ( getsign(st0_ptr) == SIGN_NEG )
+    c |= SW_C1;
+  setcc(c);
+}
+
+
+static FUNC_ST0 const fp_etc_table[] = {
+  fchs, fpu_fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
+  ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
+};
+
+void FPU_etc()
+{
+  (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
+}
diff --git a/sid/component/bochs/fpu/fpu_proto.h b/sid/component/bochs/fpu/fpu_proto.h
new file mode 100644 (file)
index 0000000..7d010ec
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef _FPU_PROTO_H
+#define _FPU_PROTO_H
+
+/* errors.c */
+extern void Un_impl(void);
+extern void FPU_illegal(void);
+extern void FPU_printall(void);
+asmlinkage void FPU_exception(int n);
+extern int real_1op_NaN(FPU_REG *a);
+extern int real_2op_NaN(FPU_REG const *b, u_char tagb, int deststnr,
+                       FPU_REG const *defaultNaN);
+extern int arith_invalid(int deststnr);
+extern int FPU_divide_by_zero(int deststnr, u_char sign);
+extern int set_precision_flag(int flags);
+extern void set_precision_flag_up(void);
+extern void set_precision_flag_down(void);
+extern int denormal_operand(void);
+extern int arith_overflow(FPU_REG *dest);
+extern int arith_round_overflow(FPU_REG *dest, u8 sign);
+extern int arith_underflow(FPU_REG *dest);
+extern void FPU_stack_overflow(void);
+extern void FPU_stack_underflow(void);
+extern void FPU_stack_underflow_i(int i);
+extern void FPU_stack_underflow_pop(int i);
+/* fpu_arith.c */
+extern void fadd__(void);
+extern void fmul__(void);
+extern void fsub__(void);
+extern void fsubr_(void);
+extern void fdiv__(void);
+extern void fdivr_(void);
+extern void fadd_i(void);
+extern void fmul_i(void);
+extern void fsubri(void);
+extern void fsub_i(void);
+extern void fdivri(void);
+extern void fdiv_i(void);
+extern void faddp_(void);
+extern void fmulp_(void);
+extern void fsubrp(void);
+extern void fsubp_(void);
+extern void fdivrp(void);
+extern void fdivp_(void);
+/* fpu_aux.c */
+extern void fclex(void);
+extern void finit(void);
+extern void finit_(void);
+extern void fstsw_(void);
+extern void fp_nop(void);
+extern void fld_i_(void);
+extern void fxch_i(void);
+extern void ffree_(void);
+extern void ffreep(void);
+extern void fst_i_(void);
+extern void fstp_i(void);
+/* fpu_entry.c */
+extern void math_emulate(long arg);
+extern void math_abort(struct info *info, unsigned int signal);
+/* fpu_etc.c */
+extern void FPU_etc(void);
+/* fpu_tags.c */
+extern int FPU_gettag0(void);
+extern int FPU_gettagi(int stnr);
+extern int FPU_gettag(int regnr);
+extern void FPU_settag0(int tag);
+extern void FPU_settagi(int stnr, int tag);
+extern void FPU_settag(int regnr, int tag);
+extern int FPU_Special(FPU_REG const *ptr);
+extern int isNaN(FPU_REG const *ptr);
+extern void FPU_pop(void);
+extern int FPU_empty_i(int stnr);
+extern int FPU_stackoverflow(FPU_REG **st_new_ptr);
+extern void FPU_sync_tags(void);
+extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr);
+extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag);
+extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag);
+/* fpu_trig.c */
+extern void FPU_triga(void);
+extern void FPU_trigb(void);
+/* get_address.c */
+extern void *FPU_get_address(u_char FPU_modrm, u32 *fpu_eip,
+                        struct address *addr, fpu_addr_modes addr_modes);
+extern void *FPU_get_address_16(u_char FPU_modrm, u32 *fpu_eip,
+                           struct address *addr, fpu_addr_modes addr_modes);
+/* load_store.c */
+extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
+                           void *data_address);
+/* poly_2xm1.c */
+extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result);
+/* poly_atan.c */
+extern void poly_atan(FPU_REG *st0_ptr, u_char st0_tag, FPU_REG *st1_ptr,
+                     u_char st1_tag);
+/* poly_l2.c */
+extern void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign);
+extern int poly_l2p1(u_char s0, u_char s1, FPU_REG *r0, FPU_REG *r1,
+                    FPU_REG *d);
+/* poly_sin.c */
+extern void poly_sine(FPU_REG *st0_ptr);
+extern void poly_cos(FPU_REG *st0_ptr);
+/* poly_tan.c */
+extern void poly_tan(FPU_REG *st0_ptr, int flag);
+/* reg_add_sub.c */
+extern int FPU_add(FPU_REG const *b, u_char tagb, int destrnr, u16 control_w);
+extern int FPU_sub(int flags, FPU_REG *rm, u16 control_w);   // bbd: changed arg2 from int to FPU_REG*
+/* reg_compare.c */
+extern int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag);
+extern void fcom_st(void);
+extern void fcompst(void);
+extern void fcompp(void);
+extern void fucom_(void);
+extern void fucomp(void);
+extern void fucompp(void);
+/* reg_constant.c */
+extern void fconst(void);
+/* reg_ld_str.c */
+extern int FPU_load_extended(long double *s, int stnr);
+extern int FPU_load_double(double *dfloat, FPU_REG *loaded_data);
+extern int FPU_load_single(float *single, FPU_REG *loaded_data);
+extern int FPU_load_int64(s64 *_s);
+extern int FPU_load_int32(s32 *_s, FPU_REG *loaded_data);
+extern int FPU_load_int16(s16 *_s, FPU_REG *loaded_data);
+extern int FPU_load_bcd(u_char *s);
+extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
+                             long double *d);
+extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat);
+extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single);
+extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, s64 *d);
+extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, s32 *d);
+extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, s16 *d);
+extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d);
+extern int FPU_round_to_int(FPU_REG *r, u_char tag);
+extern u_char *fldenv(fpu_addr_modes addr_modes, u_char *s);
+extern void frstor(fpu_addr_modes addr_modes, u_char *data_address);
+extern u_char *fstenv(fpu_addr_modes addr_modes, u_char *d);
+extern void fsave(fpu_addr_modes addr_modes, u_char *data_address);
+extern int FPU_tagof(FPU_REG *ptr);
+/* reg_mul.c */
+extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w);
+
+extern int FPU_div(int flags, FPU_REG *regrm, int control_w); // bbd: changed arg2 from int to FPU_REG*
+/* reg_convert.c */
+extern int FPU_to_exp16(FPU_REG const *a, FPU_REG *x);
+#endif /* _FPU_PROTO_H */
+
diff --git a/sid/component/bochs/fpu/fpu_system.h b/sid/component/bochs/fpu/fpu_system.h
new file mode 100644 (file)
index 0000000..96dc4ea
--- /dev/null
@@ -0,0 +1,218 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_system.h                                                             |
+ |                                                                           |
+ | Copyright (C) 1992,1994,1997                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@suburbia.net             |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _FPU_SYSTEM_H
+#define _FPU_SYSTEM_H
+
+#ifndef USE_WITH_CPU_SIM
+
+/* system dependent definitions */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+/* This sets the pointer FPU_info to point to the argument part
+   of the stack frame of math_emulate() */
+#define SETUP_DATA_AREA(arg)   FPU_info = (struct info *) &arg
+
+#define LDT_DESCRIPTOR(s)      (((struct desc_struct *)current->mm->segments)[(s) >> 3])
+#define SEG_D_SIZE(x)          ((x).b & (3 << 21))
+#define SEG_G_BIT(x)           ((x).b & (1 << 23))
+#define SEG_GRANULARITY(x)     (((x).b & (1 << 23)) ? 4096 : 1)
+#define SEG_286_MODE(x)                ((x).b & ( 0xff000000 | 0xf0000 | (1 << 23)))
+#define SEG_BASE_ADDR(s)       (((s).b & 0xff000000) \
+                                | (((s).b & 0xff) << 16) | ((s).a >> 16))
+#define SEG_LIMIT(s)           (((s).b & 0xff0000) | ((s).a & 0xffff))
+#define SEG_EXECUTE_ONLY(s)    (((s).b & ((1 << 11) | (1 << 9))) == (1 << 11))
+#define SEG_WRITE_PERM(s)      (((s).b & ((1 << 11) | (1 << 9))) == (1 << 9))
+#define SEG_EXPAND_DOWN(s)     (((s).b & ((1 << 11) | (1 << 10))) \
+                                == (1 << 10))
+
+#define I387                   (current->tss.i387)
+#define FPU_info               (I387.soft.info)
+
+#define FPU_CS                 (*(u16 *) &(FPU_info->___cs))
+#define FPU_SS                 (*(u16 *) &(FPU_info->___ss))
+#define FPU_DS                 (*(u16 *) &(FPU_info->___ds))
+#define FPU_EAX                        (FPU_info->___eax)
+#define FPU_EFLAGS             (FPU_info->___eflags)
+#define FPU_EIP                        (FPU_info->___eip)
+#define FPU_ORIG_EIP           (FPU_info->___orig_eip)
+
+#define FPU_lookahead           (I387.soft.lookahead)
+
+#define SET_AX(val16)           *(s16 *) &FPU_EAX = val16
+
+/* nz if ip_offset and cs_selector are not to be set for the current
+   instruction. */
+#define no_ip_update           (*(u_char *)&(I387.soft.no_update))
+#define FPU_rm                 (*(u_char *)&(I387.soft.rm))
+
+/* Number of bytes of data which can be legally accessed by the current
+   instruction. This only needs to hold a number <= 108, so a byte will do. */
+#define access_limit           (*(u_char *)&(I387.soft.alimit))
+
+#define partial_status         (I387.soft.swd)
+#define control_word           (I387.soft.cwd)
+#define fpu_tag_word           (I387.soft.twd)
+#define registers              (I387.soft.st_space)
+#define top                    (I387.soft.ftop)
+
+#define instruction_address    (*(struct address *)&I387.soft.fip)
+#define operand_address                (*(struct address *)&I387.soft.foo)
+
+#define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \
+                               math_abort(FPU_info,SIGSEGV)
+
+#undef FPU_IGNORE_CODE_SEGV
+#ifdef FPU_IGNORE_CODE_SEGV
+/* verify_area() is very expensive, and causes the emulator to run
+   about 20% slower if applied to the code. Anyway, errors due to bad
+   code addresses should be much rarer than errors due to bad data
+   addresses. */
+#define        FPU_code_verify_area(z)
+#else
+/* A simpler test than verify_area() can probably be done for
+   FPU_code_verify_area() because the only possible error is to step
+   past the upper boundary of a legal code area. */
+#define        FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
+#endif
+
+#define FPU_get_user(x,y)       get_user((x),(y))
+#define FPU_put_user(x,y)       put_user((x),(y))
+
+#else  /* USE_WITH_CPU_SIM */
+
+/* -----------------------------------------------------------
+ * Slimmed down version used to compile against a CPU simulator
+ * rather than a kernel (ported by Kevin Lawton)
+ * ------------------------------------------------------------ */
+
+/* Get data sizes from config.h generated from simulator's
+ * configure script
+ */
+#include "config.h"
+typedef Bit8u  u8;
+typedef Bit8s  s8;
+typedef Bit16u u16;
+typedef Bit16s s16;
+typedef Bit32u u32;
+typedef Bit32s s32;
+typedef Bit64u u64;
+typedef Bit64s s64;
+
+/* bbd: include ported linux headers after config.h for GCC_ATTRIBUTE macro */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/math_emu.h>
+#include <linux/types.h>
+
+#ifndef WORDS_BIGENDIAN
+#error "WORDS_BIGENDIAN not defined in config.h"
+#elif WORDS_BIGENDIAN == 1
+#define EMU_BIG_ENDIAN 1
+#else
+/* Nothing needed.  Lack of defining EMU_BIG_ENDIAN means
+ * small endian
+ */
+#endif
+
+
+extern unsigned fpu_get_user(void *ptr, unsigned len);
+extern void fpu_put_user(unsigned val, void *ptr, unsigned len);
+
+extern void fpu_verify_area(unsigned what, void *ptr, unsigned n);
+extern void math_emulate_init(void);
+extern unsigned fpu_get_ds(void);
+extern void fpu_set_ax(u16);
+
+#ifndef __ASSEMBLY__
+
+struct info {
+#ifdef BX_NO_EMPTY_STRUCTS
+  unsigned char donotindexme;
+#endif
+  };
+
+#define FPU_info ((struct info *) NULL)
+
+
+//
+// Minimal i387 structure, pruned from the linux headers.  Only
+// the fields which were necessary are included.
+//
+typedef struct {
+  struct {
+    s32      cwd;
+    s32      swd;
+    s32      twd;
+    s32      fip;
+    s32      fcs;
+    s32      foo;
+    s32      fos;
+    u32      fill0; /* to make sure the following aligns on an 8byte boundary */
+    u64      st_space[16];   /* 8*16 bytes per FP-reg (aligned) = 128 bytes */
+    unsigned char   ftop;
+    unsigned char   no_update;
+    unsigned char   rm;
+    unsigned char   alimit;
+    } GCC_ATTRIBUTE((aligned(16), packed)) soft;
+  } i387_t;
+
+extern i387_t i387;
+
+
+#endif
+
+#define SIGSEGV  11
+
+#define I387     i387
+
+
+#define SET_AX(val16)           fpu_set_ax(val16);
+
+#define no_ip_update            (*(u_char *)&(I387.soft.no_update))
+#define FPU_rm                  (*(u_char *)&(I387.soft.rm))
+
+
+/* Number of bytes of data which can be legally accessed by the current
+   instruction. This only needs to hold a number <= 108, so a byte will do. */
+#define access_limit            (*(u_char *)&(I387.soft.alimit))
+
+#define partial_status          (I387.soft.swd)
+#define control_word            (I387.soft.cwd)
+#define fpu_tag_word            (I387.soft.twd)
+#define registers               (I387.soft.st_space)
+#define top                     (I387.soft.ftop)
+
+#define instruction_address     (*(struct address *)&I387.soft.fip)
+#define operand_address         (*(struct address *)&I387.soft.foo)
+
+#define FPU_verify_area(x,y,z) fpu_verify_area(x,y,z)
+#define FPU_get_user(x,y)       ((x) = fpu_get_user((y), sizeof(*(y))))
+#define FPU_put_user(val,ptr)   fpu_put_user((val),(ptr),sizeof(*(ptr)))
+
+#define FPU_DS  (fpu_get_ds())
+
+#endif  /* USE_WITH_CPU_SIM */
+
+// bbd: Change a pointer to an int, with type conversions that make it legal.
+// First make it a void pointer, then convert to an integer of the same
+// size as the pointer.  Otherwise, on machines with 64-bit pointers, 
+// compilers complain when you typecast a 64-bit pointer into a 32-bit integer.
+#define PTR2INT(x) ((bx_ptr_equiv_t)(void *)(x))
+
+// bbd: Change an int to a pointer, with type conversions that make it legal.
+// Same strategy as PTR2INT: change to bx_ptr_equiv_t which is an integer
+// type of the same size as FPU_REG*.  Then the conversion to pointer
+// is legal.
+#define REGNO2PTR(x)           ((FPU_REG*)((bx_ptr_equiv_t)(x)))
+
+#endif
diff --git a/sid/component/bochs/fpu/fpu_tags.c b/sid/component/bochs/fpu/fpu_tags.c
new file mode 100644 (file)
index 0000000..cb436fe
--- /dev/null
@@ -0,0 +1,127 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_tags.c                                                               |
+ |                                                                           |
+ |  Set FPU register tags.                                                   |
+ |                                                                           |
+ | Copyright (C) 1997                                                        |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@jacobi.maths.monash.edu.au                |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+
+
+void FPU_pop(void)
+{
+  fpu_tag_word |= 3 << ((top & 7)*2);
+  top++;
+}
+
+
+int FPU_gettag0(void)
+{
+  return (fpu_tag_word >> ((top & 7)*2)) & 3;
+}
+
+
+int FPU_gettagi(int stnr)
+{
+  return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3;
+}
+
+
+int FPU_gettag(int regnr)
+{
+  return (fpu_tag_word >> ((regnr & 7)*2)) & 3;
+}
+
+
+void FPU_settag0(int tag)
+{
+  int regnr = top;
+  regnr &= 7;
+  fpu_tag_word &= ~(3 << (regnr*2));
+  fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+void FPU_settagi(int stnr, int tag)
+{
+  int regnr = stnr+top;
+  regnr &= 7;
+  fpu_tag_word &= ~(3 << (regnr*2));
+  fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+void FPU_settag(int regnr, int tag)
+{
+  regnr &= 7;
+  fpu_tag_word &= ~(3 << (regnr*2));
+  fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+int FPU_Special(FPU_REG const *ptr)
+{
+  int exp = exponent(ptr);
+
+  if ( exp == EXP_BIAS+EXP_UNDER )
+    return TW_Denormal;
+  else if ( exp != EXP_BIAS+EXP_OVER )
+    return TW_NaN;
+  else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) )
+    return TW_Infinity;
+  return TW_NaN;
+}
+
+
+int isNaN(FPU_REG const *ptr)
+{
+  return ( (exponent(ptr) == EXP_BIAS+EXP_OVER)
+          && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) );
+}
+
+
+int FPU_empty_i(int stnr)
+{
+  int regnr = (top+stnr) & 7;
+
+  return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty;
+}
+
+
+int FPU_stackoverflow(FPU_REG **st_new_ptr)
+{
+  *st_new_ptr = &st(-1);
+
+  return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty;
+}
+
+
+void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
+{
+  reg_copy(r, &st(stnr));
+  FPU_settagi(stnr, tag);
+}
+
+void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
+{
+  reg_copy(r, &st(1));
+  FPU_settagi(1, tag);
+}
+
+void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
+{
+  int regnr = top;
+  regnr &= 7;
+
+  reg_copy(r, &st(0));
+
+  fpu_tag_word &= ~(3 << (regnr*2));
+  fpu_tag_word |= (tag & 3) << (regnr*2);
+}
diff --git a/sid/component/bochs/fpu/fpu_trig.c b/sid/component/bochs/fpu/fpu_trig.c
new file mode 100644 (file)
index 0000000..1714771
--- /dev/null
@@ -0,0 +1,1890 @@
+/*---------------------------------------------------------------------------+
+ |  fpu_trig.c                                                               |
+ |                                                                           |
+ | Implementation of the FPU "transcendental" functions.                     |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "reg_constant.h"      
+
+static void rem_kernel(u64 st0, u64 *y, u64 st1, u64 q, int n);
+
+#define BETTER_THAN_486
+
+#define FCOS  4
+#define FPTAN  8
+
+/* Used only by fptan, fsin, fcos, and fsincos. */
+/* This routine produces very accurate results, similar to
+   using a value of pi with more than 128 bits precision. */
+/* Limited measurements show no results worse than 64 bit precision
+   except for the results for arguments close to 2^63, where the
+   precision of the result sometimes degrades to about 63.9 bits */
+static int trig_arg(FPU_REG *st0_ptr, int flags)
+{
+  FPU_REG tmp;
+  u_char tmptag;
+  u64 q;
+  int old_cw = control_word, saved_status = partial_status;
+  int tag, st0_tag = TAG_Valid;
+
+  if ( exponent(st0_ptr) >= 63 )
+    {
+      partial_status |= SW_C2;     /* Reduction incomplete. */
+      return -1;
+    }
+
+  if ( flags & FPTAN )
+    st0_ptr->exp ++;         /* Effectively base the following upon pi/4 */
+
+  control_word &= ~CW_RC;
+  control_word |= RC_CHOP;
+
+  setpositive(st0_ptr);
+  tag = FPU_u_div(st0_ptr,
+                 &CONST_PI2,
+                 &tmp, PR_64_BITS | RC_CHOP | 0x3f, SIGN_POS);
+
+  FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't overflow
+                                  to 2^64 */
+  q = significand(&tmp);
+
+  if ( q )
+    {
+      rem_kernel(significand(st0_ptr),
+                &significand(&tmp),
+                significand(&CONST_PI2),
+                q, exponent(st0_ptr) - exponent(&CONST_PI2));
+      setexponent16(&tmp, exponent(&CONST_PI2));
+      st0_tag = FPU_normalize_nuo(&tmp,
+                                 EXTENDED_Ebias);  /* No underflow or overflow
+                                                      is possible */
+
+      FPU_copy_to_reg0(&tmp, st0_tag);
+    }
+
+  if ( ((flags & FCOS) && !(q & 1)) || (!(flags & FCOS) && (q & 1)) )
+    {
+      st0_tag = FPU_sub(REV|LOADED|TAG_Valid, &CONST_PI2, FULL_PRECISION); //bbd: arg2 used to typecast to (int)
+
+#ifdef BETTER_THAN_486
+      /* So far, the results are exact but based upon a 64 bit
+        precision approximation to pi/2. The technique used
+        now is equivalent to using an approximation to pi/2 which
+        is accurate to about 128 bits. */
+      if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) )
+       {
+         /* This code gives the effect of having pi/2 to better than
+            128 bits precision. */
+
+         significand(&tmp) = q + 1;
+         setexponent16(&tmp, 63);
+          FPU_normalize_nuo(&tmp,
+                            EXTENDED_Ebias);  /* No underflow or overflow
+                                                 is possible */
+         tmptag =
+           FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
+                     exponent(&CONST_PI2extra) + exponent(&tmp));
+         setsign(&tmp, getsign(&CONST_PI2extra));
+         st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
+          if ( signnegative(st0_ptr) && !(flags & FPTAN) )
+           {
+             /* CONST_PI2extra is negative, so the result of the addition
+                can be negative. This means that the argument is actually
+                in a different quadrant. The correction is always < pi/2,
+                so it can't overflow into yet another quadrant. */
+              /* The function is even, so we need just adjust the sign
+                 and q. */
+             setpositive(st0_ptr);
+             q++;
+           }
+       }
+#endif /* BETTER_THAN_486 */
+    }
+#ifdef BETTER_THAN_486
+  else
+    {
+      /* So far, the results are exact but based upon a 64 bit
+        precision approximation to pi/2. The technique used
+        now is equivalent to using an approximation to pi/2 which
+        is accurate to about 128 bits. */
+      if ( ((q > 0)
+           && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
+          || (q > 1) )
+       {
+         /* This code gives the effect of having p/2 to better than
+            128 bits precision. */
+
+         significand(&tmp) = q;
+         setexponent16(&tmp, 63);
+          FPU_normalize_nuo(&tmp,
+                            EXTENDED_Ebias);  /* No underflow or overflow
+                                                 is possible.
+                                                 This must return TAG_Valid */
+         tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
+                            SIGN_POS,
+                            exponent(&CONST_PI2extra) + exponent(&tmp));
+         setsign(&tmp, getsign(&CONST_PI2extra));
+         st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), &tmp,
+                           FULL_PRECISION);
+         if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
+             ((st0_ptr->sigh > CONST_PI2.sigh)
+              || ((st0_ptr->sigh == CONST_PI2.sigh)
+                  && (st0_ptr->sigl > CONST_PI2.sigl))) )
+           {
+             /* CONST_PI2extra is negative, so the result of the
+                subtraction can be larger than pi/2. This means
+                that the argument is actually in a different quadrant.
+                The correction is always < pi/2, so it can't overflow
+                into yet another quadrant. 
+                bbd: arg2 used to typecast to (int), corrupting 64-bit ptrs
+              */
+             st0_tag = FPU_sub(REV|LOADED|TAG_Valid, &CONST_PI2,
+                               FULL_PRECISION);
+             q++;
+           }
+       }
+    }
+#endif /* BETTER_THAN_486 */
+
+  FPU_settag0(st0_tag);
+  control_word = old_cw;
+  partial_status = saved_status & ~SW_C2;     /* Reduction complete. */
+
+  if ( flags & FPTAN )
+    {
+      st0_ptr->exp --;
+      return q & 7;
+    }
+
+  return (q & 3) | (flags & FCOS);
+}
+
+
+/* Convert a s32 to register */
+static void convert_l2reg(s32 const *arg, int deststnr)
+{
+  int tag;
+  s32 num = *arg;
+  u_char sign;
+  FPU_REG *dest = &st(deststnr);
+
+  if (num == 0)
+    {
+      FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+      return;
+    }
+
+  if (num > 0)
+    { sign = SIGN_POS; }
+  else
+    { num = -num; sign = SIGN_NEG; }
+
+  dest->sigh = num;
+  dest->sigl = 0;
+  setexponent16(dest, 31);
+  tag = FPU_normalize_nuo(dest,
+                         EXTENDED_Ebias);  /* No underflow or overflow
+                                              is possible */
+  FPU_settagi(deststnr, tag);
+  setsign(dest, sign);
+  return;
+}
+
+
+static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  if ( st0_tag == TAG_Empty )
+    FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+  else if ( st0_tag == TW_NaN )
+    real_1op_NaN(st0_ptr);       /* return with a NaN in st(0) */
+#ifdef PARANOID
+  else
+    EXCEPTION(EX_INTERNAL|0x0112);
+#endif /* PARANOID */
+}
+
+
+static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  int isNaN;
+
+  switch ( st0_tag )
+    {
+    case TW_NaN:
+      isNaN = (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000);
+      if ( isNaN && !(st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
+       {
+         EXCEPTION(EX_Invalid);
+         if ( control_word & CW_Invalid )
+           {
+             /* The masked response */
+             /* Convert to a QNaN */
+             st0_ptr->sigh |= 0x40000000;
+             push();
+             FPU_copy_to_reg0(st0_ptr, TAG_Special);
+           }
+       }
+      else if ( isNaN )
+       {
+         /* A QNaN */
+         push();
+         FPU_copy_to_reg0(st0_ptr, TAG_Special);
+       }
+      else
+       {
+         /* pseudoNaN or other unsupported */
+         EXCEPTION(EX_Invalid);
+         if ( control_word & CW_Invalid )
+           {
+             /* The masked response */
+             FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+             push();
+             FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+           }
+       }
+      break;              /* return with a NaN in st(0) */
+#ifdef PARANOID
+    default:
+      EXCEPTION(EX_INTERNAL|0x0112);
+#endif /* PARANOID */
+    }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static void f2xm1(FPU_REG *st0_ptr, u_char tag)
+{
+  FPU_REG a;
+
+  clear_C1();
+
+  if ( tag == TAG_Valid )
+    {
+      /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
+      if ( exponent(st0_ptr) < 0 )
+       {
+       denormal_arg:
+
+         FPU_to_exp16(st0_ptr, &a);
+
+         /* poly_2xm1(x) requires 0 < st(0) < 1. */
+         poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+       }
+      set_precision_flag_up();   /* 80486 appears to always do this */
+      return;
+    }
+
+  if ( tag == TAG_Zero )
+    return;
+
+  if ( tag == TAG_Special )
+    tag = FPU_Special(st0_ptr);
+
+  switch ( tag )
+    {
+    case TW_Denormal:
+      if ( denormal_operand() < 0 )
+       return;
+      goto denormal_arg;
+    case TW_Infinity:
+      if ( signnegative(st0_ptr) )
+       {
+         /* -infinity gives -1 (p16-10) */
+         FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+         setnegative(st0_ptr);
+       }
+      return;
+    default:
+      single_arg_error(st0_ptr, tag);
+    }
+}
+
+
+static void fptan(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st_new_ptr;
+  u32 q;
+  u_char arg_sign = getsign(st0_ptr);
+  int invert[] = { 0, 1, 1, 0, 0, 1, 1, 0 };
+
+  /* Stack underflow has higher priority */
+  if ( st0_tag == TAG_Empty )
+    {
+      FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+      if ( control_word & CW_Invalid )
+       {
+         st_new_ptr = &st(-1);
+         push();
+         FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+       }
+      return;
+    }
+
+  if ( STACK_OVERFLOW )
+    { FPU_stack_overflow(); return; }
+
+  if ( st0_tag == TAG_Valid )
+    {
+      if ( exponent(st0_ptr) > -40 )
+       {
+          if ( (q = trig_arg(st0_ptr, FPTAN)) == -1 )
+           {
+             /* Operand is out of range */
+             return;
+           }
+
+          poly_tan(st0_ptr, invert[q]);
+          setsign(st0_ptr, ((q & 2) != 0) ^ (arg_sign != 0));
+         set_precision_flag_up();  /* We do not really know if up or down */
+       }
+      else
+       {
+         /* For a small arg, the result == the argument */
+         /* Underflow may happen */
+
+       denormal_arg:
+
+         FPU_to_exp16(st0_ptr, st0_ptr);
+      
+         st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+         FPU_settag0(st0_tag);
+       }
+      push();
+      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+      return;
+    }
+
+  if ( st0_tag == TAG_Zero )
+    {
+      push();
+      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+      setcc(0);
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+
+  if ( st0_tag == TW_Denormal )
+    {
+      if ( denormal_operand() < 0 )
+       return;
+
+      goto denormal_arg;
+    }
+
+  if ( st0_tag == TW_Infinity )
+    {
+      /* The 80486 treats infinity as an invalid operand */
+      if ( arith_invalid(0) >= 0 )
+       {
+         st_new_ptr = &st(-1);
+         push();
+         arith_invalid(0);
+       }
+      return;
+    }
+
+  single_arg_2_error(st0_ptr, st0_tag);
+}
+
+
+static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st_new_ptr;
+  u_char sign;
+  register FPU_REG *st1_ptr = st0_ptr;  /* anticipate */
+
+  if ( STACK_OVERFLOW )
+    {  FPU_stack_overflow(); return; }
+
+  clear_C1();
+
+  if ( st0_tag == TAG_Valid )
+    {
+      s32 e;
+
+      push();
+      sign = getsign(st1_ptr);
+      reg_copy(st1_ptr, st_new_ptr);
+      setexponent16(st_new_ptr, exponent(st_new_ptr));
+
+    denormal_arg:
+
+      e = exponent16(st_new_ptr);
+      convert_l2reg(&e, 1);
+      setexponentpos(st_new_ptr, 0);
+      setsign(st_new_ptr, sign);
+      FPU_settag0(TAG_Valid);       /* Needed if arg was a denormal */
+      return;
+    }
+  else if ( st0_tag == TAG_Zero )
+    {
+      sign = getsign(st0_ptr);
+
+      if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 )
+       return;
+
+      push();
+      FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+      setsign(st_new_ptr, sign);
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+
+  if ( st0_tag == TW_Denormal )
+    {
+      if (denormal_operand() < 0 )
+       return;
+
+      push();
+      sign = getsign(st1_ptr);
+      FPU_to_exp16(st1_ptr, st_new_ptr);
+      goto denormal_arg;
+    }
+  else if ( st0_tag == TW_Infinity )
+    {
+      sign = getsign(st0_ptr);
+      setpositive(st0_ptr);
+      push();
+      FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+      setsign(st_new_ptr, sign);
+      return;
+    }
+  else if ( st0_tag == TW_NaN )
+    {
+      if ( real_1op_NaN(st0_ptr) < 0 )
+       return;
+
+      push();
+      FPU_copy_to_reg0(st0_ptr, TAG_Special);
+      return;
+    }
+  else if ( st0_tag == TAG_Empty )
+    {
+      /* Is this the correct behaviour? */
+      if ( control_word & EX_Invalid )
+       {
+         FPU_stack_underflow();
+         push();
+         FPU_stack_underflow();
+       }
+      else
+       EXCEPTION(EX_StackUnder);
+    }
+#ifdef PARANOID
+  else
+    EXCEPTION(EX_INTERNAL | 0x119);
+#endif /* PARANOID */
+}
+
+
+static void fdecstp(void)
+{
+  clear_C1();
+  top--;
+}
+
+static void fincstp(void)
+{
+  clear_C1();
+  top++;
+}
+
+
+static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  int expon;
+
+  clear_C1();
+
+  if ( st0_tag == TAG_Valid )
+    {
+      u_char tag;
+      
+      if (signnegative(st0_ptr))
+       {
+         arith_invalid(0);  /* sqrt(negative) is invalid */
+         return;
+       }
+
+      /* make st(0) in  [1.0 .. 4.0) */
+      expon = exponent(st0_ptr);
+
+    denormal_arg:
+
+      setexponent16(st0_ptr, (expon & 1));
+
+      /* Do the computation, the sign of the result will be positive. */
+      tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
+      addexponent(st0_ptr, expon >> 1);
+      FPU_settag0(tag);
+      return;
+    }
+
+  if ( st0_tag == TAG_Zero )
+    return;
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+
+  if ( st0_tag == TW_Infinity )
+    {
+      if ( signnegative(st0_ptr) )
+       arith_invalid(0);  /* sqrt(-Infinity) is invalid */
+      return;
+    }
+  else if ( st0_tag == TW_Denormal )
+    {
+      if (signnegative(st0_ptr))
+       {
+         arith_invalid(0);  /* sqrt(negative) is invalid */
+         return;
+       }
+
+      if ( denormal_operand() < 0 )
+       return;
+
+      FPU_to_exp16(st0_ptr, st0_ptr);
+
+      expon = exponent16(st0_ptr);
+
+      goto denormal_arg;
+    }
+
+  single_arg_error(st0_ptr, st0_tag);
+
+}
+
+
+static void frndint_(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  int flags, tag;
+
+  if ( st0_tag == TAG_Valid )
+    {
+      u_char sign;
+
+    denormal_arg:
+
+      sign = getsign(st0_ptr);
+
+      if (exponent(st0_ptr) > 63)
+       return;
+
+      if ( st0_tag == TW_Denormal )
+       {
+         if (denormal_operand() < 0 )
+           return;
+       }
+
+      /* Fortunately, this can't overflow to 2^64 */
+      if ( (flags = FPU_round_to_int(st0_ptr, st0_tag)) )
+       set_precision_flag(flags);
+
+      setexponent16(st0_ptr, 63);
+      tag = FPU_normalize_nuo(st0_ptr,
+                             EXTENDED_Ebias);  /* No underflow or overflow
+                                                  is possible */
+      setsign(st0_ptr, sign);
+      FPU_settag0(tag);
+      return;
+    }
+
+  if ( st0_tag == TAG_Zero )
+    return;
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+
+  if ( st0_tag == TW_Denormal )
+    goto denormal_arg;
+  else if ( st0_tag == TW_Infinity )
+    return;
+  else
+    single_arg_error(st0_ptr, st0_tag);
+}
+
+
+static int fsin(FPU_REG *st0_ptr, u_char tag)
+{
+  u_char arg_sign = getsign(st0_ptr);
+
+  if ( tag == TAG_Valid )
+    {
+      u32 q;
+
+      if ( exponent(st0_ptr) > -40 )
+       {
+         if ( (q = trig_arg(st0_ptr, 0)) == -1 )
+           {
+             /* Operand is out of range */
+             return 1;
+           }
+
+         poly_sine(st0_ptr);
+         
+         if (q & 2)
+           changesign(st0_ptr);
+
+         setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
+
+         /* We do not really know if up or down */
+         set_precision_flag_up();
+         return 0;
+       }
+      else
+       {
+         /* For a small arg, the result == the argument */
+         set_precision_flag_up();  /* Must be up. */
+         return 0;
+       }
+    }
+
+  if ( tag == TAG_Zero )
+    {
+      setcc(0);
+      return 0;
+    }
+
+  if ( tag == TAG_Special )
+    tag = FPU_Special(st0_ptr);
+
+  if ( tag == TW_Denormal )
+    {
+      if ( denormal_operand() < 0 )
+       return 1;
+
+      /* For a small arg, the result == the argument */
+      /* Underflow may happen */
+      FPU_to_exp16(st0_ptr, st0_ptr);
+      
+      tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+
+      FPU_settag0(tag);
+
+      return 0;
+    }
+  else if ( tag == TW_Infinity )
+    {
+      /* The 80486 treats infinity as an invalid operand */
+      arith_invalid(0);
+      return 1;
+    }
+  else
+    {
+      single_arg_error(st0_ptr, tag);
+      return 1;
+    }
+}
+
+
+static int f_cos(FPU_REG *st0_ptr, u_char tag)
+{
+  u_char st0_sign;
+
+  st0_sign = getsign(st0_ptr);
+
+  if ( tag == TAG_Valid )
+    {
+      u32 q;
+
+      if ( exponent(st0_ptr) > -40 )
+       {
+         if ( (exponent(st0_ptr) < 0)
+             || ((exponent(st0_ptr) == 0)
+                 && (significand(st0_ptr) <= BX_CONST64(0xc90fdaa22168c234))) )
+           {
+             poly_cos(st0_ptr);
+
+             /* We do not really know if up or down */
+             set_precision_flag_down();
+         
+             return 0;
+           }
+         else if ( (q = trig_arg(st0_ptr, FCOS)) != -1 )
+           {
+             poly_sine(st0_ptr);
+
+             if ((q+1) & 2)
+               changesign(st0_ptr);
+
+             /* We do not really know if up or down */
+             set_precision_flag_down();
+         
+             return 0;
+           }
+         else
+           {
+             /* Operand is out of range */
+             return 1;
+           }
+       }
+      else
+       {
+       denormal_arg:
+
+         setcc(0);
+         FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+#ifdef PECULIAR_486
+         set_precision_flag_down();  /* 80486 appears to do this. */
+#else
+         set_precision_flag_up();  /* Must be up. */
+#endif /* PECULIAR_486 */
+         return 0;
+       }
+    }
+  else if ( tag == TAG_Zero )
+    {
+      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+      setcc(0);
+      return 0;
+    }
+
+  if ( tag == TAG_Special )
+    tag = FPU_Special(st0_ptr);
+
+  if ( tag == TW_Denormal )
+    {
+      if ( denormal_operand() < 0 )
+       return 1;
+
+      goto denormal_arg;
+    }
+  else if ( tag == TW_Infinity )
+    {
+      /* The 80486 treats infinity as an invalid operand */
+      arith_invalid(0);
+      return 1;
+    }
+  else
+    {
+      single_arg_error(st0_ptr, tag);  /* requires st0_ptr == &st(0) */
+      return 1;
+    }
+}
+
+
+static void fcos(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  f_cos(st0_ptr, st0_tag);
+}
+
+
+static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st_new_ptr;
+  FPU_REG arg;
+  u_char tag;
+
+  /* Stack underflow has higher priority */
+  if ( st0_tag == TAG_Empty )
+    {
+      FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+      if ( control_word & CW_Invalid )
+       {
+         st_new_ptr = &st(-1);
+         push();
+         FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+       }
+      return;
+    }
+
+  if ( STACK_OVERFLOW )
+    { FPU_stack_overflow(); return; }
+
+  if ( st0_tag == TAG_Special )
+    tag = FPU_Special(st0_ptr);
+  else
+    tag = st0_tag;
+
+  if ( tag == TW_NaN )
+    {
+      single_arg_2_error(st0_ptr, TW_NaN);
+      return;
+    }
+  else if ( tag == TW_Infinity )
+    {
+      /* The 80486 treats infinity as an invalid operand */
+      if ( arith_invalid(0) >= 0 )
+       {
+         /* Masked response */
+         push();
+         arith_invalid(0);
+       }
+      return;
+    }
+
+  reg_copy(st0_ptr, &arg);
+  if ( !fsin(st0_ptr, st0_tag) )
+    {
+      push();
+      FPU_copy_to_reg0(&arg, st0_tag);
+      f_cos(&st(0), st0_tag);
+    }
+  else
+    {
+      /* An error, so restore st(0) */
+      FPU_copy_to_reg0(&arg, st0_tag);
+    }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* The following all require two arguments: st(0) and st(1) */
+
+/* A lean, mean kernel for the fprem instructions. This relies upon
+   the division and rounding to an integer in do_fprem giving an
+   exact result. Because of this, rem_kernel() needs to deal only with
+   the least significant 64 bits, the more significant bits of the
+   result must be zero.
+ */
+static void rem_kernel(u64 st0, u64 *y, u64 st1, u64 q, int n)
+{
+  u64 x;
+
+#ifdef NO_ASSEMBLER
+  u64 work;
+
+  x = st0 << n;
+
+  work = (u32)st1;
+  work *= (u32)q;
+  x -= work;
+
+  work = st1 >> 32;
+  work *= (u32)q;
+  x -= work;
+
+  work = (u32)st1;
+  work *= q >> 32;
+  x -= work;
+  
+#else
+  int dummy;
+
+  x = st0 << n;
+
+  /* Do the required multiplication and subtraction in the one operation */
+
+  /* lsw x -= lsw st1 * lsw q */
+  asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
+               :"=m" (((u32 *)&x)[0]), "=m" (((u32 *)&x)[1]),
+               "=a" (dummy)
+               :"2" (((u32 *)&st1)[0]), "m" (((u32 *)&q)[0])
+               :"%dx");
+  /* msw x -= msw st1 * lsw q */
+  asm volatile ("mull %3; subl %%eax,%0"
+               :"=m" (((u32 *)&x)[1]), "=a" (dummy)
+               :"1" (((u32 *)&st1)[1]), "m" (((u32 *)&q)[0])
+               :"%dx");
+  /* msw x -= lsw st1 * msw q */
+  asm volatile ("mull %3; subl %%eax,%0"
+               :"=m" (((u32 *)&x)[1]), "=a" (dummy)
+               :"1" (((u32 *)&st1)[0]), "m" (((u32 *)&q)[1])
+               :"%dx");
+#endif
+
+  *y = x;
+}
+
+
+/* Remainder of st(0) / st(1) */
+/* This routine produces exact results, i.e. there is never any
+   rounding or truncation, etc of the result. */
+static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
+{
+  FPU_REG *st1_ptr = &st(1);
+  u_char st1_tag = FPU_gettagi(1);
+
+  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+    {
+      FPU_REG tmp, st0, st1;
+      u_char st0_sign, st1_sign;
+      u_char tmptag;
+      int tag;
+      int old_cw;
+      int expdif;
+      s64 q;
+      u16 saved_status;
+      int cc;
+
+    fprem_valid:
+      /* Convert registers for internal use. */
+      st0_sign = FPU_to_exp16(st0_ptr, &st0);
+      st1_sign = FPU_to_exp16(st1_ptr, &st1);
+      expdif = exponent16(&st0) - exponent16(&st1);
+
+      old_cw = control_word;
+      cc = 0;
+
+      /* We want the status following the denorm tests, but don't want
+        the status changed by the arithmetic operations. */
+      saved_status = partial_status;
+      control_word &= ~CW_RC;
+      control_word |= RC_CHOP;
+
+      if ( expdif < 64 )
+       {
+         /* This should be the most common case */
+
+         if ( expdif > -2 )
+           {
+             u_char sign = st0_sign ^ st1_sign;
+             tag = FPU_u_div(&st0, &st1, &tmp,
+                             PR_64_BITS | RC_CHOP | 0x3f,
+                             sign);
+             setsign(&tmp, sign);
+
+             if ( exponent(&tmp) >= 0 )
+               {
+                 FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't
+                                                  overflow to 2^64 */
+                 q = significand(&tmp);
+
+                 rem_kernel(significand(&st0),
+                            &significand(&tmp),
+                            significand(&st1),
+                            q, expdif);
+
+                 setexponent16(&tmp, exponent16(&st1));
+               }
+             else
+               {
+                 reg_copy(&st0, &tmp);
+                 q = 0;
+               }
+
+             if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
+               {
+                 /* We may need to subtract st(1) once more,
+                    to get a result <= 1/2 of st(1). */
+                 u64 x;
+                 expdif = exponent16(&st1) - exponent16(&tmp);
+                 if ( expdif <= 1 )
+                   {
+                     if ( expdif == 0 )
+                       x = significand(&st1) - significand(&tmp);
+                     else /* expdif is 1 */
+                       x = (significand(&st1) << 1) - significand(&tmp);
+                     if ( (x < significand(&tmp)) ||
+                         /* or equi-distant (from 0 & st(1)) and q is odd */
+                         ((x == significand(&tmp)) && (q & 1) ) )
+                       {
+                         st0_sign = ! st0_sign;
+                         significand(&tmp) = x;
+                         q++;
+                       }
+                   }
+               }
+
+             if (q & 4) cc |= SW_C0;
+             if (q & 2) cc |= SW_C3;
+             if (q & 1) cc |= SW_C1;
+           }
+         else
+           {
+             control_word = old_cw;
+             setcc(0);
+             return;
+           }
+       }
+      else
+       {
+         /* There is a large exponent difference ( >= 64 ) */
+         /* To make much sense, the code in this section should
+            be done at high precision. */
+         int exp_1, N;
+         u_char sign;
+
+         /* prevent overflow here */
+         /* N is 'a number between 32 and 63' (p26-113) */
+         reg_copy(&st0, &tmp);
+         tmptag = st0_tag;
+         N = (expdif & 0x0000001f) + 32;  /* This choice gives results
+                                             identical to an AMD 486 */
+         setexponent16(&tmp, N);
+         exp_1 = exponent16(&st1);
+         setexponent16(&st1, 0);
+         expdif -= N;
+
+         sign = getsign(&tmp) ^ st1_sign;
+         tag = FPU_u_div(&tmp, &st1, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
+                         sign);
+         setsign(&tmp, sign);
+
+         FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't
+                                          overflow to 2^64 */
+
+         rem_kernel(significand(&st0),
+                    &significand(&tmp),
+                    significand(&st1),
+                    significand(&tmp),
+                    exponent(&tmp)
+                    ); 
+         setexponent16(&tmp, exp_1 + expdif);
+
+         /* It is possible for the operation to be complete here.
+            What does the IEEE standard say? The Intel 80486 manual
+            implies that the operation will never be completed at this
+            point, and the behaviour of a real 80486 confirms this.
+          */
+         if ( !(tmp.sigh | tmp.sigl) )
+           {
+             /* The result is zero */
+             control_word = old_cw;
+             partial_status = saved_status;
+             FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+             setsign(&st0, st0_sign);
+#ifdef PECULIAR_486
+             setcc(SW_C2);
+#else
+             setcc(0);
+#endif /* PECULIAR_486 */
+             return;
+           }
+         cc = SW_C2;
+       }
+
+      control_word = old_cw;
+      partial_status = saved_status;
+      tag = FPU_normalize_nuo(&tmp, 0);
+      reg_copy(&tmp, st0_ptr);
+
+      /* The only condition to be looked for is underflow,
+        and it can occur here only if underflow is unmasked. */
+      if ( (exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
+         && !(control_word & CW_Underflow) )
+       {
+         setcc(cc);
+         tag = arith_underflow(st0_ptr);
+         setsign(st0_ptr, st0_sign);
+         FPU_settag0(tag);
+         return;
+       }
+      else if ( (exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero) )
+       {
+         stdexp(st0_ptr);
+         setsign(st0_ptr, st0_sign);
+       }
+      else
+       {
+         tag = FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
+       }
+      FPU_settag0(tag);
+      setcc(cc);
+
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+  if ( st1_tag == TAG_Special )
+    st1_tag = FPU_Special(st1_ptr);
+
+  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+    {
+      if ( denormal_operand() < 0 )
+       return;
+      goto fprem_valid;
+    }
+  else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+    {
+      FPU_stack_underflow();
+      return;
+    }
+  else if ( st0_tag == TAG_Zero )
+    {
+      if ( st1_tag == TAG_Valid )
+       {
+         setcc(0); return;
+       }
+      else if ( st1_tag == TW_Denormal )
+       {
+         if ( denormal_operand() < 0 )
+           return;
+         setcc(0); return;
+       }
+      else if ( st1_tag == TAG_Zero )
+       { arith_invalid(0); return; } /* fprem(?,0) always invalid */
+      else if ( st1_tag == TW_Infinity )
+       { setcc(0); return; }
+    }
+  else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+    {
+      if ( st1_tag == TAG_Zero )
+       {
+         arith_invalid(0); /* fprem(Valid,Zero) is invalid */
+         return;
+       }
+      else if ( st1_tag != TW_NaN )
+       {
+         if ( ((st0_tag == TW_Denormal) || (st1_tag == TW_Denormal))
+              && (denormal_operand() < 0) )
+           return;
+
+         if ( st1_tag == TW_Infinity )
+           {
+             /* fprem(Valid,Infinity) is o.k. */
+             setcc(0); return;
+           }
+       }
+    }
+  else if ( st0_tag == TW_Infinity )
+    {
+      if ( st1_tag != TW_NaN )
+       {
+         arith_invalid(0); /* fprem(Infinity,?) is invalid */
+         return;
+       }
+    }
+
+  /* One of the registers must contain a NaN if we got here. */
+
+#ifdef PARANOID
+  if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) )
+      EXCEPTION(EX_INTERNAL | 0x118);
+#endif /* PARANOID */
+
+  real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
+
+}
+
+
+/* ST(1) <- ST(1) * log ST;  pop ST */
+static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st1_ptr = &st(1), exponent;
+  u_char st1_tag = FPU_gettagi(1);
+  u_char sign;
+  int e, tag;
+
+  clear_C1();
+
+  if ( (st0_tag == TAG_Valid) && (st1_tag == TAG_Valid) )
+    {
+    both_valid:
+      /* Both regs are Valid or Denormal */
+      if ( signpositive(st0_ptr) )
+       {
+         if ( st0_tag == TW_Denormal )
+           FPU_to_exp16(st0_ptr, st0_ptr);
+         else
+           /* Convert st(0) for internal use. */
+           setexponent16(st0_ptr, exponent(st0_ptr));
+
+         if ( (st0_ptr->sigh == 0x80000000) && (st0_ptr->sigl == 0) )
+           {
+             /* Special case. The result can be precise. */
+             u_char esign;
+             e = exponent16(st0_ptr);
+             if ( e >= 0 )
+               {
+                 exponent.sigh = e;
+                 esign = SIGN_POS;
+               }
+             else
+               {
+                 exponent.sigh = -e;
+                 esign = SIGN_NEG;
+               }
+             exponent.sigl = 0;
+             setexponent16(&exponent, 31);
+              tag = FPU_normalize_nuo(&exponent, 0);
+             stdexp(&exponent);
+             setsign(&exponent, esign);
+             tag = FPU_mul(&exponent, tag, 1, FULL_PRECISION);
+             if ( tag >= 0 )
+               FPU_settagi(1, tag);
+           }
+         else
+           {
+             /* The usual case */
+             sign = getsign(st1_ptr);
+             if ( st1_tag == TW_Denormal )
+               FPU_to_exp16(st1_ptr, st1_ptr);
+             else
+               /* Convert st(1) for internal use. */
+               setexponent16(st1_ptr, exponent(st1_ptr));
+             poly_l2(st0_ptr, st1_ptr, sign);
+           }
+       }
+      else
+       {
+         /* negative */
+         if ( arith_invalid(1) < 0 )
+           return;
+       }
+
+      FPU_pop();
+
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+  if ( st1_tag == TAG_Special )
+    st1_tag = FPU_Special(st1_ptr);
+
+  if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
+    {
+      FPU_stack_underflow_pop(1);
+      return;
+    }
+  else if ( (st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal) )
+    {
+      if ( st0_tag == TAG_Zero )
+       {
+         if ( st1_tag == TAG_Zero )
+           {
+             /* Both args zero is invalid */
+             if ( arith_invalid(1) < 0 )
+               return;
+           }
+         else
+           {
+             u_char sign;
+             sign = getsign(st1_ptr)^SIGN_NEG;
+             if ( FPU_divide_by_zero(1, sign) < 0 )
+               return;
+
+             setsign(st1_ptr, sign);
+           }
+       }
+      else if ( st1_tag == TAG_Zero )
+       {
+         /* st(1) contains zero, st(0) valid <> 0 */
+         /* Zero is the valid answer */
+         sign = getsign(st1_ptr);
+         
+         if ( signnegative(st0_ptr) )
+           {
+             /* log(negative) */
+             if ( arith_invalid(1) < 0 )
+               return;
+           }
+         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+         else
+           {
+             if ( exponent(st0_ptr) < 0 )
+               sign ^= SIGN_NEG;
+
+             FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+             setsign(st1_ptr, sign);
+           }
+       }
+      else
+       {
+         /* One or both operands are denormals. */
+         if ( denormal_operand() < 0 )
+           return;
+         goto both_valid;
+       }
+    }
+  else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+    {
+      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+       return;
+    }
+  /* One or both arg must be an infinity */
+  else if ( st0_tag == TW_Infinity )
+    {
+      if ( (signnegative(st0_ptr)) || (st1_tag == TAG_Zero) )
+       {
+         /* log(-infinity) or 0*log(infinity) */
+         if ( arith_invalid(1) < 0 )
+           return;
+       }
+      else
+       {
+         u_char sign = getsign(st1_ptr);
+
+         if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+
+         FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+         setsign(st1_ptr, sign);
+       }
+    }
+  /* st(1) must be infinity here */
+  else if ( ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
+           && ( signpositive(st0_ptr) ) )
+    {
+      if ( exponent(st0_ptr) >= 0 )
+       {
+         if ( (exponent(st0_ptr) == 0) &&
+             (st0_ptr->sigh == 0x80000000) &&
+             (st0_ptr->sigl == 0) )
+           {
+             /* st(0) holds 1.0 */
+             /* infinity*log(1) */
+             if ( arith_invalid(1) < 0 )
+               return;
+           }
+         /* else st(0) is positive and > 1.0 */
+       }
+      else
+       {
+         /* st(0) is positive and < 1.0 */
+
+         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+
+         changesign(st1_ptr);
+       }
+    }
+  else
+    {
+      /* st(0) must be zero or negative */
+      if ( st0_tag == TAG_Zero )
+       {
+         /* This should be invalid, but a real 80486 is happy with it. */
+
+#ifndef PECULIAR_486
+         sign = getsign(st1_ptr);
+         if ( FPU_divide_by_zero(1, sign) < 0 )
+           return;
+#endif /* PECULIAR_486 */
+
+         changesign(st1_ptr);
+       }
+      else if ( arith_invalid(1) < 0 )   /* log(negative) */
+       return;
+    }
+
+  FPU_pop();
+}
+
+
+static void fpatan(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st1_ptr = &st(1);
+  u_char st1_tag = FPU_gettagi(1);
+  int tag;
+
+  clear_C1();
+  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+    {
+    valid_atan:
+
+      poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
+
+      FPU_pop();
+
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+  if ( st1_tag == TAG_Special )
+    st1_tag = FPU_Special(st1_ptr);
+
+  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+    {
+      if ( denormal_operand() < 0 )
+       return;
+
+      goto valid_atan;
+    }
+  else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
+    {
+      FPU_stack_underflow_pop(1);
+      return;
+    }
+  else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+    {
+      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0 )
+         FPU_pop();
+      return;
+    }
+  else if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
+    {
+      u_char sign = getsign(st1_ptr);
+      if ( st0_tag == TW_Infinity )
+       {
+         if ( st1_tag == TW_Infinity )
+           {
+             if ( signpositive(st0_ptr) )
+               {
+                 FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
+               }
+             else
+               {
+                 setpositive(st1_ptr);
+                 tag = FPU_u_add(&CONST_PI4, &CONST_PI2, st1_ptr,
+                                 FULL_PRECISION, SIGN_POS,
+                                 exponent(&CONST_PI4), exponent(&CONST_PI2));
+                 if ( tag >= 0 )
+                   FPU_settagi(1, tag);
+               }
+           }
+         else
+           {
+             if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+               return;
+
+             if ( signpositive(st0_ptr) )
+               {
+                 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+                 setsign(st1_ptr, sign);   /* An 80486 preserves the sign */
+                 FPU_pop();
+                 return;
+               }
+             else
+               {
+                 FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+               }
+           }
+       }
+      else
+       {
+         /* st(1) is infinity, st(0) not infinity */
+         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+
+         FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+       }
+      setsign(st1_ptr, sign);
+    }
+  else if ( st1_tag == TAG_Zero )
+    {
+      /* st(0) must be valid or zero */
+      u_char sign = getsign(st1_ptr);
+
+      if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+       return;
+
+      if ( signpositive(st0_ptr) )
+       {
+         /* An 80486 preserves the sign */
+         FPU_pop();
+         return;
+       }
+
+      FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+      setsign(st1_ptr, sign);
+    }
+  else if ( st0_tag == TAG_Zero )
+    {
+      /* st(1) must be TAG_Valid here */
+      u_char sign = getsign(st1_ptr);
+
+      if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+       return;
+
+      FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+      setsign(st1_ptr, sign);
+    }
+#ifdef PARANOID
+  else
+    EXCEPTION(EX_INTERNAL | 0x125);
+#endif /* PARANOID */
+
+  FPU_pop();
+  set_precision_flag_up();  /* We do not really know if up or down */
+}
+
+
+static void fprem(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  do_fprem(st0_ptr, st0_tag, RC_CHOP);
+}
+
+
+static void fprem1(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  do_fprem(st0_ptr, st0_tag, RC_RND);
+}
+
+
+static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  u_char sign, sign1;
+  FPU_REG *st1_ptr = &st(1), a, b;
+  u_char st1_tag = FPU_gettagi(1);
+
+  clear_C1();
+  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+    {
+    valid_yl2xp1:
+
+      sign = getsign(st0_ptr);
+      sign1 = getsign(st1_ptr);
+
+      FPU_to_exp16(st0_ptr, &a);
+      FPU_to_exp16(st1_ptr, &b);
+
+      if ( poly_l2p1(sign, sign1, &a, &b, st1_ptr) )
+       return;
+
+      FPU_pop();
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+  if ( st1_tag == TAG_Special )
+    st1_tag = FPU_Special(st1_ptr);
+
+  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+    {
+      if ( denormal_operand() < 0 )
+       return;
+
+      goto valid_yl2xp1;
+    }
+  else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+    {
+      FPU_stack_underflow_pop(1);
+      return;
+    }
+  else if ( st0_tag == TAG_Zero )
+    {
+      switch ( st1_tag )
+       {
+       case TW_Denormal:
+         if ( denormal_operand() < 0 )
+           return;
+
+       case TAG_Zero:
+       case TAG_Valid:
+         setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
+         FPU_copy_to_reg1(st0_ptr, st0_tag);
+         break;
+
+       case TW_Infinity:
+         /* Infinity*log(1) */
+         if ( arith_invalid(1) < 0 )
+           return;
+         break;
+
+       case TW_NaN:
+         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+           return;
+         break;
+
+       default:
+#ifdef PARANOID
+         EXCEPTION(EX_INTERNAL | 0x116);
+         return;
+#endif /* PARANOID */
+       }
+    }
+  else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+    {
+      switch ( st1_tag )
+       {
+       case TAG_Zero:
+         if ( signnegative(st0_ptr) )
+           {
+             if ( exponent(st0_ptr) >= 0 )
+               {
+                 /* st(0) holds <= -1.0 */
+#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */
+                 changesign(st1_ptr);
+#else
+                 if ( arith_invalid(1) < 0 )
+                   return;
+#endif /* PECULIAR_486 */
+               }
+             else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+               return;
+             else
+               changesign(st1_ptr);
+           }
+         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+         break;
+
+       case TW_Infinity:
+         if ( signnegative(st0_ptr) )
+           {
+             if ( (exponent(st0_ptr) >= 0) &&
+                 !((st0_ptr->sigh == 0x80000000) &&
+                   (st0_ptr->sigl == 0)) )
+               {
+                 /* st(0) holds < -1.0 */
+#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */
+                 changesign(st1_ptr);
+#else
+                 if ( arith_invalid(1) < 0 ) return;
+#endif /* PECULIAR_486 */
+               }
+             else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+               return;
+             else
+               changesign(st1_ptr);
+           }
+         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+         break;
+
+       case TW_NaN:
+         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+           return;
+       }
+
+    }
+  else if ( st0_tag == TW_NaN )
+    {
+      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+       return;
+    }
+  else if ( st0_tag == TW_Infinity )
+    {
+      if ( st1_tag == TW_NaN )
+       {
+         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+           return;
+       }
+      else if ( signnegative(st0_ptr) )
+       {
+#ifndef PECULIAR_486
+         /* This should have higher priority than denormals, but... */
+         if ( arith_invalid(1) < 0 )  /* log(-infinity) */
+           return;
+#endif /* PECULIAR_486 */
+         if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+#ifdef PECULIAR_486
+         /* Denormal operands actually get higher priority */
+         if ( arith_invalid(1) < 0 )  /* log(-infinity) */
+           return;
+#endif /* PECULIAR_486 */
+       }
+      else if ( st1_tag == TAG_Zero )
+       {
+         /* log(infinity) */
+         if ( arith_invalid(1) < 0 )
+           return;
+       }
+       
+      /* st(1) must be valid here. */
+
+      else if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+       return;
+
+      /* The Manual says that log(Infinity) is invalid, but a real
+        80486 sensibly says that it is o.k. */
+      else
+       {
+         u_char sign = getsign(st1_ptr);
+         FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+         setsign(st1_ptr, sign);
+       }
+    }
+#ifdef PARANOID
+  else
+    {
+      EXCEPTION(EX_INTERNAL | 0x117);
+      return;
+    }
+#endif /* PARANOID */
+
+  FPU_pop();
+  return;
+
+}
+
+
+static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
+{
+  FPU_REG *st1_ptr = &st(1);
+  u_char st1_tag = FPU_gettagi(1);
+  int old_cw = control_word;
+  u_char sign = getsign(st0_ptr);
+
+  clear_C1();
+  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+    {
+      s32 scale;
+      FPU_REG tmp;
+
+      /* Convert register for internal use. */
+      setexponent16(st0_ptr, exponent(st0_ptr));
+
+    valid_scale:
+
+      if ( exponent(st1_ptr) > 30 )
+       {
+         /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
+
+         if ( signpositive(st1_ptr) )
+           {
+             EXCEPTION(EX_Overflow);
+             FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+           }
+         else
+           {
+             EXCEPTION(EX_Underflow);
+             FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+           }
+         setsign(st0_ptr, sign);
+         return;
+       }
+
+      control_word &= ~CW_RC;
+      control_word |= RC_CHOP;
+      reg_copy(st1_ptr, &tmp);
+      FPU_round_to_int(&tmp, st1_tag);      /* This can never overflow here */
+      control_word = old_cw;
+      scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
+      scale += exponent16(st0_ptr);
+
+      setexponent16(st0_ptr, scale);
+
+      /* Use FPU_round() to properly detect under/overflow etc */
+      FPU_round(st0_ptr, 0, 0, control_word, sign);
+
+      return;
+    }
+
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+  if ( st1_tag == TAG_Special )
+    st1_tag = FPU_Special(st1_ptr);
+
+  if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+    {
+      switch ( st1_tag )
+       {
+       case TAG_Valid:
+         /* st(0) must be a denormal */
+         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+
+         FPU_to_exp16(st0_ptr, st0_ptr);  /* Will not be left on stack */
+         goto valid_scale;
+
+       case TAG_Zero:
+         if ( st0_tag == TW_Denormal )
+           denormal_operand();
+         return;
+
+       case TW_Denormal:
+         denormal_operand();
+         return;
+
+       case TW_Infinity:
+         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+           return;
+
+         if ( signpositive(st1_ptr) )
+           FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+         else
+           FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+         setsign(st0_ptr, sign);
+         return;
+
+       case TW_NaN:
+         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+         return;
+       }
+    }
+  else if ( st0_tag == TAG_Zero )
+    {
+      switch ( st1_tag )
+       {
+       case TAG_Valid:
+       case TAG_Zero:
+         return;
+
+       case TW_Denormal:
+         denormal_operand();
+         return;
+
+       case TW_Infinity:
+         if ( signpositive(st1_ptr) )
+           arith_invalid(0); /* Zero scaled by +Infinity */
+         return;
+
+       case TW_NaN:
+         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+         return;
+       }
+    }
+  else if ( st0_tag == TW_Infinity )
+    {
+      switch ( st1_tag )
+       {
+       case TAG_Valid:
+       case TAG_Zero:
+         return;
+
+       case TW_Denormal:
+         denormal_operand();
+         return;
+
+       case TW_Infinity:
+         if ( signnegative(st1_ptr) )
+           arith_invalid(0); /* Infinity scaled by -Infinity */
+         return;
+
+       case TW_NaN:
+         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+         return;
+       }
+    }
+  else if ( st0_tag == TW_NaN )
+    {
+      if ( st1_tag != TAG_Empty )
+       { real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); return; }
+    }
+
+#ifdef PARANOID
+  if ( !((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) )
+    {
+      EXCEPTION(EX_INTERNAL | 0x115);
+      return;
+    }
+#endif
+
+  /* At least one of st(0), st(1) must be empty */
+  FPU_stack_underflow();
+
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static FUNC_ST0 const trig_table_a[] = {
+  f2xm1, fyl2x, fptan, fpatan,
+  fxtract, fprem1, (FUNC_ST0)fdecstp, (FUNC_ST0)fincstp
+};
+
+void FPU_triga(void)
+{
+  (trig_table_a[FPU_rm])(&st(0), FPU_gettag0());
+}
+
+
+static FUNC_ST0 const trig_table_b[] =
+  {
+    fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0)fsin, fcos
+  };
+
+void FPU_trigb(void)
+{
+  (trig_table_b[FPU_rm])(&st(0), FPU_gettag0());
+}
diff --git a/sid/component/bochs/fpu/get_address.c b/sid/component/bochs/fpu/get_address.c
new file mode 100644 (file)
index 0000000..e54c0cc
--- /dev/null
@@ -0,0 +1,445 @@
+/*---------------------------------------------------------------------------+
+ |  get_address.c                                                            |
+ |                                                                           |
+ | Get the effective address from an FPU instruction.                        |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@suburbia.net             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
+
+#include <linux/stddef.h>
+
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#define FPU_WRITE_BIT 0x10
+
+static int reg_offset[] = {
+       offsetof(struct info,___eax),
+       offsetof(struct info,___ecx),
+       offsetof(struct info,___edx),
+       offsetof(struct info,___ebx),
+       offsetof(struct info,___esp),
+       offsetof(struct info,___ebp),
+       offsetof(struct info,___esi),
+       offsetof(struct info,___edi)
+};
+
+#define REG_(x) (*(s32 *)(reg_offset[(x)]+(u_char *) FPU_info))
+
+static int reg_offset_vm86[] = {
+       offsetof(struct info,___cs),
+       offsetof(struct info,___vm86_ds),
+       offsetof(struct info,___vm86_es),
+       offsetof(struct info,___vm86_fs),
+       offsetof(struct info,___vm86_gs),
+       offsetof(struct info,___ss),
+       offsetof(struct info,___vm86_ds)
+      };
+
+#define VM86_REG_(x) (*(unsigned short *) \
+                     (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
+
+/* These are dummy, fs and gs are not saved on the stack. */
+#define ___FS ___ds
+#define ___GS ___ds
+
+static int reg_offset_pm[] = {
+       offsetof(struct info,___cs),
+       offsetof(struct info,___ds),
+       offsetof(struct info,___es),
+       offsetof(struct info,___FS),
+       offsetof(struct info,___GS),
+       offsetof(struct info,___ss),
+       offsetof(struct info,___ds)
+      };
+
+#define PM_REG_(x) (*(unsigned short *) \
+                     (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info))
+
+
+/* Decode the SIB byte. This function assumes mod != 0 */
+static int sib(int mod, u32 *fpu_eip)
+{
+  u_char ss,index,base;
+  s32 offset;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_code_verify_area(1);
+  FPU_get_user(base, (u_char *) (*fpu_eip));   /* The SIB byte */
+  RE_ENTRANT_CHECK_ON;
+  (*fpu_eip)++;
+  ss = base >> 6;
+  index = (base >> 3) & 7;
+  base &= 7;
+
+  if ((mod == 0) && (base == 5))
+    offset = 0;              /* No base register */
+  else
+    offset = REG_(base);
+
+  if (index == 4)
+    {
+      /* No index register */
+      /* A non-zero ss is illegal */
+      if ( ss )
+       EXCEPTION(EX_Invalid);
+    }
+  else
+    {
+      offset += (REG_(index)) << ss;
+    }
+
+  if (mod == 1)
+    {
+      /* 8 bit signed displacement */
+      s32 displacement;
+      RE_ENTRANT_CHECK_OFF;
+      FPU_code_verify_area(1);
+      FPU_get_user(displacement, (signed char *) (*fpu_eip));
+      offset += displacement;
+      RE_ENTRANT_CHECK_ON;
+      (*fpu_eip)++;
+    }
+  else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
+    {
+      /* 32 bit displacement */
+      s32 displacement;
+      RE_ENTRANT_CHECK_OFF;
+      FPU_code_verify_area(4);
+      FPU_get_user(displacement, (s32 *) (*fpu_eip));
+      offset += displacement;
+      RE_ENTRANT_CHECK_ON;
+      (*fpu_eip) += 4;
+    }
+
+  return offset;
+}
+
+
+static u32 vm86_segment(u_char segment,
+                                 struct address *addr)
+{
+  segment--;
+#ifdef PARANOID
+  if ( segment > PREFIX_SS_ )
+    {
+      EXCEPTION(EX_INTERNAL|0x130);
+      math_abort(FPU_info,SIGSEGV);
+    }
+#endif /* PARANOID */
+  addr->selector = VM86_REG_(segment);
+  return (u32)VM86_REG_(segment) << 4;
+}
+
+
+/* This should work for 16 and 32 bit protected mode. */
+static s32 pm_address(u_char FPU_modrm, u_char segment,
+                      struct address *addr, s32 offset)
+{ 
+  struct desc_struct descriptor;
+  u32 base_address, limit, address, seg_top;
+
+  segment--;
+
+#ifdef PARANOID
+  /* segment is unsigned, so this also detects if segment was 0: */
+  if ( segment > PREFIX_SS_ )
+    {
+      EXCEPTION(EX_INTERNAL|0x132);
+      math_abort(FPU_info,SIGSEGV);
+    }
+#endif /* PARANOID */
+
+  switch ( segment )
+    {
+      /* fs and gs aren't used by the kernel, so they still have their
+        user-space values. */
+    case PREFIX_FS_-1:
+      /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+        in the assembler statement. */
+      __asm__("mov %%fs,%0":"=r" ((unsigned short)addr->selector));
+      break;
+    case PREFIX_GS_-1:
+      /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+        in the assembler statement. */
+      __asm__("mov %%gs,%0":"=r" ((unsigned short)addr->selector));
+      break;
+    default:
+      addr->selector = PM_REG_(segment);
+    }
+
+  descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
+  base_address = SEG_BASE_ADDR(descriptor);
+  address = base_address + offset;
+  limit = base_address
+       + (SEG_LIMIT(descriptor)+1) * SEG_GRANULARITY(descriptor) - 1;
+  if ( limit < base_address ) limit = 0xffffffff;
+
+  if ( SEG_EXPAND_DOWN(descriptor) )
+    {
+      if ( SEG_G_BIT(descriptor) )
+       seg_top = 0xffffffff;
+      else
+       {
+         seg_top = base_address + (1 << 20);
+         if ( seg_top < base_address ) seg_top = 0xffffffff;
+       }
+      access_limit =
+       (address <= limit) || (address >= seg_top) ? 0 :
+         ((seg_top-address) >= 255 ? 255 : seg_top-address);
+    }
+  else
+    {
+      access_limit =
+       (address > limit) || (address < base_address) ? 0 :
+         ((limit-address) >= 254 ? 255 : limit-address+1);
+    }
+  if ( SEG_EXECUTE_ONLY(descriptor) ||
+      (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT)) )
+    {
+      access_limit = 0;
+    }
+  return address;
+}
+
+
+/*
+       MOD R/M byte:  MOD == 3 has a special use for the FPU
+                      SIB byte used iff R/M = 100b
+
+       7   6   5   4   3   2   1   0
+       .....   .........   .........
+        MOD    OPCODE(2)     R/M
+
+
+       SIB byte
+
+       7   6   5   4   3   2   1   0
+       .....   .........   .........
+        SS      INDEX        BASE
+
+*/
+
+void *FPU_get_address(u_char FPU_modrm, u32 *fpu_eip,
+                     struct address *addr,
+                     fpu_addr_modes addr_modes)
+{
+  u_char mod;
+  unsigned rm = FPU_modrm & 7;
+  s32 *cpu_reg_ptr;
+  int address = 0;     /* Initialized just to stop compiler warnings. */
+
+  /* Memory accessed via the cs selector is write protected
+     in `non-segmented' 32 bit protected mode. */
+  if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+      && (addr_modes.override.segment == PREFIX_CS_) )
+    {
+      math_abort(FPU_info,SIGSEGV);
+    }
+
+  addr->selector = FPU_DS;   /* Default, for 32 bit non-segmented mode. */
+
+  mod = (FPU_modrm >> 6) & 3;
+
+  if (rm == 4 && mod != 3)
+    {
+      address = sib(mod, fpu_eip);
+    }
+  else
+    {
+      cpu_reg_ptr = & REG_(rm);
+      switch (mod)
+       {
+       case 0:
+         if (rm == 5)
+           {
+             /* Special case: disp32 */
+             RE_ENTRANT_CHECK_OFF;
+             FPU_code_verify_area(4);
+             FPU_get_user(address, (u32 *) (*fpu_eip));
+             (*fpu_eip) += 4;
+             RE_ENTRANT_CHECK_ON;
+             addr->offset = address;
+             return (void *) address;
+           }
+         else
+           {
+             address = *cpu_reg_ptr;  /* Just return the contents
+                                         of the cpu register */
+             addr->offset = address;
+             return (void *) address;
+           }
+       case 1:
+         /* 8 bit signed displacement */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_code_verify_area(1);
+         FPU_get_user(address, (signed char *) (*fpu_eip));
+         RE_ENTRANT_CHECK_ON;
+         (*fpu_eip)++;
+         break;
+       case 2:
+         /* 32 bit displacement */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_code_verify_area(4);
+         FPU_get_user(address, (s32 *) (*fpu_eip));
+         (*fpu_eip) += 4;
+         RE_ENTRANT_CHECK_ON;
+         break;
+       case 3:
+         /* Not legal for the FPU */
+         EXCEPTION(EX_Invalid);
+       }
+      address += *cpu_reg_ptr;
+    }
+
+  addr->offset = address;
+
+  switch ( addr_modes.default_mode )
+    {
+    case 0:
+      break;
+    case VM86:
+      address += vm86_segment(addr_modes.override.segment, addr);
+      break;
+    case PM16:
+    case SEG32:
+      address = pm_address(FPU_modrm, addr_modes.override.segment,
+                          addr, address);
+      break;
+    default:
+      EXCEPTION(EX_INTERNAL|0x133);
+    }
+
+  return (void *)address;
+}
+
+
+void *FPU_get_address_16(u_char FPU_modrm, u32 *fpu_eip,
+                        struct address *addr,
+                        fpu_addr_modes addr_modes)
+{
+  u_char mod;
+  unsigned rm = FPU_modrm & 7;
+  int address = 0;     /* Default used for mod == 0 */
+
+  /* Memory accessed via the cs selector is write protected
+     in `non-segmented' 32 bit protected mode. */
+  if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+      && (addr_modes.override.segment == PREFIX_CS_) )
+    {
+      math_abort(FPU_info,SIGSEGV);
+    }
+
+  addr->selector = FPU_DS;   /* Default, for 32 bit non-segmented mode. */
+
+  mod = (FPU_modrm >> 6) & 3;
+
+  switch (mod)
+    {
+    case 0:
+      if (rm == 6)
+       {
+         /* Special case: disp16 */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_code_verify_area(2);
+         FPU_get_user(address, (unsigned short *) (*fpu_eip));
+         (*fpu_eip) += 2;
+         RE_ENTRANT_CHECK_ON;
+         goto add_segment;
+       }
+      break;
+    case 1:
+      /* 8 bit signed displacement */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_code_verify_area(1);
+      FPU_get_user(address, (signed char *) (*fpu_eip));
+      RE_ENTRANT_CHECK_ON;
+      (*fpu_eip)++;
+      break;
+    case 2:
+      /* 16 bit displacement */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_code_verify_area(2);
+      FPU_get_user(address, (unsigned short *) (*fpu_eip));
+      (*fpu_eip) += 2;
+      RE_ENTRANT_CHECK_ON;
+      break;
+    case 3:
+      /* Not legal for the FPU */
+      EXCEPTION(EX_Invalid);
+      break;
+    }
+  switch ( rm )
+    {
+    case 0:
+      address += FPU_info->___ebx + FPU_info->___esi;
+      break;
+    case 1:
+      address += FPU_info->___ebx + FPU_info->___edi;
+      break;
+    case 2:
+      address += FPU_info->___ebp + FPU_info->___esi;
+      if ( addr_modes.override.segment == PREFIX_DEFAULT )
+       addr_modes.override.segment = PREFIX_SS_;
+      break;
+    case 3:
+      address += FPU_info->___ebp + FPU_info->___edi;
+      if ( addr_modes.override.segment == PREFIX_DEFAULT )
+       addr_modes.override.segment = PREFIX_SS_;
+      break;
+    case 4:
+      address += FPU_info->___esi;
+      break;
+    case 5:
+      address += FPU_info->___edi;
+      break;
+    case 6:
+      address += FPU_info->___ebp;
+      if ( addr_modes.override.segment == PREFIX_DEFAULT )
+       addr_modes.override.segment = PREFIX_SS_;
+      break;
+    case 7:
+      address += FPU_info->___ebx;
+      break;
+    }
+
+ add_segment:
+  address &= 0xffff;
+
+  addr->offset = address;
+
+  switch ( addr_modes.default_mode )
+    {
+    case 0:
+      break;
+    case VM86:
+      address += vm86_segment(addr_modes.override.segment, addr);
+      break;
+    case PM16:
+    case SEG32:
+      address = pm_address(FPU_modrm, addr_modes.override.segment,
+                          addr, address);
+      break;
+    default:
+      EXCEPTION(EX_INTERNAL|0x131);
+    }
+
+  return (void *)address ;
+}
diff --git a/sid/component/bochs/fpu/load_store.c b/sid/component/bochs/fpu/load_store.c
new file mode 100644 (file)
index 0000000..488fa92
--- /dev/null
@@ -0,0 +1,270 @@
+/*---------------------------------------------------------------------------+
+ |  load_store.c                                                             |
+ |                                                                           |
+ | This file contains most of the code to interpret the FPU instructions     |
+ | which load and store from user memory.                                    |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@suburbia.net             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
+#include <asm/uaccess.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+
+
+#define _NONE_ 0   /* st0_ptr etc not needed */
+#define _REG0_ 1   /* Will be storing st(0) */
+#define _PUSH_ 3   /* Need to check for space to push onto stack */
+#define _null_ 4   /* Function illegal or not implemented */
+
+#define pop_0()        { FPU_settag0(TAG_Empty); top++; }
+
+
+static u_char const type_table[32] = {
+  _PUSH_, _PUSH_, _PUSH_, _PUSH_,
+  _null_, _null_, _null_, _null_,
+  _REG0_, _REG0_, _REG0_, _REG0_,
+  _REG0_, _REG0_, _REG0_, _REG0_,
+  _NONE_, _null_, _NONE_, _PUSH_,
+  _NONE_, _PUSH_, _null_, _PUSH_,
+  _NONE_, _null_, _NONE_, _REG0_,
+  _NONE_, _REG0_, _NONE_, _REG0_
+  };
+
+u_char const data_sizes_16[32] = {
+  4,  4,  8,  2,  0,  0,  0,  0,
+  4,  4,  8,  2,  4,  4,  8,  2,
+  14, 0, 94, 10,  2, 10,  0,  8,  
+  14, 0, 94, 10,  2, 10,  2,  8
+};
+
+u_char const data_sizes_32[32] = {
+  4,  4,  8,  2,  0,  0,  0,  0,
+  4,  4,  8,  2,  4,  4,  8,  2,
+  28, 0,108, 10,  2, 10,  0,  8,  
+  28, 0,108, 10,  2, 10,  2,  8
+};
+
+int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
+                    void *data_address)
+{
+  FPU_REG loaded_data;
+  FPU_REG *st0_ptr;
+  u_char st0_tag = TAG_Empty;  /* This is just to stop a gcc warning. */
+  u_char loaded_tag;
+
+  st0_ptr = NULL;    /* Initialized just to stop compiler warnings. */
+
+  if ( addr_modes.default_mode & PROTECTED )
+    {
+      if ( addr_modes.default_mode == SEG32 )
+       {
+         if ( access_limit < data_sizes_32[type] )
+           math_abort(FPU_info,SIGSEGV);
+       }
+      else if ( addr_modes.default_mode == PM16 )
+       {
+         if ( access_limit < data_sizes_16[type] )
+           math_abort(FPU_info,SIGSEGV);
+       }
+#ifdef PARANOID
+      else
+       EXCEPTION(EX_INTERNAL|0x140);
+#endif /* PARANOID */
+    }
+
+  switch ( type_table[type] )
+    {
+    case _NONE_:
+      break;
+    case _REG0_:
+      st0_ptr = &st(0);       /* Some of these instructions pop after
+                                storing */
+      st0_tag = FPU_gettag0();
+      break;
+    case _PUSH_:
+      {
+       if ( FPU_gettagi(-1) != TAG_Empty )
+         { FPU_stack_overflow(); return 0; }
+       top--;
+       st0_ptr = &st(0);
+      }
+      break;
+    case _null_:
+      FPU_illegal();
+      return 0;
+#ifdef PARANOID
+    default:
+      EXCEPTION(EX_INTERNAL|0x141);
+      return 0;
+#endif /* PARANOID */
+    }
+
+  switch ( type )
+    {
+    case 000:       /* fld m32real */
+      clear_C1();
+      loaded_tag = FPU_load_single((float *)data_address, &loaded_data);
+      if ( (loaded_tag == TAG_Special)
+          && isNaN(&loaded_data)
+          && (real_1op_NaN(&loaded_data) < 0) )
+       {
+         top++;
+         break;
+       }
+      FPU_copy_to_reg0(&loaded_data, loaded_tag);
+      break;
+    case 001:      /* fild m32int */
+      clear_C1();
+      loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data);
+      FPU_copy_to_reg0(&loaded_data, loaded_tag);
+      break;
+    case 002:      /* fld m64real */
+      clear_C1();
+      loaded_tag = FPU_load_double((double *)data_address, &loaded_data);
+      if ( (loaded_tag == TAG_Special)
+          && isNaN(&loaded_data)
+          && (real_1op_NaN(&loaded_data) < 0) )
+       {
+         top++;
+         break;
+       }
+      FPU_copy_to_reg0(&loaded_data, loaded_tag);
+      break;
+    case 003:      /* fild m16int */
+      clear_C1();
+      loaded_tag = FPU_load_int16((s16 *)data_address, &loaded_data);
+      FPU_copy_to_reg0(&loaded_data, loaded_tag);
+      break;
+    case 010:      /* fst m32real */
+      clear_C1();
+      FPU_store_single(st0_ptr, st0_tag, (float *)data_address);
+      break;
+    case 011:      /* fist m32int */
+      clear_C1();
+      FPU_store_int32(st0_ptr, st0_tag, (s32 *)data_address);
+      break;
+    case 012:     /* fst m64real */
+      clear_C1();
+      FPU_store_double(st0_ptr, st0_tag, (double *)data_address);
+      break;
+    case 013:     /* fist m16int */
+      clear_C1();
+      FPU_store_int16(st0_ptr, st0_tag, (s16 *)data_address);
+      break;
+    case 014:     /* fstp m32real */
+      clear_C1();
+      if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 015:     /* fistp m32int */
+      clear_C1();
+      if ( FPU_store_int32(st0_ptr, st0_tag, (s32 *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 016:     /* fstp m64real */
+      clear_C1();
+      if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 017:     /* fistp m16int */
+      clear_C1();
+      if ( FPU_store_int16(st0_ptr, st0_tag, (s16 *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 020:     /* fldenv  m14/28byte */
+      fldenv(addr_modes, (u_char *)data_address);
+      /* Ensure that the values just loaded are not changed by
+        fix-up operations. */
+      return 1;
+    case 022:     /* frstor m94/108byte */
+      frstor(addr_modes, (u_char *)data_address);
+      /* Ensure that the values just loaded are not changed by
+        fix-up operations. */
+      return 1;
+    case 023:     /* fbld m80dec */
+      clear_C1();
+      loaded_tag = FPU_load_bcd((u_char *)data_address);
+      FPU_settag0(loaded_tag);
+      break;
+    case 024:     /* fldcw */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_READ, data_address, 2);
+      FPU_get_user(control_word, (u16 *) data_address);
+      RE_ENTRANT_CHECK_ON;
+      if ( partial_status & ~control_word & CW_Exceptions )
+       partial_status |= (SW_Summary | SW_Backward);
+      else
+       partial_status &= ~(SW_Summary | SW_Backward);
+#ifdef PECULIAR_486
+      control_word |= 0x40;  /* An 80486 appears to always set this bit */
+#endif /* PECULIAR_486 */
+      return 1;
+    case 025:      /* fld m80real */
+      clear_C1();
+      loaded_tag = FPU_load_extended((long double *)data_address, 0);
+      FPU_settag0(loaded_tag);
+      break;
+    case 027:      /* fild m64int */
+      clear_C1();
+      loaded_tag = FPU_load_int64((s64 *)data_address);
+      FPU_settag0(loaded_tag);
+      break;
+    case 030:     /* fstenv  m14/28byte */
+      fstenv(addr_modes, (u_char *)data_address);
+      return 1;
+    case 032:      /* fsave */
+      fsave(addr_modes, (u_char *)data_address);
+      return 1;
+    case 033:      /* fbstp m80dec */
+      clear_C1();
+      if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 034:      /* fstcw m16int */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE,data_address,2);
+      FPU_put_user(control_word, (u16 *) data_address);
+      RE_ENTRANT_CHECK_ON;
+      return 1;
+    case 035:      /* fstp m80real */
+      clear_C1();
+      if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    case 036:      /* fstsw m2byte */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE,data_address,2);
+      FPU_put_user(status_word(),(u16 *) data_address);
+      RE_ENTRANT_CHECK_ON;
+      return 1;
+    case 037:      /* fistp m64int */
+      clear_C1();
+      if ( FPU_store_int64(st0_ptr, st0_tag, (s64 *)data_address) )
+       pop_0();  /* pop only if the number was actually stored
+                    (see the 80486 manual p16-28) */
+      break;
+    }
+  return 0;
+}
diff --git a/sid/component/bochs/fpu/mul_Xsig.S b/sid/component/bochs/fpu/mul_Xsig.S
new file mode 100644 (file)
index 0000000..717785a
--- /dev/null
@@ -0,0 +1,176 @@
+/*---------------------------------------------------------------------------+
+ |  mul_Xsig.S                                                               |
+ |                                                                           |
+ | Multiply a 12 byte fixed point number by another fixed point number.      |
+ |                                                                           |
+ | Copyright (C) 1992,1994,1995                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |   void mul32_Xsig(Xsig *x, unsigned b)                                    |
+ |                                                                           |
+ |   void mul64_Xsig(Xsig *x, unsigned long long *b)                         |
+ |                                                                           |
+ |   void mul_Xsig_Xsig(Xsig *x, unsigned *b)                                |
+ |                                                                           |
+ | The result is neither rounded nor normalized, and the ls bit or so may    |
+ | be wrong.                                                                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+       .file   "mul_Xsig.S"
+
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(mul32_Xsig)
+       pushl %ebp
+       movl %esp,%ebp
+       subl $16,%esp
+       pushl %esi
+
+       movl PARAM1,%esi
+       movl PARAM2,%ecx
+
+       xor %eax,%eax
+       movl %eax,-4(%ebp)
+       movl %eax,-8(%ebp)
+
+       movl (%esi),%eax        /* lsl of Xsig */
+       mull %ecx               /* msl of b */
+       movl %edx,-12(%ebp)
+
+       movl 4(%esi),%eax       /* midl of Xsig */
+       mull %ecx               /* msl of b */
+       addl %eax,-12(%ebp)
+       adcl %edx,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull %ecx               /* msl of b */
+       addl %eax,-8(%ebp)
+       adcl %edx,-4(%ebp)
+
+       movl -12(%ebp),%eax
+       movl %eax,(%esi)
+       movl -8(%ebp),%eax
+       movl %eax,4(%esi)
+       movl -4(%ebp),%eax
+       movl %eax,8(%esi)
+
+       popl %esi
+       leave
+       ret
+
+
+ENTRY(mul64_Xsig)
+       pushl %ebp
+       movl %esp,%ebp
+       subl $16,%esp
+       pushl %esi
+
+       movl PARAM1,%esi
+       movl PARAM2,%ecx
+
+       xor %eax,%eax
+       movl %eax,-4(%ebp)
+       movl %eax,-8(%ebp)
+
+       movl (%esi),%eax        /* lsl of Xsig */
+       mull 4(%ecx)            /* msl of b */
+       movl %edx,-12(%ebp)
+
+       movl 4(%esi),%eax       /* midl of Xsig */
+       mull (%ecx)             /* lsl of b */
+       addl %edx,-12(%ebp)
+       adcl $0,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 4(%esi),%eax       /* midl of Xsig */
+       mull 4(%ecx)            /* msl of b */
+       addl %eax,-12(%ebp)
+       adcl %edx,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull (%ecx)             /* lsl of b */
+       addl %eax,-12(%ebp)
+       adcl %edx,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull 4(%ecx)            /* msl of b */
+       addl %eax,-8(%ebp)
+       adcl %edx,-4(%ebp)
+
+       movl -12(%ebp),%eax
+       movl %eax,(%esi)
+       movl -8(%ebp),%eax
+       movl %eax,4(%esi)
+       movl -4(%ebp),%eax
+       movl %eax,8(%esi)
+
+       popl %esi
+       leave
+       ret
+
+
+
+ENTRY(mul_Xsig_Xsig)
+       pushl %ebp
+       movl %esp,%ebp
+       subl $16,%esp
+       pushl %esi
+
+       movl PARAM1,%esi
+       movl PARAM2,%ecx
+
+       xor %eax,%eax
+       movl %eax,-4(%ebp)
+       movl %eax,-8(%ebp)
+
+       movl (%esi),%eax        /* lsl of Xsig */
+       mull 8(%ecx)            /* msl of b */
+       movl %edx,-12(%ebp)
+
+       movl 4(%esi),%eax       /* midl of Xsig */
+       mull 4(%ecx)            /* midl of b */
+       addl %edx,-12(%ebp)
+       adcl $0,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull (%ecx)             /* lsl of b */
+       addl %edx,-12(%ebp)
+       adcl $0,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 4(%esi),%eax       /* midl of Xsig */
+       mull 8(%ecx)            /* msl of b */
+       addl %eax,-12(%ebp)
+       adcl %edx,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull 4(%ecx)            /* midl of b */
+       addl %eax,-12(%ebp)
+       adcl %edx,-8(%ebp)
+       adcl $0,-4(%ebp)
+
+       movl 8(%esi),%eax       /* msl of Xsig */
+       mull 8(%ecx)            /* msl of b */
+       addl %eax,-8(%ebp)
+       adcl %edx,-4(%ebp)
+
+       movl -12(%ebp),%edx
+       movl %edx,(%esi)
+       movl -8(%ebp),%edx
+       movl %edx,4(%esi)
+       movl -4(%ebp),%edx
+       movl %edx,8(%esi)
+
+       popl %esi
+       leave
+       ret
+
diff --git a/sid/component/bochs/fpu/mul_Xsig.c b/sid/component/bochs/fpu/mul_Xsig.c
new file mode 100644 (file)
index 0000000..8dc4c94
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------+
+ |  mul_Xsig.S                                                               |
+ |                                                                           |
+ | Multiply a 12 byte fixed point number by another fixed point number.      |
+ |                                                                           |
+ | Copyright (C) 1992,1994,1995                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ |                                                                           |
+ | The result is neither rounded nor normalized, and the ls bit or so may    |
+ | be wrong.                                                                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void mul32_Xsig(Xsig *x, const u32 ba)
+{
+  Xsig y;
+  u32 zl;
+  u64 b = ba, z;
+
+  z = b * x->lsw;
+  y.lsw = z >> 32;
+
+  z = b * x->midw;
+  y.midw = z >> 32;
+  zl = z;
+  y.lsw += zl;
+  if ( zl > y.lsw )
+    y.midw ++;
+
+  z = b * x->msw;
+  y.msw = z >> 32;
+  zl = z;
+  y.midw += zl;
+  if ( zl > y.midw )
+    y.msw ++;
+
+  *x = y;
+
+}
+
+
+void mul64_Xsig(Xsig *x, const u64 *b)
+{
+  Xsig yh, yl;
+
+  yh = *x;
+  yl = *x;
+  mul32_Xsig(&yh, (*b) >> 32);
+  mul32_Xsig(&yl, *b);
+
+  x->msw = yh.msw;
+  x->midw = yh.midw + yl.msw;
+  if ( yh.midw > x->midw )
+    x->msw ++;
+  x->lsw = yh.lsw + yl.midw;
+  if ( yh.lsw > x->lsw )
+    {
+      x->midw ++;
+      if ( x->midw == 0 )
+       x->msw ++;
+    }
+
+}
+
+
+void mul_Xsig_Xsig(Xsig *x, const Xsig *b)
+{
+  u32 yh;
+  u64 y, z;
+
+  y = b->lsw;
+  y *= x->msw;
+  yh = y >> 32;
+
+  z = b->msw;
+  z <<= 32;
+  z += b->midw;
+  mul64_Xsig(x, &z);
+
+  x->lsw += yh;
+  if ( yh > x->lsw )
+    {
+      x->midw ++;
+      if ( x->midw == 0 )
+       x->msw ++;
+    }
+}
+
diff --git a/sid/component/bochs/fpu/poly.h b/sid/component/bochs/fpu/poly.h
new file mode 100644 (file)
index 0000000..558269f
--- /dev/null
@@ -0,0 +1,215 @@
+/*---------------------------------------------------------------------------+
+ |  poly.h                                                                   |
+ |                                                                           |
+ |  Header file for the FPU-emu poly*.c source files.                        |
+ |                                                                           |
+ | Copyright (C) 1994,1999                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
+ |                                                                           |
+ | Declarations and definitions for functions operating on Xsig (12-byte     |
+ | extended-significand) quantities.                                         |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _POLY_H
+#define _POLY_H
+
+/* This 12-byte structure is used to improve the accuracy of computation
+   of transcendental functions.
+   Intended to be used to get results better than 8-byte computation
+   allows. 9-byte would probably be sufficient.
+   */
+typedef struct {
+#ifdef EMU_BIG_ENDIAN
+  u32 msw;
+  u32 midw;
+  u32 lsw;
+#else
+  u32 lsw;
+  u32 midw;
+  u32 msw;
+#endif
+} GCC_ATTRIBUTE((packed)) Xsig;
+
+asmlinkage void mul64(u64 const *a, u64 const *b,
+                     u64 *result);
+asmlinkage void polynomial_Xsig(Xsig *, const u64 *x,
+                               const u64 terms[], const int n);
+
+asmlinkage void mul32_Xsig(Xsig *, const u32 mult);
+asmlinkage void mul64_Xsig(Xsig *, const u64 *mult);
+asmlinkage void mul_Xsig_Xsig(Xsig *dest, const Xsig *mult);
+
+asmlinkage void shr_Xsig(Xsig *, const int n);
+asmlinkage int round_Xsig(Xsig *);
+asmlinkage int norm_Xsig(Xsig *);
+asmlinkage void div_Xsig(const Xsig *x1, const Xsig *x2, Xsig *dest);
+
+/* Macro to extract the most significant 32 bits from a 64bit quantity */
+#ifdef EMU_BIG_ENDIAN
+#define LL_MSW(x)     (((u32 *)&x)[0])
+#else
+#define LL_MSW(x)     (((u32 *)&x)[1])
+#endif
+
+/* Macro to initialize an Xsig struct */
+#ifdef EMU_BIG_ENDIAN
+#define MK_XSIG(a,b,c)     { a, b, c }
+#else
+#define MK_XSIG(a,b,c)     { c, b, a }
+#endif
+
+/* Macro to access the 8 ms bytes of an Xsig as a 64bit quantity */
+#ifdef EMU_BIG_ENDIAN
+#define XSIG_LL(x)         (*(u64 *)&x.msw)
+#else
+#define XSIG_LL(x)         (*(u64 *)&x.midw)
+#endif
+
+
+/*
+   Need to run gcc with optimizations on to get these to
+   actually be in-line.
+   */
+
+/* Multiply two fixed-point 32 bit numbers, producing a 32 bit result.
+   The answer is the ms word of the product.  */
+BX_C_INLINE
+u32 mul_32_32(const u32 arg1, const u32 arg2)
+{
+#ifdef NO_ASSEMBLER
+  return (((u64)arg1) * arg2) >> 32;
+#else
+/* Some versions of gcc make it difficult to stop eax from being clobbered.
+   Merely specifying that it is used doesn't work...
+ */
+  int retval;
+  asm volatile ("mull %2; movl %%edx,%%eax" \
+               :"=a" (retval) \
+               :"0" (arg1), "g" (arg2) \
+               :"dx");
+  return retval;
+#endif
+}
+
+
+/* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
+BX_C_INLINE
+void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
+{
+#ifdef NO_ASSEMBLER
+  dest->lsw += x2->lsw;
+  if ( dest->lsw < x2->lsw )
+    {
+      dest->midw ++;
+      if ( dest->midw == 0 )
+       dest->msw ++;
+    }
+  dest->midw += x2->midw;
+  if ( dest->midw < x2->midw )
+    {
+      dest->msw ++;
+    }
+  dest->msw += x2->msw;
+#else
+  asm volatile ("movl %1,%%edi; movl %2,%%esi;
+                 movl (%%esi),%%eax; addl %%eax,(%%edi);
+                 movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);
+                 movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);"
+                 :"=g" (*dest):"g" (dest), "g" (x2)
+                 :"ax","si","di");
+#endif
+}
+
+
+/* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */
+BX_C_INLINE
+void add_two_Xsig(Xsig *dest, const Xsig *x2, s32 *exp)
+{
+#ifdef NO_ASSEMBLER
+  int ovfl = 0;
+
+  dest->lsw += x2->lsw;
+  if ( dest->lsw < x2->lsw )
+    {
+      dest->midw ++;
+      if ( dest->midw == 0 )
+       {
+         dest->msw ++;
+         if ( dest->msw == 0 )
+           ovfl = 1;
+       }
+    }
+  dest->midw += x2->midw;
+  if ( dest->midw < x2->midw )
+    {
+      dest->msw ++;
+      if ( dest->msw == 0 )
+       ovfl = 1;
+    }
+  dest->msw += x2->msw;
+  if ( dest->msw < x2->msw )
+    ovfl = 1;
+  if ( ovfl )
+    {
+      (*exp) ++;
+      dest->lsw >>= 1;
+      if ( dest->midw & 1 )
+       dest->lsw |= 0x80000000;
+      dest->midw >>= 1;
+      if ( dest->msw & 1 )
+       dest->midw |= 0x80000000;
+      dest->msw >>= 1;
+      dest->msw |= 0x80000000;
+    }
+#else
+/* Note: the constraints in the asm statement didn't always work properly
+   with gcc 2.5.8.  Changing from using edi to using ecx got around the
+   problem, but keep fingers crossed! */
+  asm volatile ("movl %2,%%ecx; movl %3,%%esi;
+                 movl (%%esi),%%eax; addl %%eax,(%%ecx);
+                 movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);
+                 movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);
+                 jnc 0f;
+                rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)
+                 movl %4,%%ecx; incl (%%ecx)
+                 movl $1,%%eax; jmp 1f;
+                 0: xorl %%eax,%%eax;
+                 1:"
+               :"=g" (*exp), "=g" (*dest)
+               :"g" (dest), "g" (x2), "g" (exp)
+               :"cx","si","ax");
+#endif
+}
+
+
+/* Negate the 12 byte Xsig */
+BX_C_INLINE
+void negate_Xsig(Xsig *x)
+{
+#ifdef NO_ASSEMBLER
+  x->lsw = ~x->lsw;
+  x->midw = ~x->midw;
+  x->msw = ~x->msw;
+  x->lsw ++;
+  if ( x->lsw == 0 )
+    {
+      x->midw ++;
+      if ( x->midw == 0 )
+       x->msw ++;
+    }
+#else
+/* Negate (subtract from 1.0) the 12 byte Xsig */
+/* This is faster in a loop on my 386 than using the "neg" instruction. */
+  asm volatile("movl %1,%%esi; "
+               "xorl %%ecx,%%ecx; "
+               "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); "
+               "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); "
+               "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); "
+               :"=g" (*x):"g" (x):"si","ax","cx");
+#endif
+}
+
+
+#endif /* _POLY_H */
diff --git a/sid/component/bochs/fpu/poly_2xm1.c b/sid/component/bochs/fpu/poly_2xm1.c
new file mode 100644 (file)
index 0000000..249c423
--- /dev/null
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------+
+ |  poly_2xm1.c                                                              |
+ |                                                                           |
+ | Function to compute 2^x-1 by a polynomial approximation.                  |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+#define        HIPOWER 11
+static const u64 lterms[HIPOWER] =
+{
+  BX_CONST64(0x0000000000000000),  /* This term done separately as 12 bytes */
+  BX_CONST64(0xf5fdeffc162c7543),
+  BX_CONST64(0x1c6b08d704a0bfa6),
+  BX_CONST64(0x0276556df749cc21),
+  BX_CONST64(0x002bb0ffcf14f6b8),
+  BX_CONST64(0x0002861225ef751c),
+  BX_CONST64(0x00001ffcbfcd5422),
+  BX_CONST64(0x00000162c005d5f1),
+  BX_CONST64(0x0000000da96ccb1b),
+  BX_CONST64(0x0000000078d1b897),
+  BX_CONST64(0x000000000422b029)
+};
+
+static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194);
+
+/* Four slices: 0.0 : 0.25 : 0.50 : 0.75 : 1.0,
+   These numbers are 2^(1/4), 2^(1/2), and 2^(3/4)
+ */
+static const Xsig shiftterm0 = MK_XSIG(0, 0, 0);
+static const Xsig shiftterm1 = MK_XSIG(0x9837f051, 0x8db8a96f, 0x46ad2318);
+static const Xsig shiftterm2 = MK_XSIG(0xb504f333, 0xf9de6484, 0x597d89b3);
+static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9);
+
+static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1,
+                                    &shiftterm2, &shiftterm3 };
+
+
+/*--- poly_2xm1() -----------------------------------------------------------+
+ | Requires st(0) which is TAG_Valid and < 1.                                |
+ +---------------------------------------------------------------------------*/
+int    poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result)
+{
+  s32       exponent, shift;
+  u64       Xll;
+  Xsig      accumulator, Denom, argSignif;
+  u_char    tag;
+
+  exponent = exponent16(arg);
+
+#ifdef PARANOID
+  if ( exponent >= 0 )         /* Don't want a |number| >= 1.0 */
+    {
+      /* Number negative, too large, or not Valid. */
+      EXCEPTION(EX_INTERNAL|0x127);
+      return 1;
+    }
+#endif /* PARANOID */
+
+  argSignif.lsw = 0;
+  XSIG_LL(argSignif) = Xll = significand(arg);
+
+  if ( exponent == -1 )
+    {
+      shift = (argSignif.msw & 0x40000000) ? 3 : 2;
+      /* subtract 0.5 or 0.75 */
+      exponent -= 2;
+      XSIG_LL(argSignif) <<= 2;
+      Xll <<= 2;
+    }
+  else if ( exponent == -2 )
+    {
+      shift = 1;
+      /* subtract 0.25 */
+      exponent--;
+      XSIG_LL(argSignif) <<= 1;
+      Xll <<= 1;
+    }
+  else
+    shift = 0;
+
+  if ( exponent < -2 )
+    {
+      /* Shift the argument right by the required places. */
+      if ( FPU_shrx(&Xll, -2-exponent) >= 0x80000000U )
+       Xll++;  /* round up */
+    }
+
+  accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+  polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER-1);
+  mul_Xsig_Xsig(&accumulator, &argSignif);
+  shr_Xsig(&accumulator, 3);
+
+  mul_Xsig_Xsig(&argSignif, &hiterm);   /* The leading term */
+  add_two_Xsig(&accumulator, &argSignif, &exponent);
+
+  if ( shift )
+    {
+      /* The argument is large, use the identity:
+        f(x+a) = f(a) * (f(x) + 1) - 1;
+        */
+      shr_Xsig(&accumulator, - exponent);
+      accumulator.msw |= 0x80000000;      /* add 1.0 */
+      mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
+      accumulator.msw &= 0x3fffffff;      /* subtract 1.0 */
+      exponent = 1;
+    }
+
+  if ( sign != SIGN_POS )
+    {
+      /* The argument is negative, use the identity:
+            f(-x) = -f(x) / (1 + f(x))
+        */
+      Denom.lsw = accumulator.lsw;
+      XSIG_LL(Denom) = XSIG_LL(accumulator);
+      if ( exponent < 0 )
+       shr_Xsig(&Denom, - exponent);
+      else if ( exponent > 0 )
+       {
+         /* exponent must be 1 here */
+         XSIG_LL(Denom) <<= 1;
+         if ( Denom.lsw & 0x80000000 )
+           XSIG_LL(Denom) |= 1;
+         (Denom.lsw) <<= 1;
+       }
+      Denom.msw |= 0x80000000;      /* add 1.0 */
+      div_Xsig(&accumulator, &Denom, &accumulator);
+    }
+
+  /* Convert to 64 bit signed-compatible */
+  exponent += round_Xsig(&accumulator);
+
+  result = &st(0);
+  significand(result) = XSIG_LL(accumulator);
+  setexponent16(result, exponent);
+
+  tag = FPU_round(result, 1, 0, FULL_PRECISION, sign);
+
+  setsign(result, sign);
+  FPU_settag0(tag);
+
+  return 0;
+
+}
diff --git a/sid/component/bochs/fpu/poly_atan.c b/sid/component/bochs/fpu/poly_atan.c
new file mode 100644 (file)
index 0000000..e984ace
--- /dev/null
@@ -0,0 +1,229 @@
+/*---------------------------------------------------------------------------+
+ |  poly_atan.c                                                              |
+ |                                                                           |
+ | Compute the arctan of a FPU_REG, using a polynomial approximation.        |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "poly.h"
+
+#define        HIPOWERon       6       /* odd poly, negative terms */
+static const u64 oddnegterms[HIPOWERon] =
+{
+  BX_CONST64(0x0000000000000000), /* Dummy (not for - 1.0) */
+  BX_CONST64(0x015328437f756467),
+  BX_CONST64(0x0005dda27b73dec6),
+  BX_CONST64(0x0000226bf2bfb91a),
+  BX_CONST64(0x000000ccc439c5f7),
+  BX_CONST64(0x0000000355438407)
+} ;
+
+#define        HIPOWERop       6       /* odd poly, positive terms */
+static const u64 oddplterms[HIPOWERop] =
+{
+/*  BX_CONST64(0xaaaaaaaaaaaaaaab),  transferred to fixedpterm[] */
+  BX_CONST64(0x0db55a71875c9ac2),
+  BX_CONST64(0x0029fce2d67880b0),
+  BX_CONST64(0x0000dfd3908b4596),
+  BX_CONST64(0x00000550fd61dab4),
+  BX_CONST64(0x0000001c9422b3f9),
+  BX_CONST64(0x000000003e3301e1)
+};
+
+static const u64 denomterm = BX_CONST64(0xebd9b842c5c53a0e);
+
+static const Xsig fixedpterm = MK_XSIG(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa);
+
+static const Xsig pi_signif = MK_XSIG(0xc90fdaa2, 0x2168c234, 0xc4c6628b);
+
+
+/*--- poly_atan() -----------------------------------------------------------+
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+void   poly_atan(FPU_REG *st0_ptr, u_char st0_tag,
+                 FPU_REG *st1_ptr, u_char st1_tag)
+{
+  u_char       transformed, inverted,
+                sign1, sign2;
+  s32           exponent;
+  s32          dummy_exp;
+  Xsig          accumulator, Numer, Denom, accumulatore, argSignif,
+                argSq, argSqSq;
+  u_char        tag;
+  
+  sign1 = getsign(st0_ptr);
+  sign2 = getsign(st1_ptr);
+  if ( st0_tag == TAG_Valid )
+    {
+      exponent = exponent(st0_ptr);
+    }
+  else
+    {
+      /* This gives non-compatible stack contents... */
+      FPU_to_exp16(st0_ptr, st0_ptr);
+      exponent = exponent16(st0_ptr);
+    }
+  if ( st1_tag == TAG_Valid )
+    {
+      exponent -= exponent(st1_ptr);
+    }
+  else
+    {
+      /* This gives non-compatible stack contents... */
+      FPU_to_exp16(st1_ptr, st1_ptr);
+      exponent -= exponent16(st1_ptr);
+    }
+
+  if ( (exponent < 0) || ((exponent == 0) &&
+                         ((st0_ptr->sigh < st1_ptr->sigh) ||
+                          ((st0_ptr->sigh == st1_ptr->sigh) &&
+                           (st0_ptr->sigl < st1_ptr->sigl))) ) )
+    {
+      inverted = 1;
+      Numer.lsw = Denom.lsw = 0;
+      XSIG_LL(Numer) = significand(st0_ptr);
+      XSIG_LL(Denom) = significand(st1_ptr);
+    }
+  else
+    {
+      inverted = 0;
+      exponent = -exponent;
+      Numer.lsw = Denom.lsw = 0;
+      XSIG_LL(Numer) = significand(st1_ptr);
+      XSIG_LL(Denom) = significand(st0_ptr);
+     }
+  div_Xsig(&Numer, &Denom, &argSignif);
+  exponent += norm_Xsig(&argSignif);
+
+  if ( (exponent >= -1)
+      || ((exponent == -2) && (argSignif.msw > 0xd413ccd0)) )
+    {
+      /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
+      /* Convert the argument by an identity for atan */
+      transformed = 1;
+
+      if ( exponent >= 0 )
+       {
+#ifdef PARANOID
+         if ( !( (exponent == 0) && 
+                (argSignif.lsw == 0) && (argSignif.midw == 0) &&
+                (argSignif.msw == 0x80000000) ) )
+           {
+             EXCEPTION(EX_INTERNAL|0x104);  /* There must be a logic error */
+             return;
+           }
+#endif /* PARANOID */
+         argSignif.msw = 0;   /* Make the transformed arg -> 0.0 */
+       }
+      else
+       {
+         Numer.lsw = Denom.lsw = argSignif.lsw;
+         XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif);
+
+         if ( exponent < -1 )
+           shr_Xsig(&Numer, -1-exponent);
+         negate_Xsig(&Numer);
+      
+         shr_Xsig(&Denom, -exponent);
+         Denom.msw |= 0x80000000;
+      
+         div_Xsig(&Numer, &Denom, &argSignif);
+
+         exponent = -1 + norm_Xsig(&argSignif);
+       }
+    }
+  else
+    {
+      transformed = 0;
+    }
+
+  argSq.lsw = argSignif.lsw; argSq.midw = argSignif.midw;
+  argSq.msw = argSignif.msw;
+  mul_Xsig_Xsig(&argSq, &argSq);
+  
+  argSqSq.lsw = argSq.lsw; argSqSq.midw = argSq.midw; argSqSq.msw = argSq.msw;
+  mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+  accumulatore.lsw = argSq.lsw;
+  XSIG_LL(accumulatore) = XSIG_LL(argSq);
+
+  shr_Xsig(&argSq, 2*(-1-exponent-1));
+  shr_Xsig(&argSqSq, 4*(-1-exponent-1));
+
+  /* Now have argSq etc with binary point at the left
+     .1xxxxxxxx */
+
+  /* Do the basic fixed point polynomial evaluation */
+  accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+  polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
+                  oddplterms, HIPOWERop-1);
+  mul64_Xsig(&accumulator, &XSIG_LL(argSq));
+  negate_Xsig(&accumulator);
+  polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms, HIPOWERon-1);
+  negate_Xsig(&accumulator);
+  add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
+
+  mul64_Xsig(&accumulatore, &denomterm);
+  shr_Xsig(&accumulatore, 1 + 2*(-1-exponent));
+  accumulatore.msw |= 0x80000000;
+
+  div_Xsig(&accumulator, &accumulatore, &accumulator);
+
+  mul_Xsig_Xsig(&accumulator, &argSignif);
+  mul_Xsig_Xsig(&accumulator, &argSq);
+
+  shr_Xsig(&accumulator, 3);
+  negate_Xsig(&accumulator);
+  add_Xsig_Xsig(&accumulator, &argSignif);
+
+  if ( transformed )
+    {
+      /* compute pi/4 - accumulator */
+      shr_Xsig(&accumulator, -1-exponent);
+      negate_Xsig(&accumulator);
+      add_Xsig_Xsig(&accumulator, &pi_signif);
+      exponent = -1;
+    }
+
+  if ( inverted )
+    {
+      /* compute pi/2 - accumulator */
+      shr_Xsig(&accumulator, -exponent);
+      negate_Xsig(&accumulator);
+      add_Xsig_Xsig(&accumulator, &pi_signif);
+      exponent = 0;
+    }
+
+  if ( sign1 )
+    {
+      /* compute pi - accumulator */
+      shr_Xsig(&accumulator, 1 - exponent);
+      negate_Xsig(&accumulator);
+      add_Xsig_Xsig(&accumulator, &pi_signif);
+      exponent = 1;
+    }
+
+  exponent += round_Xsig(&accumulator);
+
+  significand(st1_ptr) = XSIG_LL(accumulator);
+  setexponent16(st1_ptr, exponent);
+
+  tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
+  FPU_settagi(1, tag);
+
+
+  set_precision_flag_up();  /* We do not really know if up or down,
+                              use this as the default. */
+
+}
diff --git a/sid/component/bochs/fpu/poly_l2.c b/sid/component/bochs/fpu/poly_l2.c
new file mode 100644 (file)
index 0000000..26e4393
--- /dev/null
@@ -0,0 +1,272 @@
+/*---------------------------------------------------------------------------+
+ |  poly_l2.c                                                                |
+ |                                                                           |
+ | Compute the base 2 log of a FPU_REG, using a polynomial approximation.    |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+static void log2_kernel(FPU_REG const *arg, u_char argsign,
+                       Xsig *accum_result, s32 *expon);
+
+
+/*--- poly_l2() -------------------------------------------------------------+
+ |   Base 2 logarithm by a polynomial approximation.                         |
+ +---------------------------------------------------------------------------*/
+void   poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign)
+{
+  s32         exponent, expon, expon_expon;
+  Xsig         accumulator, expon_accum, yaccum;
+  u_char       sign, argsign;
+  FPU_REG      x;
+  int          tag;
+
+  exponent = exponent16(st0_ptr);
+
+  /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */
+  if ( st0_ptr->sigh > (unsigned)0xb504f334 )
+    {
+      /* Treat as  sqrt(2)/2 < st0_ptr < 1 */
+      significand(&x) = - significand(st0_ptr);
+      setexponent16(&x, -1);
+      exponent++;
+      argsign = SIGN_NEG;
+    }
+  else
+    {
+      /* Treat as  1 <= st0_ptr < sqrt(2) */
+      x.sigh = st0_ptr->sigh - 0x80000000;
+      x.sigl = st0_ptr->sigl;
+      setexponent16(&x, 0);
+      argsign = SIGN_POS;
+    }
+  tag = FPU_normalize_nuo(&x, 0);
+
+  if ( tag == TAG_Zero )
+    {
+      expon = 0;
+      accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+    }
+  else
+    {
+      log2_kernel(&x, argsign, &accumulator, &expon);
+    }
+
+  if ( exponent < 0 )
+    {
+      sign = SIGN_NEG;
+      exponent = -exponent;
+    }
+  else
+    sign = SIGN_POS;
+  expon_accum.msw = exponent; expon_accum.midw = expon_accum.lsw = 0;
+  if ( exponent )
+    {
+      expon_expon = 31 + norm_Xsig(&expon_accum);
+      shr_Xsig(&accumulator, expon_expon - expon);
+
+      if ( sign ^ argsign )
+       negate_Xsig(&accumulator);
+      add_Xsig_Xsig(&accumulator, &expon_accum);
+    }
+  else
+    {
+      expon_expon = expon;
+      sign = argsign;
+    }
+
+  yaccum.lsw = 0; XSIG_LL(yaccum) = significand(st1_ptr);
+  mul_Xsig_Xsig(&accumulator, &yaccum);
+
+  expon_expon += round_Xsig(&accumulator);
+
+  if ( accumulator.msw == 0 )
+    {
+      FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+      return;
+    }
+
+  significand(st1_ptr) = XSIG_LL(accumulator);
+  setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
+
+  tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
+  FPU_settagi(1, tag);
+
+  set_precision_flag_up();  /* 80486 appears to always do this */
+
+  return;
+
+}
+
+
+/*--- poly_l2p1() -----------------------------------------------------------+
+ |   Base 2 logarithm by a polynomial approximation.                         |
+ |   log2(x+1)                                                               |
+ +---------------------------------------------------------------------------*/
+int    poly_l2p1(u_char sign0, u_char sign1,
+                 FPU_REG *st0_ptr, FPU_REG *st1_ptr, FPU_REG *dest)
+{
+  u_char               tag;
+  s32          exponent;
+  Xsig                 accumulator, yaccum;
+
+  if ( exponent16(st0_ptr) < 0 )
+    {
+      log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
+
+      yaccum.lsw = 0;
+      XSIG_LL(yaccum) = significand(st1_ptr);
+      mul_Xsig_Xsig(&accumulator, &yaccum);
+
+      exponent += round_Xsig(&accumulator);
+
+      exponent += exponent16(st1_ptr) + 1;
+      if ( exponent < EXP_WAY_UNDER ) exponent = EXP_WAY_UNDER;
+
+      significand(dest) = XSIG_LL(accumulator);
+      setexponent16(dest, exponent);
+
+      tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1);
+      FPU_settagi(1, tag);
+
+      if ( tag == TAG_Valid )
+       set_precision_flag_up();   /* 80486 appears to always do this */
+    }
+  else
+    {
+      /* The magnitude of st0_ptr is far too large. */
+
+      if ( sign0 != SIGN_POS )
+       {
+         /* Trying to get the log of a negative number. */
+#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */
+         changesign(st1_ptr);
+#else
+         if ( arith_invalid(1) < 0 )
+           return 1;
+#endif /* PECULIAR_486 */
+       }
+
+      /* 80486 appears to do this */
+      if ( sign0 == SIGN_NEG )
+       set_precision_flag_down();
+      else
+       set_precision_flag_up();
+    }
+
+  if ( exponent(dest) <= EXP_UNDER )
+    EXCEPTION(EX_Underflow);
+
+  return 0;
+
+}
+
+
+
+
+#undef HIPOWER
+#define        HIPOWER 10
+static const u64 logterms[HIPOWER] =
+{
+  BX_CONST64(0x2a8eca5705fc2ef0),
+  BX_CONST64(0xf6384ee1d01febce),
+  BX_CONST64(0x093bb62877cdf642),
+  BX_CONST64(0x006985d8a9ec439b),
+  BX_CONST64(0x0005212c4f55a9c8),
+  BX_CONST64(0x00004326a16927f0),
+  BX_CONST64(0x0000038d1d80a0e7),
+  BX_CONST64(0x0000003141cc80c6),
+  BX_CONST64(0x00000002b1668c9f),
+  BX_CONST64(0x000000002c7a46aa)
+};
+
+static const u32 leadterm = 0xb8000000;
+
+
+/*--- log2_kernel() ---------------------------------------------------------+
+ |   Base 2 logarithm by a polynomial approximation.                         |
+ |   log2(x+1)                                                               |
+ +---------------------------------------------------------------------------*/
+static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig *accum_result,
+                       s32 *expon)
+{
+  s32    exponent, adj;
+  u64    Xsq;
+  Xsig   accumulator, Numer, Denom, argSignif, arg_signif;
+
+  exponent = exponent16(arg);
+  Numer.lsw = Denom.lsw = 0;
+  XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg);
+  if ( argsign == SIGN_POS )
+    {
+      shr_Xsig(&Denom, 2 - (1 + exponent));
+      Denom.msw |= 0x80000000;
+      div_Xsig(&Numer, &Denom, &argSignif);
+    }
+  else
+    {
+      shr_Xsig(&Denom, 1 - (1 + exponent));
+      negate_Xsig(&Denom);
+      if ( Denom.msw & 0x80000000 )
+       {
+         div_Xsig(&Numer, &Denom, &argSignif);
+         exponent ++;
+       }
+      else
+       {
+         /* Denom must be 1.0 */
+         argSignif.lsw = Numer.lsw; argSignif.midw = Numer.midw;
+         argSignif.msw = Numer.msw;
+       }
+    }
+
+#ifndef PECULIAR_486
+  /* Should check here that  |local_arg|  is within the valid range */
+  if ( exponent >= -2 )
+    {
+      if ( (exponent > -2) ||
+         (argSignif.msw > (unsigned)0xafb0ccc0) )
+       {
+         /* The argument is too large */
+       }
+    }
+#endif /* PECULIAR_486 */
+
+  arg_signif.lsw = argSignif.lsw; XSIG_LL(arg_signif) = XSIG_LL(argSignif);
+  adj = norm_Xsig(&argSignif);
+  accumulator.lsw = argSignif.lsw; XSIG_LL(accumulator) = XSIG_LL(argSignif);
+  mul_Xsig_Xsig(&accumulator, &accumulator);
+  shr_Xsig(&accumulator, 2*(-1 - (1 + exponent + adj)));
+  Xsq = XSIG_LL(accumulator);
+  if ( accumulator.lsw & 0x80000000 )
+    Xsq++;
+
+  accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+  /* Do the basic fixed point polynomial evaluation */
+  polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER-1);
+
+  mul_Xsig_Xsig(&accumulator, &argSignif);
+  shr_Xsig(&accumulator, 6 - adj);
+
+  mul32_Xsig(&arg_signif, leadterm);
+  add_two_Xsig(&accumulator, &arg_signif, &exponent);
+
+  *expon = exponent + 1;
+  accum_result->lsw = accumulator.lsw;
+  accum_result->midw = accumulator.midw;
+  accum_result->msw = accumulator.msw;
+
+}
diff --git a/sid/component/bochs/fpu/poly_sin.c b/sid/component/bochs/fpu/poly_sin.c
new file mode 100644 (file)
index 0000000..71a63f2
--- /dev/null
@@ -0,0 +1,397 @@
+/*---------------------------------------------------------------------------+
+ |  poly_sin.c                                                               |
+ |                                                                           |
+ |  Computation of an approximation of the sin function and the cosine       |
+ |  function by a polynomial.                                                |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+#define        N_COEFF_P       4
+#define        N_COEFF_N       4
+
+static const u64 pos_terms_l[N_COEFF_P] =
+{
+  BX_CONST64(0xaaaaaaaaaaaaaaab),
+  BX_CONST64(0x00d00d00d00cf906),
+  BX_CONST64(0x000006b99159a8bb),
+  BX_CONST64(0x000000000d7392e6)
+};
+
+static const u64 neg_terms_l[N_COEFF_N] =
+{
+  BX_CONST64(0x2222222222222167),
+  BX_CONST64(0x0002e3bc74aab624),
+  BX_CONST64(0x0000000b09229062),
+  BX_CONST64(0x00000000000c7973)
+};
+
+
+
+#define        N_COEFF_PH      4
+#define        N_COEFF_NH      4
+static const u64 pos_terms_h[N_COEFF_PH] =
+{
+  BX_CONST64(0x0000000000000000),
+  BX_CONST64(0x05b05b05b05b0406),
+  BX_CONST64(0x000049f93edd91a9),
+  BX_CONST64(0x00000000c9c9ed62)
+};
+
+static const u64 neg_terms_h[N_COEFF_NH] =
+{
+  BX_CONST64(0xaaaaaaaaaaaaaa98),
+  BX_CONST64(0x001a01a01a019064),
+  BX_CONST64(0x0000008f76c68a77),
+  BX_CONST64(0x0000000000d58f5e)
+};
+
+
+/*--- poly_sine() -----------------------------------------------------------+
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+void   poly_sine(FPU_REG *st0_ptr)
+{
+  int       exponent, echange;
+  Xsig      accumulator, argSqrd, argTo4;
+  s32       fix_up, adj;
+  u64       fixed_arg;
+  FPU_REG   result;
+
+  exponent = exponent(st0_ptr);
+
+  accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+
+  /* Split into two ranges, for arguments below and above 1.0 */
+  /* The boundary between upper and lower is approx 0.88309101259 */
+  if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa)) )
+    {
+      /* The argument is <= 0.88309101259 */
+
+      argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl; argSqrd.lsw = 0;
+      mul64_Xsig(&argSqrd, &significand(st0_ptr));
+      shr_Xsig(&argSqrd, 2*(-1-exponent));
+      argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+      argTo4.lsw = argSqrd.lsw;
+      mul_Xsig_Xsig(&argTo4, &argTo4);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+                     N_COEFF_N-1);
+      mul_Xsig_Xsig(&accumulator, &argSqrd);
+      negate_Xsig(&accumulator);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+                     N_COEFF_P-1);
+
+      shr_Xsig(&accumulator, 2);    /* Divide by four */
+      accumulator.msw |= 0x80000000;  /* Add 1.0 */
+
+      mul64_Xsig(&accumulator, &significand(st0_ptr));
+      mul64_Xsig(&accumulator, &significand(st0_ptr));
+      mul64_Xsig(&accumulator, &significand(st0_ptr));
+
+      /* Divide by four, FPU_REG compatible, etc */
+      exponent = 3*exponent;
+
+      /* The minimum exponent difference is 3 */
+      shr_Xsig(&accumulator, exponent(st0_ptr) - exponent);
+
+      negate_Xsig(&accumulator);
+      XSIG_LL(accumulator) += significand(st0_ptr);
+
+      echange = round_Xsig(&accumulator);
+
+      setexponentpos(&result, exponent(st0_ptr) + echange);
+    }
+  else
+    {
+      /* The argument is > 0.88309101259 */
+      /* We use sin(st(0)) = cos(pi/2-st(0)) */
+
+      fixed_arg = significand(st0_ptr);
+
+      if ( exponent == 0 )
+       {
+         /* The argument is >= 1.0 */
+
+         /* Put the binary point at the left. */
+         fixed_arg <<= 1;
+       }
+      /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+      fixed_arg = BX_CONST64(0x921fb54442d18469) - fixed_arg;
+      /* There is a special case which arises due to rounding, to fix here. */
+      if ( fixed_arg == BX_CONST64(0xffffffffffffffff))
+       fixed_arg = 0;
+
+      XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
+      mul64_Xsig(&argSqrd, &fixed_arg);
+
+      XSIG_LL(argTo4) = XSIG_LL(argSqrd); argTo4.lsw = argSqrd.lsw;
+      mul_Xsig_Xsig(&argTo4, &argTo4);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+                     N_COEFF_NH-1);
+      mul_Xsig_Xsig(&accumulator, &argSqrd);
+      negate_Xsig(&accumulator);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+                     N_COEFF_PH-1);
+      negate_Xsig(&accumulator);
+
+      mul64_Xsig(&accumulator, &fixed_arg);
+      mul64_Xsig(&accumulator, &fixed_arg);
+
+      shr_Xsig(&accumulator, 3);
+      negate_Xsig(&accumulator);
+
+      add_Xsig_Xsig(&accumulator, &argSqrd);
+
+      shr_Xsig(&accumulator, 1);
+
+      accumulator.lsw |= 1;  /* A zero accumulator here would cause problems */
+      negate_Xsig(&accumulator);
+
+      /* The basic computation is complete. Now fix the answer to
+        compensate for the error due to the approximation used for
+        pi/2
+        */
+
+      /* This has an exponent of -65 */
+      fix_up = 0x898cc517;
+      /* The fix-up needs to be improved for larger args */
+      if ( argSqrd.msw & 0xffc00000 )
+       {
+         /* Get about 32 bit precision in these: */
+         fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
+       }
+      fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
+
+      adj = accumulator.lsw;    /* temp save */
+      accumulator.lsw -= fix_up;
+      if ( accumulator.lsw > adj )
+       XSIG_LL(accumulator) --;
+
+      echange = round_Xsig(&accumulator);
+
+      setexponentpos(&result, echange - 1);
+    }
+
+  significand(&result) = XSIG_LL(accumulator);
+  setsign(&result, getsign(st0_ptr));
+  FPU_copy_to_reg0(&result, TAG_Valid);
+
+#ifdef PARANOID
+  if ( (exponent(&result) >= 0)
+      && (significand(&result) > BX_CONST64(0x8000000000000000)) )
+    {
+      EXCEPTION(EX_INTERNAL|0x150);
+    }
+#endif /* PARANOID */
+
+}
+
+
+
+/*--- poly_cos() ------------------------------------------------------------+
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+void   poly_cos(FPU_REG *st0_ptr)
+{
+  FPU_REG    result;
+  s32        exponent, exp2, echange;
+  Xsig       accumulator, argSqrd, fix_up, argTo4;
+  u64        fixed_arg;
+
+#ifdef PARANOID
+  if ( (exponent(st0_ptr) > 0)
+      || ((exponent(st0_ptr) == 0)
+         && (significand(st0_ptr) > BX_CONST64(0xc90fdaa22168c234))) )
+    {
+      EXCEPTION(EX_Invalid);
+      FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+      return;
+    }
+#endif /* PARANOID */
+
+  exponent = exponent(st0_ptr);
+
+  accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+
+  if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54)) )
+    {
+      /* arg is < 0.687705 */
+
+      argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl;
+      argSqrd.lsw = 0;
+      mul64_Xsig(&argSqrd, &significand(st0_ptr));
+
+      if ( exponent < -1 )
+       {
+         /* shift the argument right by the required places */
+         shr_Xsig(&argSqrd, 2*(-1-exponent));
+       }
+
+      argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+      argTo4.lsw = argSqrd.lsw;
+      mul_Xsig_Xsig(&argTo4, &argTo4);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+                     N_COEFF_NH-1);
+      mul_Xsig_Xsig(&accumulator, &argSqrd);
+      negate_Xsig(&accumulator);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+                     N_COEFF_PH-1);
+      negate_Xsig(&accumulator);
+
+      mul64_Xsig(&accumulator, &significand(st0_ptr));
+      mul64_Xsig(&accumulator, &significand(st0_ptr));
+      shr_Xsig(&accumulator, -2*(1+exponent));
+
+      shr_Xsig(&accumulator, 3);
+      negate_Xsig(&accumulator);
+
+      add_Xsig_Xsig(&accumulator, &argSqrd);
+
+      shr_Xsig(&accumulator, 1);
+
+      /* It doesn't matter if accumulator is all zero here, the
+        following code will work ok */
+      negate_Xsig(&accumulator);
+
+      if ( accumulator.lsw & 0x80000000 )
+       XSIG_LL(accumulator) ++;
+      if ( accumulator.msw == 0 )
+       {
+         /* The result is 1.0 */
+         FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+         return;
+       }
+      else
+       {
+         significand(&result) = XSIG_LL(accumulator);
+      
+         /* will be a valid positive nr with expon = -1 */
+         setexponentpos(&result, -1);
+       }
+    }
+  else
+    {
+      fixed_arg = significand(st0_ptr);
+
+      if ( exponent == 0 )
+       {
+         /* The argument is >= 1.0 */
+
+         /* Put the binary point at the left. */
+         fixed_arg <<= 1;
+       }
+      /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+      fixed_arg = BX_CONST64(0x921fb54442d18469) - fixed_arg;
+      /* There is a special case which arises due to rounding, to fix here. */
+      if ( fixed_arg == BX_CONST64(0xffffffffffffffff))
+       fixed_arg = 0;
+
+      exponent = -1;
+      exp2 = -1;
+
+      /* A shift is needed here only for a narrow range of arguments,
+        i.e. for fixed_arg approx 2^-32, but we pick up more... */
+      if ( !(LL_MSW(fixed_arg) & 0xffff0000) )
+       {
+         fixed_arg <<= 16;
+         exponent -= 16;
+         exp2 -= 16;
+       }
+
+      XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
+      mul64_Xsig(&argSqrd, &fixed_arg);
+
+      if ( exponent < -1 )
+       {
+         /* shift the argument right by the required places */
+         shr_Xsig(&argSqrd, 2*(-1-exponent));
+       }
+
+      argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+      argTo4.lsw = argSqrd.lsw;
+      mul_Xsig_Xsig(&argTo4, &argTo4);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+                     N_COEFF_N-1);
+      mul_Xsig_Xsig(&accumulator, &argSqrd);
+      negate_Xsig(&accumulator);
+
+      polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+                     N_COEFF_P-1);
+
+      shr_Xsig(&accumulator, 2);    /* Divide by four */
+      accumulator.msw |= 0x80000000;  /* Add 1.0 */
+
+      mul64_Xsig(&accumulator, &fixed_arg);
+      mul64_Xsig(&accumulator, &fixed_arg);
+      mul64_Xsig(&accumulator, &fixed_arg);
+
+      /* Divide by four, FPU_REG compatible, etc */
+      exponent = 3*exponent;
+
+      /* The minimum exponent difference is 3 */
+      shr_Xsig(&accumulator, exp2 - exponent);
+
+      negate_Xsig(&accumulator);
+      XSIG_LL(accumulator) += fixed_arg;
+
+      /* The basic computation is complete. Now fix the answer to
+        compensate for the error due to the approximation used for
+        pi/2
+        */
+
+      /* This has an exponent of -65 */
+      XSIG_LL(fix_up) = BX_CONST64(0x898cc51701b839a2);
+      fix_up.lsw = 0;
+
+      /* The fix-up needs to be improved for larger args */
+      if ( argSqrd.msw & 0xffc00000 )
+       {
+         /* Get about 32 bit precision in these: */
+         fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
+         fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
+       }
+
+      exp2 += norm_Xsig(&accumulator);
+      shr_Xsig(&accumulator, 1); /* Prevent overflow */
+      exp2++;
+      shr_Xsig(&fix_up, 65 + exp2);
+
+      add_Xsig_Xsig(&accumulator, &fix_up);
+
+      echange = round_Xsig(&accumulator);
+
+      setexponentpos(&result, exp2 + echange);
+      significand(&result) = XSIG_LL(accumulator);
+    }
+
+  FPU_copy_to_reg0(&result, TAG_Valid);
+
+#ifdef PARANOID
+  if ( (exponent(&result) >= 0)
+      && (significand(&result) > BX_CONST64(0x8000000000000000)) )
+    {
+      EXCEPTION(EX_INTERNAL|0x151);
+    }
+#endif /* PARANOID */
+
+}
diff --git a/sid/component/bochs/fpu/poly_tan.c b/sid/component/bochs/fpu/poly_tan.c
new file mode 100644 (file)
index 0000000..f7ab00a
--- /dev/null
@@ -0,0 +1,161 @@
+/*---------------------------------------------------------------------------+
+ |  poly_tan.c                                                               |
+ |                                                                           |
+ | Compute the tan of a FPU_REG, using a polynomial approximation.           |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+//#define DEBUG_POLY_TAN // ***********
+
+#define        HiPOWERop       3       /* odd poly, positive terms */
+static const u64 oddplterm[HiPOWERop] =
+{
+  BX_CONST64(0x0000000000000000),
+  BX_CONST64(0x0051a1cf08fca228),
+  BX_CONST64(0x0000000071284ff7)
+};
+
+#define        HiPOWERon       2       /* odd poly, negative terms */
+static const u64 oddnegterm[HiPOWERon] =
+{
+   BX_CONST64(0x1291a9a184244e80),
+   BX_CONST64(0x0000583245819c21)
+};
+
+#define        HiPOWERep       2       /* even poly, positive terms */
+static const u64 evenplterm[HiPOWERep] =
+{
+  BX_CONST64(0x0e848884b539e888),
+  BX_CONST64(0x00003c7f18b887da)
+};
+
+#define        HiPOWERen       2       /* even poly, negative terms */
+static const u64 evennegterm[HiPOWERen] =
+{
+  BX_CONST64(0xf1f0200fd51569cc),
+  BX_CONST64(0x003afb46105c4432)
+};
+
+static const u64 twothirds = BX_CONST64(0xaaaaaaaaaaaaaaab);
+
+
+/*--- poly_tan() ------------------------------------------------------------+
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+void   poly_tan(FPU_REG *st0_ptr, int invert)
+{
+  s32         exponent;
+  Xsig        argSq, argSqSq, accumulatoro, accumulatore, accum,
+              argSignif;
+
+  exponent = exponent(st0_ptr);
+
+
+#ifdef PARANOID
+  if ( signnegative(st0_ptr) ) /* Can't hack a number < 0.0 */
+    { arith_invalid(0); return; }  /* Need a positive number */
+#endif /* PARANOID */
+
+  if ( (exponent >= 0)
+       || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2)) )
+    {
+    EXCEPTION(0x250);
+    }
+  else
+    {
+      argSignif.lsw = 0;
+      XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr);
+      if ( exponent < -1 )
+       {
+         /* shift the argument right by the required places */
+         if ( FPU_shrx(&XSIG_LL(accum), -1-exponent) >= 0x80000000U )
+           XSIG_LL(accum) ++;  /* round up */
+       }
+    }
+
+  XSIG_LL(argSq) = XSIG_LL(accum); argSq.lsw = accum.lsw;
+  mul_Xsig_Xsig(&argSq, &argSq);
+  XSIG_LL(argSqSq) = XSIG_LL(argSq); argSqSq.lsw = argSq.lsw;
+  mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+  /* Compute the negative terms for the numerator polynomial */
+  accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0;
+  polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm, HiPOWERon-1);
+  mul_Xsig_Xsig(&accumulatoro, &argSq);
+  negate_Xsig(&accumulatoro);
+  /* Add the positive terms */
+  polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm, HiPOWERop-1);
+
+  
+  /* Compute the positive terms for the denominator polynomial */
+  accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0;
+  polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm, HiPOWERep-1);
+  mul_Xsig_Xsig(&accumulatore, &argSq);
+  negate_Xsig(&accumulatore);
+  /* Add the negative terms */
+  polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm, HiPOWERen-1);
+  /* Multiply by arg^2 */
+  mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+  mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+  /* de-normalize and divide by 2 */
+  shr_Xsig(&accumulatore, -2*(1+exponent) + 1);
+  negate_Xsig(&accumulatore);      /* This does 1 - accumulator */
+
+  /* Now find the ratio. */
+  if ( accumulatore.msw == 0 )
+    {
+      /* accumulatoro must contain 1.0 here, (actually, 0) but it
+        really doesn't matter what value we use because it will
+        have negligible effect in later calculations
+        */
+      XSIG_LL(accum) = BX_CONST64(0x8000000000000000);
+      accum.lsw = 0;
+    }
+  else
+    {
+      div_Xsig(&accumulatoro, &accumulatore, &accum);
+    }
+
+  /* Multiply by 1/3 * arg^3 */
+  mul64_Xsig(&accum, &XSIG_LL(argSignif));
+  mul64_Xsig(&accum, &XSIG_LL(argSignif));
+  mul64_Xsig(&accum, &XSIG_LL(argSignif));
+  mul64_Xsig(&accum, &twothirds);
+  shr_Xsig(&accum, -2*(exponent+1));
+
+
+  /* tan(arg) = arg + accum */
+  add_two_Xsig(&accum, &argSignif, &exponent);
+
+  if ( invert )
+    {
+      /* accum now contains tan(pi/2 - arg).
+        Use tan(arg) = 1.0 / tan(pi/2 - arg)
+        */
+      accumulatoro.lsw = accumulatoro.midw = 0;
+      accumulatoro.msw = 0x80000000;
+      div_Xsig(&accumulatoro, &accum, &accum);
+      exponent = - exponent;
+    }
+
+
+  /* Transfer the result */
+  exponent += round_Xsig(&accum);
+  FPU_settag0(TAG_Valid);
+  significand(st0_ptr) = XSIG_LL(accum);
+  setexponent16(st0_ptr, exponent + EXTENDED_Ebias);  /* Result is positive. */
+
+}
diff --git a/sid/component/bochs/fpu/polynom_Xsig.S b/sid/component/bochs/fpu/polynom_Xsig.S
new file mode 100644 (file)
index 0000000..7829503
--- /dev/null
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------+
+ |  polynomial_Xsig.S                                                        |
+ |                                                                           |
+ | Fixed point arithmetic polynomial evaluation.                             |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |   void polynomial_Xsig(Xsig *accum, unsigned long long *x,                |
+ |                        unsigned long long terms[], int n)                 |
+ |                                                                           |
+ | Computes:                                                                 |
+ | terms[0] + (terms[1] + (terms[2] + ... + (terms[n]*x)*x)*x)*x) ... )*x    |
+ | and adds the result to the 12 byte Xsig.                                  |
+ | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
+ | precision.                                                                |
+ |                                                                           |
+ | This function must be used carefully: most overflow of intermediate       |
+ | results is controlled, but overflow of the result is not.                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+       .file   "polynomial_Xsig.S"
+
+#include "fpu_emu.h"
+
+
+#define        TERM_SIZE       $8
+#define        SUM_MS          -20(%ebp)       /* sum ms long */
+#define SUM_MIDDLE     -24(%ebp)       /* sum middle long */
+#define        SUM_LS          -28(%ebp)       /* sum ls long */
+#define        ACCUM_MS        -4(%ebp)        /* accum ms long */
+#define        ACCUM_MIDDLE    -8(%ebp)        /* accum middle long */
+#define        ACCUM_LS        -12(%ebp)       /* accum ls long */
+#define OVERFLOWED      -16(%ebp)      /* addition overflow flag */
+
+.text
+ENTRY(polynomial_Xsig)
+       pushl   %ebp
+       movl    %esp,%ebp
+       subl    $32,%esp
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM2,%esi             /* x */
+       movl    PARAM3,%edi             /* terms */
+
+       movl    TERM_SIZE,%eax
+       mull    PARAM4                  /* n */
+       addl    %eax,%edi
+
+       movl    4(%edi),%edx            /* terms[n] */
+       movl    %edx,SUM_MS
+       movl    (%edi),%edx             /* terms[n] */
+       movl    %edx,SUM_MIDDLE
+       xor     %eax,%eax
+       movl    %eax,SUM_LS
+       movb    %al,OVERFLOWED
+
+       subl    TERM_SIZE,%edi
+       decl    PARAM4
+       js      L_accum_done
+
+L_accum_loop:
+       xor     %eax,%eax
+       movl    %eax,ACCUM_MS
+       movl    %eax,ACCUM_MIDDLE
+
+       movl    SUM_MIDDLE,%eax
+       mull    (%esi)                  /* x ls long */
+       movl    %edx,ACCUM_LS
+
+       movl    SUM_LS,%eax
+       mull    4(%esi)                 /* x ms long */
+       addl    %edx,ACCUM_LS
+       adcl    $0,ACCUM_MIDDLE
+       adcl    $0,ACCUM_MS
+
+       movl    SUM_MIDDLE,%eax
+       mull    4(%esi)                 /* x ms long */
+       addl    %eax,ACCUM_LS
+       adcl    %edx,ACCUM_MIDDLE
+       adcl    $0,ACCUM_MS
+
+       movl    SUM_MS,%eax
+       mull    (%esi)                  /* x ls long */
+       addl    %eax,ACCUM_LS
+       adcl    %edx,ACCUM_MIDDLE
+       adcl    $0,ACCUM_MS
+
+       movl    SUM_MS,%eax
+       mull    4(%esi)                 /* x ms long */
+       addl    %eax,ACCUM_MIDDLE
+       adcl    %edx,ACCUM_MS
+
+       testb   $0xff,OVERFLOWED
+       jz      L_no_overflow
+
+       movl    (%esi),%eax
+       addl    %eax,ACCUM_MIDDLE
+       movl    4(%esi),%eax
+       adcl    %eax,ACCUM_MS           /* This could overflow too */
+
+L_no_overflow:
+
+/*
+ * Now put the sum of next term and the accumulator
+ * into the sum register
+ */
+       movl    ACCUM_LS,%eax
+//     addl    (%edi),%eax             /* term ls long */
+       movl    %eax,SUM_LS
+       movl    ACCUM_MIDDLE,%eax
+//     adcl    (%edi),%eax             /* term ls long */
+       addl    (%edi),%eax             /* term ls long */
+       movl    %eax,SUM_MIDDLE
+       movl    ACCUM_MS,%eax
+       adcl    4(%edi),%eax            /* term ms long */
+       movl    %eax,SUM_MS
+       sbbb    %al,%al
+       movb    %al,OVERFLOWED          /* Used in the next iteration */
+
+       subl    TERM_SIZE,%edi
+       decl    PARAM4
+       jns     L_accum_loop
+
+L_accum_done:
+       movl    PARAM1,%edi             /* accum */
+       movl    SUM_LS,%eax
+       addl    %eax,(%edi)
+       movl    SUM_MIDDLE,%eax
+       adcl    %eax,4(%edi)
+       movl    SUM_MS,%eax
+       adcl    %eax,8(%edi)
+
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       leave
+       ret
diff --git a/sid/component/bochs/fpu/polynom_Xsig.c b/sid/component/bochs/fpu/polynom_Xsig.c
new file mode 100644 (file)
index 0000000..6cce9e0
--- /dev/null
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------+
+ |  polynomial_Xsig.c                                                        |
+ |                                                                           |
+ | Fixed point arithmetic polynomial evaluation.                             |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | Computes:                                                                 |
+ | terms[0] + (terms[1] + (terms[2] + ... + (terms[n]*x)*x)*x)*x) ... )*x    |
+ | and adds the result to the 12 byte Xsig.                                  |
+ | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
+ | precision.                                                                |
+ |                                                                           |
+ | This function must be used carefully: most overflow of intermediate       |
+ | results is controlled, but overflow of the result is not.                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void polynomial_Xsig(Xsig *accum, const u64 *x, const u64 terms[], const int n)
+{
+  int  i;
+  Xsig acc, Xprod;
+  u32  lprod;
+  u64  xlwr, xupr, prod;
+  char overflowed;
+
+  xlwr = (u32)(*x);
+  xupr = (u32)((*x) >> 32);
+
+  acc.msw = terms[n] >> 32;
+  acc.midw = terms[n];
+  acc.lsw = 0;
+  overflowed = 0;
+
+  for ( i = n-1; i >= 0; i-- )
+    {
+      /* Split the product into five parts to get a 16 byte result */
+
+      /* first word by first word */
+      prod = acc.msw * xupr;
+      Xprod.midw = prod;
+      Xprod.msw = prod >> 32;
+
+      /* first word by second word */
+      prod = acc.msw * xlwr;
+      Xprod.lsw = prod;
+      lprod = prod >> 32;
+      Xprod.midw += lprod;
+      if ( lprod > Xprod.midw )
+       Xprod.msw ++;
+
+      /* second word by first word */
+      prod = acc.midw * xupr;
+      Xprod.lsw += prod;
+      if ( (u32)prod > Xprod.lsw )
+       {
+         Xprod.midw ++;
+         if ( Xprod.midw == 0 )
+           Xprod.msw ++;
+       }
+      lprod = prod >> 32;
+      Xprod.midw += lprod;
+      if ( lprod > Xprod.midw )
+       Xprod.msw ++;
+
+      /* second word by second word */
+      prod = acc.midw * xlwr;
+      lprod = prod >> 32;
+      Xprod.lsw += lprod;
+      if ( lprod > Xprod.lsw )
+       {
+         Xprod.midw ++;
+         if ( Xprod.midw == 0 )
+           Xprod.msw ++;
+       }
+
+      /* third word by first word */
+      prod = acc.lsw * xupr;
+      lprod = prod >> 32;
+      Xprod.lsw += lprod;
+      if ( lprod > Xprod.lsw )
+       {
+         Xprod.midw ++;
+         if ( Xprod.midw == 0 )
+           Xprod.msw ++;
+       }
+
+      if ( overflowed )
+       {
+         Xprod.midw += xlwr;
+         if ( (u32)xlwr > Xprod.midw )
+           Xprod.msw ++;
+         Xprod.msw += xupr;
+         overflowed = 0;    /* We don't check this addition for overflow */
+       }
+      
+      acc.lsw = Xprod.lsw;
+      acc.midw = (u32)terms[i] + Xprod.midw;
+      acc.msw = (terms[i] >> 32) + Xprod.msw;
+      if ( Xprod.msw > acc.msw )
+       overflowed = 1;
+      if ( (u32)terms[i] > acc.midw )
+       {
+         acc.msw ++;
+         if ( acc.msw == 0 )
+           overflowed = 1;
+       }
+    }
+
+  /* We don't check the addition to accum for overflow */
+  accum->lsw += acc.lsw;
+  if ( acc.lsw > accum->lsw )
+    {
+      accum->midw ++;
+      if ( accum->midw == 0 )
+       accum->msw ++;
+    }
+  accum->midw += acc.midw;
+  if ( acc.midw > accum->midw )
+    {
+      accum->msw ++;
+    }
+  accum->msw += acc.msw;
+}
+
+
diff --git a/sid/component/bochs/fpu/reg_add_sub.c b/sid/component/bochs/fpu/reg_add_sub.c
new file mode 100644 (file)
index 0000000..5b507a1
--- /dev/null
@@ -0,0 +1,380 @@
+/*---------------------------------------------------------------------------+
+ |  reg_add_sub.c                                                            |
+ |                                                                           |
+ | Functions to add or subtract two registers and put the result in a third. |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1997                                              |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |  For each function, the destination may be any FPU_REG, including one of  |
+ | the source FPU_REGs.                                                      |
+ |  Each function returns 0 if the answer is o.k., otherwise a non-zero      |
+ | value is returned, indicating either an exception condition or an         |
+ | internal error.                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "fpu_system.h"
+
+static
+int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
+                    FPU_REG const *b, u_char tagb, u_char signb,
+                    FPU_REG *dest, int deststnr, u16 control_w);
+
+/*
+  Operates on st(0) and st(n), or on st(0) and temporary data.
+  The destination must be one of the source st(x).
+  */
+int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, u16 control_w)
+{
+  FPU_REG *a = &st(0);
+  FPU_REG *dest = &st(deststnr);
+  u_char signb = getsign(b);
+  u_char taga = FPU_gettag0();
+  u_char signa = getsign(a);
+  u_char saved_sign = getsign(dest);
+  int diff, tag, expa, expb;
+  
+  if ( !(taga | tagb) )
+    {
+      expa = exponent(a);
+      expb = exponent(b);
+
+    valid_add:
+      /* Both registers are valid */
+      if (!(signa ^ signb))
+       {
+         /* signs are the same */
+         tag = FPU_u_add(a, b, dest, control_w, signa, expa, expb);
+       }
+      else
+       {
+         /* The signs are different, so do a subtraction */
+         diff = expa - expb;
+         if (!diff)
+           {
+             diff = a->sigh - b->sigh;  /* This works only if the ms bits
+                                           are identical. */
+             if (!diff)
+               {
+                 diff = a->sigl > b->sigl;
+                 if (!diff)
+                   diff = -(a->sigl < b->sigl);
+               }
+           }
+      
+         if (diff > 0)
+           {
+             tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
+           }
+         else if ( diff < 0 )
+           {
+             tag = FPU_u_sub(b, a, dest, control_w, signb, expb, expa);
+           }
+         else
+           {
+             FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+             /* sign depends upon rounding mode */
+             setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+                     ? SIGN_POS : SIGN_NEG);
+             return TAG_Zero;
+           }
+       }
+
+      if ( tag < 0 )
+       {
+         setsign(dest, saved_sign);
+         return tag;
+       }
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+
+  if ( taga == TAG_Special )
+    taga = FPU_Special(a);
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+
+  if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+           || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+           || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+    {
+      FPU_REG x, y;
+
+      if ( denormal_operand() < 0 )
+       return FPU_Exception;
+
+      FPU_to_exp16(a, &x);
+      FPU_to_exp16(b, &y);
+      a = &x;
+      b = &y;
+      expa = exponent16(a);
+      expb = exponent16(b);
+      goto valid_add;
+    }
+
+  if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+    {
+      if ( deststnr == 0 )
+       return real_2op_NaN(b, tagb, deststnr, a);
+      else
+       return real_2op_NaN(a, taga, deststnr, a);
+    }
+
+  return add_sub_specials(a, taga, signa, b, tagb, signb,
+                         dest, deststnr, control_w);
+}
+
+
+/* Subtract b from a.  (a-b) -> dest
+ bbd: arg2 used to be int type, but sometimes pointers were forced
+ in with typecasts.  On Alphas pointers are 64 bits and ints are 32,
+ so when rm was cast back to a pointer...SEGFAULT.  Pass the pointers
+ around instead, since they are always larger precision than the
+ register numbers. */
+int FPU_sub(int flags, FPU_REG *rm, u16 control_w)
+{
+  FPU_REG const *a, *b;
+  FPU_REG *dest;
+  u_char taga, tagb, signa, signb, saved_sign, sign;
+  int diff, tag, expa, expb, deststnr;
+
+  a = &st(0);
+  taga = FPU_gettag0();
+
+  deststnr = 0;
+  if ( flags & LOADED )
+    {
+      b = rm;
+      tagb = flags & 0x0f;
+    }
+  else
+    {
+      int rmint = PTR2INT(rm);
+      b = &st(rmint);
+      tagb = FPU_gettagi(rmint);
+
+      if ( flags & DEST_RM )
+       deststnr = rmint;
+    }
+
+  signa = getsign(a);
+  signb = getsign(b);
+
+  if ( flags & REV )
+    {
+      signa ^= SIGN_NEG;
+      signb ^= SIGN_NEG;
+    }
+
+  dest = &st(deststnr);
+  saved_sign = getsign(dest);
+
+  if ( !(taga | tagb) )
+    {
+      expa = exponent(a);
+      expb = exponent(b);
+
+    valid_subtract:
+      /* Both registers are valid */
+
+      diff = expa - expb;
+
+      if (!diff)
+       {
+         diff = a->sigh - b->sigh;  /* Works only if ms bits are identical */
+         if (!diff)
+           {
+             diff = a->sigl > b->sigl;
+             if (!diff)
+               diff = -(a->sigl < b->sigl);
+           }
+       }
+
+      switch ( (((int)signa)*2 + signb) / SIGN_NEG )
+       {
+       case 0: /* P - P */
+       case 3: /* N - N */
+         if (diff > 0)
+           {
+             /* |a| > |b| */
+             tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
+           }
+         else if ( diff == 0 )
+           {
+             FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+
+             /* sign depends upon rounding mode */
+             setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+               ? SIGN_POS : SIGN_NEG);
+             return TAG_Zero;
+           }
+         else
+           {
+             sign = signa ^ SIGN_NEG;
+             tag = FPU_u_sub(b, a, dest, control_w, sign, expb, expa);
+           }
+         break;
+       case 1: /* P - N */
+         tag = FPU_u_add(a, b, dest, control_w, SIGN_POS, expa, expb);
+         break;
+       case 2: /* N - P */
+         tag = FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa, expb);
+         break;
+#ifdef PARANOID
+       default:
+         EXCEPTION(EX_INTERNAL|0x111);
+         return -1;
+#endif
+       }
+      if ( tag < 0 )
+       {
+         setsign(dest, saved_sign);
+         return tag;
+       }
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+
+  if ( taga == TAG_Special )
+    taga = FPU_Special(a);
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+
+  if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+           || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+           || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+    {
+      FPU_REG x, y;
+
+      if ( denormal_operand() < 0 )
+       return FPU_Exception;
+
+      FPU_to_exp16(a, &x);
+      FPU_to_exp16(b, &y);
+      a = &x;
+      b = &y;
+      expa = exponent16(a);
+      expb = exponent16(b);
+
+      goto valid_subtract;
+    }
+
+  if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+    {
+      FPU_REG const *d1, *d2;
+      if ( flags & REV )
+       {
+         d1 = b;
+         d2 = a;
+       }
+      else
+       {
+         d1 = a;
+         d2 = b;
+       }
+      if ( flags & LOADED )
+       return real_2op_NaN(b, tagb, deststnr, d1);
+      if ( flags & DEST_RM )
+       return real_2op_NaN(a, taga, deststnr, d2);
+      else
+       return real_2op_NaN(b, tagb, deststnr, d2);
+    }
+
+    return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
+                           dest, deststnr, control_w);
+}
+
+
+static
+int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
+                    FPU_REG const *b, u_char tagb, u_char signb,
+                    FPU_REG *dest, int deststnr, u16 control_w)
+{
+  if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
+       && (denormal_operand() < 0) )
+    return FPU_Exception;
+
+  if (taga == TAG_Zero)
+    {
+      if (tagb == TAG_Zero)
+       {
+         /* Both are zero, result will be zero. */
+         u_char different_signs = signa ^ signb;
+
+         FPU_copy_to_regi(a, TAG_Zero, deststnr);
+         if ( different_signs )
+           {
+             /* Signs are different. */
+             /* Sign of answer depends upon rounding mode. */
+             setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+                     ? SIGN_POS : SIGN_NEG);
+           }
+         else
+           setsign(dest, signa);  /* signa may differ from the sign of a. */
+         return TAG_Zero;
+       }
+      else
+       {
+         reg_copy(b, dest);
+         if ( (tagb == TW_Denormal) && (b->sigh & 0x80000000) )
+           {
+             /* A pseudoDenormal, convert it. */
+             addexponent(dest, 1);
+             tagb = TAG_Valid;
+           }
+         else if ( tagb > TAG_Empty )
+           tagb = TAG_Special;
+         setsign(dest, signb);  /* signb may differ from the sign of b. */
+         FPU_settagi(deststnr, tagb);
+         return tagb;
+       }
+    }
+  else if (tagb == TAG_Zero)
+    {
+      reg_copy(a, dest);
+      if ( (taga == TW_Denormal) && (a->sigh & 0x80000000) )
+       {
+         /* A pseudoDenormal */
+         addexponent(dest, 1);
+         taga = TAG_Valid;
+       }
+      else if ( taga > TAG_Empty )
+       taga = TAG_Special;
+      setsign(dest, signa);  /* signa may differ from the sign of a. */
+      FPU_settagi(deststnr, taga);
+      return taga;
+    }
+  else if (taga == TW_Infinity)
+    {
+      if ( (tagb != TW_Infinity) || (signa == signb) )
+       {
+         FPU_copy_to_regi(a, TAG_Special, deststnr);
+         setsign(dest, signa);  /* signa may differ from the sign of a. */
+         return taga;
+       }
+      /* Infinity-Infinity is undefined. */
+      return arith_invalid(deststnr);
+    }
+  else if (tagb == TW_Infinity)
+    {
+      FPU_copy_to_regi(b, TAG_Special, deststnr);
+      setsign(dest, signb);  /* signb may differ from the sign of b. */
+      return tagb;
+    }
+
+#ifdef PARANOID
+  EXCEPTION(EX_INTERNAL|0x101);
+#endif
+
+  return FPU_Exception;
+}
+
diff --git a/sid/component/bochs/fpu/reg_compare.c b/sid/component/bochs/fpu/reg_compare.c
new file mode 100644 (file)
index 0000000..8e3cfa1
--- /dev/null
@@ -0,0 +1,381 @@
+/*---------------------------------------------------------------------------+
+ |  reg_compare.c                                                            |
+ |                                                                           |
+ | Compare two floating point registers                                      |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | compare() is the core FPU_REG comparison function                         |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+static int compare(FPU_REG const *b, int tagb)
+{
+  int diff, exp0, expb;
+  u_char               st0_tag;
+  FPU_REG      *st0_ptr;
+  FPU_REG      x, y;
+  u_char               st0_sign, signb = getsign(b);
+
+  st0_ptr = &st(0);
+  st0_tag = FPU_gettag0();
+  st0_sign = getsign(st0_ptr);
+
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+  if ( st0_tag == TAG_Special )
+    st0_tag = FPU_Special(st0_ptr);
+
+  if ( ((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal))
+       || ((tagb != TAG_Valid) && (tagb != TW_Denormal)) )
+    {
+      if ( st0_tag == TAG_Zero )
+       {
+         if ( tagb == TAG_Zero ) return COMP_A_eq_B;
+         if ( tagb == TAG_Valid )
+           return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+         if ( tagb == TW_Denormal )
+           return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+           | COMP_Denormal;
+       }
+      else if ( tagb == TAG_Zero )
+       {
+         if ( st0_tag == TAG_Valid )
+           return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+         if ( st0_tag == TW_Denormal )
+           return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+           | COMP_Denormal;
+       }
+
+      if ( st0_tag == TW_Infinity )
+       {
+         if ( (tagb == TAG_Valid) || (tagb == TAG_Zero) )
+           return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+         else if ( tagb == TW_Denormal )
+           return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+             | COMP_Denormal;
+         else if ( tagb == TW_Infinity )
+           {
+             /* The 80486 book says that infinities can be equal! */
+             return (st0_sign == signb) ? COMP_A_eq_B :
+               ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+           }
+         /* Fall through to the NaN code */
+       }
+      else if ( tagb == TW_Infinity )
+       {
+         if ( (st0_tag == TAG_Valid) || (st0_tag == TAG_Zero) )
+           return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+         if ( st0_tag == TW_Denormal )
+           return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+               | COMP_Denormal;
+         /* Fall through to the NaN code */
+       }
+
+      /* The only possibility now should be that one of the arguments
+        is a NaN */
+      if ( (st0_tag == TW_NaN) || (tagb == TW_NaN) )
+       {
+         int signalling = 0, unsupported = 0;
+         if ( st0_tag == TW_NaN )
+           {
+             signalling = (st0_ptr->sigh & 0xc0000000) == 0x80000000;
+             unsupported = !((exponent(st0_ptr) == EXP_OVER)
+                             && (st0_ptr->sigh & 0x80000000));
+           }
+         if ( tagb == TW_NaN )
+           {
+             signalling |= (b->sigh & 0xc0000000) == 0x80000000;
+             unsupported |= !((exponent(b) == EXP_OVER)
+                              && (b->sigh & 0x80000000));
+           }
+         if ( signalling || unsupported )
+           return COMP_No_Comp | COMP_SNaN | COMP_NaN;
+         else
+           /* Neither is a signaling NaN */
+           return COMP_No_Comp | COMP_NaN;
+       }
+      
+      EXCEPTION(EX_Invalid);
+    }
+  
+  if (st0_sign != signb)
+    {
+      return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+       | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+           COMP_Denormal : 0);
+    }
+
+  if ( (st0_tag == TW_Denormal) || (tagb == TW_Denormal) )
+    {
+      FPU_to_exp16(st0_ptr, &x);
+      FPU_to_exp16(b, &y);
+      st0_ptr = &x;
+      b = &y;
+      exp0 = exponent16(st0_ptr);
+      expb = exponent16(b);
+    }
+  else
+    {
+      exp0 = exponent(st0_ptr);
+      expb = exponent(b);
+    }
+
+#ifdef PARANOID
+  if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+  if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+#endif /* PARANOID */
+
+  diff = exp0 - expb;
+  if ( diff == 0 )
+    {
+      diff = st0_ptr->sigh - b->sigh;  /* Works only if ms bits are
+                                             identical */
+      if ( diff == 0 )
+       {
+       diff = st0_ptr->sigl > b->sigl;
+       if ( diff == 0 )
+         diff = -(st0_ptr->sigl < b->sigl);
+       }
+    }
+
+  if ( diff > 0 )
+    {
+      return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+       | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+           COMP_Denormal : 0);
+    }
+  if ( diff < 0 )
+    {
+      return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+       | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+           COMP_Denormal : 0);
+    }
+
+  return COMP_A_eq_B
+    | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+       COMP_Denormal : 0);
+
+}
+
+
+/* This function requires that st(0) is not empty */
+int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
+{
+  int f, c;
+
+  c = compare(loaded_data, loaded_tag);
+
+  if (c & COMP_NaN)
+    {
+      EXCEPTION(EX_Invalid);
+      f = SW_C3 | SW_C2 | SW_C0;
+    }
+  else
+    switch (c & 7)
+      {
+      case COMP_A_lt_B:
+       f = SW_C0;
+       break;
+      case COMP_A_eq_B:
+       f = SW_C3;
+       break;
+      case COMP_A_gt_B:
+       f = 0;
+       break;
+      case COMP_No_Comp:
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#ifdef PARANOID
+      default:
+       EXCEPTION(EX_INTERNAL|0x121);
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#endif /* PARANOID */
+      }
+  setcc(f);
+  if (c & COMP_Denormal)
+    {
+      return denormal_operand() < 0;
+    }
+  return 0;
+}
+
+
+static int compare_st_st(int nr)
+{
+  int f, c;
+  FPU_REG *st_ptr;
+
+  if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
+    {
+      setcc(SW_C3 | SW_C2 | SW_C0);
+      /* Stack fault */
+      EXCEPTION(EX_StackUnder);
+      return !(control_word & CW_Invalid);
+    }
+
+  st_ptr = &st(nr);
+  c = compare(st_ptr, FPU_gettagi(nr));
+  if (c & COMP_NaN)
+    {
+      setcc(SW_C3 | SW_C2 | SW_C0);
+      EXCEPTION(EX_Invalid);
+      return !(control_word & CW_Invalid);
+    }
+  else
+    switch (c & 7)
+      {
+      case COMP_A_lt_B:
+       f = SW_C0;
+       break;
+      case COMP_A_eq_B:
+       f = SW_C3;
+       break;
+      case COMP_A_gt_B:
+       f = 0;
+       break;
+      case COMP_No_Comp:
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#ifdef PARANOID
+      default:
+       EXCEPTION(EX_INTERNAL|0x122);
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#endif /* PARANOID */
+      }
+  setcc(f);
+  if (c & COMP_Denormal)
+    {
+      return denormal_operand() < 0;
+    }
+  return 0;
+}
+
+
+static int compare_u_st_st(int nr)
+{
+  int f, c;
+  FPU_REG *st_ptr;
+
+  if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
+    {
+      setcc(SW_C3 | SW_C2 | SW_C0);
+      /* Stack fault */
+      EXCEPTION(EX_StackUnder);
+      return !(control_word & CW_Invalid);
+    }
+
+  st_ptr = &st(nr);
+  c = compare(st_ptr, FPU_gettagi(nr));
+  if (c & COMP_NaN)
+    {
+      setcc(SW_C3 | SW_C2 | SW_C0);
+      if (c & COMP_SNaN)       /* This is the only difference between
+                                 un-ordered and ordinary comparisons */
+       {
+         EXCEPTION(EX_Invalid);
+         return !(control_word & CW_Invalid);
+       }
+      return 0;
+    }
+  else
+    switch (c & 7)
+      {
+      case COMP_A_lt_B:
+       f = SW_C0;
+       break;
+      case COMP_A_eq_B:
+       f = SW_C3;
+       break;
+      case COMP_A_gt_B:
+       f = 0;
+       break;
+      case COMP_No_Comp:
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#ifdef PARANOID
+      default:
+       EXCEPTION(EX_INTERNAL|0x123);
+       f = SW_C3 | SW_C2 | SW_C0;
+       break;
+#endif /* PARANOID */
+      }
+  setcc(f);
+  if (c & COMP_Denormal)
+    {
+      return denormal_operand() < 0;
+    }
+  return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void fcom_st()
+{
+  /* fcom st(i) */
+  compare_st_st(FPU_rm);
+}
+
+
+void fcompst()
+{
+  /* fcomp st(i) */
+  if ( !compare_st_st(FPU_rm) )
+    FPU_pop();
+}
+
+
+void fcompp()
+{
+  /* fcompp */
+  if (FPU_rm != 1)
+    {
+      FPU_illegal();
+      return;
+    }
+  if ( !compare_st_st(1) )
+      poppop();
+}
+
+
+void fucom_()
+{
+  /* fucom st(i) */
+  compare_u_st_st(FPU_rm);
+
+}
+
+
+void fucomp()
+{
+  /* fucomp st(i) */
+  if ( !compare_u_st_st(FPU_rm) )
+    FPU_pop();
+}
+
+
+void fucompp()
+{
+  /* fucompp */
+  if (FPU_rm == 1)
+    {
+      if ( !compare_u_st_st(1) )
+       poppop();
+    }
+  else
+    FPU_illegal();
+}
diff --git a/sid/component/bochs/fpu/reg_constant.c b/sid/component/bochs/fpu/reg_constant.c
new file mode 100644 (file)
index 0000000..1d60636
--- /dev/null
@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------------+
+ |  reg_constant.c                                                           |
+ |                                                                           |
+ | All of the constant FPU_REGs                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
+ |                     Australia.  E-mail   billm@suburbia.net               |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "reg_constant.h"
+#include "control_w.h"
+
+
+
+FPU_REG const CONST_1    = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
+FPU_REG const CONST_2    = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
+FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000);
+FPU_REG const CONST_L2T  = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
+FPU_REG const CONST_L2E  = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
+FPU_REG const CONST_PI   = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
+// bbd: make CONST_PI2 non-const so that you can write "&CONST_PI2" when
+// calling a function.  Otherwise you get const warnings.  Surely there's
+// a better way.
+FPU_REG CONST_PI2  = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_PI4  = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_LG2  = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
+FPU_REG const CONST_LN2  = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
+
+/* Extra bits to take pi/2 to more than 128 bits precision. */
+FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66,
+                                        0xfc8f8cbb, 0xece675d1);
+
+/* Only the sign (and tag) is used in internal zeroes */
+FPU_REG const CONST_Z    = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
+
+/* Only the sign and significand (and tag) are used in internal NaNs */
+/* The 80486 never generates one of these 
+FPU_REG const CONST_SNAN = MAKE_REG(POS, EXP_OVER, 0x00000001, 0x80000000);
+ */
+/* This is the real indefinite QNaN */
+FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000);
+
+/* Only the sign (and tag) is used in internal infinities */
+FPU_REG const CONST_INF  = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
+
+
+static void fld_const(FPU_REG const *c, int adj, u_char tag)
+{
+  FPU_REG *st_new_ptr;
+
+  if ( STACK_OVERFLOW )
+    {
+      FPU_stack_overflow();
+      return;
+    }
+  push();
+  reg_copy(c, st_new_ptr);
+  st_new_ptr->sigl += adj;  /* For all our fldxxx constants, we don't need to
+                              borrow or carry. */
+  FPU_settag0(tag);
+  clear_C1();
+}
+
+/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
+   (and not one of RC_RND or RC_UP).
+   */
+#define DOWN_OR_CHOP(x)  (x & RC_DOWN)
+
+static void fld1(int rc)
+{
+  fld_const(&CONST_1, 0, TAG_Valid);
+}
+
+static void fldl2t(int rc)
+{
+  fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
+}
+
+static void fldl2e(int rc)
+{
+  fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldpi(int rc)
+{
+  fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldlg2(int rc)
+{
+  fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldln2(int rc)
+{
+  fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldz(int rc)
+{
+  fld_const(&CONST_Z, 0, TAG_Zero);
+}
+
+typedef void (*FUNC_RC)(int);
+
+static FUNC_RC constants_table[] = {
+  fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal
+};
+
+void fconst(void)
+{
+  (constants_table[FPU_rm])(control_word & CW_RC);
+}
diff --git a/sid/component/bochs/fpu/reg_constant.h b/sid/component/bochs/fpu/reg_constant.h
new file mode 100644 (file)
index 0000000..f16aaec
--- /dev/null
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------+
+ |  reg_constant.h                                                           |
+ |                                                                           |
+ | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _REG_CONSTANT_H_
+#define _REG_CONSTANT_H_
+
+#include "fpu_emu.h"
+
+extern FPU_REG const CONST_1;
+extern FPU_REG const CONST_2;
+extern FPU_REG const CONST_HALF;
+extern FPU_REG const CONST_L2T;
+extern FPU_REG const CONST_L2E;
+extern FPU_REG const CONST_PI;
+// bbd: make CONST_PI2 non-const so that you can write "&CONST_PI2" when
+// calling a function.  Otherwise you get const warnings.  Surely there's
+// a better way.
+extern FPU_REG CONST_PI2;
+extern FPU_REG const CONST_PI2extra;
+extern FPU_REG const CONST_PI4;
+extern FPU_REG const CONST_LG2;
+extern FPU_REG const CONST_LN2;
+extern FPU_REG const CONST_Z;
+extern FPU_REG const CONST_PINF;
+extern FPU_REG const CONST_INF;
+extern FPU_REG const CONST_MINF;
+extern FPU_REG const CONST_QNaN;
+
+#endif /* _REG_CONSTANT_H_ */
diff --git a/sid/component/bochs/fpu/reg_convert.c b/sid/component/bochs/fpu/reg_convert.c
new file mode 100644 (file)
index 0000000..1c285ee
--- /dev/null
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------+
+ |  reg_convert.c                                                            |
+ |                                                                           |
+ |  Convert register representation.                                         |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1996,1997                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
+{
+  int sign = getsign(a);
+
+#ifndef EMU_BIG_ENDIAN
+  *(s64 *)&(x->sigl) = *(const s64 *)&(a->sigl);
+#else
+  *(s64 *)&(x->sigh) = *(const s64 *)&(a->sigh);
+#endif
+
+  /* Set up the exponent as a 16 bit quantity. */
+  setexponent16(x, exponent(a));
+
+  if ( exponent16(x) == EXP_UNDER )
+    {
+      /* The number is a de-normal or pseudodenormal. */
+      /* We only deal with the significand and exponent. */
+
+      if (x->sigh & 0x80000000)
+       {
+         /* Is a pseudodenormal. */
+         /* This is non-80486 behaviour because the number
+            loses its 'denormal' identity. */
+         addexponent(x, 1);
+       }
+      else
+       {
+         /* Is a denormal. */
+         addexponent(x, 1);
+          FPU_normalize_nuo(x, 0);
+       }
+    }
+
+  if ( !(x->sigh & 0x80000000) )
+    {
+      EXCEPTION(EX_INTERNAL | 0x180);
+    }
+
+  return sign;
+}
+
diff --git a/sid/component/bochs/fpu/reg_divide.c b/sid/component/bochs/fpu/reg_divide.c
new file mode 100644 (file)
index 0000000..11be79d
--- /dev/null
@@ -0,0 +1,208 @@
+/*---------------------------------------------------------------------------+
+ |  reg_divide.c                                                             |
+ |                                                                           |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ |                                                                           |
+ | Copyright (C) 1996                                                        |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@jacobi.maths.monash.edu.au                |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+
+/*
+  Divide one register by another and put the result into a third register.
+bbd: arg2 used to be an int, see comments on FPU_sub.
+  */
+int FPU_div(int flags, FPU_REG *rm, int control_w)
+{
+  FPU_REG x, y;
+  FPU_REG const *a, *b, *st0_ptr, *st_ptr;
+  FPU_REG *dest;
+  u_char taga, tagb, signa, signb, sign, saved_sign;
+  int tag, deststnr;
+  int rmint = PTR2INT(rm);
+
+  if ( flags & DEST_RM )
+    deststnr = rmint;
+  else
+    deststnr = 0;
+
+  if ( flags & REV )
+    {
+      b = &st(0);
+      st0_ptr = b;
+      tagb = FPU_gettag0();
+      if ( flags & LOADED )
+       {
+         a = rm;
+         taga = flags & 0x0f;
+       }
+      else
+       {
+         a = &st(rmint);
+         st_ptr = a;
+         taga = FPU_gettagi(rmint);
+       }
+    }
+  else
+    {
+      a = &st(0);
+      st0_ptr = a;
+      taga = FPU_gettag0();
+      if ( flags & LOADED )
+       {
+         b = rm;
+         tagb = flags & 0x0f;
+       }
+      else
+       {
+         b = &st(rmint);
+         st_ptr = b;
+         tagb = FPU_gettagi(rmint);
+       }
+    }
+
+  signa = getsign(a);
+  signb = getsign(b);
+
+  sign = signa ^ signb;
+
+  dest = &st(deststnr);
+  saved_sign = getsign(dest);
+
+  if ( !(taga | tagb) )
+    {
+      /* Both regs Valid, this should be the most common case. */
+      reg_copy(a, &x);
+      reg_copy(b, &y);
+      setpositive(&x);
+      setpositive(&y);
+      tag = FPU_u_div(&x, &y, dest, control_w, sign);
+
+      if ( tag < 0 )
+       return tag;
+
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+
+  if ( taga == TAG_Special )
+    taga = FPU_Special(a);
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+
+  if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+           || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+           || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+    {
+      if ( denormal_operand() < 0 )
+       return FPU_Exception;
+
+      FPU_to_exp16(a, &x);
+      FPU_to_exp16(b, &y);
+      tag = FPU_u_div(&x, &y, dest, control_w, sign);
+      if ( tag < 0 )
+       return tag;
+
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+  else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
+    {
+      if ( tagb != TAG_Zero )
+       {
+         /* Want to find Zero/Valid */
+         if ( tagb == TW_Denormal )
+           {
+             if ( denormal_operand() < 0 )
+               return FPU_Exception;
+           }
+
+         /* The result is zero. */
+         FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+         setsign(dest, sign);
+         return TAG_Zero;
+       }
+      /* We have an exception condition, either 0/0 or Valid/Zero. */
+      if ( taga == TAG_Zero )
+       {
+         /* 0/0 */
+         return arith_invalid(deststnr);
+       }
+      /* Valid/Zero */
+      return FPU_divide_by_zero(deststnr, sign);
+    }
+  /* Must have infinities, NaNs, etc */
+  else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+    {
+      if ( flags & LOADED )
+       return real_2op_NaN((FPU_REG *)rm, flags & 0x0f, 0, st0_ptr);
+
+      if ( flags & DEST_RM )
+       {
+         int tag;
+         tag = FPU_gettag0();
+         if ( tag == TAG_Special )
+           tag = FPU_Special(st0_ptr);
+         return real_2op_NaN(st0_ptr, tag, rmint, (flags & REV) ? st0_ptr : &st(rmint));
+       }
+      else
+       {
+         int tag;
+         tag = FPU_gettagi(rmint);
+         if ( tag == TAG_Special )
+           tag = FPU_Special(&st(rmint));
+         return real_2op_NaN(&st(rmint), tag, 0, (flags & REV) ? st0_ptr : &st(rmint));
+       }
+    }
+  else if (taga == TW_Infinity)
+    {
+      if (tagb == TW_Infinity)
+       {
+         /* infinity/infinity */
+         return arith_invalid(deststnr);
+       }
+      else
+       {
+         /* tagb must be Valid or Zero */
+         if ( (tagb == TW_Denormal) && (denormal_operand() < 0) )
+           return FPU_Exception;
+         
+         /* Infinity divided by Zero or Valid does
+            not raise and exception, but returns Infinity */
+         FPU_copy_to_regi(a, TAG_Special, deststnr);
+         setsign(dest, sign);
+         return taga;
+       }
+    }
+  else if (tagb == TW_Infinity)
+    {
+      if ( (taga == TW_Denormal) && (denormal_operand() < 0) )
+       return FPU_Exception;
+
+      /* The result is zero. */
+      FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+      setsign(dest, sign);
+      return TAG_Zero;
+    }
+#ifdef PARANOID
+  else
+    {
+      EXCEPTION(EX_INTERNAL|0x102);
+      return FPU_Exception;
+    }
+#endif /* PARANOID */
+
+}
diff --git a/sid/component/bochs/fpu/reg_ld_str.c b/sid/component/bochs/fpu/reg_ld_str.c
new file mode 100644 (file)
index 0000000..fb2cec0
--- /dev/null
@@ -0,0 +1,1460 @@
+/*---------------------------------------------------------------------------+
+ |  reg_ld_str.c                                                             |
+ |                                                                           |
+ | All of the functions which transfer data between user memory and FPU_REGs.|
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1996,1997                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+#include <asm/uaccess.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "reg_constant.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+#define DOUBLE_Emax 1023         /* largest valid exponent */
+#define DOUBLE_Ebias 1023
+#define DOUBLE_Emin (-1022)      /* smallest valid exponent */
+
+#define SINGLE_Emax 127          /* largest valid exponent */
+#define SINGLE_Ebias 127
+#define SINGLE_Emin (-126)       /* smallest valid exponent */
+
+
+static u_char normalize_no_excep(FPU_REG *r, int exp, int sign)
+{
+  u_char tag;
+
+  setexponent16(r, exp);
+
+  tag = FPU_normalize_nuo(r, 0);
+  stdexp(r);
+  if ( sign )
+    setnegative(r);
+
+  return tag;
+}
+
+
+int FPU_tagof(FPU_REG *ptr)
+{
+  int exp;
+
+  exp = exponent16(ptr) & 0x7fff;
+  if ( exp == 0 )
+    {
+      if ( !(ptr->sigh | ptr->sigl) )
+       {
+         return TAG_Zero;
+       }
+      /* The number is a de-normal or pseudodenormal. */
+      return TAG_Special;
+    }
+
+  if ( exp == 0x7fff )
+    {
+      /* Is an Infinity, a NaN, or an unsupported data type. */
+      return TAG_Special;
+    }
+
+  if ( !(ptr->sigh & 0x80000000) )
+    {
+      /* Unsupported data type. */
+      /* Valid numbers have the ms bit set to 1. */
+      /* Unnormal. */
+      return TAG_Special;
+    }
+
+  return TAG_Valid;
+}
+
+
+/* Get a long double from user memory */
+int FPU_load_extended(long double *s, int stnr)
+{
+  FPU_REG *sti_ptr = &st(stnr);
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, s, 10);
+#ifndef USE_WITH_CPU_SIM
+  __copy_from_user(sti_ptr, s, 10);
+#else
+  FPU_get_user(sti_ptr->sigl, (u32*)(((u8*)s)+0));
+  FPU_get_user(sti_ptr->sigh, (u32*)(((u8*)s)+4));
+  FPU_get_user(sti_ptr->exp,  (u16*)(((u8*)s)+8));
+#endif
+  RE_ENTRANT_CHECK_ON;
+
+  return FPU_tagof(sti_ptr);
+}
+
+
+/* Get a double from user memory */
+int FPU_load_double(double *dfloat, FPU_REG *loaded_data)
+{
+  int exp, tag, negative;
+  u32 m64, l64;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, dfloat, 8);
+  FPU_get_user(m64, 1 + (u32 *) dfloat);
+  FPU_get_user(l64, (u32 *) dfloat);
+  RE_ENTRANT_CHECK_ON;
+
+  negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+  exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
+  m64 &= 0xfffff;
+  if ( exp > DOUBLE_Emax + EXTENDED_Ebias )
+    {
+      /* Infinity or NaN */
+      if ((m64 == 0) && (l64 == 0))
+       {
+         /* +- infinity */
+         loaded_data->sigh = 0x80000000;
+         loaded_data->sigl = 0x00000000;
+         exp = EXP_Infinity + EXTENDED_Ebias;
+         tag = TAG_Special;
+       }
+      else
+       {
+         /* Must be a signaling or quiet NaN */
+         exp = EXP_NaN + EXTENDED_Ebias;
+         loaded_data->sigh = (m64 << 11) | 0x80000000;
+         loaded_data->sigh |= l64 >> 21;
+         loaded_data->sigl = l64 << 11;
+         tag = TAG_Special;    /* The calling function must look for NaNs */
+       }
+    }
+  else if ( exp < DOUBLE_Emin + EXTENDED_Ebias )
+    {
+      /* Zero or de-normal */
+      if ((m64 == 0) && (l64 == 0))
+       {
+         /* Zero */
+         reg_copy(&CONST_Z, loaded_data);
+         exp = 0;
+         tag = TAG_Zero;
+       }
+      else
+       {
+         /* De-normal */
+         loaded_data->sigh = m64 << 11;
+         loaded_data->sigh |= l64 >> 21;
+         loaded_data->sigl = l64 << 11;
+
+         return normalize_no_excep(loaded_data, DOUBLE_Emin, negative)
+           | (denormal_operand() < 0 ? FPU_Exception : 0);
+       }
+    }
+  else
+    {
+      loaded_data->sigh = (m64 << 11) | 0x80000000;
+      loaded_data->sigh |= l64 >> 21;
+      loaded_data->sigl = l64 << 11;
+
+      tag = TAG_Valid;
+    }
+
+  setexponent16(loaded_data, exp | negative);
+
+  return tag;
+}
+
+
+/* Get a float from user memory */
+int FPU_load_single(float *single, FPU_REG *loaded_data)
+{
+  u32 m32;
+  int exp, tag, negative;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, single, 4);
+  FPU_get_user(m32, (u32 *) single);
+  RE_ENTRANT_CHECK_ON;
+
+  negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+
+  if (!(m32 & 0x7fffffff))
+    {
+      /* Zero */
+      reg_copy(&CONST_Z, loaded_data);
+      addexponent(loaded_data, negative);
+      return TAG_Zero;
+    }
+  exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
+  m32 = (m32 & 0x7fffff) << 8;
+  if ( exp < SINGLE_Emin + EXTENDED_Ebias )
+    {
+      /* De-normals */
+      loaded_data->sigh = m32;
+      loaded_data->sigl = 0;
+
+      return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
+       | (denormal_operand() < 0 ? FPU_Exception : 0);
+    }
+  else if ( exp > SINGLE_Emax + EXTENDED_Ebias )
+    {
+    /* Infinity or NaN */
+      if ( m32 == 0 )
+       {
+         /* +- infinity */
+         loaded_data->sigh = 0x80000000;
+         loaded_data->sigl = 0x00000000;
+         exp = EXP_Infinity + EXTENDED_Ebias;
+         tag = TAG_Special;
+       }
+      else
+       {
+         /* Must be a signaling or quiet NaN */
+         exp = EXP_NaN + EXTENDED_Ebias;
+         loaded_data->sigh = m32 | 0x80000000;
+         loaded_data->sigl = 0;
+         tag = TAG_Special;  /* The calling function must look for NaNs */
+       }
+    }
+  else
+    {
+      loaded_data->sigh = m32 | 0x80000000;
+      loaded_data->sigl = 0;
+      tag = TAG_Valid;
+    }
+
+  setexponent16(loaded_data, exp | negative);  /* Set the sign. */
+
+  return tag;
+}
+
+
+/* Get a 64bit quantity from user memory */
+int FPU_load_int64(s64 *_s)
+{
+  s64 s;
+  int sign;
+  FPU_REG *st0_ptr = &st(0);
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, _s, 8);
+#ifndef USE_WITH_CPU_SIM
+  copy_from_user(&s,_s,8);
+#else
+  {
+  u32 chunk0, chunk1;
+  FPU_get_user(chunk0, (u32*)(((u8*)_s)+0));
+  FPU_get_user(chunk1, (u32*)(((u8*)_s)+4));
+  s = chunk0;
+  s |= (((u64)chunk1) << 32);
+  }
+#endif
+  RE_ENTRANT_CHECK_ON;
+
+  if (s == 0)
+    {
+      reg_copy(&CONST_Z, st0_ptr);
+      return TAG_Zero;
+    }
+
+  if (s > 0)
+    sign = SIGN_Positive;
+  else
+  {
+    s = -s;
+    sign = SIGN_Negative;
+  }
+
+  significand(st0_ptr) = s;
+
+  return normalize_no_excep(st0_ptr, 63, sign);
+}
+
+
+/* Get a long from user memory */
+int FPU_load_int32(s32 *_s, FPU_REG *loaded_data)
+{
+  s32 s;
+  int negative;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, _s, 4);
+  FPU_get_user(s, _s);
+  RE_ENTRANT_CHECK_ON;
+
+  if (s == 0)
+    { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+
+  if (s > 0)
+    negative = SIGN_Positive;
+  else
+    {
+      s = -s;
+      negative = SIGN_Negative;
+    }
+
+  loaded_data->sigh = s;
+  loaded_data->sigl = 0;
+
+  return normalize_no_excep(loaded_data, 31, negative);
+}
+
+
+/* Get a short from user memory */
+int FPU_load_int16(s16 *_s, FPU_REG *loaded_data)
+{
+  int s, negative;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, _s, 2);
+  /* Cast as short to get the sign extended. */
+  FPU_get_user(s, _s);
+  RE_ENTRANT_CHECK_ON;
+
+  if (s == 0)
+    { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+
+  if (s > 0)
+    negative = SIGN_Positive;
+  else
+    {
+      s = -s;
+      negative = SIGN_Negative;
+    }
+
+  loaded_data->sigh = s << 16;
+  loaded_data->sigl = 0;
+
+  return normalize_no_excep(loaded_data, 15, negative);
+}
+
+
+/* Get a packed bcd array from user memory */
+int FPU_load_bcd(u_char *s)
+{
+  FPU_REG *st0_ptr = &st(0);
+  int pos;
+  u_char bcd;
+  s64 l=0;
+  int sign;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ, s, 10);
+  RE_ENTRANT_CHECK_ON;
+  for ( pos = 8; pos >= 0; pos--)
+    {
+      l *= 10;
+      RE_ENTRANT_CHECK_OFF;
+      FPU_get_user(bcd, (u_char *) s+pos);
+      RE_ENTRANT_CHECK_ON;
+      l += bcd >> 4;
+      l *= 10;
+      l += bcd & 0x0f;
+    }
+  RE_ENTRANT_CHECK_OFF;
+  FPU_get_user(sign, (u_char *) s+9);
+  sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
+  RE_ENTRANT_CHECK_ON;
+
+  if ( l == 0 )
+    {
+      reg_copy(&CONST_Z, st0_ptr);
+      addexponent(st0_ptr, sign);   /* Set the sign. */
+      return TAG_Zero;
+    }
+  else
+    {
+      significand(st0_ptr) = l;
+      return normalize_no_excep(st0_ptr, 63, sign);
+    }
+}
+
+/*===========================================================================*/
+
+/* Put a long double into user memory */
+int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
+{
+  /*
+    The only exception raised by an attempt to store to an
+    extended format is the Invalid Stack exception, i.e.
+    attempting to store from an empty register.
+   */
+
+  if ( st0_tag != TAG_Empty )
+    {
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE, d, 10);
+
+      FPU_put_user(st0_ptr->sigl, (u32 *) d);
+      FPU_put_user(st0_ptr->sigh, (u32 *) ((u_char *)d + 4));
+      FPU_put_user(exponent16(st0_ptr), (u16 *) ((u_char *)d + 8));
+      RE_ENTRANT_CHECK_ON;
+
+      return 1;
+    }
+
+  /* Empty register (stack underflow) */
+  EXCEPTION(EX_StackUnder);
+  if ( control_word & CW_Invalid )
+    {
+      /* The masked response */
+      /* Put out the QNaN indefinite */
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE,d,10);
+      FPU_put_user(0, (u32 *) d);
+      FPU_put_user(0xc0000000, 1 + (u32 *) d);
+      FPU_put_user(0xffff, 4 + (s16 *) d);
+      RE_ENTRANT_CHECK_ON;
+      return 1;
+    }
+  else
+    return 0;
+
+}
+
+
+/* Put a double into user memory */
+int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
+{
+  u32 l[2];
+  u32 increment = 0;   /* avoid gcc warnings */
+  int precision_loss;
+  int exp;
+  FPU_REG tmp;
+
+  if ( st0_tag == TAG_Valid )
+    {
+      reg_copy(st0_ptr, &tmp);
+      exp = exponent(&tmp);
+
+      if ( exp < DOUBLE_Emin )     /* It may be a denormal */
+       {
+         addexponent(&tmp, -DOUBLE_Emin + 52);  /* largest exp to be 51 */
+
+       denormal_arg:
+
+         if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
+           {
+#ifdef PECULIAR_486
+             /* Did it round to a non-denormal ? */
+             /* This behaviour might be regarded as peculiar, it appears
+                that the 80486 rounds to the dest precision, then
+                converts to decide underflow. */
+             if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&
+                 (st0_ptr->sigl & 0x000007ff)) )
+#endif /* PECULIAR_486 */
+               {
+                 EXCEPTION(EX_Underflow);
+                 /* This is a special case: see sec 16.2.5.1 of
+                    the 80486 book */
+                 if ( !(control_word & CW_Underflow) )
+                   return 0;
+               }
+             EXCEPTION(precision_loss);
+             if ( !(control_word & CW_Precision) )
+               return 0;
+           }
+         l[0] = tmp.sigl;
+         l[1] = tmp.sigh;
+       }
+      else
+       {
+         if ( tmp.sigl & 0x000007ff )
+           {
+             precision_loss = 1;
+             switch (control_word & CW_RC)
+               {
+               case RC_RND:
+                 /* Rounding can get a little messy.. */
+                 increment = ((tmp.sigl & 0x7ff) > 0x400) |  /* nearest */
+                   ((tmp.sigl & 0xc00) == 0xc00);            /* odd -> even */
+                 break;
+               case RC_DOWN:   /* towards -infinity */
+                 increment = signpositive(&tmp) ? 0 : tmp.sigl & 0x7ff;
+                 break;
+               case RC_UP:     /* towards +infinity */
+                 increment = signpositive(&tmp) ? tmp.sigl & 0x7ff : 0;
+                 break;
+               case RC_CHOP:
+                 increment = 0;
+                 break;
+               }
+         
+             /* Truncate the mantissa */
+             tmp.sigl &= 0xfffff800;
+         
+             if ( increment )
+               {
+                 if ( tmp.sigl >= 0xfffff800 )
+                   {
+                     /* the sigl part overflows */
+                     if ( tmp.sigh == 0xffffffff )
+                       {
+                         /* The sigh part overflows */
+                         tmp.sigh = 0x80000000;
+                         exp++;
+                         if (exp >= EXP_OVER)
+                           goto overflow;
+                       }
+                     else
+                       {
+                         tmp.sigh ++;
+                       }
+                     tmp.sigl = 0x00000000;
+                   }
+                 else
+                   {
+                     /* We only need to increment sigl */
+                     tmp.sigl += 0x00000800;
+                   }
+               }
+           }
+         else
+           precision_loss = 0;
+         
+         l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
+         l[1] = ((tmp.sigh >> 11) & 0xfffff);
+
+         if ( exp > DOUBLE_Emax )
+           {
+           overflow:
+             EXCEPTION(EX_Overflow);
+             if ( !(control_word & CW_Overflow) )
+               return 0;
+             set_precision_flag_up();
+             if ( !(control_word & CW_Precision) )
+               return 0;
+
+             /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+             /* Overflow to infinity */
+             l[0] = 0x00000000;        /* Set to */
+             l[1] = 0x7ff00000;        /* + INF */
+           }
+         else
+           {
+             if ( precision_loss )
+               {
+                 if ( increment )
+                   set_precision_flag_up();
+                 else
+                   set_precision_flag_down();
+               }
+             /* Add the exponent */
+             l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);
+           }
+       }
+    }
+  else if (st0_tag == TAG_Zero)
+    {
+      /* Number is zero */
+      l[0] = 0;
+      l[1] = 0;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if ( st0_tag == TW_Denormal )
+       {
+         /* A denormal will always underflow. */
+#ifndef PECULIAR_486
+         /* An 80486 is supposed to be able to generate
+            a denormal exception here, but... */
+         /* Underflow has priority. */
+         if ( control_word & CW_Underflow )
+           denormal_operand();
+#endif /* PECULIAR_486 */
+         reg_copy(st0_ptr, &tmp);
+         goto denormal_arg;
+       }
+      else if (st0_tag == TW_Infinity)
+       {
+         l[0] = 0;
+         l[1] = 0x7ff00000;
+       }
+      else if (st0_tag == TW_NaN)
+       {
+         /* Is it really a NaN ? */
+         if ( (exponent(st0_ptr) == EXP_OVER)
+              && (st0_ptr->sigh & 0x80000000) )
+           {
+             /* See if we can get a valid NaN from the FPU_REG */
+             l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21);
+             l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+             if ( !(st0_ptr->sigh & 0x40000000) )
+               {
+                 /* It is a signalling NaN */
+                 EXCEPTION(EX_Invalid);
+                 if ( !(control_word & CW_Invalid) )
+                   return 0;
+                 l[1] |= (0x40000000 >> 11);
+               }
+             l[1] |= 0x7ff00000;
+           }
+         else
+           {
+             /* It is an unsupported data type */
+             EXCEPTION(EX_Invalid);
+             if ( !(control_word & CW_Invalid) )
+               return 0;
+             l[0] = 0;
+             l[1] = 0xfff80000;
+           }
+       }
+    }
+  else if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      if ( control_word & CW_Invalid )
+       {
+         /* The masked response */
+         /* Put out the QNaN indefinite */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
+         FPU_put_user(0, (u32 *) dfloat);
+         FPU_put_user(0xfff80000, 1 + (u32 *) dfloat);
+         RE_ENTRANT_CHECK_ON;
+         return 1;
+       }
+      else
+       return 0;
+    }
+  if ( getsign(st0_ptr) )
+    l[1] |= 0x80000000;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
+  FPU_put_user(l[0], (u32 *)dfloat);
+  FPU_put_user(l[1], 1 + (u32 *)dfloat);
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+
+/* Put a float into user memory */
+int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
+{
+  s32 templ;
+  u32 increment = 0;           /* avoid gcc warnings */
+  int precision_loss;
+  int exp;
+  FPU_REG tmp;
+
+  if ( st0_tag == TAG_Valid )
+    {
+
+      reg_copy(st0_ptr, &tmp);
+      exp = exponent(&tmp);
+
+      if ( exp < SINGLE_Emin )
+       {
+         addexponent(&tmp, -SINGLE_Emin + 23);  /* largest exp to be 22 */
+
+       denormal_arg:
+
+         if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
+           {
+#ifdef PECULIAR_486
+             /* Did it round to a non-denormal ? */
+             /* This behaviour might be regarded as peculiar, it appears
+                that the 80486 rounds to the dest precision, then
+                converts to decide underflow. */
+             if ( !((tmp.sigl == 0x00800000) &&
+                 ((st0_ptr->sigh & 0x000000ff) || st0_ptr->sigl)) )
+#endif /* PECULIAR_486 */
+               {
+                 EXCEPTION(EX_Underflow);
+                 /* This is a special case: see sec 16.2.5.1 of
+                    the 80486 book */
+                 if ( !(control_word & CW_Underflow) )
+                   return 0;
+               }
+             EXCEPTION(precision_loss);
+             if ( !(control_word & CW_Precision) )
+               return 0;
+           }
+         templ = tmp.sigl;
+      }
+      else
+       {
+         if ( tmp.sigl | (tmp.sigh & 0x000000ff) )
+           {
+             u32 sigh = tmp.sigh;
+             u32 sigl = tmp.sigl;
+             
+             precision_loss = 1;
+             switch (control_word & CW_RC)
+               {
+               case RC_RND:
+                 increment = ((sigh & 0xff) > 0x80)       /* more than half */
+                   || (((sigh & 0xff) == 0x80) && sigl)   /* more than half */
+                   || ((sigh & 0x180) == 0x180);        /* round to even */
+                 break;
+               case RC_DOWN:   /* towards -infinity */
+                 increment = signpositive(&tmp)
+                   ? 0 : (sigl | (sigh & 0xff));
+                 break;
+               case RC_UP:     /* towards +infinity */
+                 increment = signpositive(&tmp)
+                   ? (sigl | (sigh & 0xff)) : 0;
+                 break;
+               case RC_CHOP:
+                 increment = 0;
+                 break;
+               }
+         
+             /* Truncate part of the mantissa */
+             tmp.sigl = 0;
+         
+             if (increment)
+               {
+                 if ( sigh >= 0xffffff00 )
+                   {
+                     /* The sigh part overflows */
+                     tmp.sigh = 0x80000000;
+                     exp++;
+                     if ( exp >= EXP_OVER )
+                       goto overflow;
+                   }
+                 else
+                   {
+                     tmp.sigh &= 0xffffff00;
+                     tmp.sigh += 0x100;
+                   }
+               }
+             else
+               {
+                 tmp.sigh &= 0xffffff00;  /* Finish the truncation */
+               }
+           }
+         else
+           precision_loss = 0;
+      
+         templ = (tmp.sigh >> 8) & 0x007fffff;
+
+         if ( exp > SINGLE_Emax )
+           {
+           overflow:
+             EXCEPTION(EX_Overflow);
+             if ( !(control_word & CW_Overflow) )
+               return 0;
+             set_precision_flag_up();
+             if ( !(control_word & CW_Precision) )
+               return 0;
+
+             /* This is a special case: see sec 16.2.5.1 of the 80486 book. */
+             /* Masked response is overflow to infinity. */
+             templ = 0x7f800000;
+           }
+         else
+           {
+             if ( precision_loss )
+               {
+                 if ( increment )
+                   set_precision_flag_up();
+                 else
+                   set_precision_flag_down();
+               }
+             /* Add the exponent */
+             templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
+           }
+       }
+    }
+  else if (st0_tag == TAG_Zero)
+    {
+      templ = 0;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if (st0_tag == TW_Denormal)
+       {
+         reg_copy(st0_ptr, &tmp);
+
+         /* A denormal will always underflow. */
+#ifndef PECULIAR_486
+         /* An 80486 is supposed to be able to generate
+            a denormal exception here, but... */
+         /* Underflow has priority. */
+         if ( control_word & CW_Underflow )
+           denormal_operand();
+#endif /* PECULIAR_486 */
+         goto denormal_arg;
+       }
+      else if (st0_tag == TW_Infinity)
+       {
+         templ = 0x7f800000;
+       }
+      else if (st0_tag == TW_NaN)
+       {
+         /* Is it really a NaN ? */
+         if ( (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000) )
+           {
+             /* See if we can get a valid NaN from the FPU_REG */
+             templ = st0_ptr->sigh >> 8;
+             if ( !(st0_ptr->sigh & 0x40000000) )
+               {
+                 /* It is a signalling NaN */
+                 EXCEPTION(EX_Invalid);
+                 if ( !(control_word & CW_Invalid) )
+                   return 0;
+                 templ |= (0x40000000 >> 8);
+               }
+             templ |= 0x7f800000;
+           }
+         else
+           {
+             /* It is an unsupported data type */
+             EXCEPTION(EX_Invalid);
+             if ( !(control_word & CW_Invalid) )
+               return 0;
+             templ = 0xffc00000;
+           }
+       }
+#ifdef PARANOID
+      else
+       {
+         EXCEPTION(EX_INTERNAL|0x164);
+         return 0;
+       }
+#endif
+    }
+  else if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      if ( control_word & EX_Invalid )
+       {
+         /* The masked response */
+         /* Put out the QNaN indefinite */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_verify_area(VERIFY_WRITE,(void *)single,4);
+         FPU_put_user(0xffc00000, (u32 *) single);
+         RE_ENTRANT_CHECK_ON;
+         return 1;
+       }
+      else
+       return 0;
+    }
+#ifdef PARANOID
+  else
+    {
+      EXCEPTION(EX_INTERNAL|0x163);
+      return 0;
+    }
+#endif
+  if ( getsign(st0_ptr) )
+    templ |= 0x80000000;
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,(void *)single,4);
+  FPU_put_user(templ,(u32 *) single);
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+
+/* Put a 64bit quantity into user memory */
+int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, s64 *d)
+{
+  FPU_REG t;
+  s64 tll;
+  int precision_loss;
+
+  if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      goto invalid_operand;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if ( (st0_tag == TW_Infinity) ||
+          (st0_tag == TW_NaN) )
+       {
+         EXCEPTION(EX_Invalid);
+         goto invalid_operand;
+       }
+    }
+
+  reg_copy(st0_ptr, &t);
+  precision_loss = FPU_round_to_int(&t, st0_tag);
+#ifndef EMU_BIG_ENDIAN
+  ((u32 *)&tll)[0] = t.sigl;
+  ((u32 *)&tll)[1] = t.sigh;
+#else
+  ((u32 *)&tll)[0] = t.sigh;
+  ((u32 *)&tll)[1] = t.sigl;
+#endif
+  if ( (precision_loss == 1) ||
+      ((t.sigh & 0x80000000) &&
+       !((t.sigh == 0x80000000) && (t.sigl == 0) &&
+        signnegative(&t))) )
+    {
+      EXCEPTION(EX_Invalid);
+      /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+    invalid_operand:
+      if ( control_word & EX_Invalid )
+       {
+         /* Produce something like QNaN "indefinite" */
+         tll = BX_CONST64(0x8000000000000000);
+       }
+      else
+       return 0;
+    }
+  else
+    {
+      if ( precision_loss )
+       set_precision_flag(precision_loss);
+      if ( signnegative(&t) )
+       tll = - tll;
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,(void *)d,8);
+#ifndef USE_WITH_CPU_SIM
+  copy_to_user(d, &tll, 8);
+#else
+  FPU_put_user((u32) tll,       (u32*)(((u8 *)d)+0));
+  FPU_put_user((u32) (tll>>32), (u32*)(((u8 *)d)+4));
+#endif
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+
+/* Put a long into user memory */
+int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, s32 *d)
+{
+  FPU_REG t;
+  int precision_loss;
+
+  if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      goto invalid_operand;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if ( (st0_tag == TW_Infinity) ||
+          (st0_tag == TW_NaN) )
+       {
+         EXCEPTION(EX_Invalid);
+         goto invalid_operand;
+       }
+    }
+
+  reg_copy(st0_ptr, &t);
+  precision_loss = FPU_round_to_int(&t, st0_tag);
+  if (t.sigh ||
+      ((t.sigl & 0x80000000) &&
+       !((t.sigl == 0x80000000) && signnegative(&t))) )
+    {
+      EXCEPTION(EX_Invalid);
+      /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+    invalid_operand:
+      if ( control_word & EX_Invalid )
+       {
+         /* Produce something like QNaN "indefinite" */
+         t.sigl = 0x80000000;
+       }
+      else
+       return 0;
+    }
+  else
+    {
+      if ( precision_loss )
+       set_precision_flag(precision_loss);
+      if ( signnegative(&t) )
+       t.sigl = -(s32)t.sigl;
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,d,4);
+  FPU_put_user(t.sigl, (u32 *) d);
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+
+/* Put a short into user memory */
+int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, s16 *d)
+{
+  FPU_REG t;
+  int precision_loss;
+
+  if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      goto invalid_operand;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if ( (st0_tag == TW_Infinity) ||
+          (st0_tag == TW_NaN) )
+       {
+         EXCEPTION(EX_Invalid);
+         goto invalid_operand;
+       }
+    }
+
+  reg_copy(st0_ptr, &t);
+  precision_loss = FPU_round_to_int(&t, st0_tag);
+  if (t.sigh ||
+      ((t.sigl & 0xffff8000) &&
+       !((t.sigl == 0x8000) && signnegative(&t))) )
+    {
+      EXCEPTION(EX_Invalid);
+      /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+    invalid_operand:
+      if ( control_word & EX_Invalid )
+       {
+         /* Produce something like QNaN "indefinite" */
+         t.sigl = 0x8000;
+       }
+      else
+       return 0;
+    }
+  else
+    {
+      if ( precision_loss )
+       set_precision_flag(precision_loss);
+      if ( signnegative(&t) )
+       t.sigl = -t.sigl;
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,d,2);
+  FPU_put_user((s16)t.sigl,(s16 *) d);
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+
+/* Put a packed bcd array into user memory */
+int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
+{
+  FPU_REG t;
+  u64 ll;
+  u_char b;
+  int i, precision_loss;
+  u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;
+
+  if ( st0_tag == TAG_Empty )
+    {
+      /* Empty register (stack underflow) */
+      EXCEPTION(EX_StackUnder);
+      goto invalid_operand;
+    }
+  else if ( st0_tag == TAG_Special )
+    {
+      st0_tag = FPU_Special(st0_ptr);
+      if ( (st0_tag == TW_Infinity) ||
+          (st0_tag == TW_NaN) )
+       {
+         EXCEPTION(EX_Invalid);
+         goto invalid_operand;
+       }
+    }
+
+  reg_copy(st0_ptr, &t);
+  precision_loss = FPU_round_to_int(&t, st0_tag);
+  ll = significand(&t);
+
+  /* Check for overflow, by comparing with 999999999999999999 decimal. */
+  if ( (t.sigh > 0x0de0b6b3) ||
+      ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff)) )
+    {
+      EXCEPTION(EX_Invalid);
+      /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+    invalid_operand:
+      if ( control_word & CW_Invalid )
+       {
+         /* Produce the QNaN "indefinite" */
+         RE_ENTRANT_CHECK_OFF;
+         FPU_verify_area(VERIFY_WRITE,d,10);
+         for ( i = 0; i < 7; i++)
+           FPU_put_user(0, (u_char *) d+i); /* These bytes "undefined" */
+         FPU_put_user(0xc0, (u_char *) d+7); /* This byte "undefined" */
+         FPU_put_user(0xff, (u_char *) d+8);
+         FPU_put_user(0xff, (u_char *) d+9);
+         RE_ENTRANT_CHECK_ON;
+         return 1;
+       }
+      else
+       return 0;
+    }
+  else if ( precision_loss )
+    {
+      /* Precision loss doesn't stop the data transfer */
+      set_precision_flag(precision_loss);
+    }
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,d,10);
+  RE_ENTRANT_CHECK_ON;
+  for ( i = 0; i < 9; i++)
+    {
+      b = FPU_div_small(&ll, 10);
+      b |= (FPU_div_small(&ll, 10)) << 4;
+      RE_ENTRANT_CHECK_OFF;
+      FPU_put_user(b,(u_char *) d+i);
+      RE_ENTRANT_CHECK_ON;
+    }
+  RE_ENTRANT_CHECK_OFF;
+  FPU_put_user(sign,(u_char *) d+9);
+  RE_ENTRANT_CHECK_ON;
+
+  return 1;
+}
+
+/*===========================================================================*/
+
+/* r gets mangled such that sig is int, sign: 
+   it is NOT normalized */
+/* The return value (in eax) is zero if the result is exact,
+   if bits are changed due to rounding, truncation, etc, then
+   a non-zero value is returned */
+/* Overflow is signalled by a non-zero return value (in eax).
+   In the case of overflow, the returned significand always has the
+   largest possible value */
+int FPU_round_to_int(FPU_REG *r, u_char tag)
+{
+  u_char     very_big;
+  unsigned eax;
+
+  if (tag == TAG_Zero)
+    {
+      /* Make sure that zero is returned */
+      significand(r) = 0;
+      return 0;        /* o.k. */
+    }
+
+  if (exponent(r) > 63)
+    {
+      r->sigl = r->sigh = ~0;      /* The largest representable number */
+      return 1;        /* overflow */
+    }
+
+#ifndef EMU_BIG_ENDIAN
+  eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
+#else
+  eax = FPU_shrxs(&r->sigh, 63 - exponent(r));
+#endif
+  very_big = !(~(r->sigh) | ~(r->sigl));  /* test for 0xfff...fff */
+#define        half_or_more    (eax & 0x80000000)
+#define        frac_part       (eax)
+#define more_than_half  ((eax & 0x80000001) == 0x80000001)
+  switch (control_word & CW_RC)
+    {
+    case RC_RND:
+      if ( more_than_half                      /* nearest */
+         || (half_or_more && (r->sigl & 1)) )  /* odd -> even */
+       {
+         if ( very_big ) return 1;        /* overflow */
+         significand(r) ++;
+         return PRECISION_LOST_UP;
+       }
+      break;
+    case RC_DOWN:
+      if (frac_part && getsign(r))
+       {
+         if ( very_big ) return 1;        /* overflow */
+         significand(r) ++;
+         return PRECISION_LOST_UP;
+       }
+      break;
+    case RC_UP:
+      if (frac_part && !getsign(r))
+       {
+         if ( very_big ) return 1;        /* overflow */
+         significand(r) ++;
+         return PRECISION_LOST_UP;
+       }
+      break;
+    case RC_CHOP:
+      break;
+    }
+
+  return eax ? PRECISION_LOST_DOWN : 0;
+
+}
+
+/*===========================================================================*/
+
+u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
+{
+  u16 tag_word = 0;
+  u_char tag;
+  int i;
+
+  if ( (addr_modes.default_mode == VM86) ||
+      ((addr_modes.default_mode == PM16)
+      ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
+    {
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_READ, s, 0x0e);
+      FPU_get_user(control_word, (u16 *) s);
+      FPU_get_user(partial_status, (u16 *) (s+2));
+      FPU_get_user(tag_word, (u16 *) (s+4));
+      FPU_get_user(instruction_address.offset, (u16 *) (s+6));
+      FPU_get_user(instruction_address.selector, (u16 *) (s+8));
+      FPU_get_user(operand_address.offset, (u16 *) (s+0x0a));
+      FPU_get_user(operand_address.selector, (u16 *) (s+0x0c));
+      RE_ENTRANT_CHECK_ON;
+      s += 0x0e;
+      if ( addr_modes.default_mode == VM86 )
+       {
+         instruction_address.offset
+           += (instruction_address.selector & 0xf000) << 4;
+         operand_address.offset += (operand_address.selector & 0xf000) << 4;
+       }
+    }
+  else
+    {
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_READ, s, 0x1c);
+      FPU_get_user(control_word, (u16 *) s);
+      FPU_get_user(partial_status, (u16 *) (s+4));
+      FPU_get_user(tag_word, (u16 *) (s+8));
+      FPU_get_user(instruction_address.offset, (u32 *) (s+0x0c));
+      FPU_get_user(instruction_address.selector, (u16 *) (s+0x10));
+      FPU_get_user(instruction_address.opcode, (u16 *) (s+0x12));
+      FPU_get_user(operand_address.offset, (u32 *) (s+0x14));
+      FPU_get_user(operand_address.selector, (u32 *) (s+0x18));
+      RE_ENTRANT_CHECK_ON;
+      s += 0x1c;
+    }
+
+#ifdef PECULIAR_486
+  control_word &= ~0xe080;
+#endif /* PECULIAR_486 */
+
+  top = (partial_status >> SW_Top_Shift) & 7;
+
+  if ( partial_status & ~control_word & CW_Exceptions )
+    partial_status |= (SW_Summary | SW_Backward);
+  else
+    partial_status &= ~(SW_Summary | SW_Backward);
+
+  for ( i = 0; i < 8; i++ )
+    {
+      tag = tag_word & 3;
+      tag_word >>= 2;
+
+      if ( tag == TAG_Empty )
+       /* New tag is empty.  Accept it */
+       FPU_settag(i, TAG_Empty);
+      else if ( FPU_gettag(i) == TAG_Empty )
+       {
+         /* Old tag is empty and new tag is not empty.  New tag is determined
+            by old reg contents */
+         if ( exponent(&fpu_register(i)) == - EXTENDED_Ebias )
+           {
+             if ( !(fpu_register(i).sigl | fpu_register(i).sigh) )
+               FPU_settag(i, TAG_Zero);
+             else
+               FPU_settag(i, TAG_Special);
+           }
+         else if ( exponent(&fpu_register(i)) == 0x7fff - EXTENDED_Ebias )
+           {
+             FPU_settag(i, TAG_Special);
+           }
+         else if ( fpu_register(i).sigh & 0x80000000 )
+           FPU_settag(i, TAG_Valid);
+         else
+           FPU_settag(i, TAG_Special);   /* An Un-normal */
+       }
+      /* Else old tag is not empty and new tag is not empty.  Old tag
+        remains correct */
+    }
+
+  return s;
+}
+
+
+void frstor(fpu_addr_modes addr_modes, u_char *data_address)
+{
+  int i, regnr;
+  u_char *s = fldenv(addr_modes, data_address);
+  int offset = (top & 7) * sizeof(FPU_REG), other = 8*sizeof(FPU_REG) - offset;
+
+  /* Copy all registers in stack order. */
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_READ,s,80);
+#ifndef USE_WITH_CPU_SIM
+  __copy_from_user(register_base+offset, s, other);
+  if ( offset )
+    __copy_from_user(register_base, s+other, offset);
+#else
+  {
+  FPU_REG *fpu_reg_p;
+
+  fpu_reg_p = (FPU_REG *) (register_base+offset);
+  while (other>0) {
+    FPU_get_user(fpu_reg_p->sigl, (u32*)(s+0));
+    FPU_get_user(fpu_reg_p->sigh, (u32*)(s+4));
+    FPU_get_user(fpu_reg_p->exp,  (u16*)(s+8));
+    fpu_reg_p++;
+    s += 10;
+    other -= sizeof(FPU_REG);
+    }
+  fpu_reg_p = (FPU_REG *) register_base;
+  while (offset>0) {
+    FPU_get_user(fpu_reg_p->sigl, (u32*)(s+0));
+    FPU_get_user(fpu_reg_p->sigh, (u32*)(s+4));
+    FPU_get_user(fpu_reg_p->exp,  (u16*)(s+8));
+    fpu_reg_p++;
+    s += 10;
+    offset -= sizeof(FPU_REG);
+    }
+  }
+#endif
+  RE_ENTRANT_CHECK_ON;
+
+  for ( i = 0; i < 8; i++ )
+    {
+      regnr = (i+top) & 7;
+      if ( FPU_gettag(regnr) != TAG_Empty )
+       /* The loaded data over-rides all other cases. */
+       FPU_settag(regnr, FPU_tagof(&st(i)));
+    }
+
+}
+
+
+u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
+{
+  if ( (addr_modes.default_mode == VM86) ||
+      ((addr_modes.default_mode == PM16)
+      ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
+    {
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE,d,14);
+#ifdef PECULIAR_486
+      FPU_put_user(control_word & ~0xe080, (u32 *) d);
+#else
+      FPU_put_user(control_word, (u16 *) d);
+#endif /* PECULIAR_486 */
+      FPU_put_user(status_word(), (u16 *) (d+2));
+      FPU_put_user(fpu_tag_word, (u16 *) (d+4));
+      FPU_put_user(instruction_address.offset, (u16 *) (d+6));
+      FPU_put_user(operand_address.offset, (u16 *) (d+0x0a));
+      if ( addr_modes.default_mode == VM86 )
+       {
+         FPU_put_user((instruction_address.offset & 0xf0000) >> 4,
+                     (u16 *) (d+8));
+         FPU_put_user((operand_address.offset & 0xf0000) >> 4,
+                     (u16 *) (d+0x0c));
+       }
+      else
+       {
+         FPU_put_user(instruction_address.selector, (u16 *) (d+8));
+         FPU_put_user(operand_address.selector, (u16 *) (d+0x0c));
+       }
+      RE_ENTRANT_CHECK_ON;
+      d += 0x0e;
+    }
+  else
+    {
+      RE_ENTRANT_CHECK_OFF;
+      FPU_verify_area(VERIFY_WRITE, d, 7*4);
+#ifdef PECULIAR_486
+      control_word &= ~0xe080;
+      /* An 80486 sets nearly all of the reserved bits to 1. */
+      control_word |= 0xffff0040;
+      partial_status = status_word() | 0xffff0000;
+      fpu_tag_word |= 0xffff0000;
+      I387.soft.fcs &= ~0xf8000000;
+      I387.soft.fos |= 0xffff0000;
+#endif /* PECULIAR_486 */
+#ifndef USE_WITH_CPU_SIM
+      __copy_to_user(d, &control_word, 7*4);
+#else
+      FPU_put_user((u32) I387.soft.cwd, (u32*)(((u8 *)d)+0));
+      FPU_put_user((u32) I387.soft.swd, (u32*)(((u8 *)d)+4));
+      FPU_put_user((u32) I387.soft.twd, (u32*)(((u8 *)d)+8));
+      FPU_put_user((u32) I387.soft.fip, (u32*)(((u8 *)d)+12));
+      FPU_put_user((u32) I387.soft.fcs, (u32*)(((u8 *)d)+16));
+      FPU_put_user((u32) I387.soft.foo, (u32*)(((u8 *)d)+20));
+      FPU_put_user((u32) I387.soft.fos, (u32*)(((u8 *)d)+24));
+#endif
+      RE_ENTRANT_CHECK_ON;
+      d += 0x1c;
+    }
+  
+  control_word |= CW_Exceptions;
+  partial_status &= ~(SW_Summary | SW_Backward);
+
+  return d;
+}
+
+
+void fsave(fpu_addr_modes addr_modes, u_char *data_address)
+{
+  u_char *d;
+  int offset = (top & 7) * sizeof(FPU_REG), other = 8*sizeof(FPU_REG) - offset;
+
+  d = fstenv(addr_modes, data_address);
+
+  RE_ENTRANT_CHECK_OFF;
+  FPU_verify_area(VERIFY_WRITE,d,80);
+
+  /* Copy all registers in stack order. */
+#ifndef USE_WITH_CPU_SIM
+  __copy_to_user(d, register_base+offset, other);
+  if ( offset )
+    __copy_to_user(d+other, register_base, offset);
+#else
+  {
+  FPU_REG *fpu_reg_p;
+
+  fpu_reg_p = (FPU_REG *) (register_base+offset);
+  while (other>0) {
+    FPU_put_user(fpu_reg_p->sigl, (u32*)(d+0));
+    FPU_put_user(fpu_reg_p->sigh, (u32*)(d+4));
+    FPU_put_user(fpu_reg_p->exp,  (u16*)(d+8));
+    fpu_reg_p++;
+    d += 10;
+    other -= sizeof(FPU_REG);
+    }
+  fpu_reg_p = (FPU_REG *) register_base;
+  while (offset>0) {
+    FPU_put_user(fpu_reg_p->sigl, (u32*)(d+0));
+    FPU_put_user(fpu_reg_p->sigh, (u32*)(d+4));
+    FPU_put_user(fpu_reg_p->exp,  (u16*)(d+8));
+    fpu_reg_p++;
+    d += 10;
+    offset -= sizeof(FPU_REG);
+    }
+  }
+#endif
+  RE_ENTRANT_CHECK_ON;
+
+  finit();
+}
+
+/*===========================================================================*/
diff --git a/sid/component/bochs/fpu/reg_mul.c b/sid/component/bochs/fpu/reg_mul.c
new file mode 100644 (file)
index 0000000..04f68b7
--- /dev/null
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------+
+ |  reg_mul.c                                                                |
+ |                                                                           |
+ | Multiply one FPU_REG by another, put the result in a destination FPU_REG. |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1997                                              |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ | Returns the tag of the result if no exceptions or errors occurred.        |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_system.h"
+
+
+/*
+  Multiply two registers to give a register result.
+  The sources are st(deststnr) and (b,tagb,signb).
+  The destination is st(deststnr).
+  */
+/* This routine must be called with non-empty source registers */
+int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
+{
+  FPU_REG *a = &st(deststnr);
+  FPU_REG *dest = a;
+  u_char taga = FPU_gettagi(deststnr);
+  u_char saved_sign = getsign(dest);
+  u_char sign = (getsign(a) ^ getsign(b));
+  int tag;
+
+
+  if ( !(taga | tagb) )
+    {
+      /* Both regs Valid, this should be the most common case. */
+
+      tag = FPU_u_mul(a, b, dest, control_w, sign, exponent(a) + exponent(b));
+      if ( tag < 0 )
+       {
+         setsign(dest, saved_sign);
+         return tag;
+       }
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+
+  if ( taga == TAG_Special )
+    taga = FPU_Special(a);
+  if ( tagb == TAG_Special )
+    tagb = FPU_Special(b);
+
+  if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+           || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+           || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+    {
+      FPU_REG x, y;
+      if ( denormal_operand() < 0 )
+       return FPU_Exception;
+
+      FPU_to_exp16(a, &x);
+      FPU_to_exp16(b, &y);
+      tag = FPU_u_mul(&x, &y, dest, control_w, sign,
+                     exponent16(&x) + exponent16(&y));
+      if ( tag < 0 )
+       {
+         setsign(dest, saved_sign);
+         return tag;
+       }
+      FPU_settagi(deststnr, tag);
+      return tag;
+    }
+  else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
+    {
+      if ( ((tagb == TW_Denormal) || (taga == TW_Denormal))
+          && (denormal_operand() < 0) )
+       return FPU_Exception;
+
+      /* Must have either both arguments == zero, or
+        one valid and the other zero.
+        The result is therefore zero. */
+      FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+      /* The 80486 book says that the answer is +0, but a real
+        80486 behaves this way.
+        IEEE-754 apparently says it should be this way. */
+      setsign(dest, sign);
+      return TAG_Zero;
+    }
+      /* Must have infinities, NaNs, etc */
+  else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+    {
+      return real_2op_NaN(b, tagb, deststnr, &st(0));
+    }
+  else if ( ((taga == TW_Infinity) && (tagb == TAG_Zero))
+           || ((tagb == TW_Infinity) && (taga == TAG_Zero)) )
+    {
+      return arith_invalid(deststnr);  /* Zero*Infinity is invalid */
+    }
+  else if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
+           && (denormal_operand() < 0) )
+    {
+      return FPU_Exception;
+    }
+  else if (taga == TW_Infinity)
+    {
+      FPU_copy_to_regi(a, TAG_Special, deststnr);
+      setsign(dest, sign);
+      return TAG_Special;
+    }
+  else if (tagb == TW_Infinity)
+    {
+      FPU_copy_to_regi(b, TAG_Special, deststnr);
+      setsign(dest, sign);
+      return TAG_Special;
+    }
+
+#ifdef PARANOID
+  else
+    {
+      EXCEPTION(EX_INTERNAL|0x102);
+      return FPU_Exception;
+    }
+#endif /* PARANOID */
+
+}
diff --git a/sid/component/bochs/fpu/reg_norm.S b/sid/component/bochs/fpu/reg_norm.S
new file mode 100644 (file)
index 0000000..65e6a69
--- /dev/null
@@ -0,0 +1,71 @@
+/*---------------------------------------------------------------------------+
+ |  reg_norm.S                                                               |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1997,1999                               |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | Normalize the value in a FPU_REG.                                         |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |    int FPU_normalize_nuo(FPU_REG *n, int bias)                            |
+ |                                                                           |
+ |    Return value is the tag of the answer.                                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+
+/* Normalise without reporting underflow or overflow */
+ENTRY(FPU_normalize_nuo)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %ebx
+
+       movl    PARAM1,%ebx
+
+       movl    SIGH(%ebx),%edx
+       movl    SIGL(%ebx),%eax
+
+       orl     %edx,%edx       /* ms bits */
+       js      L_exit_nuo_valid        /* Already normalized */
+       jnz     L_nuo_shift_1   /* Shift left 1 - 31 bits */
+
+       orl     %eax,%eax
+       jz      L_exit_nuo_zero         /* The contents are zero */
+
+       movl    %eax,%edx
+       xorl    %eax,%eax
+       subw    $32,EXP(%ebx)   /* This can cause an underflow */
+
+/* We need to shift left by 1 - 31 bits */
+L_nuo_shift_1:
+       bsrl    %edx,%ecx       /* get the required shift in %ecx */
+       subl    $31,%ecx
+       negl    %ecx
+       shld    %cl,%eax,%edx
+       shl     %cl,%eax
+       subw    %cx,EXP(%ebx)   /* This can cause an underflow */
+
+       movl    %edx,SIGH(%ebx)
+       movl    %eax,SIGL(%ebx)
+
+L_exit_nuo_valid:
+        movl    PARAM2,%eax
+        addw    %ax,EXP(%ebx)
+       movl    TAG_Valid,%eax
+
+       popl    %ebx
+       leave
+       ret
+
+L_exit_nuo_zero:
+       movw    EXP_UNDER,EXP(%ebx)
+        movl    PARAM2,%eax
+        addw    %ax,EXP(%ebx)
+        movl    TAG_Zero,%eax
+
+       popl    %ebx
+       leave
+       ret
diff --git a/sid/component/bochs/fpu/reg_norm.c b/sid/component/bochs/fpu/reg_norm.c
new file mode 100644 (file)
index 0000000..b08dbc8
--- /dev/null
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------+
+ |  reg_norm.c                                                               |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1997,1999                               |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | Normalize the value in a FPU_REG.                                         |
+ |                                                                           |
+ |                                                                           |
+ |    Return value is the tag of the answer.                                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+
+
+int FPU_normalize_nuo(FPU_REG *x, int bias)
+{
+
+  if ( ! (x->sigh & 0x80000000) )
+    {
+      if ( x->sigh == 0 )
+       {
+         if ( x->sigl == 0 )
+           {
+             x->exp = EXP_UNDER;
+             return TAG_Zero;
+           }
+         x->sigh = x->sigl;
+         x->sigl = 0;
+         x->exp -= 32;
+       }
+      while ( !(x->sigh & 0x80000000) )
+       {
+         x->sigh <<= 1;
+         if ( x->sigl & 0x80000000 )
+           x->sigh |= 1;
+         x->sigl <<= 1;
+         x->exp --;
+       }
+    }
+
+  x->exp += bias;
+
+  return TAG_Valid;
+}
diff --git a/sid/component/bochs/fpu/reg_round.S b/sid/component/bochs/fpu/reg_round.S
new file mode 100644 (file)
index 0000000..6e7bb24
--- /dev/null
@@ -0,0 +1,710 @@
+       .file "reg_round.S"
+/*---------------------------------------------------------------------------+
+ |  reg_round.S                                                              |
+ |                                                                           |
+ | Rounding/truncation/etc for FPU basic arithmetic functions.               |
+ |                                                                           |
+ | Copyright (C) 1993,1995,1997                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@suburbia.net               |
+ |                                                                           |
+ | This code has four possible entry points.                                 |
+ | The following must be entered by a jmp instruction:                       |
+ |   fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit.                  |
+ |                                                                           |
+ | The FPU_round entry point is intended to be used by C code.               |
+ | From C, call as:                                                          |
+ |  int FPU_round(FPU_REG *arg, unsigned int extent, unsigned int control_w) |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ | For correct "up" and "down" rounding, the argument must have the correct  |
+ | sign.                                                                     |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Four entry points.                                                        |
+ |                                                                           |
+ | Needed by both the fpu_reg_round and fpu_reg_round_sqrt entry points:     |
+ |  %eax:%ebx  64 bit significand                                            |
+ |  %edx       32 bit extension of the significand                           |
+ |  %edi       pointer to an FPU_REG for the result to be stored             |
+ |  stack      calling function must have set up a C stack frame and         |
+ |             pushed %esi, %edi, and %ebx                                   |
+ |                                                                           |
+ | Needed just for the fpu_reg_round_sqrt entry point:                       |
+ |  %cx  A control word in the same format as the FPU control word.          |
+ | Otherwise, PARAM4 must give such a value.                                 |
+ |                                                                           |
+ |                                                                           |
+ | The significand and its extension are assumed to be exact in the          |
+ | following sense:                                                          |
+ |   If the significand by itself is the exact result then the significand   |
+ |   extension (%edx) must contain 0, otherwise the significand extension    |
+ |   must be non-zero.                                                       |
+ |   If the significand extension is non-zero then the significand is        |
+ |   smaller than the magnitude of the correct exact result by an amount     |
+ |   greater than zero and less than one ls bit of the significand.          |
+ |   The significand extension is only required to have three possible       |
+ |   non-zero values:                                                        |
+ |       less than 0x80000000  <=> the significand is less than 1/2 an ls    |
+ |                                 bit smaller than the magnitude of the     |
+ |                                 true exact result.                        |
+ |         exactly 0x80000000  <=> the significand is exactly 1/2 an ls bit  |
+ |                                 smaller than the magnitude of the true    |
+ |                                 exact result.                             |
+ |    greater than 0x80000000  <=> the significand is more than 1/2 an ls    |
+ |                                 bit smaller than the magnitude of the     |
+ |                                 true exact result.                        |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |  The code in this module has become quite complex, but it should handle   |
+ |  all of the FPU flags which are set at this stage of the basic arithmetic |
+ |  computations.                                                            |
+ |  There are a few rare cases where the results are not set identically to  |
+ |  a real FPU. These require a bit more thought because at this stage the   |
+ |  results of the code here appear to be more consistent...                 |
+ |  This may be changed in a future version.                                 |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+
+/* Flags for FPU_bits_lost */
+#define        LOST_DOWN       $1
+#define        LOST_UP         $2
+
+/* Flags for FPU_denormal */
+#define        DENORMAL        $1
+#define        UNMASKED_UNDERFLOW $2
+
+
+#ifndef NON_REENTRANT_FPU
+/*     Make the code re-entrant by putting
+       local storage on the stack: */
+#define FPU_bits_lost  (%esp)
+#define FPU_denormal   1(%esp)
+
+#else
+/*     Not re-entrant, so we can gain speed by putting
+       local storage in a static area: */
+.data
+       .align 4,0
+FPU_bits_lost:
+       .byte   0
+FPU_denormal:
+       .byte   0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+.globl fpu_reg_round
+.globl fpu_reg_round_sqrt
+.globl fpu_Arith_exit
+
+/* Entry point when called from C */
+ENTRY(FPU_round)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%edi
+       movl    SIGH(%edi),%eax
+       movl    SIGL(%edi),%ebx
+       movl    PARAM2,%edx
+
+fpu_reg_round:                 /* Normal entry point */
+       movl    PARAM4,%ecx
+
+#ifndef NON_REENTRANT_FPU
+       pushl   %ebx            /* adjust the stack pointer */
+#endif /* NON_REENTRANT_FPU */
+
+#ifdef PARANOID
+/* Cannot use this here yet */
+/*     orl     %eax,%eax */
+/*     jns     L_entry_bugged */
+#endif /* PARANOID */
+
+       cmpw    EXP_UNDER,EXP(%edi)
+       jle     L_Make_denorm                   /* The number is a de-normal */
+
+       movb    $0,FPU_denormal                 /* 0 -> not a de-normal */
+
+Denorm_done:
+       movb    $0,FPU_bits_lost                /* No bits yet lost in rounding */
+
+       movl    %ecx,%esi
+       andl    CW_PC,%ecx
+       cmpl    PR_64_BITS,%ecx
+       je      LRound_To_64
+
+       cmpl    PR_53_BITS,%ecx
+       je      LRound_To_53
+
+       cmpl    PR_24_BITS,%ecx
+       je      LRound_To_24
+
+#ifdef PECULIAR_486
+/* With the precision control bits set to 01 "(reserved)", a real 80486
+   behaves as if the precision control bits were set to 11 "64 bits" */
+       cmpl    PR_RESERVED_BITS,%ecx
+       je      LRound_To_64
+#ifdef PARANOID
+       jmp     L_bugged_denorm_486
+#endif /* PARANOID */
+#else
+#ifdef PARANOID
+       jmp     L_bugged_denorm /* There is no bug, just a bad control word */
+#endif /* PARANOID */
+#endif /* PECULIAR_486 */
+
+
+/* Round etc to 24 bit precision */
+LRound_To_24:
+       movl    %esi,%ecx
+       andl    CW_RC,%ecx
+       cmpl    RC_RND,%ecx
+       je      LRound_nearest_24
+
+       cmpl    RC_CHOP,%ecx
+       je      LCheck_truncate_24
+
+       cmpl    RC_UP,%ecx              /* Towards +infinity */
+       je      LUp_24
+
+       cmpl    RC_DOWN,%ecx            /* Towards -infinity */
+       je      LDown_24
+
+#ifdef PARANOID
+       jmp     L_bugged_round24
+#endif /* PARANOID */
+
+LUp_24:
+       cmpb    SIGN_POS,PARAM5
+       jne     LCheck_truncate_24      /* If negative then  up==truncate */
+
+       jmp     LCheck_24_round_up
+
+LDown_24:
+       cmpb    SIGN_POS,PARAM5
+       je      LCheck_truncate_24      /* If positive then  down==truncate */
+
+LCheck_24_round_up:
+       movl    %eax,%ecx
+       andl    $0x000000ff,%ecx
+       orl     %ebx,%ecx
+       orl     %edx,%ecx
+       jnz     LDo_24_round_up
+       jmp     L_Re_normalise
+
+LRound_nearest_24:
+       /* Do rounding of the 24th bit if needed (nearest or even) */
+       movl    %eax,%ecx
+       andl    $0x000000ff,%ecx
+       cmpl    $0x00000080,%ecx
+       jc      LCheck_truncate_24      /* less than half, no increment needed */
+
+       jne     LGreater_Half_24        /* greater than half, increment needed */
+
+       /* Possibly half, we need to check the ls bits */
+       orl     %ebx,%ebx
+       jnz     LGreater_Half_24        /* greater than half, increment needed */
+
+       orl     %edx,%edx
+       jnz     LGreater_Half_24        /* greater than half, increment needed */
+
+       /* Exactly half, increment only if 24th bit is 1 (round to even) */
+       testl   $0x00000100,%eax
+       jz      LDo_truncate_24
+
+LGreater_Half_24:                      /* Rounding: increment at the 24th bit */
+LDo_24_round_up:
+       andl    $0xffffff00,%eax        /* Truncate to 24 bits */
+       xorl    %ebx,%ebx
+       movb    LOST_UP,FPU_bits_lost
+       addl    $0x00000100,%eax
+       jmp     LCheck_Round_Overflow
+
+LCheck_truncate_24:
+       movl    %eax,%ecx
+       andl    $0x000000ff,%ecx
+       orl     %ebx,%ecx
+       orl     %edx,%ecx
+       jz      L_Re_normalise          /* No truncation needed */
+
+LDo_truncate_24:
+       andl    $0xffffff00,%eax        /* Truncate to 24 bits */
+       xorl    %ebx,%ebx
+       movb    LOST_DOWN,FPU_bits_lost
+       jmp     L_Re_normalise
+
+
+/* Round etc to 53 bit precision */
+LRound_To_53:
+       movl    %esi,%ecx
+       andl    CW_RC,%ecx
+       cmpl    RC_RND,%ecx
+       je      LRound_nearest_53
+
+       cmpl    RC_CHOP,%ecx
+       je      LCheck_truncate_53
+
+       cmpl    RC_UP,%ecx              /* Towards +infinity */
+       je      LUp_53
+
+       cmpl    RC_DOWN,%ecx            /* Towards -infinity */
+       je      LDown_53
+
+#ifdef PARANOID
+       jmp     L_bugged_round53
+#endif /* PARANOID */
+
+LUp_53:
+       cmpb    SIGN_POS,PARAM5
+       jne     LCheck_truncate_53      /* If negative then  up==truncate */
+
+       jmp     LCheck_53_round_up
+
+LDown_53:
+       cmpb    SIGN_POS,PARAM5
+       je      LCheck_truncate_53      /* If positive then  down==truncate */
+
+LCheck_53_round_up:
+       movl    %ebx,%ecx
+       andl    $0x000007ff,%ecx
+       orl     %edx,%ecx
+       jnz     LDo_53_round_up
+       jmp     L_Re_normalise
+
+LRound_nearest_53:
+       /* Do rounding of the 53rd bit if needed (nearest or even) */
+       movl    %ebx,%ecx
+       andl    $0x000007ff,%ecx
+       cmpl    $0x00000400,%ecx
+       jc      LCheck_truncate_53      /* less than half, no increment needed */
+
+       jnz     LGreater_Half_53        /* greater than half, increment needed */
+
+       /* Possibly half, we need to check the ls bits */
+       orl     %edx,%edx
+       jnz     LGreater_Half_53        /* greater than half, increment needed */
+
+       /* Exactly half, increment only if 53rd bit is 1 (round to even) */
+       testl   $0x00000800,%ebx
+       jz      LTruncate_53
+
+LGreater_Half_53:                      /* Rounding: increment at the 53rd bit */
+LDo_53_round_up:
+       movb    LOST_UP,FPU_bits_lost
+       andl    $0xfffff800,%ebx        /* Truncate to 53 bits */
+       addl    $0x00000800,%ebx
+       adcl    $0,%eax
+       jmp     LCheck_Round_Overflow
+
+LCheck_truncate_53:
+       movl    %ebx,%ecx
+       andl    $0x000007ff,%ecx
+       orl     %edx,%ecx
+       jz      L_Re_normalise
+
+LTruncate_53:
+       movb    LOST_DOWN,FPU_bits_lost
+       andl    $0xfffff800,%ebx        /* Truncate to 53 bits */
+       jmp     L_Re_normalise
+
+
+/* Round etc to 64 bit precision */
+LRound_To_64:
+       movl    %esi,%ecx
+       andl    CW_RC,%ecx
+       cmpl    RC_RND,%ecx
+       je      LRound_nearest_64
+
+       cmpl    RC_CHOP,%ecx
+       je      LCheck_truncate_64
+
+       cmpl    RC_UP,%ecx              /* Towards +infinity */
+       je      LUp_64
+
+       cmpl    RC_DOWN,%ecx            /* Towards -infinity */
+       je      LDown_64
+
+#ifdef PARANOID
+       jmp     L_bugged_round64
+#endif /* PARANOID */
+
+LUp_64:
+       cmpb    SIGN_POS,PARAM5
+       jne     LCheck_truncate_64      /* If negative then  up==truncate */
+
+       orl     %edx,%edx
+       jnz     LDo_64_round_up
+       jmp     L_Re_normalise
+
+LDown_64:
+       cmpb    SIGN_POS,PARAM5
+       je      LCheck_truncate_64      /* If positive then  down==truncate */
+
+       orl     %edx,%edx
+       jnz     LDo_64_round_up
+       jmp     L_Re_normalise
+
+LRound_nearest_64:
+       cmpl    $0x80000000,%edx
+       jc      LCheck_truncate_64
+
+       jne     LDo_64_round_up
+
+       /* Now test for round-to-even */
+       testb   $1,%bl
+       jz      LCheck_truncate_64
+
+LDo_64_round_up:
+       movb    LOST_UP,FPU_bits_lost
+       addl    $1,%ebx
+       adcl    $0,%eax
+
+LCheck_Round_Overflow:
+       jnc     L_Re_normalise
+
+       /* Overflow, adjust the result (significand to 1.0) */
+       rcrl    $1,%eax
+       rcrl    $1,%ebx
+       incw    EXP(%edi)
+       jmp     L_Re_normalise
+
+LCheck_truncate_64:
+       orl     %edx,%edx
+       jz      L_Re_normalise
+
+LTruncate_64:
+       movb    LOST_DOWN,FPU_bits_lost
+
+L_Re_normalise:
+       testb   $0xff,FPU_denormal
+       jnz     Normalise_result
+
+L_Normalised:
+       movl    TAG_Valid,%edx
+
+L_deNormalised:
+       cmpb    LOST_UP,FPU_bits_lost
+       je      L_precision_lost_up
+
+       cmpb    LOST_DOWN,FPU_bits_lost
+       je      L_precision_lost_down
+
+L_no_precision_loss:
+       /* store the result */
+
+L_Store_significand:
+       movl    %eax,SIGH(%edi)
+       movl    %ebx,SIGL(%edi)
+
+       cmpw    EXP_OVER,EXP(%edi)
+       jge     L_overflow
+
+       movl    %edx,%eax
+
+       /* Convert the exponent to 80x87 form. */
+       addw    EXTENDED_Ebias,EXP(%edi)
+       andw    $0x7fff,EXP(%edi)
+
+fpu_reg_round_signed_special_exit:
+
+       cmpb    SIGN_POS,PARAM5
+       je      fpu_reg_round_special_exit
+
+       orw     $0x8000,EXP(%edi)       /* Negative sign for the result. */
+
+fpu_reg_round_special_exit:
+
+#ifndef NON_REENTRANT_FPU
+       popl    %ebx            /* adjust the stack pointer */
+#endif /* NON_REENTRANT_FPU */
+
+fpu_Arith_exit:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       leave
+       ret
+
+
+/*
+ * Set the FPU status flags to represent precision loss due to
+ * round-up.
+ */
+L_precision_lost_up:
+       push    %edx
+       push    %eax
+       call    SYMBOL_NAME(set_precision_flag_up)
+       popl    %eax
+       popl    %edx
+       jmp     L_no_precision_loss
+
+/*
+ * Set the FPU status flags to represent precision loss due to
+ * truncation.
+ */
+L_precision_lost_down:
+       push    %edx
+       push    %eax
+       call    SYMBOL_NAME(set_precision_flag_down)
+       popl    %eax
+       popl    %edx
+       jmp     L_no_precision_loss
+
+
+/*
+ * The number is a denormal (which might get rounded up to a normal)
+ * Shift the number right the required number of bits, which will
+ * have to be undone later...
+ */
+L_Make_denorm:
+       /* The action to be taken depends upon whether the underflow
+          exception is masked */
+       testb   CW_Underflow,%cl                /* Underflow mask. */
+       jz      Unmasked_underflow              /* Do not make a denormal. */
+
+       movb    DENORMAL,FPU_denormal
+
+       pushl   %ecx            /* Save */
+       movw    EXP_UNDER+1,%cx
+       subw    EXP(%edi),%cx
+
+       cmpw    $64,%cx /* shrd only works for 0..31 bits */
+       jnc     Denorm_shift_more_than_63
+
+       cmpw    $32,%cx /* shrd only works for 0..31 bits */
+       jnc     Denorm_shift_more_than_32
+
+/*
+ * We got here without jumps by assuming that the most common requirement
+ *   is for a small de-normalising shift.
+ * Shift by [1..31] bits
+ */
+       addw    %cx,EXP(%edi)
+       orl     %edx,%edx       /* extension */
+       setne   %ch             /* Save whether %edx is non-zero */
+       xorl    %edx,%edx
+       shrd    %cl,%ebx,%edx
+       shrd    %cl,%eax,%ebx
+       shr     %cl,%eax
+       orb     %ch,%dl
+       popl    %ecx
+       jmp     Denorm_done
+
+/* Shift by [32..63] bits */
+Denorm_shift_more_than_32:
+       addw    %cx,EXP(%edi)
+       subb    $32,%cl
+       orl     %edx,%edx
+       setne   %ch
+       orb     %ch,%bl
+       xorl    %edx,%edx
+       shrd    %cl,%ebx,%edx
+       shrd    %cl,%eax,%ebx
+       shr     %cl,%eax
+       orl     %edx,%edx               /* test these 32 bits */
+       setne   %cl
+       orb     %ch,%bl
+       orb     %cl,%bl
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       popl    %ecx
+       jmp     Denorm_done
+
+/* Shift by [64..) bits */
+Denorm_shift_more_than_63:
+       cmpw    $64,%cx
+       jne     Denorm_shift_more_than_64
+
+/* Exactly 64 bit shift */
+       addw    %cx,EXP(%edi)
+       xorl    %ecx,%ecx
+       orl     %edx,%edx
+       setne   %cl
+       orl     %ebx,%ebx
+       setne   %ch
+       orb     %ch,%cl
+       orb     %cl,%al
+       movl    %eax,%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       popl    %ecx
+       jmp     Denorm_done
+
+Denorm_shift_more_than_64:
+       movw    EXP_UNDER+1,EXP(%edi)
+/* This is easy, %eax must be non-zero, so.. */
+       movl    $1,%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       popl    %ecx
+       jmp     Denorm_done
+
+
+Unmasked_underflow:
+       movb    UNMASKED_UNDERFLOW,FPU_denormal
+       jmp     Denorm_done
+
+
+/* Undo the de-normalisation. */
+Normalise_result:
+       cmpb    UNMASKED_UNDERFLOW,FPU_denormal
+       je      Signal_underflow
+
+/* The number must be a denormal if we got here. */
+#ifdef PARANOID
+       /* But check it... just in case. */
+       cmpw    EXP_UNDER+1,EXP(%edi)
+       jne     L_norm_bugged
+#endif /* PARANOID */
+
+#ifdef PECULIAR_486
+       /*
+        * This implements a special feature of 80486 behaviour.
+        * Underflow will be signalled even if the number is
+        * not a denormal after rounding.
+        * This difference occurs only for masked underflow, and not
+        * in the unmasked case.
+        * Actual 80486 behaviour differs from this in some circumstances.
+        */
+       orl     %eax,%eax               /* ms bits */
+       js      LPseudoDenormal         /* Will be masked underflow */
+#else
+       orl     %eax,%eax               /* ms bits */
+       js      L_Normalised            /* No longer a denormal */
+#endif /* PECULIAR_486 */
+
+       jnz     LDenormal_adj_exponent
+
+       orl     %ebx,%ebx
+       jz      L_underflow_to_zero     /* The contents are zero */
+
+LDenormal_adj_exponent:
+       decw    EXP(%edi)
+
+LPseudoDenormal:
+       testb   $0xff,FPU_bits_lost     /* bits lost == underflow */
+       movl    TAG_Special,%edx
+       jz      L_deNormalised
+
+       /* There must be a masked underflow */
+       push    %eax
+       pushl   EX_Underflow
+       call    EXCEPTION
+       popl    %eax
+       popl    %eax
+       movl    TAG_Special,%edx
+       jmp     L_deNormalised
+
+
+/*
+ * The operations resulted in a number too small to represent.
+ * Masked response.
+ */
+L_underflow_to_zero:
+       push    %eax
+       call    SYMBOL_NAME(set_precision_flag_down)
+       popl    %eax
+
+       push    %eax
+       pushl   EX_Underflow
+       call    EXCEPTION
+       popl    %eax
+       popl    %eax
+
+/* Reduce the exponent to EXP_UNDER */
+       movw    EXP_UNDER,EXP(%edi)
+       movl    TAG_Zero,%edx
+       jmp     L_Store_significand
+
+
+/* The operations resulted in a number too large to represent. */
+L_overflow:
+        pushw   PARAM5
+       addw    EXTENDED_Ebias,EXP(%edi)        /* Set for unmasked response. */
+       push    %edi
+        call    SYMBOL_NAME(arith_round_overflow)
+       pop     %edi
+       jmp     fpu_reg_round_signed_special_exit
+
+
+Signal_underflow:
+       /* The number may have been changed to a non-denormal */
+       /* by the rounding operations. */
+       cmpw    EXP_UNDER,EXP(%edi)
+       jle     Do_unmasked_underflow
+
+       jmp     L_Normalised
+
+Do_unmasked_underflow:
+       /* Increase the exponent by the magic number */
+       addw    $(3*(1<<13)),EXP(%edi)
+       push    %eax
+       pushl   EX_Underflow
+       call    EXCEPTION
+       popl    %eax
+       popl    %eax
+       jmp     L_Normalised
+
+
+#ifdef PARANOID
+#ifdef PECULIAR_486
+L_bugged_denorm_486:
+       pushl   EX_INTERNAL|0x236
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+#else
+L_bugged_denorm:
+       pushl   EX_INTERNAL|0x230
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+#endif /* PECULIAR_486 */
+
+L_bugged_round24:
+       pushl   EX_INTERNAL|0x231
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+
+L_bugged_round53:
+       pushl   EX_INTERNAL|0x232
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+
+L_bugged_round64:
+       pushl   EX_INTERNAL|0x233
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+
+L_norm_bugged:
+       pushl   EX_INTERNAL|0x234
+       call    EXCEPTION
+       popl    %ebx
+       jmp     L_exception_exit
+
+L_entry_bugged:
+       pushl   EX_INTERNAL|0x235
+       call    EXCEPTION
+       popl    %ebx
+L_exception_exit:
+       mov     $-1,%eax
+       jmp     fpu_reg_round_special_exit
+#endif /* PARANOID */
diff --git a/sid/component/bochs/fpu/reg_round.c b/sid/component/bochs/fpu/reg_round.c
new file mode 100644 (file)
index 0000000..37af469
--- /dev/null
@@ -0,0 +1,538 @@
+/*---------------------------------------------------------------------------+
+ |  reg_round.c                                                              |
+ |                                                                           |
+ | Rounding/truncation/etc for FPU basic arithmetic functions.               |
+ |                                                                           |
+ | Copyright (C) 1993,1995,1997,1999                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | This code has four possible entry points.                                 |
+ | The following must be entered by a jmp instruction:                       |
+ |   fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit.                  |
+ |                                                                           |
+ | The FPU_round entry point is intended to be used by C code.               |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ | For correct "up" and "down" rounding, the argument must have the correct  |
+ | sign.                                                                     |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |                                                                           |
+ | The significand and its extension are assumed to be exact in the          |
+ | following sense:                                                          |
+ |   If the significand by itself is the exact result then the significand   |
+ |   extension (%edx) must contain 0, otherwise the significand extension    |
+ |   must be non-zero.                                                       |
+ |   If the significand extension is non-zero then the significand is        |
+ |   smaller than the magnitude of the correct exact result by an amount     |
+ |   greater than zero and less than one ls bit of the significand.          |
+ |   The significand extension is only required to have three possible       |
+ |   non-zero values:                                                        |
+ |       less than 0x80000000  <=> the significand is less than 1/2 an ls    |
+ |                                 bit smaller than the magnitude of the     |
+ |                                 true exact result.                        |
+ |         exactly 0x80000000  <=> the significand is exactly 1/2 an ls bit  |
+ |                                 smaller than the magnitude of the true    |
+ |                                 exact result.                             |
+ |    greater than 0x80000000  <=> the significand is more than 1/2 an ls    |
+ |                                 bit smaller than the magnitude of the     |
+ |                                 true exact result.                        |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |  The code in this module has become quite complex, but it should handle   |
+ |  all of the FPU flags which are set at this stage of the basic arithmetic |
+ |  computations.                                                            |
+ |  There are a few rare cases where the results are not set identically to  |
+ |  a real FPU. These require a bit more thought because at this stage the   |
+ |  results of the code here appear to be more consistent...                 |
+ |  This may be changed in a future version.                                 |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+
+/* Flags for FPU_bits_lost */
+#define        LOST_DOWN       1
+#define        LOST_UP         2
+
+/* Flags for FPU_denormal */
+#define        DENORMAL        1
+#define        UNMASKED_UNDERFLOW 2
+
+
+int round_up_64(FPU_REG *x, u32 extent)
+{
+  x->sigl ++;
+  if ( x->sigl == 0 )
+    {
+      x->sigh ++;
+      if ( x->sigh == 0 )
+       {
+         x->sigh = 0x80000000;
+         x->exp ++;
+       }
+    }
+  return LOST_UP;
+}
+
+
+int truncate_64(FPU_REG *x, u32 extent)
+{
+  return LOST_DOWN;
+}
+
+
+int round_up_53(FPU_REG *x, u32 extent)
+{
+  x->sigl &= 0xfffff800;
+  x->sigl += 0x800;
+  if ( x->sigl == 0 )
+    {
+      x->sigh ++;
+      if ( x->sigh == 0 )
+       {
+         x->sigh = 0x80000000;
+         x->exp ++;
+       }
+    }
+  return LOST_UP;
+}
+
+
+int truncate_53(FPU_REG *x, u32 extent)
+{
+  x->sigl &= 0xfffff800;
+  return LOST_DOWN;
+}
+
+
+int round_up_24(FPU_REG *x, u32 extent)
+{
+  x->sigl = 0;
+  x->sigh &= 0xffffff00;
+  x->sigh += 0x100;
+  if ( x->sigh == 0 )
+    {
+      x->sigh = 0x80000000;
+      x->exp ++;
+    }
+  return LOST_UP;
+}
+
+
+int truncate_24(FPU_REG *x, u32 extent)
+{
+  x->sigl = 0;
+  x->sigh &= 0xffffff00;
+  return LOST_DOWN;
+}
+
+
+int FPU_round(FPU_REG *x, u32 extent, int dummy, u16 control_w, u8 sign)
+{
+  u64 work;
+  u32 leading;
+  s16 expon = x->exp;
+  int FPU_bits_lost = 0, FPU_denormal, shift, tag;
+
+  if ( expon <= EXP_UNDER )
+    {
+      /* A denormal or zero */
+      if ( control_w & CW_Underflow )
+       {
+         /* Underflow is masked. */
+         FPU_denormal = DENORMAL;
+         shift = EXP_UNDER+1 - expon;
+         if ( shift >= 64 )
+           {
+             if ( shift == 64 )
+               {
+                 x->exp += 64;
+                 if ( extent | x->sigl )
+                   extent = x->sigh | 1;
+                 else
+                   extent = x->sigh;
+               }
+             else
+               {
+                 x->exp = EXP_UNDER+1;
+                 extent = 1;
+               }
+             significand(x) = 0;
+           }
+         else
+           {
+             x->exp += shift;
+             if ( shift >= 32 )
+               {
+                 shift -= 32;
+                 if ( shift )
+                   {
+                     extent |= x->sigl;
+                     work = significand(x) >> shift;
+                     if ( extent )
+                       extent = work | 1;
+                     else
+                       extent = work;
+                     x->sigl = x->sigh >>= shift;
+                   }
+                 else
+                   {
+                     if ( extent )
+                       extent = x->sigl | 1;
+                     else
+                       extent = x->sigl;
+                     x->sigl = x->sigh;
+                   }
+                 x->sigh = 0;
+               }
+             else
+               {
+                 /* Shift by 1 to 32 places. */
+                 work = x->sigl;
+                 work <<= 32;
+                 work |= extent;
+                 work >>= shift;
+                 if ( extent )
+                   extent = 1;
+                 extent |= work;
+                 significand(x) >>= shift;
+               }
+           }
+       }
+      else
+       {
+         /* Unmasked underflow. */
+         FPU_denormal = UNMASKED_UNDERFLOW;
+       }
+    }
+  else
+    FPU_denormal = 0;
+
+  switch ( control_w & CW_PC )
+    {
+    case 01:
+#ifndef PECULIAR_486
+      /* With the precision control bits set to 01 "(reserved)", a real 80486
+        behaves as if the precision control bits were set to 11 "64 bits" */
+#ifdef PARANOID
+       EXCEPTION(EX_INTERNAL|0x236);
+       return -1;
+#endif
+#endif
+       /* Fall through to the 64 bit case. */
+    case PR_64_BITS:
+      if ( extent )
+       {
+         switch ( control_w & CW_RC )
+           {
+           case RC_RND:                /* Nearest or even */
+             /* See if there is exactly half a ulp. */
+             if ( extent == 0x80000000 )
+               {
+                 /* Round to even. */
+                 if ( x->sigl & 0x1 )
+                   /* Odd */
+                   FPU_bits_lost = round_up_64(x, extent);
+                 else
+                   /* Even */
+                   FPU_bits_lost = truncate_64(x, extent);
+               }
+             else if ( extent > 0x80000000 )
+               {
+                 /* Greater than half */
+                 FPU_bits_lost = round_up_64(x, extent);
+               }
+             else
+               {
+                 /* Less than half */
+                 FPU_bits_lost = truncate_64(x, extent);
+               }
+             break;
+
+           case RC_CHOP:               /* Truncate */
+             FPU_bits_lost = truncate_64(x, extent);
+             break;
+             
+           case RC_UP:         /* Towards +infinity */
+             if ( sign == SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_64(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_64(x, extent);
+               }
+             break;
+
+           case RC_DOWN:               /* Towards -infinity */
+             if ( sign != SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_64(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_64(x, extent);
+               }
+             break;
+
+           default:
+             EXCEPTION(EX_INTERNAL|0x231);
+             return -1;
+           }
+       }
+      break;
+
+    case PR_53_BITS:
+      leading = x->sigl & 0x7ff;
+      if ( extent || leading )
+       {
+         switch ( control_w & CW_RC )
+           {
+           case RC_RND:                /* Nearest or even */
+             /* See if there is exactly half a ulp. */
+             if ( leading == 0x400 )
+               {
+                 if ( extent == 0 )
+                   {
+                     /* Round to even. */
+                     if ( x->sigl & 0x800 )
+                       /* Odd */
+                       FPU_bits_lost = round_up_53(x, extent);
+                     else
+                       /* Even */
+                       FPU_bits_lost = truncate_53(x, extent);
+                   }
+                 else
+                   {
+                     /* Greater than half */
+                     FPU_bits_lost = round_up_53(x, extent);
+                   }
+               }
+             else if ( leading > 0x400 )
+               {
+                 /* Greater than half */
+                 FPU_bits_lost = round_up_53(x, extent);
+               }
+             else
+               {
+                 /* Less than half */
+                 FPU_bits_lost = truncate_53(x, extent);
+               }
+             break;
+
+           case RC_CHOP:               /* Truncate */
+             FPU_bits_lost = truncate_53(x, extent);
+             break;
+
+           case RC_UP:         /* Towards +infinity */
+             if ( sign == SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_53(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_53(x, extent);
+               }
+             break;
+
+           case RC_DOWN:               /* Towards -infinity */
+             if ( sign != SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_53(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_53(x, extent);
+               }
+             break;
+
+           default:
+             EXCEPTION(EX_INTERNAL|0x231);
+             return -1;
+           }
+       }
+      break;
+
+    case PR_24_BITS:
+      leading = x->sigh & 0xff;
+      if ( leading || x->sigl || extent )
+       {
+         switch ( control_w & CW_RC )
+           {
+           case RC_RND:                /* Nearest or even */
+             /* See if there is exactly half a ulp. */
+             if ( leading == 0x80 )
+               {
+                 if ( (x->sigl == 0) && (extent == 0) )
+                   {
+                     /* Round to even. */
+                     if ( x->sigh & 0x100 )
+                       /* Odd */
+                       FPU_bits_lost = round_up_24(x, extent);
+                     else
+                       /* Even */
+                       FPU_bits_lost = truncate_24(x, extent);
+                   }
+                 else
+                   {
+                     /* Greater than half */
+                     FPU_bits_lost = round_up_24(x, extent);
+                   }
+               }
+             else if ( leading > 0x80 )
+               {
+                 /* Greater than half */
+                 FPU_bits_lost = round_up_24(x, extent);
+               }
+             else
+               {
+                 /* Less than half */
+                 FPU_bits_lost = truncate_24(x, extent);
+               }
+             break;
+
+           case RC_CHOP:               /* Truncate */
+             FPU_bits_lost = truncate_24(x, extent);
+             break;
+
+           case RC_UP:         /* Towards +infinity */
+             if ( sign == SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_24(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_24(x, extent);
+               }
+             break;
+
+           case RC_DOWN:               /* Towards -infinity */
+             if ( sign != SIGN_POS)
+               {
+                 FPU_bits_lost = round_up_24(x, extent);
+               }
+             else
+               {
+                 FPU_bits_lost = truncate_24(x, extent);
+               }
+             break;
+
+           default:
+             EXCEPTION(EX_INTERNAL|0x231);
+             return -1;
+           }
+       }
+      break;
+
+    default:
+#ifdef PARANOID
+       EXCEPTION(EX_INTERNAL|0x230);
+       return -1;
+#endif
+      break;
+    }
+
+  tag = TAG_Valid;
+
+  if ( FPU_denormal )
+    {
+      /* Undo the de-normalisation. */
+      if ( FPU_denormal == UNMASKED_UNDERFLOW )
+       {
+         if ( x->exp <= EXP_UNDER )
+           {
+             /* Increase the exponent by the magic number */
+             x->exp += 3 * (1 << 13);
+             EXCEPTION(EX_Underflow);
+           }
+       }
+      else
+       {
+         if ( x->exp != EXP_UNDER+1 )
+           {
+             EXCEPTION(EX_INTERNAL|0x234);
+           }
+         if ( (x->sigh == 0) && (x->sigl == 0) )
+           {
+             /* Underflow to zero */
+             set_precision_flag_down();
+             EXCEPTION(EX_Underflow);
+             x->exp = EXP_UNDER;
+             tag = TAG_Zero;
+             FPU_bits_lost = 0;  /* Stop another call to
+                                    set_precision_flag_down() */
+           }
+         else
+           {
+             if ( x->sigh & 0x80000000 )
+               {
+#ifdef PECULIAR_486
+       /*
+        * This implements a special feature of 80486 behaviour.
+        * Underflow will be signalled even if the number is
+        * not a denormal after rounding.
+        * This difference occurs only for masked underflow, and not
+        * in the unmasked case.
+        * Actual 80486 behaviour differs from this in some circumstances.
+        */
+             /* Will be masked underflow */
+#else
+             /* No longer a denormal */
+#endif
+               }
+             else
+#ifndef PECULIAR_486
+               {
+#endif
+               x->exp --;
+
+             if ( FPU_bits_lost )
+               {
+                 /* There must be a masked underflow */
+                 EXCEPTION(EX_Underflow);
+               }
+
+             tag = TAG_Special;
+#ifndef PECULIAR_486
+               }
+#endif
+           }
+       }
+    }
+
+
+  if ( FPU_bits_lost == LOST_UP )
+    set_precision_flag_up();
+  else   if ( FPU_bits_lost == LOST_DOWN )
+    set_precision_flag_down();
+
+  if ( x->exp >= EXP_OVER )
+    {
+      x->exp += EXTENDED_Ebias;
+      tag = arith_round_overflow(x, sign);
+    }
+  else
+    {
+      x->exp += EXTENDED_Ebias;
+      x->exp &= 0x7fff;
+    }
+
+  if ( sign != SIGN_POS )
+    x->exp |= 0x8000;
+
+  return tag;
+
+}
+
+
+
diff --git a/sid/component/bochs/fpu/reg_u_add.S b/sid/component/bochs/fpu/reg_u_add.S
new file mode 100644 (file)
index 0000000..47c4c24
--- /dev/null
@@ -0,0 +1,167 @@
+       .file   "reg_u_add.S"
+/*---------------------------------------------------------------------------+
+ |  reg_u_add.S                                                              |
+ |                                                                           |
+ | Add two valid (TAG_Valid) FPU_REG numbers, of the same sign, and put the  |
+ |   result in a destination FPU_REG.                                        |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |   int  FPU_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,             |
+ |                                                int control_w)             |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*
+ |    Kernel addition routine FPU_u_add(reg *arg1, reg *arg2, reg *answ).
+ |    Takes two valid reg f.p. numbers (TAG_Valid), which are
+ |    treated as unsigned numbers,
+ |    and returns their sum as a TAG_Valid or TAG_Special f.p. number.
+ |    The returned number is normalized.
+ |    Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+.text
+ENTRY(FPU_u_add)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%esi             /* source 1 */
+       movl    PARAM2,%edi             /* source 2 */
+
+       movl    PARAM6,%ecx
+       movl    %ecx,%edx
+       subl    PARAM7,%ecx                     /* exp1 - exp2 */
+       jge     L_arg1_larger
+
+       /* num1 is smaller */
+       movl    SIGL(%esi),%ebx
+       movl    SIGH(%esi),%eax
+
+       movl    %edi,%esi
+       movl    PARAM7,%edx
+       negw    %cx
+       jmp     L_accum_loaded
+
+L_arg1_larger:
+       /* num1 has larger or equal exponent */
+       movl    SIGL(%edi),%ebx
+       movl    SIGH(%edi),%eax
+
+L_accum_loaded:
+       movl    PARAM3,%edi             /* destination */
+       movw    %dx,EXP(%edi)           /* Copy exponent to destination */
+
+       xorl    %edx,%edx               /* clear the extension */
+
+#ifdef PARANOID
+       testl   $0x80000000,%eax
+       je      L_bugged
+
+       testl   $0x80000000,SIGH(%esi)
+       je      L_bugged
+#endif /* PARANOID */
+
+/* The number to be shifted is in %eax:%ebx:%edx */
+       cmpw    $32,%cx         /* shrd only works for 0..31 bits */
+       jnc     L_more_than_31
+
+/* less than 32 bits */
+       shrd    %cl,%ebx,%edx
+       shrd    %cl,%eax,%ebx
+       shr     %cl,%eax
+       jmp     L_shift_done
+
+L_more_than_31:
+       cmpw    $64,%cx
+       jnc     L_more_than_63
+
+       subb    $32,%cl
+       jz      L_exactly_32
+
+       shrd    %cl,%eax,%edx
+       shr     %cl,%eax
+       orl     %ebx,%ebx
+       jz      L_more_31_no_low        /* none of the lowest bits is set */
+
+       orl     $1,%edx                 /* record the fact in the extension */
+
+L_more_31_no_low:
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       jmp     L_shift_done
+
+L_exactly_32:
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       jmp     L_shift_done
+
+L_more_than_63:
+       cmpw    $65,%cx
+       jnc     L_more_than_64
+
+       movl    %eax,%edx
+       orl     %ebx,%ebx
+       jz      L_more_63_no_low
+
+       orl     $1,%edx
+       jmp     L_more_63_no_low
+
+L_more_than_64:
+       movl    $1,%edx         /* The shifted nr always at least one '1' */
+
+L_more_63_no_low:
+       xorl    %ebx,%ebx
+       xorl    %eax,%eax
+
+L_shift_done:
+       /* Now do the addition */
+       addl    SIGL(%esi),%ebx
+       adcl    SIGH(%esi),%eax
+       jnc     L_round_the_result
+
+       /* Overflow, adjust the result */
+       rcrl    $1,%eax
+       rcrl    $1,%ebx
+       rcrl    $1,%edx
+       jnc     L_no_bit_lost
+
+       orl     $1,%edx
+
+L_no_bit_lost:
+       incw    EXP(%edi)
+
+L_round_the_result:
+       jmp     fpu_reg_round   /* Round the result */
+
+
+
+#ifdef PARANOID
+/* If we ever get here then we have problems! */
+L_bugged:
+       pushl   EX_INTERNAL|0x201
+       call    EXCEPTION
+       pop     %ebx
+       movl    $-1,%eax
+       jmp     L_exit
+
+L_exit:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       leave
+       ret
+#endif /* PARANOID */
diff --git a/sid/component/bochs/fpu/reg_u_add.c b/sid/component/bochs/fpu/reg_u_add.c
new file mode 100644 (file)
index 0000000..60a81b5
--- /dev/null
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------+
+ |  reg_u_add.c                                                              |
+ |                                                                           |
+ | Add two valid (TAG_Valid) FPU_REG numbers, of the same sign, and put the  |
+ |   result in a destination FPU_REG.                                        |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*
+ |    Kernel addition routine FPU_u_add(reg *arg1, reg *arg2, reg *answ).
+ |    Takes two valid reg f.p. numbers (TAG_Valid), which are
+ |    treated as unsigned numbers,
+ |    and returns their sum as a TAG_Valid or TAG_Special f.p. number.
+ |    The returned number is normalized.
+ |    Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+int  FPU_u_add(const FPU_REG *arg1, const FPU_REG *arg2, FPU_REG *answ,
+              u16 control_w, u_char sign, s32 expa, s32 expb)
+{
+  const FPU_REG *rtmp;
+  FPU_REG shifted;
+  u32 extent = 0;
+  int ediff = expa - expb, ed2, eflag, ovfl, carry;
+
+  if ( ediff < 0 )
+    {
+      ediff = -ediff;
+      rtmp = arg1;
+      arg1 = arg2;
+      arg2 = rtmp;
+      expa = expb;
+    }
+
+  /* Now we have exponent of arg1 >= exponent of arg2 */
+  
+  answ->exp = expa;
+
+#ifdef PARANOID
+  if ( !(arg1->sigh & 0x80000000) || !(arg2->sigh & 0x80000000) )
+    {
+      EXCEPTION(EX_INTERNAL|0x201);
+      return -1;
+    }
+#endif
+
+  if ( ediff == 0 )
+    {
+      extent = 0;
+      shifted.sigl = arg2->sigl;
+      shifted.sigh = arg2->sigh;
+    }
+  else if ( ediff < 32 )
+    {
+      ed2 = 32 - ediff;
+      extent = arg2->sigl << ed2;
+      shifted.sigl = arg2->sigl >> ediff;
+      shifted.sigl |= (arg2->sigh << ed2);
+      shifted.sigh = arg2->sigh >> ediff;
+    }
+  else if ( ediff < 64 )
+    {
+      ediff -= 32;
+      if ( ! ediff )
+       {
+         eflag = 0;
+         extent = arg2->sigl;
+         shifted.sigl = arg2->sigh;
+       }
+      else
+       {
+         ed2 = 32 - ediff;
+         eflag = arg2->sigl;
+         if ( eflag )
+           extent |= 1;
+         extent = arg2->sigl >> ediff;
+         extent |= (arg2->sigh << ed2);
+         shifted.sigl = arg2->sigh >> ediff;
+       }
+      shifted.sigh = 0;
+    }
+  else
+    {
+      ediff -= 64;
+      if ( ! ediff )
+       {
+         eflag = arg2->sigl;
+         extent = arg2->sigh;
+       }
+      else
+       {
+         ed2 = 64 - ediff;
+         eflag = arg2->sigl | arg2->sigh;
+         extent = arg2->sigh >> ediff;
+       }
+      shifted.sigl = 0;
+      shifted.sigh = 0;
+      if ( eflag )
+       extent |= 1;
+    }
+
+  answ->sigh = arg1->sigh + shifted.sigh;
+  ovfl = shifted.sigh > answ->sigh;
+  answ->sigl = arg1->sigl + shifted.sigl;
+  if ( shifted.sigl > answ->sigl )
+    {
+      answ->sigh ++;
+      if ( answ->sigh == 0 )
+       ovfl = 1;
+    }
+  if ( ovfl )
+    {
+      carry = extent & 1;
+      extent >>= 1;
+      extent |= carry;
+      if ( answ->sigl & 1 )
+       extent |= 0x80000000;
+      answ->sigl >>= 1;
+      if ( answ->sigh & 1 )
+       answ->sigl |= 0x80000000;
+      answ->sigh >>= 1;
+      answ->sigh |= 0x80000000;
+      answ->exp ++;
+    }
+
+  return FPU_round(answ, extent, 0, control_w, sign);
+
+}
diff --git a/sid/component/bochs/fpu/reg_u_div.S b/sid/component/bochs/fpu/reg_u_div.S
new file mode 100644 (file)
index 0000000..663fa7b
--- /dev/null
@@ -0,0 +1,473 @@
+       .file   "reg_u_div.S"
+/*---------------------------------------------------------------------------+
+ |  reg_u_div.S                                                              |
+ |                                                                           |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Call from C as:                                                           |
+ |    int FPU_u_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest,                   |
+ |                unsigned int control_word, char *sign)                     |
+ |                                                                           |
+ |  Does not compute the destination exponent, but does adjust it.           |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+/* #define     dSIGL(x)        (x) */
+/* #define     dSIGH(x)        4(x) */
+
+
+#ifndef NON_REENTRANT_FPU
+/*
+       Local storage on the stack:
+       Result:         FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+       Overflow flag:  ovfl_flag
+ */
+#define FPU_accum_3    -4(%ebp)
+#define FPU_accum_2    -8(%ebp)
+#define FPU_accum_1    -12(%ebp)
+#define FPU_accum_0    -16(%ebp)
+#define FPU_result_1   -20(%ebp)
+#define FPU_result_2   -24(%ebp)
+#define FPU_ovfl_flag  -28(%ebp)
+
+#else
+.data
+/*
+       Local storage in a static area:
+       Result:         FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+       Overflow flag:  ovfl_flag
+ */
+       .align 4,0
+FPU_accum_3:
+       .long   0
+FPU_accum_2:
+       .long   0
+FPU_accum_1:
+       .long   0
+FPU_accum_0:
+       .long   0
+FPU_result_1:
+       .long   0
+FPU_result_2:
+       .long   0
+FPU_ovfl_flag:
+       .byte   0
+#endif /* NON_REENTRANT_FPU */
+
+#define REGA   PARAM1
+#define REGB   PARAM2
+#define DEST   PARAM3
+
+.text
+ENTRY(FPU_u_div)
+       pushl   %ebp
+       movl    %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+       subl    $28,%esp
+#endif /* NON_REENTRANT_FPU */
+
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    REGA,%esi
+       movl    REGB,%ebx
+       movl    DEST,%edi
+
+       movw    EXP(%esi),%dx
+       movw    EXP(%ebx),%ax
+       .byte   0x0f,0xbf,0xc0  /* movsx        %ax,%eax */
+       .byte   0x0f,0xbf,0xd2  /* movsx        %dx,%edx */
+       subl    %eax,%edx
+       addl    EXP_BIAS,%edx
+
+       /* A denormal and a large number can cause an exponent underflow */
+       cmpl    EXP_WAY_UNDER,%edx
+       jg      xExp_not_underflow
+
+       /* Set to a really low value allow correct handling */
+       movl    EXP_WAY_UNDER,%edx
+
+xExp_not_underflow:
+
+       movw    %dx,EXP(%edi)
+
+#ifdef PARANOID
+/*     testl   $0x80000000, SIGH(%esi) // Dividend */
+/*     je      L_bugged */
+       testl   $0x80000000, SIGH(%ebx) /* Divisor */
+       je      L_bugged
+#endif /* PARANOID */
+
+/* Check if the divisor can be treated as having just 32 bits */
+       cmpl    $0,SIGL(%ebx)
+       jnz     L_Full_Division /* Can't do a quick divide */
+
+/* We should be able to zip through the division here */
+       movl    SIGH(%ebx),%ecx /* The divisor */
+       movl    SIGH(%esi),%edx /* Dividend */
+       movl    SIGL(%esi),%eax /* Dividend */
+
+       cmpl    %ecx,%edx
+       setaeb  FPU_ovfl_flag   /* Keep a record */
+       jb      L_no_adjust
+
+       subl    %ecx,%edx       /* Prevent the overflow */
+
+L_no_adjust:
+       /* Divide the 64 bit number by the 32 bit denominator */
+       divl    %ecx
+       movl    %eax,FPU_result_2
+
+       /* Work on the remainder of the first division */
+       xorl    %eax,%eax
+       divl    %ecx
+       movl    %eax,FPU_result_1
+
+       /* Work on the remainder of the 64 bit division */
+       xorl    %eax,%eax
+       divl    %ecx
+
+       testb   $255,FPU_ovfl_flag      /* was the num > denom ? */
+       je      L_no_overflow
+
+       /* Do the shifting here */
+       /* increase the exponent */
+       incw    EXP(%edi)
+
+       /* shift the mantissa right one bit */
+       stc                     /* To set the ms bit */
+       rcrl    FPU_result_2
+       rcrl    FPU_result_1
+       rcrl    %eax
+
+L_no_overflow:
+       jmp     LRound_precision        /* Do the rounding as required */
+
+
+/*---------------------------------------------------------------------------+
+ |  Divide:   Return  arg1/arg2 to arg3.                                     |
+ |                                                                           |
+ |  This routine does not use the exponents of arg1 and arg2, but does       |
+ |  adjust the exponent of arg3.                                             |
+ |                                                                           |
+ |  The maximum returned value is (ignoring exponents)                       |
+ |               .ffffffff ffffffff                                          |
+ |               ------------------  =  1.ffffffff fffffffe                  |
+ |               .80000000 00000000                                          |
+ | and the minimum is                                                        |
+ |               .80000000 00000000                                          |
+ |               ------------------  =  .80000000 00000001   (rounded)       |
+ |               .ffffffff ffffffff                                          |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+
+L_Full_Division:
+       /* Save extended dividend in local register */
+       movl    SIGL(%esi),%eax
+       movl    %eax,FPU_accum_2
+       movl    SIGH(%esi),%eax
+       movl    %eax,FPU_accum_3
+       xorl    %eax,%eax
+       movl    %eax,FPU_accum_1        /* zero the extension */
+       movl    %eax,FPU_accum_0        /* zero the extension */
+
+       movl    SIGL(%esi),%eax /* Get the current num */
+       movl    SIGH(%esi),%edx
+
+/*----------------------------------------------------------------------*/
+/* Initialization done.
+   Do the first 32 bits. */
+
+       movb    $0,FPU_ovfl_flag
+       cmpl    SIGH(%ebx),%edx /* Test for imminent overflow */
+       jb      LLess_than_1
+       ja      LGreater_than_1
+
+       cmpl    SIGL(%ebx),%eax
+       jb      LLess_than_1
+
+LGreater_than_1:
+/* The dividend is greater or equal, would cause overflow */
+       setaeb  FPU_ovfl_flag           /* Keep a record */
+
+       subl    SIGL(%ebx),%eax
+       sbbl    SIGH(%ebx),%edx /* Prevent the overflow */
+       movl    %eax,FPU_accum_2
+       movl    %edx,FPU_accum_3
+
+LLess_than_1:
+/* At this point, we have a dividend < divisor, with a record of
+   adjustment in FPU_ovfl_flag */
+
+       /* We will divide by a number which is too large */
+       movl    SIGH(%ebx),%ecx
+       addl    $1,%ecx
+       jnc     LFirst_div_not_1
+
+       /* here we need to divide by 100000000h,
+          i.e., no division at all.. */
+       mov     %edx,%eax
+       jmp     LFirst_div_done
+
+LFirst_div_not_1:
+       divl    %ecx            /* Divide the numerator by the augmented
+                                  denom ms dw */
+
+LFirst_div_done:
+       movl    %eax,FPU_result_2       /* Put the result in the answer */
+
+       mull    SIGH(%ebx)      /* mul by the ms dw of the denom */
+
+       subl    %eax,FPU_accum_2        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_3
+
+       movl    FPU_result_2,%eax       /* Get the result back */
+       mull    SIGL(%ebx)      /* now mul the ls dw of the denom */
+
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+       sbbl    $0,FPU_accum_3
+       je      LDo_2nd_32_bits         /* Must check for non-zero result here */
+
+#ifdef PARANOID
+       jb      L_bugged_1
+#endif /* PARANOID */
+
+       /* need to subtract another once of the denom */
+       incl    FPU_result_2    /* Correct the answer */
+
+       movl    SIGL(%ebx),%eax
+       movl    SIGH(%ebx),%edx
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+
+#ifdef PARANOID
+       sbbl    $0,FPU_accum_3
+       jne     L_bugged_1      /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* Half of the main problem is done, there is just a reduced numerator
+   to handle now.
+   Work with the second 32 bits, FPU_accum_0 not used from now on */
+LDo_2nd_32_bits:
+       movl    FPU_accum_2,%edx        /* get the reduced num */
+       movl    FPU_accum_1,%eax
+
+       /* need to check for possible subsequent overflow */
+       cmpl    SIGH(%ebx),%edx
+       jb      LDo_2nd_div
+       ja      LPrevent_2nd_overflow
+
+       cmpl    SIGL(%ebx),%eax
+       jb      LDo_2nd_div
+
+LPrevent_2nd_overflow:
+/* The numerator is greater or equal, would cause overflow */
+       /* prevent overflow */
+       subl    SIGL(%ebx),%eax
+       sbbl    SIGH(%ebx),%edx
+       movl    %edx,FPU_accum_2
+       movl    %eax,FPU_accum_1
+
+       incl    FPU_result_2    /* Reflect the subtraction in the answer */
+
+#ifdef PARANOID
+       je      L_bugged_2      /* Can't bump the result to 1.0 */
+#endif /* PARANOID */
+
+LDo_2nd_div:
+       cmpl    $0,%ecx         /* augmented denom msw */
+       jnz     LSecond_div_not_1
+
+       /* %ecx == 0, we are dividing by 1.0 */
+       mov     %edx,%eax
+       jmp     LSecond_div_done
+
+LSecond_div_not_1:
+       divl    %ecx            /* Divide the numerator by the denom ms dw */
+
+LSecond_div_done:
+       movl    %eax,FPU_result_1       /* Put the result in the answer */
+
+       mull    SIGH(%ebx)      /* mul by the ms dw of the denom */
+
+       subl    %eax,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+#endif /* PARANOID */
+
+       movl    FPU_result_1,%eax       /* Get the result back */
+       mull    SIGL(%ebx)      /* now mul the ls dw of the denom */
+
+       subl    %eax,FPU_accum_0        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_1        /* Subtract from the num local reg */
+       sbbl    $0,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+#endif /* PARANOID */
+
+       jz      LDo_3rd_32_bits
+
+#ifdef PARANOID
+       cmpl    $1,FPU_accum_2
+       jne     L_bugged_2
+#endif /* PARANOID */
+
+       /* need to subtract another once of the denom */
+       movl    SIGL(%ebx),%eax
+       movl    SIGH(%ebx),%edx
+       subl    %eax,FPU_accum_0        /* Subtract from the num local reg */
+       sbbl    %edx,FPU_accum_1
+       sbbl    $0,FPU_accum_2
+
+#ifdef PARANOID
+       jc      L_bugged_2
+       jne     L_bugged_2
+#endif /* PARANOID */
+
+       addl    $1,FPU_result_1 /* Correct the answer */
+       adcl    $0,FPU_result_2
+
+#ifdef PARANOID
+       jc      L_bugged_2      /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* The division is essentially finished here, we just need to perform
+   tidying operations.
+   Deal with the 3rd 32 bits */
+LDo_3rd_32_bits:
+       movl    FPU_accum_1,%edx                /* get the reduced num */
+       movl    FPU_accum_0,%eax
+
+       /* need to check for possible subsequent overflow */
+       cmpl    SIGH(%ebx),%edx /* denom */
+       jb      LRound_prep
+       ja      LPrevent_3rd_overflow
+
+       cmpl    SIGL(%ebx),%eax /* denom */
+       jb      LRound_prep
+
+LPrevent_3rd_overflow:
+       /* prevent overflow */
+       subl    SIGL(%ebx),%eax
+       sbbl    SIGH(%ebx),%edx
+       movl    %edx,FPU_accum_1
+       movl    %eax,FPU_accum_0
+
+       addl    $1,FPU_result_1 /* Reflect the subtraction in the answer */
+       adcl    $0,FPU_result_2
+       jne     LRound_prep
+       jnc     LRound_prep
+
+       /* This is a tricky spot, there is an overflow of the answer */
+       movb    $255,FPU_ovfl_flag              /* Overflow -> 1.000 */
+
+LRound_prep:
+/*
+ * Prepare for rounding.
+ * To test for rounding, we just need to compare 2*accum with the
+ * denom.
+ */
+       movl    FPU_accum_0,%ecx
+       movl    FPU_accum_1,%edx
+       movl    %ecx,%eax
+       orl     %edx,%eax
+       jz      LRound_ovfl             /* The accumulator contains zero. */
+
+       /* Multiply by 2 */
+       clc
+       rcll    $1,%ecx
+       rcll    $1,%edx
+       jc      LRound_large            /* No need to compare, denom smaller */
+
+       subl    SIGL(%ebx),%ecx
+       sbbl    SIGH(%ebx),%edx
+       jnc     LRound_not_small
+
+       movl    $0x70000000,%eax        /* Denom was larger */
+       jmp     LRound_ovfl
+
+LRound_not_small:
+       jnz     LRound_large
+
+       movl    $0x80000000,%eax        /* Remainder was exactly 1/2 denom */
+       jmp     LRound_ovfl
+
+LRound_large:
+       movl    $0xff000000,%eax        /* Denom was smaller */
+
+LRound_ovfl:
+/* We are now ready to deal with rounding, but first we must get
+   the bits properly aligned */
+       testb   $255,FPU_ovfl_flag      /* was the num > denom ? */
+       je      LRound_precision
+
+       incw    EXP(%edi)
+
+       /* shift the mantissa right one bit */
+       stc                     /* Will set the ms bit */
+       rcrl    FPU_result_2
+       rcrl    FPU_result_1
+       rcrl    %eax
+
+/* Round the result as required */
+LRound_precision:
+       decw    EXP(%edi)       /* binary point between 1st & 2nd bits */
+
+       movl    %eax,%edx
+       movl    FPU_result_1,%ebx
+       movl    FPU_result_2,%eax
+       jmp     fpu_reg_round
+
+
+#ifdef PARANOID
+/* The logic is wrong if we got here */
+L_bugged:
+       pushl   EX_INTERNAL|0x202
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_bugged_1:
+       pushl   EX_INTERNAL|0x203
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_bugged_2:
+       pushl   EX_INTERNAL|0x204
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_exit:
+       movl    $-1,%eax
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+
+       leave
+       ret
+#endif /* PARANOID */
diff --git a/sid/component/bochs/fpu/reg_u_div.c b/sid/component/bochs/fpu/reg_u_div.c
new file mode 100644 (file)
index 0000000..c063a61
--- /dev/null
@@ -0,0 +1,276 @@
+/*---------------------------------------------------------------------------+
+ |  reg_u_div.c                                                              |
+ |                                                                           |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |                                                                           |
+ |  Does not compute the destination exponent, but does adjust it.           |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include <asm/types.h>
+
+
+int FPU_u_div(const FPU_REG *a, const FPU_REG *b, FPU_REG *dest,
+             u16 control_w, u8 sign)
+{
+  s32 exp;
+  u32 divr32, rem, rat1, rat2, work32, accum3, prodh;
+  u64 work64, divr64, prod64, accum64;
+  u8 ovfl;
+
+  exp = (s32)a->exp - (s32)b->exp;
+
+  if ( exp < EXP_WAY_UNDER )
+    exp = EXP_WAY_UNDER;
+
+  dest->exp = exp;
+#ifdef PARANOID
+  if ( !(b->sigh & 0x80000000) )
+    {
+      EXCEPTION(EX_INTERNAL|0x202);
+    }
+#endif
+
+  work64 = significand(a);
+
+  /* We can save a lot of time if the divisor has all its lowest
+     32 bits equal to zero. */
+  if ( b->sigl == 0 )
+    {
+      divr32 = b->sigh;
+      ovfl = a->sigh >= divr32;
+      rat1 = work64 / divr32;
+      rem = work64 % divr32;
+      work64 = rem;
+      work64 <<= 32;
+      rat2 = work64 / divr32;
+      rem = work64 % divr32;
+
+      work64 = rem;
+      work64 <<= 32;
+      rem = work64 / divr32;
+
+      if ( ovfl )
+       {
+         rem >>= 1;
+         if ( rat2 & 1 )
+           rem |= 0x80000000;
+         rat2 >>= 1;
+         if ( rat1 & 1 )
+           rat2 |= 0x80000000;
+         rat1 >>= 1;
+         rat1 |= 0x80000000;
+         dest->exp ++;
+       }
+      dest->sigh = rat1;
+      dest->sigl = rat2;
+
+      dest->exp --;
+      return FPU_round(dest, rem, 0, control_w, sign);
+    }
+
+  /* This may take a little time... */
+
+  accum64 = work64;
+  divr64 = significand(b);
+
+  if ( (ovfl = accum64 >= divr64) )
+    accum64 -= divr64;
+  divr32 = b->sigh+1;
+
+  if ( divr32 != 0 )
+    {
+      rat1 = accum64 / divr32;
+    }
+  else
+    rat1 = accum64 >> 32;
+  prod64 = rat1 * (u64)b->sigh;
+
+  accum64 -= prod64;
+  prod64 = rat1 * (u64)b->sigl;
+  accum3 = prod64;
+  if ( accum3 )
+    {
+      accum3 = -accum3;
+      accum64 --;
+    }
+  prodh = prod64 >> 32;
+  accum64 -= prodh;
+
+  work32 = accum64 >> 32;
+  if ( work32 )
+    {
+#ifdef PARANOID
+      if ( work32 != 1 )
+       {
+         EXCEPTION(EX_INTERNAL|0x203);
+       }
+#endif
+
+      /* Need to subtract the divisor once more. */
+      work32 = accum3;
+      accum3 = work32 - b->sigl;
+      if ( accum3 > work32 )
+       accum64 --;
+      rat1 ++;
+      accum64 -= b->sigh;
+
+#ifdef PARANOID
+      if ( (accum64 >> 32) )
+       {
+         EXCEPTION(EX_INTERNAL|0x203);
+       }
+#endif
+    }
+
+  /* Now we essentially repeat what we have just done, but shifted
+     32 bits. */
+
+  accum64 <<= 32;
+  accum64 |= accum3;
+  if ( accum64 >= divr64 )
+    {
+      accum64 -= divr64;
+      rat1 ++;
+    }
+  if ( divr32 != 0 )
+    {
+      rat2 = accum64 / divr32;
+    }
+  else
+    rat2 = accum64 >> 32;
+  prod64 = rat2 * (u64)b->sigh;
+
+  accum64 -= prod64;
+  prod64 = rat2 * (u64)b->sigl;
+  accum3 = prod64;
+  if ( accum3 )
+    {
+      accum3 = -accum3;
+      accum64 --;
+    }
+  prodh = prod64 >> 32;
+  accum64 -= prodh;
+
+  work32 = accum64 >> 32;
+  if ( work32 )
+    {
+#ifdef PARANOID
+      if ( work32 != 1 )
+       {
+         EXCEPTION(EX_INTERNAL|0x203);
+       }
+#endif
+
+      /* Need to subtract the divisor once more. */
+      work32 = accum3;
+      accum3 = work32 - b->sigl;
+      if ( accum3 > work32 )
+       accum64 --;
+      rat2 ++;
+      if ( rat2 == 0 )
+       rat1 ++;
+      accum64 -= b->sigh;
+
+#ifdef PARANOID
+      if ( (accum64 >> 32) )
+       {
+         EXCEPTION(EX_INTERNAL|0x203);
+       }
+#endif
+    }
+
+  /* Tidy up the remainder */
+
+  accum64 <<= 32;
+  accum64 |= accum3;
+  if ( accum64 >= divr64 )
+    {
+      accum64 -= divr64;
+      rat2 ++;
+      if ( rat2 == 0 )
+       {
+         rat1 ++;
+#ifdef PARANOID
+         /* No overflow should be possible here */
+         if ( rat1 == 0 )
+           {
+             EXCEPTION(EX_INTERNAL|0x203);
+           }
+       }
+#endif
+    }
+
+  /* The basic division is done, now we must be careful with the
+     remainder. */
+
+  if ( ovfl )
+    {
+      if ( rat2 & 1 )
+       rem = 0x80000000;
+      else
+       rem = 0;
+      rat2 >>= 1;
+      if ( rat1 & 1 )
+       rat2 |= 0x80000000;
+      rat1 >>= 1;
+      rat1 |= 0x80000000;
+
+      if ( accum64 )
+       rem |= 0xff0000;
+
+      dest->exp ++;
+    }
+  else
+    {
+      /* Now we just need to know how large the remainder is
+        relative to half the divisor. */
+      if ( accum64 == 0 )
+       rem = 0;
+      else
+       {
+         accum3 = accum64 >> 32;
+         if ( accum3 & 0x80000000 )
+           {
+             /* The remainder is definitely larger than 1/2 divisor. */
+             rem = 0xff000000;
+           }
+         else
+           {
+             accum64 <<= 1;
+             if ( accum64 >= divr64 )
+               {
+                 accum64 -= divr64;
+                 if ( accum64 == 0 )
+                   rem = 0x80000000;
+                 else
+                   rem = 0xff000000;
+               }
+             else
+               rem = 0x7f000000;
+           }
+       }
+    }
+
+  dest->sigh = rat1;
+  dest->sigl = rat2;
+
+  dest->exp --;
+  return FPU_round(dest, rem, 0, control_w, sign);
+
+}
+
diff --git a/sid/component/bochs/fpu/reg_u_mul.S b/sid/component/bochs/fpu/reg_u_mul.S
new file mode 100644 (file)
index 0000000..c84360d
--- /dev/null
@@ -0,0 +1,148 @@
+       .file   "reg_u_mul.S"
+/*---------------------------------------------------------------------------+
+ |  reg_u_mul.S                                                              |
+ |                                                                           |
+ | Core multiplication routine                                               |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |   Basic multiplication routine.                                           |
+ |   Does not check the resulting exponent for overflow/underflow            |
+ |                                                                           |
+ |   FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw);         |
+ |                                                                           |
+ |   Internal working is at approx 128 bits.                                 |
+ |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+
+#ifndef NON_REENTRANT_FPU
+/*  Local storage on the stack: */
+#define FPU_accum_0    -4(%ebp)        /* ms word */
+#define FPU_accum_1    -8(%ebp)
+
+#else
+/*  Local storage in a static area: */
+.data
+       .align 4,0
+FPU_accum_0:
+       .long   0
+FPU_accum_1:
+       .long   0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(FPU_u_mul)
+       pushl   %ebp
+       movl    %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+       subl    $8,%esp
+#endif /* NON_REENTRANT_FPU */
+
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%esi
+       movl    PARAM2,%edi
+
+#ifdef PARANOID
+       testl   $0x80000000,SIGH(%esi)
+       jz      L_bugged
+       testl   $0x80000000,SIGH(%edi)
+       jz      L_bugged
+#endif /* PARANOID */
+
+       xorl    %ecx,%ecx
+       xorl    %ebx,%ebx
+
+       movl    SIGL(%esi),%eax
+       mull    SIGL(%edi)
+       movl    %eax,FPU_accum_0
+       movl    %edx,FPU_accum_1
+
+       movl    SIGL(%esi),%eax
+       mull    SIGH(%edi)
+       addl    %eax,FPU_accum_1
+       adcl    %edx,%ebx
+/*     adcl    $0,%ecx         // overflow here is not possible */
+
+       movl    SIGH(%esi),%eax
+       mull    SIGL(%edi)
+       addl    %eax,FPU_accum_1
+       adcl    %edx,%ebx
+       adcl    $0,%ecx
+
+       movl    SIGH(%esi),%eax
+       mull    SIGH(%edi)
+       addl    %eax,%ebx
+       adcl    %edx,%ecx
+
+       /* Get the sum of the exponents. */
+       movl    PARAM6,%eax
+       subl    EXP_BIAS-1,%eax
+
+       /* Two denormals can cause an exponent underflow */
+       cmpl    EXP_WAY_UNDER,%eax
+       jg      Exp_not_underflow
+
+       /* Set to a really low value allow correct handling */
+       movl    EXP_WAY_UNDER,%eax
+
+Exp_not_underflow:
+
+/*  Have now finished with the sources */
+       movl    PARAM3,%edi     /* Point to the destination */
+       movw    %ax,EXP(%edi)
+
+/*  Now make sure that the result is normalized */
+       testl   $0x80000000,%ecx
+       jnz     LResult_Normalised
+
+       /* Normalize by shifting left one bit */
+       shll    $1,FPU_accum_0
+       rcll    $1,FPU_accum_1
+       rcll    $1,%ebx
+       rcll    $1,%ecx
+       decw    EXP(%edi)
+
+LResult_Normalised:
+       movl    FPU_accum_0,%eax
+       movl    FPU_accum_1,%edx
+       orl     %eax,%eax
+       jz      L_extent_zero
+
+       orl     $1,%edx
+
+L_extent_zero:
+       movl    %ecx,%eax
+       jmp     fpu_reg_round
+
+
+#ifdef PARANOID
+L_bugged:
+       pushl   EX_INTERNAL|0x205
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_exit
+
+L_exit:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       leave
+       ret
+#endif /* PARANOID */
+
diff --git a/sid/component/bochs/fpu/reg_u_mul.c b/sid/component/bochs/fpu/reg_u_mul.c
new file mode 100644 (file)
index 0000000..690a00a
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------+
+ |  reg_u_mul.c                                                              |
+ |                                                                           |
+ | Core multiplication routine                                               |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |   Basic multiplication routine.                                           |
+ |   Does not check the resulting exponent for overflow/underflow            |
+ |                                                                           |
+ |   Internal working is at approx 128 bits.                                 |
+ |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+int FPU_u_mul(const FPU_REG *a, const FPU_REG *b, FPU_REG *c, u16 cw,
+             u_char sign, int expon)
+{
+  u64 mu, ml, mi;
+  u32 lh, ll, th, tl;
+
+#ifdef PARANOID
+  if ( ! (a->sigh & 0x80000000) || ! (b->sigh & 0x80000000) )
+    {
+      EXCEPTION(EX_INTERNAL|0x205);
+    }
+#endif
+
+  ml = a->sigl;
+  ml *= b->sigl;
+  ll = ml;
+  lh = ml >> 32;
+
+  mu = a->sigh;
+  mu *= b->sigh;
+
+  mi = a->sigh;
+  mi *= b->sigl;
+  tl = mi;
+  th = mi >> 32;
+  lh += tl;
+  if ( tl > lh )
+    mu ++;
+  mu += th;
+
+  mi = a->sigl;
+  mi *= b->sigh;
+  tl = mi;
+  th = mi >> 32;
+  lh += tl;
+  if ( tl > lh )
+    mu ++;
+  mu += th;
+
+  ml = lh;
+  ml <<= 32;
+  ml += ll;
+
+  expon -= EXP_BIAS-1;
+  if ( expon <= EXP_WAY_UNDER )
+    expon = EXP_WAY_UNDER;
+
+  c->exp = expon;
+
+  if ( ! (mu & BX_CONST64(0x8000000000000000)) )
+    {
+      mu <<= 1;
+      if ( ml & BX_CONST64(0x8000000000000000) )
+       mu |= 1;
+      ml <<= 1;
+      c->exp --;
+    }
+
+  ll = ml;
+  lh = ml >> 32;
+
+  if ( ll )
+    lh |= 1;
+
+  c->sigl = mu;
+  c->sigh = mu >> 32;
+
+  return FPU_round(c, lh, 0, cw, sign);
+  
+}
diff --git a/sid/component/bochs/fpu/reg_u_sub.S b/sid/component/bochs/fpu/reg_u_sub.S
new file mode 100644 (file)
index 0000000..236d3f1
--- /dev/null
@@ -0,0 +1,272 @@
+       .file   "reg_u_sub.S"
+/*---------------------------------------------------------------------------+
+ |  reg_u_sub.S                                                              |
+ |                                                                           |
+ | Core floating point subtraction routine.                                  |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |    int FPU_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,             |
+ |                                                int control_w)             |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*
+ |    Kernel subtraction routine FPU_u_sub(reg *arg1, reg *arg2, reg *answ).
+ |    Takes two valid reg f.p. numbers (TAG_Valid), which are
+ |    treated as unsigned numbers,
+ |    and returns their difference as a TAG_Valid or TAG_Zero f.p.
+ |    number.
+ |    The first number (arg1) must be the larger.
+ |    The returned number is normalized.
+ |    Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+.text
+ENTRY(FPU_u_sub)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%esi     /* source 1 */
+       movl    PARAM2,%edi     /* source 2 */
+       
+       movl    PARAM6,%ecx
+       subl    PARAM7,%ecx     /* exp1 - exp2 */
+
+#ifdef PARANOID
+       /* source 2 is always smaller than source 1 */
+       js      L_bugged_1
+
+       testl   $0x80000000,SIGH(%edi)  /* The args are assumed to be be normalized */
+       je      L_bugged_2
+
+       testl   $0x80000000,SIGH(%esi)
+       je      L_bugged_2
+#endif /* PARANOID */
+
+/*--------------------------------------+
+ |     Form a register holding the     |
+ |     smaller number                  |
+ +--------------------------------------*/
+       movl    SIGH(%edi),%eax /* register ms word */
+       movl    SIGL(%edi),%ebx /* register ls word */
+
+       movl    PARAM3,%edi     /* destination */
+       movl    PARAM6,%edx
+       movw    %dx,EXP(%edi)   /* Copy exponent to destination */
+
+       xorl    %edx,%edx       /* register extension */
+
+/*--------------------------------------+
+ |     Shift the temporary register    |
+ |      right the required number of   |
+ |     places.                         |
+ +--------------------------------------*/
+
+       cmpw    $32,%cx         /* shrd only works for 0..31 bits */
+       jnc     L_more_than_31
+
+/* less than 32 bits */
+       shrd    %cl,%ebx,%edx
+       shrd    %cl,%eax,%ebx
+       shr     %cl,%eax
+       jmp     L_shift_done
+
+L_more_than_31:
+       cmpw    $64,%cx
+       jnc     L_more_than_63
+
+       subb    $32,%cl
+       jz      L_exactly_32
+
+       shrd    %cl,%eax,%edx
+       shr     %cl,%eax
+       orl     %ebx,%ebx
+       jz      L_more_31_no_low        /* none of the lowest bits is set */
+
+       orl     $1,%edx                 /* record the fact in the extension */
+
+L_more_31_no_low:
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       jmp     L_shift_done
+
+L_exactly_32:
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       jmp     L_shift_done
+
+L_more_than_63:
+       cmpw    $65,%cx
+       jnc     L_more_than_64
+
+       /* Shift right by 64 bits */
+       movl    %eax,%edx
+       orl     %ebx,%ebx
+       jz      L_more_63_no_low
+
+       orl     $1,%edx
+       jmp     L_more_63_no_low
+
+L_more_than_64:
+       jne     L_more_than_65
+
+       /* Shift right by 65 bits */
+       /* Carry is clear if we get here */
+       movl    %eax,%edx
+       rcrl    %edx
+       jnc     L_shift_65_nc
+
+       orl     $1,%edx
+       jmp     L_more_63_no_low
+
+L_shift_65_nc:
+       orl     %ebx,%ebx
+       jz      L_more_63_no_low
+
+       orl     $1,%edx
+       jmp     L_more_63_no_low
+
+L_more_than_65:
+       movl    $1,%edx         /* The shifted nr always at least one '1' */
+
+L_more_63_no_low:
+       xorl    %ebx,%ebx
+       xorl    %eax,%eax
+
+L_shift_done:
+L_subtr:
+/*------------------------------+
+ |     Do the subtraction      |
+ +------------------------------*/
+       xorl    %ecx,%ecx
+       subl    %edx,%ecx
+       movl    %ecx,%edx
+       movl    SIGL(%esi),%ecx
+       sbbl    %ebx,%ecx
+       movl    %ecx,%ebx
+       movl    SIGH(%esi),%ecx
+       sbbl    %eax,%ecx
+       movl    %ecx,%eax
+
+#ifdef PARANOID
+       /* We can never get a borrow */
+       jc      L_bugged
+#endif /* PARANOID */
+
+/*--------------------------------------+
+ |     Normalize the result            |
+ +--------------------------------------*/
+       testl   $0x80000000,%eax
+       jnz     L_round         /* no shifting needed */
+
+       orl     %eax,%eax
+       jnz     L_shift_1       /* shift left 1 - 31 bits */
+
+       orl     %ebx,%ebx
+       jnz     L_shift_32      /* shift left 32 - 63 bits */
+
+/*
+ *      A rare case, the only one which is non-zero if we got here
+ *         is:           1000000 .... 0000
+ *                      -0111111 .... 1111 1
+ *                       -------------------- 
+ *                       0000000 .... 0000 1 
+ */
+
+       cmpl    $0x80000000,%edx
+       jnz     L_must_be_zero
+
+       /* Shift left 64 bits */
+       subw    $64,EXP(%edi)
+       xchg    %edx,%eax
+       jmp     fpu_reg_round
+
+L_must_be_zero:
+#ifdef PARANOID
+       orl     %edx,%edx
+       jnz     L_bugged_3
+#endif /* PARANOID */
+
+       /* The result is zero */
+       movw    $0,EXP(%edi)            /* exponent */
+       movl    $0,SIGL(%edi)
+       movl    $0,SIGH(%edi)
+       movl    TAG_Zero,%eax
+       jmp     L_exit
+
+L_shift_32:
+       movl    %ebx,%eax
+       movl    %edx,%ebx
+       movl    $0,%edx
+       subw    $32,EXP(%edi)   /* Can get underflow here */
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+       bsrl    %eax,%ecx       /* get the required shift in %ecx */
+       subl    $31,%ecx
+       negl    %ecx
+       shld    %cl,%ebx,%eax
+       shld    %cl,%edx,%ebx
+       shl     %cl,%edx
+       subw    %cx,EXP(%edi)   /* Can get underflow here */
+
+L_round:
+       jmp     fpu_reg_round   /* Round the result */
+
+
+#ifdef PARANOID
+L_bugged_1:
+       pushl   EX_INTERNAL|0x206
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_error_exit
+
+L_bugged_2:
+       pushl   EX_INTERNAL|0x209
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_error_exit
+
+L_bugged_3:
+       pushl   EX_INTERNAL|0x210
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_error_exit
+
+L_bugged_4:
+       pushl   EX_INTERNAL|0x211
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_error_exit
+
+L_bugged:
+       pushl   EX_INTERNAL|0x212
+       call    EXCEPTION
+       pop     %ebx
+       jmp     L_error_exit
+
+L_error_exit:
+       movl    $-1,%eax
+
+#endif /* PARANOID */
+
+L_exit:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       leave
+       ret
diff --git a/sid/component/bochs/fpu/reg_u_sub.c b/sid/component/bochs/fpu/reg_u_sub.c
new file mode 100644 (file)
index 0000000..657e512
--- /dev/null
@@ -0,0 +1,221 @@
+/*---------------------------------------------------------------------------+
+ |  reg_u_sub.c                                                              |
+ |                                                                           |
+ | Core floating point subtraction routine.                                  |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997,1999                                    |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
+ |    one was raised, or -1 on internal error.                               |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*
+ |    Kernel subtraction routine FPU_u_sub(reg *arg1, reg *arg2, reg *answ).
+ |    Takes two valid reg f.p. numbers (TAG_Valid), which are
+ |    treated as unsigned numbers,
+ |    and returns their difference as a TAG_Valid or TAG_Zero f.p.
+ |    number.
+ |    The first number (arg1) must be the larger.
+ |    The returned number is normalized.
+ |    Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+
+int  FPU_u_sub(const FPU_REG *arg1, const FPU_REG *arg2, FPU_REG *dest,
+              u16 control_w, u_char sign, int expa, int expb)
+{
+  FPU_REG shifted, answ;
+  u32 extent;
+  int ediff = expa - expb, ed2, borrow;
+
+#ifdef PARANOID
+  if ( ediff < 0 )
+    {
+      EXCEPTION(EX_INTERNAL|0x206);
+      return -1;
+    }
+#endif
+  
+  answ.exp = expa;
+
+#ifdef PARANOID
+  if ( !(arg1->sigh & 0x80000000) || !(arg2->sigh & 0x80000000) )
+    {
+      EXCEPTION(EX_INTERNAL|0x209);
+      return -1;
+    }
+#endif
+
+  if ( ediff == 0 )
+    {
+      shifted.sigl = arg2->sigl;
+      shifted.sigh = arg2->sigh;
+      extent = 0;
+    }
+  else if ( ediff < 32 )
+    {
+      ed2 = 32 - ediff;
+      extent = arg2->sigl << ed2;
+      shifted.sigl = arg2->sigl >> ediff;
+      shifted.sigl |= (arg2->sigh << ed2);
+      shifted.sigh = arg2->sigh >> ediff;
+    }
+  else if ( ediff < 64 )
+    {
+      ediff -= 32;
+      if ( ! ediff )
+       {
+         extent = arg2->sigl;
+         shifted.sigl = arg2->sigh;
+         shifted.sigh = 0;
+       }
+      else
+       {
+         ed2 = 32 - ediff;
+         extent = arg2->sigl >> ediff;
+         extent |= (arg2->sigh << ed2);
+         if ( arg2->sigl << ed2 )
+           extent |= 1;
+         shifted.sigl = arg2->sigh >> ediff;
+         shifted.sigh = 0;
+       }
+    }
+  else
+    {
+      ediff -= 64;
+      if ( ! ediff )
+       {
+         extent = arg2->sigh;
+         if ( arg2->sigl )
+           extent |= 1;
+         shifted.sigl = 0;
+         shifted.sigh = 0;
+       }
+      else
+       {
+         if ( ediff < 32 )
+           {
+             extent = arg2->sigh >> ediff;
+             if ( arg2->sigl || (arg2->sigh << (32-ediff)) )
+               extent |= 1;
+           }
+         else
+           extent = 1;
+         shifted.sigl = 0;
+         shifted.sigh = 0;
+       }
+    }
+
+  extent = -extent;
+  borrow = extent;
+  answ.sigl = arg1->sigl - shifted.sigl;
+  if ( answ.sigl > arg1->sigl )
+    {
+      if ( borrow )
+       answ.sigl --;
+      borrow = 1;
+    }
+  else if ( borrow )
+    {
+      answ.sigl --;
+      if ( answ.sigl != 0xffffffff )
+       borrow = 0;
+    }
+  answ.sigh = arg1->sigh - shifted.sigh;
+  if ( answ.sigh > arg1->sigh )
+    {
+      if ( borrow )
+       answ.sigh --;
+      borrow = 1;
+    }
+  else if ( borrow )
+    {
+      answ.sigh --;
+      if ( answ.sigh != 0xffffffff )
+       borrow = 0;
+    }
+
+#ifdef PARANOID
+  if ( borrow )
+    {
+      /* This can only occur if the code is bugged */
+      EXCEPTION(EX_INTERNAL|0x212);
+      return -1;
+    }
+#endif
+
+  if ( answ.sigh & 0x80000000 )
+    {
+      /*
+       The simpler "*dest = answ" is broken in gcc
+      */
+      dest->exp = answ.exp;
+      dest->sigh = answ.sigh;
+      dest->sigl = answ.sigl;
+      return FPU_round(dest, extent, 0, control_w, sign);
+    }
+
+  if ( answ.sigh == 0 )
+    {
+      if ( answ.sigl )
+       {
+         answ.sigh = answ.sigl;
+         answ.sigl = extent;
+         extent = 0;
+         answ.exp -= 32;
+       }
+      else if ( extent )
+       {
+/*
+ *      A rare case, the only one which is non-zero if we got here
+ *         is:           1000000 .... 0000
+ *                      -0111111 .... 1111 1
+ *                       -------------------- 
+ *                       0000000 .... 0000 1 
+ */
+         if ( extent != 0x80000000 )
+           {
+             /* This can only occur if the code is bugged */
+             EXCEPTION(EX_INTERNAL|0x210);
+             return -1;
+           }
+         dest->sigh = extent;
+         dest->sigl = extent = 0;
+         dest->exp -= 64;
+         return FPU_round(dest, extent, 0, control_w, sign);
+       }
+      else
+       {
+         dest->exp = 0;
+         dest->sigh = dest->sigl = 0;
+         return TAG_Zero;
+       }
+    }
+
+  while ( !(answ.sigh & 0x80000000) )
+    {
+      answ.sigh <<= 1;
+      if ( answ.sigl & 0x80000000 )
+       answ.sigh |= 1;
+      answ.sigl <<= 1;
+      if ( extent & 0x80000000 )
+       answ.sigl |= 1;
+      extent <<= 1;
+      answ.exp --;
+    }
+
+  dest->exp = answ.exp;
+  dest->sigh = answ.sigh;
+  dest->sigl = answ.sigl;
+
+  return FPU_round(dest, extent, 0, control_w, sign);
+
+}
diff --git a/sid/component/bochs/fpu/round_Xsig.S b/sid/component/bochs/fpu/round_Xsig.S
new file mode 100644 (file)
index 0000000..bbe0e87
--- /dev/null
@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------------+
+ |  round_Xsig.S                                                             |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ | Normalize and round a 12 byte quantity.                                   |
+ | Call from C as:                                                           |
+ |   int round_Xsig(Xsig *n)                                                 |
+ |                                                                           |
+ | Normalize a 12 byte quantity.                                             |
+ | Call from C as:                                                           |
+ |   int norm_Xsig(Xsig *n)                                                  |
+ |                                                                           |
+ | Each function returns the size of the shift (nr of bits).                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+       .file   "round_Xsig.S"
+
+#include "fpu_emu.h"
+
+
+.text
+ENTRY(round_Xsig)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %ebx            /* Reserve some space */
+       pushl   %ebx
+       pushl   %esi
+
+       movl    PARAM1,%esi
+
+       movl    8(%esi),%edx
+       movl    4(%esi),%ebx
+       movl    (%esi),%eax
+
+       movl    $0,-4(%ebp)
+
+       orl     %edx,%edx       /* ms bits */
+       js      L_round         /* Already normalized */
+       jnz     L_shift_1       /* Shift left 1 - 31 bits */
+
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       movl    $-32,-4(%ebp)
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+       bsrl    %edx,%ecx       /* get the required shift in %ecx */
+       subl    $31,%ecx
+       negl    %ecx
+       subl    %ecx,-4(%ebp)
+       shld    %cl,%ebx,%edx
+       shld    %cl,%eax,%ebx
+       shl     %cl,%eax
+
+L_round:
+       testl   $0x80000000,%eax
+       jz      L_exit
+
+       addl    $1,%ebx
+       adcl    $0,%edx
+       jnz     L_exit
+
+       movl    $0x80000000,%edx
+       incl    -4(%ebp)
+
+L_exit:
+       movl    %edx,8(%esi)
+       movl    %ebx,4(%esi)
+       movl    %eax,(%esi)
+
+       movl    -4(%ebp),%eax
+
+       popl    %esi
+       popl    %ebx
+       leave
+       ret
+
+
+
+
+ENTRY(norm_Xsig)
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %ebx            /* Reserve some space */
+       pushl   %ebx
+       pushl   %esi
+
+       movl    PARAM1,%esi
+
+       movl    8(%esi),%edx
+       movl    4(%esi),%ebx
+       movl    (%esi),%eax
+
+       movl    $0,-4(%ebp)
+
+       orl     %edx,%edx       /* ms bits */
+       js      L_n_exit                /* Already normalized */
+       jnz     L_n_shift_1     /* Shift left 1 - 31 bits */
+
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       movl    $-32,-4(%ebp)
+
+       orl     %edx,%edx       /* ms bits */
+       js      L_n_exit        /* Normalized now */
+       jnz     L_n_shift_1     /* Shift left 1 - 31 bits */
+
+       movl    %ebx,%edx
+       movl    %eax,%ebx
+       xorl    %eax,%eax
+       addl    $-32,-4(%ebp)
+       jmp     L_n_exit        /* Might not be normalized,
+                                  but shift no more. */
+
+/* We need to shift left by 1 - 31 bits */
+L_n_shift_1:
+       bsrl    %edx,%ecx       /* get the required shift in %ecx */
+       subl    $31,%ecx
+       negl    %ecx
+       subl    %ecx,-4(%ebp)
+       shld    %cl,%ebx,%edx
+       shld    %cl,%eax,%ebx
+       shl     %cl,%eax
+
+L_n_exit:
+       movl    %edx,8(%esi)
+       movl    %ebx,4(%esi)
+       movl    %eax,(%esi)
+
+       movl    -4(%ebp),%eax
+
+       popl    %esi
+       popl    %ebx
+       leave
+       ret
+
diff --git a/sid/component/bochs/fpu/round_Xsig.c b/sid/component/bochs/fpu/round_Xsig.c
new file mode 100644 (file)
index 0000000..adf45b5
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------+
+ |  round_Xsig.c                                                             |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1995,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ | Normalize and round a 12 byte quantity.                                   |
+ |   int round_Xsig(Xsig *n)                                                 |
+ |                                                                           |
+ | Normalize a 12 byte quantity.                                             |
+ |   int norm_Xsig(Xsig *n)                                                  |
+ |                                                                           |
+ | Each function returns the size of the shift (nr of bits).                 |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+int round_Xsig(Xsig *x)
+{
+  int n = 0;
+
+  if ( x->msw == 0 )
+    {
+      x->msw = x->midw;
+      x->midw = x->lsw;
+      x->lsw = 0;
+      n = 32;
+    }
+  while ( !(x->msw & 0x80000000) )
+    {
+      x->msw <<= 1;
+      if ( x->midw & 0x80000000 ) x->msw |= 1;
+      x->midw <<= 1;
+      if ( x->lsw & 0x80000000 ) x->midw |= 1;
+      x->lsw <<= 1;
+      n++;
+    }
+  if ( x->lsw & 0x80000000 )
+    {
+      x->midw ++;
+      if ( x->midw == 0 )
+       x->msw ++;
+      if ( x->msw == 0 )
+       {
+         x->msw = 0x80000000;
+         n--;
+       }
+    }
+  
+
+  return -n;
+}
+
+
+int norm_Xsig(Xsig *x)
+{
+  int n = 0;
+
+  if ( x->msw == 0 )
+    {
+      if ( x->midw == 0 )
+       {
+         x->msw = x->lsw;
+         x->midw = 0;
+         x->lsw = 0;
+         n = 64;
+       }
+      else
+       {
+         x->msw = x->midw;
+         x->midw = x->lsw;
+         x->lsw = 0;
+         n = 32;
+       }
+    }
+  while ( !(x->msw & 0x80000000) )
+    {
+      x->msw <<= 1;
+      if ( x->midw & 0x80000000 ) x->msw |= 1;
+      x->midw <<= 1;
+      if ( x->lsw & 0x80000000 ) x->midw |= 1;
+      x->lsw <<= 1;
+      n++;
+    }
+
+  return -n;
+}
+
+
+
+
+
diff --git a/sid/component/bochs/fpu/shr_Xsig.S b/sid/component/bochs/fpu/shr_Xsig.S
new file mode 100644 (file)
index 0000000..31cdd11
--- /dev/null
@@ -0,0 +1,87 @@
+       .file   "shr_Xsig.S"
+/*---------------------------------------------------------------------------+
+ |  shr_Xsig.S                                                               |
+ |                                                                           |
+ | 12 byte right shift function                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1994,1995                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |   void shr_Xsig(Xsig *arg, unsigned nr)                                   |
+ |                                                                           |
+ |   Extended shift right function.                                          |
+ |   Fastest for small shifts.                                               |
+ |   Shifts the 12 byte quantity pointed to by the first arg (arg)           |
+ |   right by the number of bits specified by the second arg (nr).           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(shr_Xsig)
+       push    %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       movl    PARAM2,%ecx
+       movl    PARAM1,%esi
+       cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
+       jnc     L_more_than_31
+
+/* less than 32 bits */
+       pushl   %ebx
+       movl    (%esi),%eax     /* lsl */
+       movl    4(%esi),%ebx    /* midl */
+       movl    8(%esi),%edx    /* msl */
+       shrd    %cl,%ebx,%eax
+       shrd    %cl,%edx,%ebx
+       shr     %cl,%edx
+       movl    %eax,(%esi)
+       movl    %ebx,4(%esi)
+       movl    %edx,8(%esi)
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+
+L_more_than_31:
+       cmpl    $64,%ecx
+       jnc     L_more_than_63
+
+       subb    $32,%cl
+       movl    4(%esi),%eax    /* midl */
+       movl    8(%esi),%edx    /* msl */
+       shrd    %cl,%edx,%eax
+       shr     %cl,%edx
+       movl    %eax,(%esi)
+       movl    %edx,4(%esi)
+       movl    $0,8(%esi)
+       popl    %esi
+       leave
+       ret
+
+L_more_than_63:
+       cmpl    $96,%ecx
+       jnc     L_more_than_95
+
+       subb    $64,%cl
+       movl    8(%esi),%eax    /* msl */
+       shr     %cl,%eax
+       xorl    %edx,%edx
+       movl    %eax,(%esi)
+       movl    %edx,4(%esi)
+       movl    %edx,8(%esi)
+       popl    %esi
+       leave
+       ret
+
+L_more_than_95:
+       xorl    %eax,%eax
+       movl    %eax,(%esi)
+       movl    %eax,4(%esi)
+       movl    %eax,8(%esi)
+       popl    %esi
+       leave
+       ret
diff --git a/sid/component/bochs/fpu/shr_Xsig.c b/sid/component/bochs/fpu/shr_Xsig.c
new file mode 100644 (file)
index 0000000..a259b87
--- /dev/null
@@ -0,0 +1,41 @@
+/*---------------------------------------------------------------------------+
+ |  shr_Xsig.S                                                               |
+ |                                                                           |
+ | 12 byte right shift function                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1994,1995                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ |                                                                           |
+ |   Extended shift right function.                                          |
+ |   Fastest for small shifts.                                               |
+ |   Shifts the 12 byte quantity pointed to by the first arg (arg)           |
+ |   right by the number of bits specified by the second arg (nr).           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+void shr_Xsig(Xsig *arg, const int nr)
+{
+  int n = nr;
+
+  while ( n >= 32 )
+    {
+      arg->lsw = arg->midw;
+      arg->midw = arg->msw;
+      arg->msw = 0;
+      n -= 32;
+    }
+
+  if ( n <= 0 )
+    return;
+
+  arg->lsw = (arg->lsw >> n) | (arg->midw << (32-n));
+  arg->midw = (arg->midw >> n) | (arg->msw << (32-n));
+  arg->msw >>= n;
+
+}
+
diff --git a/sid/component/bochs/fpu/status_w.h b/sid/component/bochs/fpu/status_w.h
new file mode 100644 (file)
index 0000000..d38e3a9
--- /dev/null
@@ -0,0 +1,67 @@
+/*---------------------------------------------------------------------------+
+ |  status_w.h                                                               |
+ |                                                                           |
+ | Copyright (C) 1992,1993                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _STATUS_H_
+#define _STATUS_H_
+
+#include "fpu_emu.h"    /* for definition of PECULIAR_486 */
+
+#ifdef __ASSEMBLY__
+#define        Const__(x)      $##x
+#else
+#define        Const__(x)      x
+#endif
+
+#define SW_Backward            Const__(0x8000) /* backward compatibility */
+#define SW_C3          Const__(0x4000) /* condition bit 3 */
+#define SW_Top         Const__(0x3800) /* top of stack */
+#define SW_Top_Shift   Const__(11)     /* shift for top of stack bits */
+#define SW_C2          Const__(0x0400) /* condition bit 2 */
+#define SW_C1          Const__(0x0200) /* condition bit 1 */
+#define SW_C0          Const__(0x0100) /* condition bit 0 */
+#define SW_Summary             Const__(0x0080) /* exception summary */
+#define SW_Stack_Fault Const__(0x0040) /* stack fault */
+#define SW_Precision           Const__(0x0020) /* loss of precision */
+#define SW_Underflow           Const__(0x0010) /* underflow */
+#define SW_Overflow            Const__(0x0008) /* overflow */
+#define SW_Zero_Div            Const__(0x0004) /* divide by zero */
+#define SW_Denorm_Op           Const__(0x0002) /* denormalized operand */
+#define SW_Invalid             Const__(0x0001) /* invalid operation */
+
+#define SW_Exc_Mask     Const__(0x27f)  /* Status word exception bit mask */
+
+#ifndef __ASSEMBLY__
+
+#define COMP_A_gt_B    1
+#define COMP_A_eq_B    2
+#define COMP_A_lt_B    3
+#define COMP_No_Comp   4
+#define COMP_Denormal   0x20
+#define COMP_NaN       0x40
+#define COMP_SNaN      0x80
+
+#define status_word() \
+  ((partial_status & ~SW_Top & 0xffff) | ((top << SW_Top_Shift) & SW_Top))
+// bbd: use do {...} while (0) structure instead of using curly brackets
+// inside parens, which most compilers do not like.
+#define setcc(cc) do { \
+  partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \
+  partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); } while(0)
+
+#ifdef PECULIAR_486
+   /* Default, this conveys no information, but an 80486 does it. */
+   /* Clear the SW_C1 bit, "other bits undefined". */
+#  define clear_C1()  { partial_status &= ~SW_C1; }
+# else
+#  define clear_C1()
+#endif /* PECULIAR_486 */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _STATUS_H_ */
diff --git a/sid/component/bochs/fpu/stubs/asm/desc.h b/sid/component/bochs/fpu/stubs/asm/desc.h
new file mode 100644 (file)
index 0000000..d369d01
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __ARCH_DESC_H
+#define __ARCH_DESC_H
+
+struct desc_struct {
+       unsigned long a,b;
+};
+
+extern struct desc_struct gdt_table[];
+extern struct desc_struct *idt, *gdt;
+
+struct Xgt_desc_struct {
+       unsigned short size;
+       unsigned long address GCC_ATTRIBUTE((packed));
+};
+
+#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
+#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
+
+/*
+ * Entry into gdt where to find first TSS. GDT layout:
+ *   0 - null
+ *   1 - not used
+ *   2 - kernel code segment
+ *   3 - kernel data segment
+ *   4 - user code segment
+ *   5 - user data segment
+ *   6 - not used
+ *   7 - not used
+ *   8 - APM BIOS support
+ *   9 - APM BIOS support
+ *  10 - APM BIOS support
+ *  11 - APM BIOS support
+ *  12 - TSS #0
+ *  13 - LDT #0
+ *  14 - TSS #1
+ *  15 - LDT #1
+ */
+#define FIRST_TSS_ENTRY 12
+#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
+#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
+#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
+#define load_TR(n) __asm__ __volatile__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
+#define load_ldt(n) __asm__ __volatile__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
+#define store_TR(n) \
+__asm__("str %%ax\n\t" \
+       "subl %2,%%eax\n\t" \
+       "shrl $4,%%eax" \
+       :"=a" (n) \
+       :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
+
+extern void set_intr_gate(unsigned int irq, void * addr);
+extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
+extern void set_tss_desc(unsigned int n, void *addr);
+
+/*
+ * This is the ldt that every process will get unless we need
+ * something other than this.
+ */
+extern struct desc_struct default_ldt;
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/asm/math_emu.h b/sid/component/bochs/fpu/stubs/asm/math_emu.h
new file mode 100644 (file)
index 0000000..adb1118
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _I386_MATH_EMU_H
+#define _I386_MATH_EMU_H
+
+// Don't really need anything in here.
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/asm/sigcontext.h b/sid/component/bochs/fpu/stubs/asm/sigcontext.h
new file mode 100644 (file)
index 0000000..d7b2f58
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef _ASMi386_SIGCONTEXT_H
+#define _ASMi386_SIGCONTEXT_H
+
+/*
+ * As documented in the iBCS2 standard..
+ *
+ * The first part of "struct _fpstate" is just the
+ * normal i387 hardware setup, the extra "status"
+ * word is used to save the coprocessor status word
+ * before entering the handler.
+ */
+struct _fpreg {
+       unsigned short significand[4];
+       unsigned short exponent;
+};
+
+struct _fpstate {
+       unsigned long   cw,
+                       sw,
+                       tag,
+                       ipoff,
+                       cssel,
+                       dataoff,
+                       datasel;
+       struct _fpreg   _st[8];
+       unsigned long   status;
+};
+
+#if 0
+/* sigcontext is not needed by bochs, and it conflicts with some other
+   machine types (DEC OSF1) */
+struct sigcontext {
+       unsigned short gs, __gsh;
+       unsigned short fs, __fsh;
+       unsigned short es, __esh;
+       unsigned short ds, __dsh;
+       unsigned long edi;
+       unsigned long esi;
+       unsigned long ebp;
+       unsigned long esp;
+       unsigned long ebx;
+       unsigned long edx;
+       unsigned long ecx;
+       unsigned long eax;
+       unsigned long trapno;
+       unsigned long err;
+       unsigned long eip;
+       unsigned short cs, __csh;
+       unsigned long eflags;
+       unsigned long esp_at_signal;
+       unsigned short ss, __ssh;
+       struct _fpstate * fpstate;
+       unsigned long oldmask;
+       unsigned long cr2;
+};
+#endif
+
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/asm/types.h b/sid/component/bochs/fpu/stubs/asm/types.h
new file mode 100644 (file)
index 0000000..a963dca
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _I386_TYPES_H
+#define _I386_TYPES_H
+
+#ifndef __ASSEMBLY__
+#endif
+
+#endif  /* _I386_TYPES_H */
diff --git a/sid/component/bochs/fpu/stubs/asm/uaccess.h b/sid/component/bochs/fpu/stubs/asm/uaccess.h
new file mode 100644 (file)
index 0000000..4cd87bb
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _I386_UACCESS_H
+#define _I386_UACCESS_H
+
+
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/kernel.h b/sid/component/bochs/fpu/stubs/linux/kernel.h
new file mode 100644 (file)
index 0000000..05372b6
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+int printk(const char * fmt, ...)
+        GCC_ATTRIBUTE((format (printf, 1, 2)));
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/linkage.h b/sid/component/bochs/fpu/stubs/linux/linkage.h
new file mode 100644 (file)
index 0000000..b1856a7
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _LINUX_LINKAGE_H
+#define _LINUX_LINKAGE_H
+
+#ifdef __cplusplus
+#define CPP_ASMLINKAGE extern "C"
+#else
+#define CPP_ASMLINKAGE
+#endif
+
+#if defined __i386__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 7)
+#define asmlinkage CPP_ASMLINKAGE GCC_ATTRIBUTE((regparm(0)))
+#else
+#define asmlinkage CPP_ASMLINKAGE
+#endif
+
+#define SYMBOL_NAME_STR(X) #X
+#define SYMBOL_NAME(X) X
+#ifdef __STDC__
+#define SYMBOL_NAME_LABEL(X) X##:
+#else
+#define SYMBOL_NAME_LABEL(X) X/**/:
+#endif
+
+#ifdef __arm__
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+#else
+#ifdef __mc68000__
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+#else
+#if !defined(__i486__) && !defined(__i586__)
+#define __ALIGN .align 4,0x90
+#define __ALIGN_STR ".align 4,0x90"
+#else  /* __i486__/__i586__ */
+#define __ALIGN .align 16,0x90
+#define __ALIGN_STR ".align 16,0x90"
+#endif /* __i486__/__i586__ */
+#endif /* __mc68000__ */
+#endif /* __arm__ */
+
+#ifdef __ASSEMBLY__
+
+#define ALIGN __ALIGN
+#define ALIGN_STR __ALIGN_STR
+
+#define ENTRY(name) \
+  .globl SYMBOL_NAME(name); \
+  ALIGN; \
+  SYMBOL_NAME_LABEL(name)
+
+#endif
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/mm.h b/sid/component/bochs/fpu/stubs/linux/mm.h
new file mode 100644 (file)
index 0000000..e6d6cc2
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LINUX_MM_H
+#define _LINUX_MM_H
+
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/signal.h b/sid/component/bochs/fpu/stubs/linux/signal.h
new file mode 100644 (file)
index 0000000..457158d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASMi386_SIGNAL_H
+#define _ASMi386_SIGNAL_H
+
+#define SIGILL           4
+#define SIGFPE           8
+#define SIGSEGV         11
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/stddef.h b/sid/component/bochs/fpu/stubs/linux/stddef.h
new file mode 100644 (file)
index 0000000..c6221e7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _LINUX_STDDEF_H
+#define _LINUX_STDDEF_H
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+
+#undef NULL
+#define NULL ((void *)0)
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif
diff --git a/sid/component/bochs/fpu/stubs/linux/types.h b/sid/component/bochs/fpu/stubs/linux/types.h
new file mode 100644 (file)
index 0000000..5ea5a61
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+#define u_char bx_u_char
+#define u_short bx_u_short
+#define u_int bx_u_int
+#define u_long bx_u_long
+#define unchar bx_unchar
+#define ushort bx_ushort
+#define uint bx_uint
+#define ulong bx_ulong
+
+/* bsd */
+typedef unsigned char           u_char;
+typedef unsigned short          u_short;
+typedef unsigned int            u_int;
+typedef unsigned long           u_long;
+
+/* sysv */
+typedef unsigned char           unchar;
+typedef unsigned short          ushort;
+typedef unsigned int            uint;
+typedef unsigned long           ulong;
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#endif
+
+#endif /* _LINUX_TYPES_H */
diff --git a/sid/component/bochs/fpu/version.h b/sid/component/bochs/fpu/version.h
new file mode 100644 (file)
index 0000000..23fcd25
--- /dev/null
@@ -0,0 +1,12 @@
+/*---------------------------------------------------------------------------+
+ |  version.h                                                                |
+ |                                                                           |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1994,1996,1997,1999                               |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@melbpc.org.au                             |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#define FPU_VERSION "wm-FPU-emu version 2.05"
diff --git a/sid/component/bochs/fpu/wmFPUemu_glue.cc b/sid/component/bochs/fpu/wmFPUemu_glue.cc
new file mode 100644 (file)
index 0000000..a450e10
--- /dev/null
@@ -0,0 +1,260 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+//
+// This is the glue logic needed to connect the wm-FPU-emu
+// FPU emulator written by Bill Metzenthen to bochs.
+//
+
+
+#include "bochs.h"
+extern "C" {
+#include "fpu_emu.h"
+#include "linux/signal.h"
+}
+
+#define LOG_THIS genlog->
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+// Use this to hold a pointer to the instruction since
+// we can't pass this to the FPU emulation routines, which
+// will ultimately call routines here.
+static BxInstruction_t *fpu_iptr = NULL;
+static BX_CPU_C *fpu_cpu_ptr = NULL;
+
+i387_t i387;
+
+extern "C" void
+math_emulate2(fpu_addr_modes addr_modes,
+              u_char  FPU_modrm,
+              u_char byte1,
+              void *data_address,
+              struct address data_sel_off,
+              struct address entry_sel_off);
+
+extern "C" void printfp(char *s, FPU_REG *r);
+
+
+  // This is called by bochs upon reset
+  void
+BX_CPU_C::fpu_init(void)
+{
+  finit();
+}
+
+  void
+BX_CPU_C::fpu_execute(BxInstruction_t *i)
+{
+  fpu_addr_modes addr_modes;
+  void *data_address;
+  struct address data_sel_off;
+  struct address entry_sel_off;
+  Boolean is_32;
+
+  fpu_iptr = i;
+  fpu_cpu_ptr = this;
+
+#if 0
+  addr_modes.default_mode = VM86;
+  addr_modes.default_mode = 0; // FPU_CS == __USER_CS && FPU_DS == __USER_DS
+  addr_modes.default_mode = SEG32;
+  addr_modes.default_mode = PM16;
+#endif
+  if (protected_mode()) {
+    addr_modes.default_mode = SEG32;
+    }
+  else if (v8086_mode()) {
+    addr_modes.default_mode = VM86;
+    }
+  else {
+    // real mode, use vm86 for now
+    addr_modes.default_mode = VM86;
+    }
+
+
+  // Mark if instruction used opsize or addrsize prefixes
+  // Actually, addr_modes.override.address_size is not used,
+  // could delete that code.
+  is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+  if (i->as_32 == is_32)
+    addr_modes.override.address_size = 0;
+  else
+    addr_modes.override.address_size = ADDR_SIZE_PREFIX;
+  if (i->os_32 == is_32)
+    addr_modes.override.operand_size = 0;
+  else
+    addr_modes.override.operand_size = OP_SIZE_PREFIX;
+
+  // For now set access_limit to max.  It seems to be
+  // a number from 0..255 denoting how many bytes the
+  // current instruction can access according to its
+  // memory operand.  255 means >= 255.
+access_limit = 0xff;
+
+  // fill in orig eip here in offset
+  // fill in CS in selector
+  entry_sel_off.offset = BX_CPU_THIS_PTR prev_eip;
+  entry_sel_off.selector = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+
+// should set these fields to 0 if mem operand not used
+  data_address = (void *) i->rm_addr;
+  data_sel_off.offset = i->rm_addr;
+  data_sel_off.selector = BX_CPU_THIS_PTR sregs[i->seg].selector.value;
+
+  math_emulate2(addr_modes, i->modrm, i->b1, data_address,
+                data_sel_off, entry_sel_off);
+}
+
+
+  unsigned
+fpu_get_ds(void)
+{
+  return(fpu_cpu_ptr->sregs[BX_SEG_REG_DS].selector.value);
+}
+
+  void
+fpu_set_ax(unsigned short val16)
+{
+// define to set AX in the current CPU -- not ideal.
+#undef AX
+#define AX (fpu_cpu_ptr->gen_reg[0].word.rx)
+  AX = val16;
+#undef AX
+//BX_DEBUG(( "fpu_set_ax(0x%04x)\n", (unsigned) val16));
+}
+
+  void
+fpu_verify_area(unsigned what, void *ptr, unsigned n)
+{
+  bx_segment_reg_t *seg;
+
+  seg = &fpu_cpu_ptr->sregs[fpu_iptr->seg];
+
+  if (what == VERIFY_READ) {
+    fpu_cpu_ptr->read_virtual_checks(seg, PTR2INT(ptr), n);
+    }
+  else {  // VERIFY_WRITE
+    fpu_cpu_ptr->write_virtual_checks(seg, PTR2INT(ptr), n);
+    }
+//BX_DEBUG(( "verify_area: 0x%x\n", PTR2INT(ptr)));
+}
+
+
+  void
+FPU_printall(void)
+{
+  BX_PANIC(("FPU_printall\n"));
+}
+
+
+  unsigned
+fpu_get_user(void *ptr, unsigned len)
+{
+  Bit32u val32;
+  Bit16u val16;
+  Bit8u  val8;
+
+  switch (len) {
+    case 1:
+      fpu_cpu_ptr->read_virtual_byte(fpu_iptr->seg, PTR2INT(ptr), &val8);
+      val32 = val8;
+      break;
+    case 2:
+      fpu_cpu_ptr->read_virtual_word(fpu_iptr->seg, PTR2INT(ptr), &val16);
+      val32 = val16;
+      break;
+    case 4:
+      fpu_cpu_ptr->read_virtual_dword(fpu_iptr->seg, PTR2INT(ptr), &val32);
+      break;
+    default:
+      BX_PANIC(("fpu_get_user: len=%u\n", len));
+    }
+  return(val32);
+}
+
+  void
+fpu_put_user(unsigned val, void *ptr, unsigned len)
+{
+  Bit32u val32;
+  Bit16u val16;
+  Bit8u  val8;
+
+  switch (len) {
+    case 1:
+      val8 = val;
+      fpu_cpu_ptr->write_virtual_byte(fpu_iptr->seg, PTR2INT(ptr), &val8);
+      break;
+    case 2:
+      val16 = val;
+      fpu_cpu_ptr->write_virtual_word(fpu_iptr->seg, PTR2INT(ptr), &val16);
+      break;
+    case 4:
+      val32 = val;
+      fpu_cpu_ptr->write_virtual_dword(fpu_iptr->seg, PTR2INT(ptr), &val32);
+      break;
+    default:
+      BX_PANIC(("fpu_put_user: len=%u\n", len));
+    }
+}
+
+  void
+math_abort(struct info *info, unsigned int signal)
+{
+  UNUSED(info); // info is always passed NULL
+#if BX_CPU_LEVEL >= 4
+
+// values of signal:
+//   SIGILL  : opcodes which are illegal
+//   SIGFPE  : unmasked FP exception before WAIT or non-control instruction
+//   SIGSEGV : access data beyond segment violation
+  switch (signal) {
+    case SIGFPE:
+      if (fpu_cpu_ptr->cr0.ne == 0) {
+        // MSDOS compatibility external interrupt (IRQ13)
+        BX_PANIC (("math_abort: MSDOS compatibility not supported yet\n"));
+        }
+      fpu_cpu_ptr->exception(BX_MF_EXCEPTION, 0, 0);
+      // execution does not reach here
+
+    case SIGILL:
+      BX_PANIC (("math_abort: SIGILL not implemented yet.\n"));
+      break;
+    case SIGSEGV:
+      BX_PANIC (("math_abort: SIGSEGV not implemented yet.\n"));
+      break;
+    }
+
+#else
+  UNUSED(signal);
+  BX_INFO(("math_abort: CPU<4 not supported yet\n"));
+#endif
+}
+
+  int
+printk(const char * fmt, ...)
+{
+  BX_INFO(("printk not complete: %s\n", fmt));
+  return(0); // for now
+}
diff --git a/sid/component/bochs/fpu/wm_shrx.S b/sid/component/bochs/fpu/wm_shrx.S
new file mode 100644 (file)
index 0000000..5184283
--- /dev/null
@@ -0,0 +1,204 @@
+       .file   "wm_shrx.S"
+/*---------------------------------------------------------------------------+
+ |  wm_shrx.S                                                                |
+ |                                                                           |
+ | 64 bit right shift functions                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1995                                                   |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |   unsigned FPU_shrx(void *arg1, unsigned arg2)                            |
+ | and                                                                       |
+ |   unsigned FPU_shrxs(void *arg1, unsigned arg2)                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+/*---------------------------------------------------------------------------+
+ |   unsigned FPU_shrx(void *arg1, unsigned arg2)                            |
+ |                                                                           |
+ |   Extended shift right function.                                          |
+ |   Fastest for small shifts.                                               |
+ |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
+ |   right by the number of bits specified by the second arg (arg2).         |
+ |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
+ |                [  64 bit arg ][ eax ]                                     |
+ |            shift right  --------->                                        |
+ |   The eax register is initialized to 0 before the shifting.               |
+ |   Results returned in the 64 bit arg and eax.                             |
+ +---------------------------------------------------------------------------*/
+
+ENTRY(FPU_shrx)
+       push    %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       movl    PARAM2,%ecx
+       movl    PARAM1,%esi
+       cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
+       jnc     L_more_than_31
+
+/* less than 32 bits */
+       pushl   %ebx
+       movl    (%esi),%ebx     /* lsl */
+       movl    4(%esi),%edx    /* msl */
+       xorl    %eax,%eax       /* extension */
+       shrd    %cl,%ebx,%eax
+       shrd    %cl,%edx,%ebx
+       shr     %cl,%edx
+       movl    %ebx,(%esi)
+       movl    %edx,4(%esi)
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+
+L_more_than_31:
+       cmpl    $64,%ecx
+       jnc     L_more_than_63
+
+       subb    $32,%cl
+       movl    (%esi),%eax     /* lsl */
+       movl    4(%esi),%edx    /* msl */
+       shrd    %cl,%edx,%eax
+       shr     %cl,%edx
+       movl    %edx,(%esi)
+       movl    $0,4(%esi)
+       popl    %esi
+       leave
+       ret
+
+L_more_than_63:
+       cmpl    $96,%ecx
+       jnc     L_more_than_95
+
+       subb    $64,%cl
+       movl    4(%esi),%eax    /* msl */
+       shr     %cl,%eax
+       xorl    %edx,%edx
+       movl    %edx,(%esi)
+       movl    %edx,4(%esi)
+       popl    %esi
+       leave
+       ret
+
+L_more_than_95:
+       xorl    %eax,%eax
+       movl    %eax,(%esi)
+       movl    %eax,4(%esi)
+       popl    %esi
+       leave
+       ret
+
+
+/*---------------------------------------------------------------------------+
+ |   unsigned FPU_shrxs(void *arg1, unsigned arg2)                           |
+ |                                                                           |
+ |   Extended shift right function (optimized for small floating point       |
+ |   integers).                                                              |
+ |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
+ |   right by the number of bits specified by the second arg (arg2).         |
+ |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
+ |                [  64 bit arg ][ eax ]                                     |
+ |            shift right  --------->                                        |
+ |   The eax register is initialized to 0 before the shifting.               |
+ |   The lower 8 bits of eax are lost and replaced by a flag which is        |
+ |   set (to 0x01) if any bit, apart from the first one, is set in the       |
+ |   part which has been shifted out of the arg.                             |
+ |   Results returned in the 64 bit arg and eax.                             |
+ +---------------------------------------------------------------------------*/
+ENTRY(FPU_shrxs)
+       push    %ebp
+       movl    %esp,%ebp
+       pushl   %esi
+       pushl   %ebx
+       movl    PARAM2,%ecx
+       movl    PARAM1,%esi
+       cmpl    $64,%ecx        /* shrd only works for 0..31 bits */
+       jnc     Ls_more_than_63
+
+       cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
+       jc      Ls_less_than_32
+
+/* We got here without jumps by assuming that the most common requirement
+   is for small integers */
+/* Shift by [32..63] bits */
+       subb    $32,%cl
+       movl    (%esi),%eax     /* lsl */
+       movl    4(%esi),%edx    /* msl */
+       xorl    %ebx,%ebx
+       shrd    %cl,%eax,%ebx
+       shrd    %cl,%edx,%eax
+       shr     %cl,%edx
+       orl     %ebx,%ebx               /* test these 32 bits */
+       setne   %bl
+       test    $0x7fffffff,%eax        /* and 31 bits here */
+       setne   %bh
+       orw     %bx,%bx                 /* Any of the 63 bit set ? */
+       setne   %al
+       movl    %edx,(%esi)
+       movl    $0,4(%esi)
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+
+/* Shift by [0..31] bits */
+Ls_less_than_32:
+       movl    (%esi),%ebx     /* lsl */
+       movl    4(%esi),%edx    /* msl */
+       xorl    %eax,%eax       /* extension */
+       shrd    %cl,%ebx,%eax
+       shrd    %cl,%edx,%ebx
+       shr     %cl,%edx
+       test    $0x7fffffff,%eax        /* only need to look at eax here */
+       setne   %al
+       movl    %ebx,(%esi)
+       movl    %edx,4(%esi)
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+
+/* Shift by [64..95] bits */
+Ls_more_than_63:
+       cmpl    $96,%ecx
+       jnc     Ls_more_than_95
+
+       subb    $64,%cl
+       movl    (%esi),%ebx     /* lsl */
+       movl    4(%esi),%eax    /* msl */
+       xorl    %edx,%edx       /* extension */
+       shrd    %cl,%ebx,%edx
+       shrd    %cl,%eax,%ebx
+       shr     %cl,%eax
+       orl     %ebx,%edx
+       setne   %bl
+       test    $0x7fffffff,%eax        /* only need to look at eax here */
+       setne   %bh
+       orw     %bx,%bx
+       setne   %al
+       xorl    %edx,%edx
+       movl    %edx,(%esi)     /* set to zero */
+       movl    %edx,4(%esi)    /* set to zero */
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+
+Ls_more_than_95:
+/* Shift by [96..inf) bits */
+       xorl    %eax,%eax
+       movl    (%esi),%ebx
+       orl     4(%esi),%ebx
+       setne   %al
+       xorl    %ebx,%ebx
+       movl    %ebx,(%esi)
+       movl    %ebx,4(%esi)
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
diff --git a/sid/component/bochs/fpu/wm_shrx.c b/sid/component/bochs/fpu/wm_shrx.c
new file mode 100644 (file)
index 0000000..fd9cb74
--- /dev/null
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------+
+ |  wm_shrx.c                                                                |
+ |                                                                           |
+ | 64 bit right shift functions                                              |
+ |                                                                           |
+ | Copyright (C) 1992,1995,1999                                              |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |   unsigned FPU_shrx(void *arg1, unsigned arg2)                            |
+ |                                                                           |
+ |   Extended shift right function.                                          |
+ |   Fastest for small shifts.                                               |
+ |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
+ |   right by the number of bits specified by the second arg (arg2).         |
+ |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
+ |                [  64 bit arg ][ eax ]                                     |
+ |            shift right  --------->                                        |
+ |   The eax register is initialized to 0 before the shifting.               |
+ |   Results returned in the 64 bit arg and eax.                             |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+
+unsigned FPU_shrx(void *arg1, u32 arg2)
+{
+  u32 x;
+
+  if ( arg2 >= 64 )
+    {
+      if ( arg2 >= 96 )
+       {
+         *(u64 *)arg1 = 0;
+         return 0;
+       }
+      arg2 -= 64;
+      x = (*(u64 *)arg1) >> 32;
+      *(u64 *)arg1 = 0;
+
+      if ( arg2 )
+       return x >> arg2;
+      else
+       return x;
+    }
+
+  if ( arg2 < 32 )
+    {
+      if ( arg2 == 0 )
+       return 0;
+
+      x = (*(u64 *)arg1) << (32 - arg2);
+    }
+  else if ( arg2 > 32 )
+    {
+      x = (*(u64 *)arg1) >> (arg2 - 32);
+    }
+  else
+    {
+      /* arg2 == 32 */
+      x = *(u64 *)arg1;
+    }
+
+  (*(u64 *)arg1) >>= arg2;
+
+  return x;
+
+}
+
+
+/*---------------------------------------------------------------------------+
+ |   unsigned FPU_shrxs(void *arg1, unsigned arg2)                           |
+ |                                                                           |
+ |   Extended shift right function (optimized for small floating point       |
+ |   integers).                                                              |
+ |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
+ |   right by the number of bits specified by the second arg (arg2).         |
+ |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
+ |                [  64 bit arg ][ eax ]                                     |
+ |            shift right  --------->                                        |
+ |   The eax register is initialized to 0 before the shifting.               |
+ |   The lower 8 bits of eax are lost and replaced by a flag which is        |
+ |   set (to 0x01) if any bit, apart from the first one, is set in the       |
+ |   part which has been shifted out of the arg.                             |
+ |   Results returned in the 64 bit arg and eax.                             |
+ +---------------------------------------------------------------------------*/
+
+unsigned FPU_shrxs(void *arg1, u32 arg2)
+{
+  u32 x, bits;
+  u64 lost;
+
+  if ( arg2 >= 64 )
+    {
+      if ( arg2 >= 96 )
+       {
+         bits = *(u64 *)arg1 != 0;
+         *(u64 *)arg1 = 0;
+         return bits ? 1 : 0;
+       }
+      arg2 -= 64;
+      lost = (*(u64 *)arg1) << (32 - arg2);
+      x = (*(u64 *)arg1) >> 32;
+      *(u64 *)arg1 = 0;
+
+      if ( arg2 )
+       x >>= arg2;
+
+      if ( lost )
+       x |= 1;
+
+      return x;
+    }
+
+  if ( arg2 < 32 )
+    {
+      if ( arg2 == 0 )
+       /* No bits are lost */
+       return 0;
+
+      /* No bits are lost */
+      x = (*(u64 *)arg1) << (32 - arg2);
+    }
+  else if ( arg2 > 32 )
+    {
+      bits = (*(u64 *)arg1);
+      bits <<= (64 - arg2);
+      x = (*(u64 *)arg1) >> (arg2 - 32);
+      if ( bits )
+       x |= 1;
+    }
+  else
+    {
+      /* arg2 == 32 */
+      /* No bits are lost */
+      x = *(u64 *)arg1;
+    }
+
+  (*(u64 *)arg1) >>= arg2;
+
+  if ( x & 0x7fffffff )
+    x |= 1;
+
+  return x;
+
+}
+
diff --git a/sid/component/bochs/fpu/wm_sqrt.S b/sid/component/bochs/fpu/wm_sqrt.S
new file mode 100644 (file)
index 0000000..b261dc4
--- /dev/null
@@ -0,0 +1,470 @@
+       .file   "wm_sqrt.S"
+/*---------------------------------------------------------------------------+
+ |  wm_sqrt.S                                                                |
+ |                                                                           |
+ | Fixed point arithmetic square root evaluation.                            |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997                                         |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@suburbia.net               |
+ |                                                                           |
+ | Call from C as:                                                           |
+ |    int wm_sqrt(FPU_REG *n, unsigned int control_word)                     |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |  wm_sqrt(FPU_REG *n, unsigned int control_word)                           |
+ |    returns the square root of n in n.                                     |
+ |                                                                           |
+ |  Use Newton's method to compute the square root of a number, which must   |
+ |  be in the range  [1.0 .. 4.0),  to 64 bits accuracy.                     |
+ |  Does not check the sign or tag of the argument.                          |
+ |  Sets the exponent, but not the sign or tag of the result.                |
+ |                                                                           |
+ |  The guess is kept in %esi:%edi                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#ifndef NON_REENTRANT_FPU
+/*     Local storage on the stack: */
+#define FPU_accum_3    -4(%ebp)        /* ms word */
+#define FPU_accum_2    -8(%ebp)
+#define FPU_accum_1    -12(%ebp)
+#define FPU_accum_0    -16(%ebp)
+
+/*
+ * The de-normalised argument:
+ *                  sq_2                  sq_1              sq_0
+ *        b b b b b b b ... b b b   b b b .... b b b   b 0 0 0 ... 0
+ *           ^ binary point here
+ */
+#define FPU_fsqrt_arg_2        -20(%ebp)       /* ms word */
+#define FPU_fsqrt_arg_1        -24(%ebp)
+#define FPU_fsqrt_arg_0        -28(%ebp)       /* ls word, at most the ms bit is set */
+
+#else
+/*     Local storage in a static area: */
+.data
+       .align 4,0
+FPU_accum_3:
+       .long   0               /* ms word */
+FPU_accum_2:
+       .long   0
+FPU_accum_1:
+       .long   0
+FPU_accum_0:
+       .long   0
+
+/* The de-normalised argument:
+                    sq_2                  sq_1              sq_0
+          b b b b b b b ... b b b   b b b .... b b b   b 0 0 0 ... 0
+             ^ binary point here
+ */
+FPU_fsqrt_arg_2:
+       .long   0               /* ms word */
+FPU_fsqrt_arg_1:
+       .long   0
+FPU_fsqrt_arg_0:
+       .long   0               /* ls word, at most the ms bit is set */
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(wm_sqrt)
+       pushl   %ebp
+       movl    %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+       subl    $28,%esp
+#endif /* NON_REENTRANT_FPU */
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    PARAM1,%esi
+
+       movl    SIGH(%esi),%eax
+       movl    SIGL(%esi),%ecx
+       xorl    %edx,%edx
+
+/* We use a rough linear estimate for the first guess.. */
+
+       cmpw    EXP_BIAS,EXP(%esi)
+       jnz     sqrt_arg_ge_2
+
+       shrl    $1,%eax                 /* arg is in the range  [1.0 .. 2.0) */
+       rcrl    $1,%ecx
+       rcrl    $1,%edx
+
+sqrt_arg_ge_2:
+/* From here on, n is never accessed directly again until it is
+   replaced by the answer. */
+
+       movl    %eax,FPU_fsqrt_arg_2            /* ms word of n */
+       movl    %ecx,FPU_fsqrt_arg_1
+       movl    %edx,FPU_fsqrt_arg_0
+
+/* Make a linear first estimate */
+       shrl    $1,%eax
+       addl    $0x40000000,%eax
+       movl    $0xaaaaaaaa,%ecx
+       mull    %ecx
+       shll    %edx                    /* max result was 7fff... */
+       testl   $0x80000000,%edx        /* but min was 3fff... */
+       jnz     sqrt_prelim_no_adjust
+
+       movl    $0x80000000,%edx        /* round up */
+
+sqrt_prelim_no_adjust:
+       movl    %edx,%esi       /* Our first guess */
+
+/* We have now computed (approx)   (2 + x) / 3, which forms the basis
+   for a few iterations of Newton's method */
+
+       movl    FPU_fsqrt_arg_2,%ecx    /* ms word */
+
+/*
+ * From our initial estimate, three iterations are enough to get us
+ * to 30 bits or so. This will then allow two iterations at better
+ * precision to complete the process.
+ */
+
+/* Compute  (g + n/g)/2  at each iteration (g is the guess). */
+       shrl    %ecx            /* Doing this first will prevent a divide */
+                               /* overflow later. */
+
+       movl    %ecx,%edx       /* msw of the arg / 2 */
+       divl    %esi            /* current estimate */
+       shrl    %esi            /* divide by 2 */
+       addl    %eax,%esi       /* the new estimate */
+
+       movl    %ecx,%edx
+       divl    %esi
+       shrl    %esi
+       addl    %eax,%esi
+
+       movl    %ecx,%edx
+       divl    %esi
+       shrl    %esi
+       addl    %eax,%esi
+
+/*
+ * Now that an estimate accurate to about 30 bits has been obtained (in %esi),
+ * we improve it to 60 bits or so.
+ *
+ * The strategy from now on is to compute new estimates from
+ *      guess := guess + (n - guess^2) / (2 * guess)
+ */
+
+/* First, find the square of the guess */
+       movl    %esi,%eax
+       mull    %esi
+/* guess^2 now in %edx:%eax */
+
+       movl    FPU_fsqrt_arg_1,%ecx
+       subl    %ecx,%eax
+       movl    FPU_fsqrt_arg_2,%ecx    /* ms word of normalized n */
+       sbbl    %ecx,%edx
+       jnc     sqrt_stage_2_positive
+
+/* Subtraction gives a negative result,
+   negate the result before division. */
+       notl    %edx
+       notl    %eax
+       addl    $1,%eax
+       adcl    $0,%edx
+
+       divl    %esi
+       movl    %eax,%ecx
+
+       movl    %edx,%eax
+       divl    %esi
+       jmp     sqrt_stage_2_finish
+
+sqrt_stage_2_positive:
+       divl    %esi
+       movl    %eax,%ecx
+
+       movl    %edx,%eax
+       divl    %esi
+
+       notl    %ecx
+       notl    %eax
+       addl    $1,%eax
+       adcl    $0,%ecx
+
+sqrt_stage_2_finish:
+       sarl    $1,%ecx         /* divide by 2 */
+       rcrl    $1,%eax
+
+       /* Form the new estimate in %esi:%edi */
+       movl    %eax,%edi
+       addl    %ecx,%esi
+
+       jnz     sqrt_stage_2_done       /* result should be [1..2) */
+
+#ifdef PARANOID
+/* It should be possible to get here only if the arg is ffff....ffff */
+       cmp     $0xffffffff,FPU_fsqrt_arg_1
+       jnz     sqrt_stage_2_error
+#endif /* PARANOID */
+
+/* The best rounded result. */
+       xorl    %eax,%eax
+       decl    %eax
+       movl    %eax,%edi
+       movl    %eax,%esi
+       movl    $0x7fffffff,%eax
+       jmp     sqrt_round_result
+
+#ifdef PARANOID
+sqrt_stage_2_error:
+       pushl   EX_INTERNAL|0x213
+       call    EXCEPTION
+#endif /* PARANOID */
+
+sqrt_stage_2_done:
+
+/* Now the square root has been computed to better than 60 bits. */
+
+/* Find the square of the guess. */
+       movl    %edi,%eax               /* ls word of guess */
+       mull    %edi
+       movl    %edx,FPU_accum_1
+
+       movl    %esi,%eax
+       mull    %esi
+       movl    %edx,FPU_accum_3
+       movl    %eax,FPU_accum_2
+
+       movl    %edi,%eax
+       mull    %esi
+       addl    %eax,FPU_accum_1
+       adcl    %edx,FPU_accum_2
+       adcl    $0,FPU_accum_3
+
+/*     movl    %esi,%eax */
+/*     mull    %edi */
+       addl    %eax,FPU_accum_1
+       adcl    %edx,FPU_accum_2
+       adcl    $0,FPU_accum_3
+
+/* guess^2 now in FPU_accum_3:FPU_accum_2:FPU_accum_1 */
+
+       movl    FPU_fsqrt_arg_0,%eax            /* get normalized n */
+       subl    %eax,FPU_accum_1
+       movl    FPU_fsqrt_arg_1,%eax
+       sbbl    %eax,FPU_accum_2
+       movl    FPU_fsqrt_arg_2,%eax            /* ms word of normalized n */
+       sbbl    %eax,FPU_accum_3
+       jnc     sqrt_stage_3_positive
+
+/* Subtraction gives a negative result,
+   negate the result before division */
+       notl    FPU_accum_1
+       notl    FPU_accum_2
+       notl    FPU_accum_3
+       addl    $1,FPU_accum_1
+       adcl    $0,FPU_accum_2
+
+#ifdef PARANOID
+       adcl    $0,FPU_accum_3  /* This must be zero */
+       jz      sqrt_stage_3_no_error
+
+sqrt_stage_3_error:
+       pushl   EX_INTERNAL|0x207
+       call    EXCEPTION
+
+sqrt_stage_3_no_error:
+#endif /* PARANOID */
+
+       movl    FPU_accum_2,%edx
+       movl    FPU_accum_1,%eax
+       divl    %esi
+       movl    %eax,%ecx
+
+       movl    %edx,%eax
+       divl    %esi
+
+       sarl    $1,%ecx         /* divide by 2 */
+       rcrl    $1,%eax
+
+       /* prepare to round the result */
+
+       addl    %ecx,%edi
+       adcl    $0,%esi
+
+       jmp     sqrt_stage_3_finished
+
+sqrt_stage_3_positive:
+       movl    FPU_accum_2,%edx
+       movl    FPU_accum_1,%eax
+       divl    %esi
+       movl    %eax,%ecx
+
+       movl    %edx,%eax
+       divl    %esi
+
+       sarl    $1,%ecx         /* divide by 2 */
+       rcrl    $1,%eax
+
+       /* prepare to round the result */
+
+       notl    %eax            /* Negate the correction term */
+       notl    %ecx
+       addl    $1,%eax
+       adcl    $0,%ecx         /* carry here ==> correction == 0 */
+       adcl    $0xffffffff,%esi
+
+       addl    %ecx,%edi
+       adcl    $0,%esi
+
+sqrt_stage_3_finished:
+
+/*
+ * The result in %esi:%edi:%eax should be good to about 90 bits here,
+ * and the rounding information here does not have sufficient accuracy
+ * in a few rare cases.
+ */
+       cmpl    $0xffffffe0,%eax
+       ja      sqrt_near_exact_x
+
+       cmpl    $0x00000020,%eax
+       jb      sqrt_near_exact
+
+       cmpl    $0x7fffffe0,%eax
+       jb      sqrt_round_result
+
+       cmpl    $0x80000020,%eax
+       jb      sqrt_get_more_precision
+
+sqrt_round_result:
+/* Set up for rounding operations */
+       movl    %eax,%edx
+       movl    %esi,%eax
+       movl    %edi,%ebx
+       movl    PARAM1,%edi
+       movw    EXP_BIAS,EXP(%edi)      /* Result is in  [1.0 .. 2.0) */
+       jmp     fpu_reg_round
+
+
+sqrt_near_exact_x:
+/* First, the estimate must be rounded up. */
+       addl    $1,%edi
+       adcl    $0,%esi
+
+sqrt_near_exact:
+/*
+ * This is an easy case because x^1/2 is monotonic.
+ * We need just find the square of our estimate, compare it
+ * with the argument, and deduce whether our estimate is
+ * above, below, or exact. We use the fact that the estimate
+ * is known to be accurate to about 90 bits.
+ */
+       movl    %edi,%eax               /* ls word of guess */
+       mull    %edi
+       movl    %edx,%ebx               /* 2nd ls word of square */
+       movl    %eax,%ecx               /* ls word of square */
+
+       movl    %edi,%eax
+       mull    %esi
+       addl    %eax,%ebx
+       addl    %eax,%ebx
+
+#ifdef PARANOID
+       cmp     $0xffffffb0,%ebx
+       jb      sqrt_near_exact_ok
+
+       cmp     $0x00000050,%ebx
+       ja      sqrt_near_exact_ok
+
+       pushl   EX_INTERNAL|0x214
+       call    EXCEPTION
+
+sqrt_near_exact_ok:
+#endif /* PARANOID */
+
+       or      %ebx,%ebx
+       js      sqrt_near_exact_small
+
+       jnz     sqrt_near_exact_large
+
+       or      %ebx,%edx
+       jnz     sqrt_near_exact_large
+
+/* Our estimate is exactly the right answer */
+       xorl    %eax,%eax
+       jmp     sqrt_round_result
+
+sqrt_near_exact_small:
+/* Our estimate is too small */
+       movl    $0x000000ff,%eax
+       jmp     sqrt_round_result
+       
+sqrt_near_exact_large:
+/* Our estimate is too large, we need to decrement it */
+       subl    $1,%edi
+       sbbl    $0,%esi
+       movl    $0xffffff00,%eax
+       jmp     sqrt_round_result
+
+
+sqrt_get_more_precision:
+/* This case is almost the same as the above, except we start
+   with an extra bit of precision in the estimate. */
+       stc                     /* The extra bit. */
+       rcll    $1,%edi         /* Shift the estimate left one bit */
+       rcll    $1,%esi
+
+       movl    %edi,%eax               /* ls word of guess */
+       mull    %edi
+       movl    %edx,%ebx               /* 2nd ls word of square */
+       movl    %eax,%ecx               /* ls word of square */
+
+       movl    %edi,%eax
+       mull    %esi
+       addl    %eax,%ebx
+       addl    %eax,%ebx
+
+/* Put our estimate back to its original value */
+       stc                     /* The ms bit. */
+       rcrl    $1,%esi         /* Shift the estimate left one bit */
+       rcrl    $1,%edi
+
+#ifdef PARANOID
+       cmp     $0xffffff60,%ebx
+       jb      sqrt_more_prec_ok
+
+       cmp     $0x000000a0,%ebx
+       ja      sqrt_more_prec_ok
+
+       pushl   EX_INTERNAL|0x215
+       call    EXCEPTION
+
+sqrt_more_prec_ok:
+#endif /* PARANOID */
+
+       or      %ebx,%ebx
+       js      sqrt_more_prec_small
+
+       jnz     sqrt_more_prec_large
+
+       or      %ebx,%ecx
+       jnz     sqrt_more_prec_large
+
+/* Our estimate is exactly the right answer */
+       movl    $0x80000000,%eax
+       jmp     sqrt_round_result
+
+sqrt_more_prec_small:
+/* Our estimate is too small */
+       movl    $0x800000ff,%eax
+       jmp     sqrt_round_result
+       
+sqrt_more_prec_large:
+/* Our estimate is too large */
+       movl    $0x7fffff00,%eax
+       jmp     sqrt_round_result
diff --git a/sid/component/bochs/fpu/wm_sqrt.c b/sid/component/bochs/fpu/wm_sqrt.c
new file mode 100644 (file)
index 0000000..1b8e900
--- /dev/null
@@ -0,0 +1,340 @@
+/*---------------------------------------------------------------------------+
+ |  wm_sqrt.c                                                                |
+ |                                                                           |
+ | Fixed point arithmetic square root evaluation.                            |
+ |                                                                           |
+ | Copyright (C) 1992,1993,1995,1997,1999                                    |
+ |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ |    returns the square root of n in n.                                     |
+ |                                                                           |
+ |  Use Newton's method to compute the square root of a number, which must   |
+ |  be in the range  [1.0 .. 4.0),  to 64 bits accuracy.                     |
+ |  Does not check the sign or tag of the argument.                          |
+ |  Sets the exponent, but not the sign or tag of the result.                |
+ |                                                                           |
+ |  The guess is kept in %esi:%edi                                           |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+/*
+  The following value indicates the trailing bits (of 96 bits)
+  which may be in error when the final Newton iteration is finished
+  (0x20 corresponds to the last 5 bits in error, i.e. 91 bits precision).
+  A check of the following code with more than 3 billion (3.0e9) random
+  and selected values showed that 0x10 was always a large enough value,
+  so 0x20 should be a conservative choice.
+ */
+#define ERR_MARGIN 0x20
+
+
+int wm_sqrt(FPU_REG *n, s32 dummy1, s32 dummy2, u16 control_w, u8 sign)
+{
+  u64 nn, guess, halfn, lowr, mid, upr, diff, uwork;
+  s64 work;
+  u32 ne, guess32, work32, diff32, mid32;
+  int shifted;
+
+  nn = significand(n);
+  ne = 0;
+  if ( exponent16(n) == EXP_BIAS )
+    {
+      /* Shift the argument right one position. */
+      if ( nn & 1 )
+       ne = 0x80000000;
+      nn >>= 1;
+      guess = n->sigh >> 2;
+      shifted = 1;
+    }
+  else
+    {
+      guess = n->sigh >> 1;
+      shifted = 0;
+    }
+
+  guess += 0x40000000;
+  guess *= 0xaaaaaaaa;
+  guess <<= 1;
+  guess32 = guess >> 32;
+  if ( !(guess32 & 0x80000000) )
+    guess32 = 0x80000000;
+  halfn = nn >> 1;
+
+  guess32 = halfn / guess32 + (guess32 >> 1);
+  guess32 = halfn / guess32 + (guess32 >> 1);
+  guess32 = halfn / guess32 + (guess32 >> 1);
+
+
+/*
+ * Now that an estimate accurate to about 30 bits has been obtained,
+ * we improve it to 60 bits or so.
+ *
+ * The strategy from now on is to compute new estimates from
+ *      guess := guess + (n - guess^2) / (2 * guess)
+ */
+
+  work = guess32;
+  work = nn - work * guess32;
+  work <<= 28;       /* 29 - 1 */
+  work /= guess32;
+  work <<= 3;        /* 29 + 3 = 32 */
+  work += ((u64)guess32) << 32;
+
+  if ( work == 0 )  /* This happens in one or two special cases */
+    work = BX_CONST64(0xffffffffffffffff);
+
+  guess = work;
+
+  /* guess is now accurate to about 60 bits */
+
+
+  if ( work > 0 )
+    {
+#ifdef PARANOID
+      if ( (n->sigh != 0xffffffff) && (n->sigl != 0xffffffff) )
+       {
+         EXCEPTION(EX_INTERNAL|0x213);
+       }
+#endif
+      /* We know the answer here. */
+      return FPU_round(n, 0x7fffffff, 0, control_w, sign);
+    }
+
+  /* Refine the guess to significantly more than 64 bits. */
+
+  /* First, square the current guess. */
+
+  guess32 = guess >> 32;
+  work32 = guess;
+
+  /* lower 32 times lower 32 */
+  lowr = work32;
+  lowr *= work32;
+
+  /* lower 32 times upper 32 */
+  mid = guess32;
+  mid *= work32;
+
+  /* upper 32 times upper 32 */
+  upr = guess32;
+  upr *= guess32;
+
+  /* upper 32 bits of the middle product times 2 */
+  upr += mid >> (32-1);
+
+  /* lower 32 bits of the middle product times 2 */
+  work32 = mid << 1;
+
+  /* upper 32 bits of the lower product */
+  mid32 = lowr >> 32;
+  mid32 += work32;
+  if ( mid32 < work32 )
+    upr ++;
+
+  /* We now have the first 96 bits (truncated) of the square of the guess */
+
+  diff = upr - nn;
+  diff32 = mid32 - ne;
+  if ( diff32 > mid32 )
+    diff --;
+
+  if ( ((s64)diff) < 0 )
+    {
+      /* The difference is negative, negate it. */
+      diff32 = -((s32)diff32);
+      diff = ~diff;
+      if ( diff32 == 0 )
+       diff ++;
+#ifdef PARANOID
+      if ( (diff >> 32) != 0 )
+       {
+         EXCEPTION(EX_INTERNAL|0x207);
+       }
+#endif
+
+      diff <<= 32;
+      diff |= diff32;
+      work32 = diff / guess32;
+      work = work32;
+      work <<= 32;
+
+      diff = diff % guess32;
+      diff <<= 32;
+      work32 = diff / guess32;
+
+      work |= work32;
+
+      work >>= 1;
+      work32 = work >> 32;
+
+
+      guess += work32;       /* The first 64 bits */
+      guess32 = work;        /* The next 32 bits */
+      /* The guess should now be good to about 90 bits */
+    }
+  else
+    {
+      /* The difference is positive. */
+      diff <<= 32;
+      diff |= diff32;
+
+      work32 = diff / guess32;
+      work = work32;
+      work <<= 32;
+
+      diff = diff % guess32;
+      diff <<= 32;
+      work32 = diff / guess32;
+
+      work |= work32;
+
+      work >>= 1;
+      work32 = work >> 32;
+
+      guess32 = work;        /* The last 32 bits (of 96) */
+      guess32 = -guess32;
+      if ( guess32 )
+       guess --;
+      guess -= work32;       /* The first 64 bits */
+      /* The guess should now be good to about 90 bits */
+    }
+
+
+  setexponent16(n, 0);
+
+  if ( guess32 >= (u32) -ERR_MARGIN )
+    {
+      /* Nearly exact, we round the 64 bit result upward. */
+      guess ++;
+    }
+  else if ( (guess32 > ERR_MARGIN) &&
+          ((guess32 < 0x80000000-ERR_MARGIN)
+           || (guess32 > 0x80000000+ERR_MARGIN)) )
+    {
+      /* We have enough accuracy to decide rounding */
+      significand(n) = guess;
+      return FPU_round(n, guess32, 0, control_w, sign);
+    }
+
+  if ( (guess32 <= ERR_MARGIN) || (guess32 >= (u32) -ERR_MARGIN) )
+    {
+      /*
+       * This is an easy case because x^1/2 is monotonic.
+       * We need just find the square of our estimate, compare it
+       * with the argument, and deduce whether our estimate is
+       * above, below, or exact. We use the fact that the estimate
+       * is known to be accurate to about 90 bits.
+       */
+
+
+      /* We compute the lower 64 bits of the 128 bit product */
+      work32 = guess;
+      lowr = work32;
+      lowr *= work32;
+
+      uwork = guess >> 32;
+      work32 = guess;
+      uwork *= work32;
+      uwork <<= 33;   /* 33 = 32+1 (for two times the product) */
+
+      lowr += uwork;  /* We now have the 64 bits */
+
+      /* We need only look at bits 65..96 of the square of guess. */
+      if ( shifted )
+       work32 = lowr >> 31;
+      else
+       work32 = lowr >> 32;
+
+#ifdef PARANOID
+      if ( ((s32)work32 > 3*ERR_MARGIN) || ((s32)work32 < -3*ERR_MARGIN) )
+       {
+         EXCEPTION(EX_INTERNAL|0x214);
+       }
+#endif
+
+      significand(n) = guess;
+      if ( (s32)work32 > 0 )
+       {
+         /* guess is too large */
+         significand(n) --;
+         return FPU_round(n, 0xffffff00, 0, control_w, sign);
+       }
+      else if ( (s32)work32 < 0 )
+       {
+         /* guess is a little too small */
+         return FPU_round(n, 0x000000ff, 0, control_w, sign);
+       }
+
+      else if ( (u32)lowr != 0 )
+       {
+
+         /* guess is too large */
+         significand(n) --;
+         return FPU_round(n, 0xffffff00, 0, control_w, sign);
+       }
+
+      /* Our guess is precise. */
+      return FPU_round(n, 0, 0, control_w, sign);
+    }
+
+  /* Very similar to the case above, but the last bit is near 0.5.
+     We handle this just like the case above but we shift everything
+     by one bit. */
+
+
+  uwork = guess;
+  uwork <<= 1;
+  uwork |= 1;      /* add the half bit */
+
+  /* We compute the lower 64 bits of the 128 bit product */
+  work32 = uwork;
+  lowr = work32;
+  lowr *= work32;
+
+  work32 = uwork >> 32;
+  uwork &= 0xffffffff;
+  uwork *= work32;
+  uwork <<= 33;   /* 33 = 32+1 (for two times the product) */
+
+  lowr += uwork;  /* We now have the 64 bits. The lowest 32 bits of lowr
+                    are not all zero (the lsb is 1). */
+
+  /* We need only look at bits 65..96 of the square of guess. */
+  if ( shifted )
+    work32 = lowr >> 31;
+  else
+    work32 = lowr >> 32;
+
+#ifdef PARANOID
+  if ( ((s32)work32 > 4*3*ERR_MARGIN) || ((s32)work32 < -4*3*ERR_MARGIN) )
+    {
+      EXCEPTION(EX_INTERNAL|0x215);
+    }
+#endif
+
+  significand(n) = guess;
+  if ( (s32)work32 < 0 )
+    {
+      /* guess plus half bit is a little too small */
+      return FPU_round(n, 0x800000ff, 0, control_w, sign);
+    }
+  else /* Note that the lower 64 bits of the product are not all zero */
+    {
+      /* guess plus half bit is too large */
+      return FPU_round(n, 0x7fffff00, 0, control_w, sign);
+    }
+
+  /*
+    Note that the result of a square root cannot have precisely a half bit
+    of a least significant place (it is left as an exercise for the reader
+    to prove this! (hint: 65 bit*65 bit => n bits)).
+  */
+
+}
+
diff --git a/sid/component/bochs/install-sh b/sid/component/bochs/install-sh
new file mode 100644 (file)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/sid/component/bochs/instrument.h b/sid/component/bochs/instrument.h
new file mode 100644 (file)
index 0000000..031a4fd
--- /dev/null
@@ -0,0 +1,251 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+// possible types passed to BX_INSTR_TLB_CNTRL()
+#define BX_INSTR_MOV_CR3     10
+#define BX_INSTR_INVLPG      11
+#define BX_INSTR_TASKSWITCH  12
+
+// possible types passed to BX_INSTR_CACHE_CNTRL()
+#define BX_INSTR_INVD      20
+#define BX_INSTR_WBINVD    21
+
+
+
+#if BX_INSTRUMENTATION
+
+#define BX_INSTR_IS_CALL  10
+#define BX_INSTR_IS_RET   11
+#define BX_INSTR_IS_IRET  12
+#define BX_INSTR_IS_JMP   13
+#define BX_INSTR_IS_INT   14
+
+
+// called from the CPU core
+void bx_instr_cnear_branch_taken(Bit32u new_eip);
+void bx_instr_cnear_branch_not_taken(void);
+void bx_instr_ucnear_branch(unsigned what, Bit32u new_eip);
+void bx_instr_far_branch(unsigned what, Bit32u new_cs, Bit32u new_eip);
+void bx_instr_opcode_byte1(Bit8u);
+void bx_instr_opcode_byte2(Bit8u);
+void bx_instr_opcode_g1ebib(unsigned nnn);
+void bx_instr_opcode_g1eviv(unsigned nnn);
+void bx_instr_opcode_g1evib(unsigned nnn);
+void bx_instr_opcode_g2ebib(unsigned nnn);
+void bx_instr_opcode_g2evib(unsigned nnn);
+void bx_instr_opcode_g2eb1(unsigned nnn);
+void bx_instr_opcode_g2ev1(unsigned nnn);
+void bx_instr_opcode_g2ebcl(unsigned nnn);
+void bx_instr_opcode_g2evcl(unsigned nnn);
+void bx_instr_opcode_g3eb(unsigned nnn);
+void bx_instr_opcode_g3ev(unsigned nnn);
+void bx_instr_opcode_g4(unsigned nnn);
+void bx_instr_opcode_g5(unsigned nnn);
+void bx_instr_opcode_g6(unsigned nnn);
+void bx_instr_opcode_g7(unsigned nnn);
+void bx_instr_opcode_g8evib(unsigned nnn);
+void bx_instr_mem_code(Bit32u linear, unsigned size);
+void bx_instr_mem_data(Bit32u linear, unsigned size, unsigned rw);
+void bx_instr_opcode_begin(Bit32u linear);
+void bx_instr_opcode_end(Bit32u linear);
+void bx_instr_fetch_byte(Bit8u val8);
+void bx_instr_fetch_word(Bit16u val16);
+void bx_instr_fetch_dword(Bit32u val32);
+void bx_instr_phy_write(Bit32u addr, unsigned len);
+void bx_instr_phy_read(Bit32u addr, unsigned len);
+void bx_instr_interrupt(unsigned vector);
+void bx_instr_exception(unsigned vector);
+void bx_instr_inp(Bit16u addr, unsigned len);
+void bx_instr_outp(Bit16u addr, unsigned len);
+void bx_instr_tlb_cntrl(unsigned what, Bit32u newval);
+void bx_instr_cache_cntrl(unsigned what);
+void bx_instr_hwinterrupt(unsigned vector, Bit32u cs, Bit32u eip);
+void bx_instr_init(void);
+void bx_instr_shutdown(void);
+void bx_instr_opcode_repeating(void);
+void bx_instr_prefix_as(void);
+void bx_instr_prefix_os(void);
+void bx_instr_prefix_rep(void);
+void bx_instr_prefix_repne(void);
+void bx_instr_prefix_lock(void);
+void bx_instr_prefix_cs(void);
+void bx_instr_prefix_ss(void);
+void bx_instr_prefix_ds(void);
+void bx_instr_prefix_es(void);
+void bx_instr_prefix_fs(void);
+void bx_instr_prefix_gs(void);
+void bx_instr_modrm32(unsigned modrm);
+void bx_instr_sib32(unsigned sib);
+void bx_instr_modrm16(unsigned modrm);
+void bx_instr_iret(void);
+void bx_instr_debug_prompt(void);
+void bx_instr_lin_read(Bit32u lin, Bit32u phy, unsigned len);
+void bx_instr_lin_write(Bit32u lin, Bit32u phy, unsigned len);
+
+// called from the debug prompt
+void bx_instr_start(void);
+void bx_instr_stop(void);
+void bx_instr_reset(void);
+void bx_instr_print(void);
+
+#  define BX_INSTR_INIT()                      bx_instr_init()
+#  define BX_INSTR_SHUTDOWN()                  bx_instr_shutdown()
+#  define BX_INSTR_CNEAR_BRANCH_TAKEN(new_eip) bx_instr_cnear_branch_taken(new_eip)
+#  define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN()    bx_instr_cnear_branch_not_taken()
+#  define BX_INSTR_UCNEAR_BRANCH(what, new_eip) bx_instr_ucnear_branch(what, new_eip)
+#  define BX_INSTR_FAR_BRANCH(what, new_cs, new_eip) bx_instr_far_branch(what, new_cs, new_eip)
+#  define BX_INSTR_OPCODE_BEGIN(linear)        bx_instr_opcode_begin(linear)
+#  define BX_INSTR_OPCODE_END(linear)          bx_instr_opcode_end(linear)
+#  define BX_INSTR_OPCODE_BYTE1(b)             bx_instr_opcode_byte1(b)
+#  define BX_INSTR_OPCODE_BYTE2(b)             bx_instr_opcode_byte2(b)
+#  define BX_INSTR_OPCODE_G1EbIb(nnn)          bx_instr_opcode_g1ebib(nnn)
+#  define BX_INSTR_OPCODE_G1EvIv(nnn)          bx_instr_opcode_g1eviv(nnn)
+#  define BX_INSTR_OPCODE_G1EvIb(nnn)          bx_instr_opcode_g1evib(nnn)
+#  define BX_INSTR_OPCODE_G2EbIb(nnn)          bx_instr_opcode_g2ebib(nnn)
+#  define BX_INSTR_OPCODE_G2EvIb(nnn)          bx_instr_opcode_g2evib(nnn)
+#  define BX_INSTR_OPCODE_G2Eb1(nnn)           bx_instr_opcode_g2eb1(nnn)
+#  define BX_INSTR_OPCODE_G2Ev1(nnn)           bx_instr_opcode_g2ev1(nnn)
+#  define BX_INSTR_OPCODE_G2EbCL(nnn)          bx_instr_opcode_g2ebcl(nnn)
+#  define BX_INSTR_OPCODE_G2EvCL(nnn)          bx_instr_opcode_g2evcl(nnn)
+#  define BX_INSTR_OPCODE_G3Eb(nnn)            bx_instr_opcode_g3eb(nnn)
+#  define BX_INSTR_OPCODE_G3Ev(nnn)            bx_instr_opcode_g3ev(nnn)
+#  define BX_INSTR_OPCODE_G4(nnn)              bx_instr_opcode_g4(nnn)
+#  define BX_INSTR_OPCODE_G5(nnn)              bx_instr_opcode_g5(nnn)
+#  define BX_INSTR_OPCODE_G6(nnn)              bx_instr_opcode_g6(nnn)
+#  define BX_INSTR_OPCODE_G7(nnn)              bx_instr_opcode_g7(nnn)
+#  define BX_INSTR_OPCODE_G8EvIb(nnn)          bx_instr_opcode_g8evib(nnn)
+#  define BX_INSTR_MEM_CODE(linear, size)      bx_instr_mem_code(linear, size)
+#  define BX_INSTR_MEM_DATA(linear, size, rw)  bx_instr_mem_data(linear, size, rw)
+#  define BX_INSTR_EXCEPTION(vector)           bx_instr_exception(vector)
+#  define BX_INSTR_INP(addr, len)              bx_instr_inp(addr, len)
+#  define BX_INSTR_OUTP(addr, len)             bx_instr_outp(addr, len)
+#  define BX_INSTR_FETCH_BYTE(val8)            bx_instr_fetch_byte(val8)
+#  define BX_INSTR_FETCH_WORD(val16)           bx_instr_fetch_word(val16)
+#  define BX_INSTR_FETCH_DWORD(val32)          bx_instr_fetch_dword(val32)
+#  define BX_INSTR_PHY_WRITE(addr, len)        bx_instr_phy_write(addr, len)
+#  define BX_INSTR_PHY_READ(addr, len)         bx_instr_phy_read(addr, len)
+#  define BX_INSTR_INTERRUPT(vector)           bx_instr_interrupt(vector)
+
+#  define BX_INSTR_TLB_CNTRL(what, newval)     bx_instr_tlb_cntrl(what, newval)
+#  define BX_INSTR_CACHE_CNTRL(what)           bx_instr_cache_cntrl(what)
+#  define BX_INSTR_HWINTERRUPT(vector, cs, eip) bx_instr_hwinterrupt(vector, cs, eip)
+#  define BX_INSTR_OPCODE_REPEATING()           bx_instr_opcode_repeating()
+
+#  define BX_INSTR_PREFIX_AS()                 bx_instr_prefix_as()
+#  define BX_INSTR_PREFIX_OS()                 bx_instr_prefix_os()
+#  define BX_INSTR_PREFIX_REP()                bx_instr_prefix_rep()
+#  define BX_INSTR_PREFIX_REPNE()              bx_instr_prefix_repne()
+#  define BX_INSTR_PREFIX_LOCK()               bx_instr_prefix_lock()
+#  define BX_INSTR_PREFIX_CS()                 bx_instr_prefix_cs()
+#  define BX_INSTR_PREFIX_SS()                 bx_instr_prefix_ss()
+#  define BX_INSTR_PREFIX_DS()                 bx_instr_prefix_ds()
+#  define BX_INSTR_PREFIX_ES()                 bx_instr_prefix_es()
+#  define BX_INSTR_PREFIX_FS()                 bx_instr_prefix_fs()
+#  define BX_INSTR_PREFIX_GS()                 bx_instr_prefix_gs()
+
+#  define BX_INSTR_MODRM32(modrm)              bx_instr_modrm32(modrm)
+#  define BX_INSTR_SIB32(sib)                  bx_instr_sib32(sib)
+#  define BX_INSTR_MODRM16(modrm)              bx_instr_modrm16(modrm)
+#  define BX_INSTR_SIB_mod0_base5(ss)
+#  define BX_INSTR_SIB_MOD0_IND4()
+#  define BX_INSTR_SIB_MOD1_IND4()
+#  define BX_INSTR_SIB_MOD2_IND4()
+
+#  define BX_INSTR_IRET()                      bx_instr_iret()
+#  define BX_INSTR_DEBUG_PROMPT()              bx_instr_debug_prompt()
+
+#  define BX_INSTR_LIN_READ(lin, phy, len)  bx_instr_lin_read(lin, phy, len)
+#  define BX_INSTR_LIN_WRITE(lin, phy, len) bx_instr_lin_write(lin, phy, len)
+
+#else  // #if BX_INSTRUMENTATION
+#  define BX_INSTR_INIT()
+#  define BX_INSTR_SHUTDOWN()
+#  define BX_INSTR_CNEAR_BRANCH_TAKEN(new_eip)
+#  define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN()
+#  define BX_INSTR_UCNEAR_BRANCH(what, new_eip)
+#  define BX_INSTR_FAR_BRANCH(what, new_cs, new_eip)
+#  define BX_INSTR_OPCODE_BEGIN(linear)
+#  define BX_INSTR_OPCODE_END(linear)
+#  define BX_INSTR_OPCODE_BYTE1(b)
+#  define BX_INSTR_OPCODE_BYTE2(b)
+#  define BX_INSTR_OPCODE_G1EbIb(nnn)
+#  define BX_INSTR_OPCODE_G1EvIv(nnn)
+#  define BX_INSTR_OPCODE_G1EvIb(nnn)
+#  define BX_INSTR_OPCODE_G2EbIb(nnn)
+#  define BX_INSTR_OPCODE_G2EvIb(nnn)
+#  define BX_INSTR_OPCODE_G2Eb1(nnn)
+#  define BX_INSTR_OPCODE_G2Ev1(nnn)
+#  define BX_INSTR_OPCODE_G2EbCL(nnn)
+#  define BX_INSTR_OPCODE_G2EvCL(nnn)
+#  define BX_INSTR_OPCODE_G3Eb(nnn)
+#  define BX_INSTR_OPCODE_G3Ev(nnn)
+#  define BX_INSTR_OPCODE_G4(nnn)
+#  define BX_INSTR_OPCODE_G5(nnn)
+#  define BX_INSTR_OPCODE_G6(nnn)
+#  define BX_INSTR_OPCODE_G7(nnn)
+#  define BX_INSTR_OPCODE_G8EvIb(nnn)
+#  define BX_INSTR_MEM_CODE(linear, size)
+#  define BX_INSTR_MEM_DATA(linear, size, rw)
+#  define BX_INSTR_EXCEPTION(vector)
+#  define BX_INSTR_INP(addr, len)
+#  define BX_INSTR_OUTP(addr, len)
+#  define BX_INSTR_FETCH_BYTE(val8)
+#  define BX_INSTR_FETCH_WORD(val16)
+#  define BX_INSTR_FETCH_DWORD(val32)
+#  define BX_INSTR_PHY_WRITE(addr, len)
+#  define BX_INSTR_PHY_READ(addr, len)
+#  define BX_INSTR_INTERRUPT(vector)
+#  define BX_INSTR_TLB_CNTRL(what, newval)
+#  define BX_INSTR_CACHE_CNTRL(what)
+#  define BX_INSTR_HWINTERRUPT(vector, cs, eip)
+#  define BX_INSTR_OPCODE_REPEATING()
+
+#  define BX_INSTR_PREFIX_AS()
+#  define BX_INSTR_PREFIX_OS()
+#  define BX_INSTR_PREFIX_REP()
+#  define BX_INSTR_PREFIX_REPNE()
+#  define BX_INSTR_PREFIX_LOCK()
+#  define BX_INSTR_PREFIX_CS()
+#  define BX_INSTR_PREFIX_SS()
+#  define BX_INSTR_PREFIX_DS()
+#  define BX_INSTR_PREFIX_ES()
+#  define BX_INSTR_PREFIX_FS()
+#  define BX_INSTR_PREFIX_GS()
+
+#  define BX_INSTR_MODRM32(modrm)
+#  define BX_INSTR_SIB32(sib)
+#  define BX_INSTR_MODRM16(modrm)
+#  define BX_INSTR_SIB_mod0_base5(ss)
+#  define BX_INSTR_SIB_MOD0_IND4()
+#  define BX_INSTR_SIB_MOD1_IND4()
+#  define BX_INSTR_SIB_MOD2_IND4()
+
+#  define BX_INSTR_IRET()
+#  define BX_INSTR_DEBUG_PROMPT()
+
+#  define BX_INSTR_LIN_READ(lin, phy, len)
+#  define BX_INSTR_LIN_WRITE(lin, phy, len)
+
+#endif  // #if BX_INSTRUMENTATION
+
diff --git a/sid/component/bochs/ltconfig b/sid/component/bochs/ltconfig
new file mode 100644 (file)
index 0000000..c14d83c
--- /dev/null
@@ -0,0 +1,3114 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}"   = Xset; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4* | osf5*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:991: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1015: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1018: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left by newer dlltools.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols'
+
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      cat $export_symbols | while read symbol; do
+        set dummy \$symbol;
+        case \$# in
+          2) echo "    \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;;
+          *) echo "     \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;;
+        esac;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+        whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+        whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)  # As osf3* with the addition of the -msym flag
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+  rhapsody*)
+    archive_cmds='$CC -bundle -undefined suppress -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flags_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+                                       
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o 
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $linkopts'
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  unixware7*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1653: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1654: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1657: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  case "$host_os" in
+  hpux10.20*)
+    # TODO:  Does this work for hpux-11 too?
+    deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    file_magic_cmd=/usr/bin/file
+    file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method=pass_all
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rhapsody*)
+  version_type=sunos
+  library_names_spec='${libname}.so'
+  soname_spec='${libname}.so'
+  shlibpath_var=DYLD_LIBRARY_PATH
+  deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    sequent)
+      file_magic_cmd='/bin/file'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+      ;;
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2248: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2256 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2288: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2293 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2335: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2343 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2375: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2380 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2423: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2431 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2488: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2493 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2526: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2534 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2599: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2607 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/sid/component/bochs/ltmain.sh b/sid/component/bochs/ltmain.sh
new file mode 100644 (file)
index 0000000..a9b7a67
--- /dev/null
@@ -0,0 +1,4028 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+       case "$arg" in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+       if test "$user_target" != "no"; then
+         $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+         exit 1
+       fi
+       user_target=next
+       ;;
+
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+      esac
+
+      case "$user_target" in
+      next)
+       # The next one is the -o target name
+       user_target=yes
+       continue
+       ;;
+      yes)
+       # We got the output file
+       user_target=set
+       libobj="$arg"
+       continue
+       ;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case "$user_target" in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until ln "$0" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      command="$base_compile $srcfile $pic_flag -DPIC"
+      if test "$build_old_libs" = yes; then
+       lo_libobj="$libobj"
+       dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$dir" = "X$libobj"; then
+         dir="$objdir"
+       else
+         dir="$dir/$objdir"
+       fi
+       libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+       if test -d "$dir"; then
+         $show "$rm $libobj"
+         $run $rm $libobj
+       else
+         $show "$mkdir $dir"
+         $run $mkdir $dir
+         status=$?
+         if test $status -ne 0 && test ! -d $dir; then
+           exit $status
+         fi
+       fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+       output_obj="$libobj"
+       command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+       output_obj="$obj"
+       command="$command -o $output_obj"
+      fi
+
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+       $show "$mv $output_obj $libobj"
+       if $run $mv $output_obj $libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+       # Rename the .lo from within objdir to obj
+       if test -f $obj; then
+         $show $rm $obj
+         $run $rm $obj
+       fi
+
+       $show "$mv $libobj $obj"
+       if $run $mv $libobj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+
+       xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$obj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+       libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+       # Now arrange that obj and lo_libobj become the same file
+       $show "(cd $xdir && $LN_S $baseobj $libobj)"
+       if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+         exit 0
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      command="$base_compile $srcfile"
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+       output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > \$libobj" || exit $?
+      else
+       # Move the .lo from within objdir
+       $show "$mv $libobj $lo_libobj"
+       if $run $mv $libobj $lo_libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    case "$host" in
+    *-*-cygwin* | *-*-mingw* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+      # This is a source program that is used to create import libraries
+      # on Windows for dlls which lack them. Don't remove nor modify the
+      # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999 Free Software Foundation, Inc.
+# 
+#  This file is part of GNU libtool.
+# 
+#  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.
+#  */
+# 
+#  #include <stdio.h>          /* for printf() */
+#  #include <unistd.h>         /* for open(), lseek(), read() */
+#  #include <fcntl.h>          /* for O_RDONLY, O_BINARY */
+#  #include <string.h>         /* for strdup() */
+# 
+#  static unsigned int
+#  pe_get16 (fd, offset)
+#       int fd;
+#       int offset;
+#  {
+#    unsigned char b[2];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 2);
+#    return b[0] + (b[1]<<8);
+#  }
+# 
+#  static unsigned int
+#  pe_get32 (fd, offset)
+#      int fd;
+#      int offset;
+#  {
+#    unsigned char b[4];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 4);
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  static unsigned int
+#  pe_as32 (ptr)
+#       void *ptr;
+#  {
+#    unsigned char *b = ptr;
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  int
+#  main (argc, argv)
+#      int argc;
+#      char *argv[];
+#  {
+#      int dll;
+#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#      unsigned long export_rva, export_size, nsections, secptr, expptr;
+#      unsigned long name_rvas, nexp;
+#      unsigned char *expdata, *erva;
+#      char *filename, *dll_name;
+# 
+#      filename = argv[1];
+# 
+#      dll = open(filename, O_RDONLY|O_BINARY);
+#      if (!dll)
+#      return 1;
+# 
+#      dll_name = filename;
+#    
+#      for (i=0; filename[i]; i++)
+#      if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#          dll_name = filename + i +1;
+# 
+#      pe_header_offset = pe_get32 (dll, 0x3c);
+#      opthdr_ofs = pe_header_offset + 4 + 20;
+#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
+# 
+#      if (num_entries < 1) /* no exports */
+#      return 1;
+# 
+#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#      export_size = pe_get32 (dll, opthdr_ofs + 100);
+#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#      secptr = (pe_header_offset + 4 + 20 +
+#            pe_get16 (dll, pe_header_offset + 4 + 16));
+# 
+#      expptr = 0;
+#      for (i = 0; i < nsections; i++)
+#      {
+#      char sname[8];
+#      unsigned long secptr1 = secptr + 40 * i;
+#      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#      lseek(dll, secptr1, SEEK_SET);
+#      read(dll, sname, 8);
+#      if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#      {
+#          expptr = fptr + (export_rva - vaddr);
+#          if (export_rva + export_size > vaddr + vsize)
+#              export_size = vsize - (export_rva - vaddr);
+#          break;
+#      }
+#      }
+# 
+#      expdata = (unsigned char*)malloc(export_size);
+#      lseek (dll, expptr, SEEK_SET);
+#      read (dll, expdata, export_size);
+#      erva = expdata - export_rva;
+# 
+#      nexp = pe_as32 (expdata+24);
+#      name_rvas = pe_as32 (expdata+32);
+# 
+#      printf ("EXPORTS\n");
+#      for (i = 0; i<nexp; i++)
+#      {
+#      unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#      printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#      }
+# 
+#      return 0;
+#  }
+# /* impgen.c ends here */
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    linkopts=
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      lib_search_path=
+    fi
+    # now prepend the system-specific ones
+    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+    
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    module=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       prefer_static_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case "$prev" in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case "$prev" in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case "$arg" in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit 1
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case "$arg" in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit 1
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: not more than one -exported-symbols argument allowed"
+         exit 1
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           absdir="$dir"
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case " $deplibs " in
+       *" $arg "*) ;;
+       *) deplibs="$deplibs $arg";;
+       esac
+       case " $lib_search_path " in
+       *" $dir "*) ;;
+       *) lib_search_path="$lib_search_path $dir";;
+       esac
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2*)
+         dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+         case ":$dllsearchpath:" in
+         ::) dllsearchpath="$dllsearchdir";;
+         *":$dllsearchdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+         esac
+         ;;
+       esac
+       ;;
+
+      -l*)
+       if test "$arg" = "-lc"; then
+         case "$host" in
+         *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+           # These systems don't actually have c library (as such)
+           continue
+           ;;
+         esac
+       elif test "$arg" = "-lm"; then
+         case "$host" in
+         *-*-cygwin* | *-*-beos*)
+           # These systems don't actually have math library (as such)
+           continue
+           ;;
+         esac
+       fi
+       deplibs="$deplibs $arg"
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit 1
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.o | *.obj | *.a | *.lib)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       dlname=
+       libdir=
+       library_names=
+       old_library=
+
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+         exit 1
+       fi
+
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variable installed.
+       installed=yes
+
+       # Read the .la file
+       # If there is no directory component, then add one.
+       case "$arg" in
+       */* | *\\*) . $arg ;;
+       *) . ./$arg ;;
+       esac
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+         exit 1
+       fi
+
+       # Find the relevant object directory and library name.
+       name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+       if test "X$installed" = Xyes; then
+         dir="$libdir"
+       else
+         dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$dir" = "X$arg"; then
+           dir="$objdir"
+         else
+           dir="$dir/$objdir"
+         fi
+       fi
+
+       if test -n "$dependency_libs"; then
+         # Extract -R and -L from dependency_libs
+         temp_deplibs=
+         for deplib in $dependency_libs; do
+           case "$deplib" in
+           -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+                case " $rpath $xrpath " in
+                *" $temp_xrpath "*) ;;
+                *) xrpath="$xrpath $temp_xrpath";;
+                esac;;
+           -L*) case "$compile_command $temp_deplibs " in
+                *" $deplib "*) ;;
+                *) temp_deplibs="$temp_deplibs $deplib";;
+                esac
+                temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+                case " $lib_search_path " in
+                *" $temp_dir "*) ;;
+                *) lib_search_path="$lib_search_path $temp_dir";;
+                esac
+                ;;
+           *) temp_deplibs="$temp_deplibs $deplib";;
+           esac
+         done
+         dependency_libs="$temp_deplibs"
+       fi
+
+       if test -z "$libdir"; then
+         # It is a libtool convenience library, so add in its objects.
+         convenience="$convenience $dir/$old_library"
+         old_convenience="$old_convenience $dir/$old_library"
+         deplibs="$deplibs$dependency_libs"
+         compile_command="$compile_command $dir/$old_library$dependency_libs"
+         finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+         continue
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking statically,
+           # we need to preload.
+           prev=dlprefiles
+         else
+           # We should not create a dependency on this library, but we
+           # may need any libraries it requires.
+           compile_command="$compile_command$dependency_libs"
+           finalize_command="$finalize_command$dependency_libs"
+           prev=
+           continue
+         fi
+       fi
+
+       # The library was specified with -dlpreopen.
+       if test "$prev" = dlprefiles; then
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           dlprefiles="$dlprefiles $dir/$old_library"
+         else
+           dlprefiles="$dlprefiles $dir/$linklib"
+         fi
+         prev=
+       fi
+
+       if test -n "$library_names" &&
+          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+         link_against_libtool_libs="$link_against_libtool_libs $arg"
+         if test -n "$shlibpath_var"; then
+           # Make sure the rpath contains only unique directories.
+           case "$temp_rpath " in
+           *" $dir "*) ;;
+           *) temp_rpath="$temp_rpath $dir" ;;
+           esac
+         fi
+
+         # We need an absolute path.
+         case "$dir" in
+         [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+         *)
+           absdir=`cd "$dir" && pwd`
+           if test -z "$absdir"; then
+             $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+             $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+             absdir="$dir"
+           fi
+           ;;
+         esac
+         
+         # This is the magic to use -rpath.
+         # Skip directories that are in the system default run-time
+         # search path, unless they have been requested with -R.
+         case " $sys_lib_dlsearch_path " in
+         *" $absdir "*) ;;
+         *)
+           case "$compile_rpath " in
+           *" $absdir "*) ;;
+           *) compile_rpath="$compile_rpath $absdir" 
+           esac
+           ;;
+         esac
+
+         case " $sys_lib_dlsearch_path " in
+         *" $libdir "*) ;;
+         *)
+           case "$finalize_rpath " in
+           *" $libdir "*) ;;
+           *) finalize_rpath="$finalize_rpath $libdir"
+           esac
+           ;;
+         esac
+
+         lib_linked=yes
+         case "$hardcode_action" in
+         immediate | unsupported)
+           if test "$hardcode_direct" = no; then
+             compile_command="$compile_command $dir/$linklib"
+             deplibs="$deplibs $dir/$linklib"
+             case "$host" in
+             *-*-cygwin* | *-*-mingw* | *-*-os2*)
+               dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+               if test -n "$dllsearchpath"; then
+                 dllsearchpath="$dllsearchpath:$dllsearchdir"
+               else
+                 dllsearchpath="$dllsearchdir"
+               fi
+               ;;
+             esac
+           elif test "$hardcode_minus_L" = no; then
+             case "$host" in
+             *-*-sunos*)
+               compile_shlibpath="$compile_shlibpath$dir:"
+               ;;
+             esac
+             case "$compile_command " in
+             *" -L$dir "*) ;;
+             *) compile_command="$compile_command -L$dir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$dir -l$name"
+           elif test "$hardcode_shlibpath_var" = no; then
+             case ":$compile_shlibpath:" in
+             *":$dir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$dir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         relink)
+           if test "$hardcode_direct" = yes; then
+             compile_command="$compile_command $absdir/$linklib"
+             deplibs="$deplibs $absdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             case "$compile_command " in
+             *" -L$absdir "*) ;;
+             *) compile_command="$compile_command -L$absdir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$absdir -l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case ":$compile_shlibpath:" in
+             *":$absdir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$absdir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         *)
+           lib_linked=no
+           ;;
+         esac
+
+         if test "$lib_linked" != yes; then
+           $echo "$modename: configuration error: unsupported hardcode properties"
+           exit 1
+         fi
+
+         # Finalize command for both is simple: just hardcode it.
+         if test "$hardcode_direct" = yes; then
+           finalize_command="$finalize_command $libdir/$linklib"
+         elif test "$hardcode_minus_L" = yes; then
+           case "$finalize_command " in
+           *" -L$libdir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         elif test "$hardcode_shlibpath_var" = yes; then
+           case ":$finalize_shlibpath:" in
+           *":$libdir:"*) ;;
+           *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         else
+           # We cannot seem to hardcode it, guess we'll fake it.
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       else
+         # Transform directly to old archives if we don't build new libraries.
+         if test -n "$pic_flag" && test -z "$old_library"; then
+           $echo "$modename: cannot find static library for \`$arg'" 1>&2
+           exit 1
+         fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           case "$compile_command " in
+           *" -L$dir "*) ;;
+           *) compile_command="$compile_command -L$dir";;
+           esac
+           compile_command="$compile_command -l$name"
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$dir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       fi
+
+       # Add in any libraries that this one depends upon.
+       compile_command="$compile_command$dependency_libs"
+       finalize_command="$finalize_command$dependency_libs"
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    *.a | *.lib)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$outputname" in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      if test -n "$objs"; then
+       $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+       exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+        exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         libext=al
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+       dependency_libs="$deplibs"
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       current="$2"
+       revision="$3"
+       age="$4"
+
+       # Check that each of the things are valid numbers.
+       case "$current" in
+       [0-9]*) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$revision" in
+       [0-9]*) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$age" in
+       [0-9]*) ;;
+       *)
+         $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       if test $age -gt $current; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case "$version_type" in
+       none) ;;
+
+       irix)
+         major=`expr $current - $age + 1`
+         versuffix="$major.$revision"
+         verstring="sgi$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test $loop != 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="sgi$major.$iface:$verstring"
+         done
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test $loop != 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       windows)
+         # Like Linux, but with '-' rather than '.', since we only
+         # want one extension on Windows 95.
+         major=`expr $current - $age`
+         versuffix="-$major-$age-$revision"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         verstring="0.0"
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+       
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+
+       dependency_libs="$deplibs"
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+         # these systems don't actually have a c library (as such)!
+         ;;
+        *-*-rhapsody*)
+         # rhapsody is a little odd...
+         deplibs="$deplibs -framework System"
+         ;;
+       *)
+         # Add libc to deplibs on all other systems.
+         deplibs="$deplibs -lc"
+         ;;
+       esac
+      fi
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $output_objdir; then
+       $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+       $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      else
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case "$deplibs_check_method" in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behaviour.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $CC -o conftest conftest.c $deplibs
+         if test $? -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name="`expr $i : '-l\(.*\)'`"
+             # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               deplib_matches=`eval \\$echo \"$library_names_spec\"`
+               set dummy $deplib_matches
+               deplib_match=$2
+               if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                 newdeplibs="$newdeplibs $i"
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning: This library needs some functionality provided by $i."
+                 echo "*** I have the capability to make that library automatically link in when"
+                 echo "*** you link to this library.  But I can only do this if you have a"
+                 echo "*** shared version of the library, which you do not appear to have."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occured in the first compile.  Let's try to salvage the situation:
+           # Compile a seperate program for each library.
+           for i in $deplibs; do
+             name="`expr $i : '-l\(.*\)'`"
+            # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               $rm conftest
+               $CC -o conftest conftest.c $i
+               # Did it work?
+               if test $? -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   echo
+                   echo "*** Warning: This library needs some functionality provided by $i."
+                   echo "*** I have the capability to make that library automatically link in when"
+                   echo "*** you link to this library.  But I can only do this if you have a"
+                   echo "*** shared version of the library, which you do not appear to have."
+                 fi
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 echo "***  make it link in!  You will probably need to install it or some"
+                 echo "*** library that it depends on before this library will be fully"
+                 echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+         for a_deplib in $deplibs; do
+           name="`expr $a_deplib : '-l\(.*\)'`"
+           # If $name is empty we are operating on a -L argument.
+           if test "$name" != "" ; then
+             libname=`eval \\$echo \"$libname_spec\"`
+             for i in $lib_search_path; do
+                   potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                   for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue 
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+                       case "$potliblink" in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | sed 10q \
+                        | egrep "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                   done
+             done
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               echo
+               echo "*** Warning: This library needs some functionality provided by $a_deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have."
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+              -e 's/ -[LR][^ ]*//g' -e 's/[    ]//g' |
+            grep . >/dev/null; then
+           echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           echo
+           echo "*** Warning: libtool could not satisfy all declared inter-library"
+           echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           echo "*** a static module, that should work as long as the dlopening"
+           echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             echo
+             echo "*** However, this would only work if libtool was able to extract symbol"
+             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             echo "*** not find such a program.  So, this module is probably useless."
+             echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           echo "*** The inter-library dependencies that have been dropped here will be"
+           echo "*** automatically added whenever a program is linked with this library"
+           echo "*** or is declared to -dlopen it."
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       # Get the real and link names of the library.
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+
+       lib="$output_objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Ensure that we have .o objects for linkers which dislike .lo
+       # (e.g. aix) in case we are running --disable-static
+       for obj in $libobjs; do
+         xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$obj"; then
+           xdir="."
+         else
+           xdir="$xdir"
+         fi
+         baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+         oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+         if test ! -f $xdir/$oldobj; then
+           $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+           $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+         fi
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           eval cmds=\"$export_symbols_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd" || exit $?
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "mkdir $gentop"
+           $run mkdir "$gentop"
+           status=$?
+           if test $status -ne 0 && test ! -d "$gentop"; then
+             exit $status
+           fi
+           generated="$generated $gentop"
+
+           for xlib in $convenience; do
+             # Extract the objects.
+             case "$xlib" in
+             [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+             *) xabs=`pwd`"/$xlib" ;;
+             esac
+             xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+             xdir="$gentop/$xlib"
+
+             $show "${rm}r $xdir"
+             $run ${rm}r "$xdir"
+             $show "mkdir $xdir"
+             $run mkdir "$xdir"
+             status=$?
+             if test $status -ne 0 && test ! -d "$xdir"; then
+               exit $status
+             fi
+             $show "(cd $xdir && $AR x $xabs)"
+             $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+             libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+           done
+         fi
+       fi
+
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linkopts="$linkopts $flag"
+       fi
+
+       # Do each of the archive commands.
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval cmds=\"$archive_expsym_cmds\"
+       else
+         eval cmds=\"$archive_cmds\"
+       fi
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    *.lo | *.o | *.obj)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+       if test -n "$objs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit 1
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl= 
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         $show "${rm}r $gentop"
+         $run ${rm}r "$gentop"
+         $show "mkdir $gentop"
+         $run mkdir "$gentop"
+         status=$?
+         if test $status -ne 0 && test ! -d "$gentop"; then
+           exit $status
+         fi
+         generated="$generated $gentop"
+
+         for xlib in $convenience; do
+           # Extract the objects.
+           case "$xlib" in
+           [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+           *) xabs=`pwd`"/$xlib" ;;
+           esac
+           xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+           xdir="$gentop/$xlib"
+
+           $show "${rm}r $xdir"
+           $run ${rm}r "$xdir"
+           $show "mkdir $xdir"
+           $run mkdir "$xdir"
+           status=$?
+           if test $status -ne 0 && test ! -d "$xdir"; then
+             exit $status
+           fi
+           $show "(cd $xdir && $AR x $xabs)"
+           $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+           reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+         done
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > $libobj" || exit $?
+       exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       eval cmds=\"$reload_cmds\"
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      else
+       # Just create a symlink.
+       $show $rm $libobj
+       $run $rm $libobj
+       xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$libobj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+       oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+       $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+       $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    # Anything else should be a program.
+    *)
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi 
+      fi
+    
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$compile_rpath " in
+         *" $libdir "*) ;;
+         *) compile_rpath="$compile_rpath $libdir" ;;
+         esac
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      # Create the binary in the object directory, then wrap it.
+      if test ! -d $output_objdir; then
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case "$dlsyms" in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+           
+           if test -n "$export_symbols_regex"; then
+             $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$output.exp"
+             $run $rm $export_symbols
+             $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+           else
+             $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+             $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`echo "$arg" | sed -e 's%^.*/%%'`
+           $run eval 'echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
+               -e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
+                 < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case "$host" in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)\r
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+         compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit 1
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       status=$?
+       
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case "$dir" in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+       
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+       case "$0" in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+       esac
+       $rm $output
+       trap "$rm $output; exit 1" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  link_against_libtool_libs='$link_against_libtool_libs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         echo >> $output "\
+  program=lt-'$outputname'
+  progdir=\"\$thisdir/$objdir\"
+  
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if (cd \"\$thisdir\" && eval \$relink_command); then :
+      else
+       $rm \"\$progdir/\$file\"
+       exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+       case $host in
+         # win32 systems need to use the prog path for dll
+         # lookup to work
+       *-*-cygwin*)
+         $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+         ;;
+
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       $show "${rm}r $gentop"
+       $run ${rm}r "$gentop"
+       $show "mkdir $gentop"
+       $run mkdir "$gentop"
+       status=$?
+       if test $status -ne 0 && test ! -d "$gentop"; then
+         exit $status
+       fi
+       generated="$generated $gentop"
+         
+       # Add in members from convenience archives.
+       for xlib in $addlibs; do
+         # Extract the objects.
+         case "$xlib" in
+         [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+         *) xabs=`pwd`"/$xlib" ;;
+         esac
+         xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+         xdir="$gentop/$xlib"
+
+         $show "${rm}r $xdir"
+         $run ${rm}r "$xdir"
+         $show "mkdir $xdir"
+         $run mkdir "$xdir"
+         status=$?
+         if test $status -ne 0 && test ! -d "$xdir"; then
+           exit $status
+         fi
+         $show "(cd $xdir && $AR x $xabs)"
+         $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+         oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+       done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       eval cmds=\"$old_archive_from_new_cmds\"
+      else
+       # Ensure that we have .o objects in place in case we decided
+       # not to build a shared library, and have fallen back to building
+       # static libs even though --disable-static was passed!
+       for oldobj in $oldobjs; do
+         if test ! -f $oldobj; then
+           xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$oldobj"; then
+             xdir="."
+           else
+             xdir="$xdir"
+           fi
+           baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+           obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+           $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+           $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+         fi
+       done
+
+       eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      if test -n "$xrpath"; then
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+       done
+       dependency_libs="$temp_xrpath $dependency_libs"
+      fi
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+         fi
+         $rm $output
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest="$arg"
+       continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*) ;;
+
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest="$arg"
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+    fi
+    case "$destdir" in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case "$file" in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a | *.lib)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       library_names=
+       old_library=
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$realname $destdir/$realname"
+         $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+         if test $# -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         eval cmds=\"$postinstall_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case "$destfile" in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.o | *.obj)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit 0
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         link_against_libtool_libs=
+         relink_command=
+
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$link_against_libtool_libs"; then
+           $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+           exit 1
+         fi
+
+         finalize=yes
+         for lib in $link_against_libtool_libs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case "$lib" in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir="/tmp"
+             test -n "$TMPDIR" && tmpdir="$TMPDIR"
+              tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null`
+              if test $? = 0 ; then :
+              else
+                tmpdir="$tmpdir/libtool-$$"
+              fi
+             if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+             else
+               $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+               continue
+             fi
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         eval cmds=\"$finish_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+        # Export the shlibpath_var.
+        eval "export $shlibpath_var"
+      fi
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+        eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+        $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $dir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+         $show "$rm $rmfiles"
+         $run $rm $rmfiles
+
+         if test -n "$library_names"; then
+           # Do each command in the postuninstall commands.
+           eval cmds=\"$postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         if test -n "$old_library"; then
+           # Do each command in the old_postuninstall commands.
+           eval cmds=\"$old_postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         # FIXME: should reinstall the best remaining shared library.
+       fi
+       ;;
+
+      *.lo)
+       if test "$build_old_libs" = yes; then
+         oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+         rmfiles="$rmfiles $dir/$oldobj"
+       fi
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+
+      *)
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/sid/component/bochs/memory/Makefile.am b/sid/component/bochs/memory/Makefile.am
new file mode 100644 (file)
index 0000000..1f5e914
--- /dev/null
@@ -0,0 +1,12 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+##         sid/include in build tree       bochs/cpu   component/bochs sid/include in src tree     bochs/memory
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../cpu
+
+noinst_LTLIBRARIES = libmemory.la
+
+libmemory_la_SOURCES = memory.cc memory-sid.cc misc_mem.cc memory.h memory-sid.h
+
+libmemory_la_LDFLAGS = -no-undefined
diff --git a/sid/component/bochs/memory/Makefile.in b/sid/component/bochs/memory/Makefile.in
new file mode 100644 (file)
index 0000000..f9ffb6f
--- /dev/null
@@ -0,0 +1,411 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../cpu
+
+noinst_LTLIBRARIES = libmemory.la
+
+libmemory_la_SOURCES = memory.cc memory-sid.cc misc_mem.cc memory.h memory-sid.h
+
+libmemory_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libmemory_la_LIBADD = 
+libmemory_la_OBJECTS =  memory.lo memory-sid.lo misc_mem.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES =  .deps/memory-sid.P .deps/memory.P .deps/misc_mem.P
+SOURCES = $(libmemory_la_SOURCES)
+OBJECTS = $(libmemory_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign memory/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmemory.la: $(libmemory_la_OBJECTS) $(libmemory_la_DEPENDENCIES)
+       $(CXXLINK)  $(libmemory_la_LDFLAGS) $(libmemory_la_OBJECTS) $(libmemory_la_LIBADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = memory
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign memory/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstLTLIBRARIES clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstLTLIBRARIES distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstLTLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sid/component/bochs/memory/memory-sid.cc b/sid/component/bochs/memory/memory-sid.cc
new file mode 100644 (file)
index 0000000..2310190
--- /dev/null
@@ -0,0 +1,113 @@
+//  memory-sid.cc - override bx_mem_c physical memory access functions. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#include "bochs.h"
+#include "x86.h"
+#define LOG_THIS BX_MEM_THIS
+
+  void
+sid_mem_c::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+    try {
+        switch(len)
+        {
+          case 4:
+          {
+              Bit32u data32 = * ((Bit32u *) data);
+              sid_cpu->write_data_memory_4 (cpu->eip, addr, data32);
+              break;
+          }
+          case 2:
+          {
+              Bit16u data16 = * ((Bit16u *) data);
+              sid_cpu->write_data_memory_2 (cpu->eip, addr, data16);
+              break;
+          }
+          case 1:
+          {
+              Bit8u data8 =  * ((Bit8u *) data);
+              sid_cpu->write_data_memory_1 (cpu->eip, addr, data8);
+              break;
+          }
+          default:
+          {
+              Bit8u data8;
+              Bit8u *data_ptr = (Bit8u *) data;
+              
+              for (unsigned i = 0; i < len; i++)
+              {
+                  data8 = * data_ptr;
+                  sid_cpu->write_data_memory_1 (cpu->eip, addr, data8);
+                  data_ptr++;
+                  addr++;
+              }
+              break;
+          }
+        }
+    } catch (sidutil::cpu_memory_fault e) {
+        cerr << "[MEM ] caught cpu_memory_fault exeception" << endl;
+        cerr << "[MEM ] pc = " << setbase(16) << e.pc << endl;
+        cerr << "[MEM ] address = " << e.address << endl;
+        cerr << "[MEM ] status: " << (e.status == sid::bus::ok ? "ok" :
+                                       (e.status == sid::bus::misaligned ? "misaligned" :
+                                        (e.status == sid::bus::unmapped ? "unmapped" : "unpermitted"))) << endl;
+        
+        cerr << "[MEM ] operation: " << e.operation << setbase(10) << endl;
+        BX_PANIC(("sid_mem_c::write_physical: error\n"));
+    }
+}
+
+  void
+sid_mem_c::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+    try {
+        switch (len)
+        {
+          case 4:
+              * ((Bit32u *) data) = sid_cpu->read_data_memory_4 (cpu->eip, addr);
+              break;
+          case 2:
+              * ((Bit16u *) data) = sid_cpu->read_data_memory_2 (cpu->eip, addr);
+              break;
+          case 1:
+              * ((Bit8u *) data) = sid_cpu->read_data_memory_1 (cpu->eip, addr);
+              break;
+          default:
+              Bit8u data8;
+              Bit8u * data_ptr = (Bit8u *) data;
+              
+              for (unsigned i = 0; i < len; i++)
+              {
+                  * data_ptr = sid_cpu->read_data_memory_1 (cpu->eip, addr);
+                  data_ptr++;
+                  addr++;
+              }
+              break;          
+        }
+    } catch (sidutil::cpu_memory_fault e) {
+        cerr << "[MEM ] caught cpu_memory_fault exeception" << endl;
+        cerr << "[MEM ] pc = " << setbase(16) << e.pc << endl;
+        cerr << "[MEM ] address = " << e.address << endl;
+        cerr << "[MEM ] status: " << (e.status == sid::bus::ok ? "ok" :
+                                       (e.status == sid::bus::misaligned ? "misaligned" :
+                                        (e.status == sid::bus::unmapped ? "unmapped" : "unpermitted"))) << endl;
+        
+        cerr << "[MEM ] operation: " << e.operation << setbase(10) << endl;
+        BX_PANIC(("sid_mem_c::read_physical: error\n"));
+    }
+}
diff --git a/sid/component/bochs/memory/memory-sid.h b/sid/component/bochs/memory/memory-sid.h
new file mode 100644 (file)
index 0000000..eed11bd
--- /dev/null
@@ -0,0 +1,37 @@
+//  memory-sid.h - declaration of the sid_mem_c class. -*- C++ -*-
+//
+//  Copyright (C) 2001 Red Hat.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#ifndef __MEMORY_SID_H__
+#define __MEMORY_SID_H__
+
+#include "memory.h"
+
+class x86_cpu;
+
+class sid_mem_c : public BX_MEM_C {
+
+public:
+    x86_cpu *sid_cpu;
+    
+    void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+    void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+};
+
+extern sid_mem_c bx_mem;
+
+#endif // __MEMORY_SID_H__
diff --git a/sid/component/bochs/memory/memory.cc b/sid/component/bochs/memory/memory.cc
new file mode 100644 (file)
index 0000000..75317bc
--- /dev/null
@@ -0,0 +1,474 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#include "bochs.h"
+#define LOG_THIS BX_MEM_THIS
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+
+  void
+BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+  Bit8u *data_ptr;
+  Bit32u a20addr;
+
+
+  a20addr = A20ADDR(addr);
+  BX_INSTR_PHY_WRITE(a20addr, len);
+
+#if BX_DEBUGGER
+  // (mch) Check for physical write break points, TODO
+  // (bbd) Each breakpoint should have an associated CPU#, TODO
+  for (int i = 0; i < num_write_watchpoints; i++)
+        if (write_watchpoint[i] == a20addr) {
+              BX_CPU(0)->break_point = BREAK_POINT_WRITE;
+              break;
+        }
+#endif
+
+
+  if ( (a20addr + len) <= BX_MEM_THIS len ) {
+    // all of data is within limits of physical memory
+    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+      if (len == 4) {
+        if ((a20addr & 0x00000003) == 0) {
+          // write 4byte data to aligned memory location
+          Bit32u data32;
+
+          data32 = * (Bit32u *) data;
+#ifdef BX_BIG_ENDIAN
+          data32 = (data32 << 24) | (data32 >> 24) |
+            ((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
+#endif
+          * ((Bit32u *) (&vector[a20addr])) = data32;
+          BX_DBG_DIRTY_PAGE(a20addr >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          return;
+          }
+        else {
+          Bit32u data32;
+
+          data32 = * (Bit32u *) data;
+          * ((Bit8u *) (&vector[a20addr]))         = data32; data32 >>= 8;
+          BX_DBG_DIRTY_PAGE(a20addr >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          * ((Bit8u *) (&vector[A20ADDR(addr+1)])) = data32; data32 >>= 8;
+          * ((Bit8u *) (&vector[A20ADDR(addr+2)])) = data32; data32 >>= 8;
+          * ((Bit8u *) (&vector[A20ADDR(addr+3)])) = data32;
+          // worst case, last byte is in different page; possible extra dirty page
+          BX_DBG_DIRTY_PAGE(A20ADDR(addr+3) >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          return;
+          }
+        }
+      if (len == 2) {
+        if ((a20addr & 0x00000001) == 0) {
+          // write 2-byte data to aligned memory location
+          Bit16u data16;
+
+          data16 = * (Bit16u *) data;
+#ifdef BX_BIG_ENDIAN
+          data16 = (data16 >> 8) | (data16 << 8);
+#endif
+          * ((Bit16u *) (&vector[a20addr])) = data16;
+          BX_DBG_DIRTY_PAGE(a20addr >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          return;
+          }
+        else {
+          Bit16u data16;
+
+          data16 = * (Bit16u *) data;
+          * ((Bit8u *) (&vector[a20addr])) = (Bit8u) data16;
+          BX_DBG_DIRTY_PAGE(a20addr >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          * ((Bit8u *) (&vector[A20ADDR(a20addr+1)])) = (data16 >> 8);
+          BX_DBG_DIRTY_PAGE(A20ADDR(a20addr+1) >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          return;
+          }
+        }
+      if (len == 1) {
+        Bit8u data8;
+
+        data8 = * (Bit8u *) data;
+        * ((Bit8u *) (&vector[a20addr])) = data8;
+        BX_DBG_DIRTY_PAGE(a20addr >> 12);
+        BX_DYN_DIRTY_PAGE(a20addr >> 12);
+        return;
+        }
+      // len == 3 case can just fall thru to special cases handling
+      }
+
+#ifdef BX_LITTLE_ENDIAN
+  data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+  data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+write_one:
+    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+      // addr *not* in range 00080000 .. 000FFFFF
+      vector[a20addr] = *data_ptr;
+      BX_DBG_DIRTY_PAGE(a20addr >> 12);
+      BX_DYN_DIRTY_PAGE(a20addr >> 12);
+inc_one:
+      if (len == 1) return;
+      len--;
+      addr++;
+      a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+      data_ptr++;
+#else // BX_BIG_ENDIAN
+      data_ptr--;
+#endif
+      goto write_one;
+      }
+
+    // addr in range 00080000 .. 000FFFFF
+
+    if (a20addr <= 0x0009ffff) {
+      // regular memory 80000 .. 9FFFF
+      vector[a20addr] = *data_ptr;
+      BX_DBG_DIRTY_PAGE(a20addr >> 12);
+      BX_DYN_DIRTY_PAGE(a20addr >> 12);
+      goto inc_one;
+      }
+    if (a20addr <= 0x000bffff) {
+      // VGA memory A0000 .. BFFFF
+      BX_VGA_MEM_WRITE(a20addr, *data_ptr);
+      BX_DBG_DIRTY_PAGE(a20addr >> 12);
+      BX_DYN_DIRTY_PAGE(a20addr >> 12);
+      BX_DBG_UCMEM_REPORT(a20addr, 1, BX_WRITE, *data_ptr); // obsolete
+      goto inc_one;
+      }
+    // adapter ROM     C0000 .. DFFFF
+    // ROM BIOS memory E0000 .. FFFFF
+    // (ignore write)
+    //BX_INFO(("ROM lock %08x: len=%u\n",
+    //  (unsigned) a20addr, (unsigned) len));
+#if BX_PCI_SUPPORT == 0
+#if BX_SHADOW_RAM
+    // Write it since its in shadow RAM
+    vector[a20addr] = *data_ptr;
+    BX_DBG_DIRTY_PAGE(a20addr >> 12);
+    BX_DYN_DIRTY_PAGE(a20addr >> 12);
+#else
+    // ignore write to ROM
+#endif
+#else
+    // Write Based on 440fx Programming
+    if (bx_options.i440FXSupport &&
+        ((a20addr >= 0xC0000) && (a20addr <= 0xFFFFF))) {
+      switch (bx_devices.pci->wr_memType(a20addr & 0xFC000)) {
+        case 0x0:   // Writes to ShadowRAM
+//        BX_INFO(("Writing to ShadowRAM %08x, len %u ! \n", (unsigned) a20addr, (unsigned) len));
+          vector[a20addr] = *data_ptr;
+          BX_DBG_DIRTY_PAGE(a20addr >> 12);
+          BX_DYN_DIRTY_PAGE(a20addr >> 12);
+          goto inc_one;
+
+        case 0x1:   // Writes to ROM, Inhibit
+//        bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)] = *data_ptr;
+//        BX_INFO(("Writing to ROM %08x, Data %02x ! \n", (unsigned) a20addr, *data_ptr));
+          goto inc_one;
+        default:
+          BX_PANIC(("write_physical: default case\n"));
+          goto inc_one;
+        }
+      }
+#endif
+    goto inc_one;
+    }
+
+  else {
+    // some or all of data is outside limits of physical memory
+    unsigned i;
+
+#ifdef BX_LITTLE_ENDIAN
+  data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+  data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+#if BX_SUPPORT_APIC
+    bx_generic_apic_c *local_apic = &cpu->local_apic;
+    bx_generic_apic_c *ioapic = bx_devices.ioapic;
+    if (local_apic->is_selected (a20addr, len)) {
+      local_apic->write (a20addr, (Bit32u *)data, len);
+      return;
+    } else if (ioapic->is_selected (a20addr, len)) {
+      ioapic->write (a20addr, (Bit32u *)data, len);
+      return;
+    }
+    else 
+#endif
+    for (i = 0; i < len; i++) {
+      if (a20addr < BX_MEM_THIS len) {
+        vector[a20addr] = *data_ptr;
+        BX_DBG_DIRTY_PAGE(a20addr >> 12);
+        BX_DYN_DIRTY_PAGE(a20addr >> 12);
+        }
+      // otherwise ignore byte, since it overruns memory
+      addr++;
+      a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+      data_ptr++;
+#else // BX_BIG_ENDIAN
+      data_ptr--;
+#endif
+      }
+    return;
+    }
+}
+
+
+  void
+BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+  Bit8u *data_ptr;
+  Bit32u a20addr;
+
+
+  a20addr = A20ADDR(addr);
+  BX_INSTR_PHY_READ(a20addr, len);
+
+#if BX_DEBUGGER
+  // (mch) Check for physical read break points, TODO
+  // (bbd) Each breakpoint should have an associated CPU#, TODO
+  for (int i = 0; i < num_read_watchpoints; i++)
+        if (read_watchpoint[i] == a20addr) {
+              BX_CPU(0)->break_point = BREAK_POINT_READ;
+              break;
+        }
+#endif
+
+  if ( (a20addr + len) <= BX_MEM_THIS len ) {
+    // all of data is within limits of physical memory
+    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+      if (len == 4) {
+        if ((a20addr & 0x00000003) == 0) {
+          // read 4-byte data from aligned memory location
+          Bit32u data32;
+
+          data32 = * ((Bit32u *) (&vector[a20addr]));
+#ifdef BX_BIG_ENDIAN
+          data32 = (data32 << 24) | (data32 >> 24) |
+                   ((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
+#endif
+          * (Bit32u *) data = data32;
+          return;
+          }
+        else {
+          Bit32u data32;
+
+          data32  = * ((Bit8u *) (&vector[A20ADDR(addr+3)])); data32 <<= 8;
+          data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+2)])); data32 <<= 8;
+          data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data32 <<= 8;
+          data32 |= * ((Bit8u *) (&vector[a20addr]));
+
+          * (Bit32u *) data = data32;
+          return;
+          }
+        }
+      if (len == 2) {
+        if ((a20addr & 0x00000001) == 0) {
+          // read 2-byte data from aligned memory location
+          Bit16u data16;
+
+          data16 = * ((Bit16u *) (&vector[a20addr]));
+#ifdef BX_BIG_ENDIAN
+          data16 = (data16 >> 8) | (data16 << 8);
+#endif
+
+          * (Bit16u *) data =  data16;
+          return;
+          }
+        else {
+          Bit16u data16;
+
+          data16  = * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data16 <<= 8;
+          data16 |= * ((Bit8u *) (&vector[a20addr]));
+
+          * (Bit16u *) data = data16;
+          return;
+          }
+        }
+      if (len == 1) {
+        Bit8u data8;
+
+        data8 = * ((Bit8u *) (&vector[a20addr]));
+        * (Bit8u *) data = data8;
+        return;
+        }
+      // len == 3 case can just fall thru to special cases handling
+      }
+
+
+#ifdef BX_LITTLE_ENDIAN
+    data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+    data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+
+
+read_one:
+    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+      // addr *not* in range 00080000 .. 000FFFFF
+      *data_ptr = vector[a20addr];
+inc_one:
+      if (len == 1) return;
+      len--;
+      addr++;
+      a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+      data_ptr++;
+#else // BX_BIG_ENDIAN
+      data_ptr--;
+#endif
+      goto read_one;
+      }
+
+    // addr in range 00080000 .. 000FFFFF
+#if BX_PCI_SUPPORT == 0
+    if ((a20addr <= 0x0009ffff) || (a20addr >= 0x000c0000) ) {
+      // regular memory 80000 .. 9FFFF, C0000 .. F0000
+      *data_ptr = vector[a20addr];
+      goto inc_one;
+      }
+    // VGA memory A0000 .. BFFFF
+    *data_ptr = BX_VGA_MEM_READ(a20addr);
+    BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr); // obsolete
+    goto inc_one;
+#else   // #if BX_PCI_SUPPORT == 0
+    if (a20addr <= 0x0009ffff) {
+      *data_ptr = vector[a20addr];
+      goto inc_one;
+      }
+    if (a20addr <= 0x000BFFFF) {
+      // VGA memory A0000 .. BFFFF
+      *data_ptr = BX_VGA_MEM_READ(a20addr);
+      BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr);
+      goto inc_one;
+      }
+
+    // a20addr in C0000 .. FFFFF
+    if (!bx_options.i440FXSupport) {
+      *data_ptr = vector[a20addr];
+      goto inc_one;
+      }
+    else {
+      switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
+        case 0x0:   // Read from ShadowRAM
+          *data_ptr = vector[a20addr];
+          BX_INFO(("Reading from ShadowRAM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+          goto inc_one;
+
+        case 0x1:   // Read from ROM
+          *data_ptr = bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)];
+          //BX_INFO(("Reading from ROM %08x, Data %02x  \n", (unsigned) a20addr, *data_ptr));
+          goto inc_one;
+        default:
+          BX_PANIC(("::read_physical: default case\n"));
+        }
+      }
+    goto inc_one;
+#endif  // #if BX_PCI_SUPPORT == 0
+    }
+  else {
+    // some or all of data is outside limits of physical memory
+    unsigned i;
+
+#ifdef BX_LITTLE_ENDIAN
+    data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+    data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+#if BX_SUPPORT_APIC
+    bx_generic_apic_c *local_apic = &cpu->local_apic;
+    bx_generic_apic_c *ioapic = bx_devices.ioapic;
+    if (local_apic->is_selected (addr, len)) {
+      local_apic->read (addr, data, len);
+      return;
+    } else if (ioapic->is_selected (addr, len)) {
+      ioapic->read (addr, data, len);
+      return;
+    }
+#endif
+    for (i = 0; i < len; i++) {
+#if BX_PCI_SUPPORT == 0
+      if (a20addr < BX_MEM_THIS len)
+        *data_ptr = vector[a20addr];
+      else
+        *data_ptr = 0xff;
+#else   // BX_PCI_SUPPORT == 0
+      if (a20addr < BX_MEM_THIS len) {
+        if ((a20addr >= 0x000C0000) && (a20addr <= 0x000FFFFF)) {
+          if (!bx_options.i440FXSupport)
+            *data_ptr = vector[a20addr];
+          else {
+            switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
+              case 0x0:   // Read from ROM
+                *data_ptr = vector[a20addr];
+                //BX_INFO(("Reading from ROM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+                break;
+
+              case 0x1:   // Read from Shadow RAM
+                *data_ptr = bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)];
+                BX_INFO(("Reading from ShadowRAM %08x, Data %02x  \n", (unsigned) a20addr, *data_ptr));
+                break;
+              default:
+                BX_PANIC(("read_physical: default case\n"));
+              } // Switch
+            }
+          }
+        else {
+          *data_ptr = vector[a20addr];
+          BX_INFO(("Reading from Norm %08x, Data %02x  \n", (unsigned) a20addr, *data_ptr));
+          }
+        }
+      else 
+        *data_ptr = 0xff;
+#endif  // BX_PCI_SUPPORT == 0
+      addr++;
+      a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+      data_ptr++;
+#else // BX_BIG_ENDIAN
+      data_ptr--;
+#endif
+      }
+    return;
+    }
+}
+
+#endif // #if BX_PROVIDE_CPU_MEMORY
diff --git a/sid/component/bochs/memory/memory.h b/sid/component/bochs/memory/memory.h
new file mode 100644 (file)
index 0000000..e5a07b4
--- /dev/null
@@ -0,0 +1,84 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+#ifndef __MEMORY_H__
+#define __MEMORY_H__
+
+#define BX_USE_MEM_SMF 0
+
+#if BX_USE_MEM_SMF
+// if static member functions on, then there is only one memory
+#  define BX_MEM_SMF  static
+#  define BX_MEM_THIS BX_MEM(0)->
+#else
+#  define BX_MEM_SMF
+#  define BX_MEM_THIS this->
+#endif
+
+
+
+class BX_MEM_C : public logfunctions {
+
+public:
+  Bit8u   *vector;
+  size_t  len;
+  size_t  megabytes;  // (len in Megabytes)
+#if BX_DEBUGGER
+  unsigned char dbg_dirty_pages[(BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096];
+  Bit32u dbg_count_dirty_pages () {
+    return (BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096;
+  }
+#endif
+
+  BX_MEM_C(void);
+  BX_MEM_C(size_t memsize);
+  ~BX_MEM_C(void);
+  BX_MEM_SMF void    init_memory(int memsize);
+  BX_MEM_SMF void    read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+  BX_MEM_SMF void    write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+  BX_MEM_SMF void    load_ROM(const char *path, Bit32u romaddress);
+  BX_MEM_SMF Bit32u  get_memory_in_k(void);
+  BX_MEM_SMF Boolean dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf);
+  BX_MEM_SMF Boolean dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf);
+  BX_MEM_SMF Boolean dbg_crc32(
+    unsigned long (*f)(unsigned char *buf, int len),
+    Bit32u addr1, Bit32u addr2, Bit32u *crc);
+  };
+
+#if BX_SUPPORT_SID
+#else
+#if BX_PROVIDE_CPU_MEMORY==1
+#if BX_SMP_PROCESSORS==1
+extern BX_MEM_C    bx_mem;
+#else
+extern BX_MEM_C    *bx_mem_array[BX_ADDRESS_SPACES];
+#endif  /* BX_SMP_PROCESSORS */
+#endif  /* BX_PROVIDE_CPU_MEMORY==1 */
+#endif // BX_SUPPORT_SID
+
+#if BX_DEBUGGER
+#  define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1;
+#else
+#  define BX_DBG_DIRTY_PAGE(page)
+#endif
+
+#endif // __MEMORY_H__
diff --git a/sid/component/bochs/memory/misc_mem.cc b/sid/component/bochs/memory/misc_mem.cc
new file mode 100644 (file)
index 0000000..c9948ec
--- /dev/null
@@ -0,0 +1,281 @@
+//  Copyright (C) 2001  MandrakeSoft S.A.
+//
+//    MandrakeSoft S.A.
+//    43, rue d'Aboukir
+//    75002 Paris - France
+//    http://www.linux-mandrake.com/
+//    http://www.mandrakesoft.com/
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2 of the License, or (at your option) any later version.
+//
+//  This library 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
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+
+
+
+
+
+
+#include "bochs.h"
+#define LOG_THIS BX_MEM(0)->
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+  Bit32u
+BX_MEM_C::get_memory_in_k(void)
+{
+  BX_INFO(("%uKB\n", (unsigned)(BX_MEM_THIS megabytes*1024)));
+
+  return(BX_MEM_THIS megabytes * 1024);
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+  // BX_MEM_C constructor
+BX_MEM_C::BX_MEM_C(void)
+{
+  char mem[32];
+  sprintf(mem, "[MEM%d]", BX_SIM_ID);
+  setprefix(mem);
+  settype(MEMLOG);
+
+  vector = NULL;
+  len    = 0;
+  megabytes = 0;
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+  // BX_MEM_C constructor
+BX_MEM_C::BX_MEM_C(size_t memsize)
+{
+  vector = new Bit8u[memsize];
+  len    = memsize;
+  megabytes = len / (1024*1024);
+  BX_INFO(("Init(%uB == %.2f)\n",memsize, megabytes));
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+// BX_MEM_C destructor
+BX_MEM_C::~BX_MEM_C(void)
+{
+  if (this-> vector != NULL) {
+    delete this->vector;
+    }
+  else {
+    BX_DEBUG(("(%u)   memory not freed as it wasn't allocated!\n", BX_SIM_ID));
+    }
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+  void
+BX_MEM_C::init_memory(int memsize)
+{
+  // you can pass 0 if memory has been allocated already through
+  // the constructor, or the desired size of memory if it hasn't
+
+  if (BX_MEM_THIS vector == NULL) {
+    // memory not already allocated, do now...
+    BX_MEM_THIS vector = new Bit8u[memsize];
+    BX_MEM_THIS len    = memsize;
+    BX_MEM_THIS megabytes = memsize / (1024*1024);
+    BX_INFO(("Init(%uB == %.2fMB).\n", memsize, (float)(BX_MEM_THIS megabytes) ));
+    }
+  // initialize all memory to 0x00
+  memset(BX_MEM_THIS vector, 0x00, BX_MEM_THIS len);
+
+  // initialize ROM area (0xc0000 .. 0xfffff) to 0xff
+  memset(BX_MEM_THIS vector + 0xc0000, 0xff, 0x40000);
+
+#if BX_DEBUGGER
+  // initialize dirty pages table
+  memset(dbg_dirty_pages, 0, sizeof(dbg_dirty_pages));
+
+  if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
+    BX_INFO(("Error: memory larger than dirty page table can handle\n"));
+    BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS\n"));
+    }
+#endif
+
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+  void
+BX_MEM_C::load_ROM(const char *path, Bit32u romaddress)
+{
+  struct stat stat_buf;
+  int fd, ret;
+  unsigned long size, offset;
+
+  // read in ROM BIOS image file
+  fd = open(path, O_RDONLY
+#ifdef O_BINARY
+            | O_BINARY
+#endif
+           );
+  if (fd < 0) {
+    BX_INFO(( "ROM: couldn't open ROM image file '%s'.\n", path));
+    exit(1);
+    }
+  ret = fstat(fd, &stat_buf);
+  if (ret) {
+    BX_INFO(( "ROM: couldn't stat ROM image file '%s'.\n", path));
+    exit(1);
+    }
+
+  size = stat_buf.st_size;
+
+  if ( (romaddress + size) > BX_MEM_THIS len ) {
+    BX_INFO(( "ROM: ROM address range > physical memsize!\n"));
+    exit(1);
+    }
+
+  offset = 0;
+  while (size > 0) {
+#if BX_PCI_SUPPORT
+    if (bx_options.i440FXSupport)
+      ret = read(fd, (bx_ptr_t) &bx_devices.pci->s.i440fx.shadow[romaddress - 0xC0000 + offset],
+                 size);
+    else
+      ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
+#else
+    ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
+#endif
+    if (ret <= 0) {
+      BX_PANIC(( "ROM: read failed on BIOS image\n"));
+      }
+    size -= ret;
+    offset += ret;
+    }
+  close(fd);
+#if BX_PCI_SUPPORT
+  if (bx_options.i440FXSupport)
+    BX_INFO(("rom in i440FX RAM 0x%06x/%u ('%s')\n",
+                       (unsigned) romaddress,
+                       (unsigned) stat_buf.st_size,
+                       path
+               ));
+  else
+    BX_INFO(("rom at 0x%06x/%u ('%s')\n",
+                       (unsigned) romaddress,
+                       (unsigned) stat_buf.st_size,
+                       path
+               ));
+#else  // #if BX_PCI_SUPPORT
+  BX_INFO(("rom at 0x%06x/%u ('%s')\n",
+                       (unsigned) romaddress,
+                       (unsigned) stat_buf.st_size,
+                       path
+               ));
+#endif // #if BX_PCI_SUPPORT
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if ( BX_DEBUGGER || BX_DISASM )
+  Boolean
+BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
+{
+  if ( (addr + len) > this->len ) {
+    BX_INFO(("dbg_fetch_mem out of range. %p > %p\n",
+      addr+len, this->len));
+    return(0); // error, beyond limits of memory
+    }
+  for (; len>0; len--) {
+#if BX_SUPPORT_VGA
+    if ( (addr & 0xfffe0000) == 0x000a0000 ) {
+      *buf = BX_VGA_MEM_READ(addr);
+      }
+    else {
+#endif
+#if BX_PCI_SUPPORT == 0
+      *buf = vector[addr];
+#else
+      if ( bx_options.i440FXSupport &&
+          ((addr >= 0x000C0000) && (addr <= 0x000FFFFF)) ) {
+        switch (bx_devices.pci->rd_memType (addr)) {
+          case 0x0:  // Fetch from ShadowRAM
+            *buf = vector[addr];
+//          BX_INFO(("Fetching from ShadowRAM %06x, len %u !\n", (unsigned)addr, (unsigned)len));
+            break;
+
+          case 0x1:  // Fetch from ROM
+            *buf = bx_pci.s.i440fx.shadow[(addr - 0xC0000)];
+//          BX_INFO(("Fetching from ROM %06x, Data %02x \n", (unsigned)addr, *buf));
+            break;
+          default:
+            BX_PANIC(("dbg_fetch_mem: default case\n"));
+          }
+        }
+      else
+        *buf = vector[addr];
+#endif  // #if BX_PCI_SUPPORT == 0
+      }
+    buf++;
+    addr++;
+    }
+  return(1);
+}
+#endif
+
+#if BX_DEBUGGER
+  Boolean
+BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
+{
+  if ( (addr + len) > this->len ) {
+    return(0); // error, beyond limits of memory
+    }
+  for (; len>0; len--) {
+#if BX_SUPPORT_VGA
+    if ( (addr & 0xfffe0000) == 0x000a0000 ) {
+      BX_VGA_MEM_WRITE(addr, *buf);
+      }
+    else
+#endif
+      vector[addr] = *buf;
+    buf++;
+    addr++;
+    }
+  return(1);
+}
+#endif
+
+  Boolean
+BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
+    Bit32u addr1, Bit32u addr2, Bit32u *crc)
+{
+  unsigned len;
+
+  *crc = 0;
+  if (addr1 > addr2)
+    return(0);
+
+  if (addr2 >= this->len) {
+    return(0); // error, specified address past last phy mem addr
+    }
+  
+  len = 1 + addr2 - addr1;
+  *crc = f(vector + addr1, len);
+
+  return(1);
+}
diff --git a/sid/component/bochs/missing b/sid/component/bochs/missing
new file mode 100644 (file)
index 0000000..7789652
--- /dev/null
@@ -0,0 +1,190 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/sid/component/bochs/mkinstalldirs b/sid/component/bochs/mkinstalldirs
new file mode 100644 (file)
index 0000000..6b3b5fc
--- /dev/null
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id$
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp"
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+         errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/sid/component/bochs/stamp-h.in b/sid/component/bochs/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
index fa36b93..6ae14d9 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
index 54d2faf..0a09a5f 100644 (file)
@@ -4,6 +4,22 @@
        in basic_cpu now.
        * compCGEN.cxx: Corresponding change.
 
+2001-08-22  graydon hoare  <graydon@redhat.com>
+
+       * Makefile.am: Add missing dis-buf.c
+       * Makefile.in: Regenerate.
+
+2001-08-16  graydon hoare  <graydon@redhat.com>
+
+       * Makefile.am: gcc -> $(CC) fix.
+       * Makefile.in: Regenerate.
+
+2001-08-15  graydon hoare  <graydon@redhat.com>
+
+       * Makefile.am: Add support for building and
+       linking invididual objects from opcodes.
+       * Makefile.in: Regenerate.
+
 2001-08-03  matthew green  <mrg@redhat.com>
 
        * cgen-cpu.h (~cgen_bi_endian_cpu): Add throw() specifier.
index 64a4c40..93b6dd7 100644 (file)
@@ -18,14 +18,35 @@ AM_CXXFLAGS=$(TOP_CXXFLAGS)
 AM_MAKEFLAGS= "TOP_CXXFLAGS=$(TOP_CXXFLAGS)"
 MAKEOVERRIDES=
 
-OPCODES = ../../../opcodes/libopcodes.la
 LIBIBERTY = -L../../../libiberty -liberty
 TRACEDIS = tracedis.c
 
 libcgencpu_la_SOURCES = compCGEN.cxx $(TRACEDIS)
 libcgencpu_la_LDFLAGS = -module -no-undefined
-libcgencpu_la_LIBADD = @cpu_libs@ $(OPCODES) $(INTLLIBS) $(LIBIBERTY)
-libcgencpu_la_DEPENDENCIES = @cpu_libs@
+libcgencpu_la_LIBADD = @cpu_libs@ $(INTLLIBS) $(LIBIBERTY) cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+libcgencpu_la_DEPENDENCIES = @cpu_libs@ cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+       -I../../../opcodes \
+       -I../../../bfd \
+       -I../../../intl \
+       -I$(srcdir)/../../../opcodes \
+       -I$(srcdir)/../../../include \
+       -I$(srcdir)/../../../bfd     \
+       -I$(srcdir)/../../../intl    \
+       -D_GNU_SOURCE 
+
+cgen-asm.lo: ../../../opcodes/cgen-asm.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-dis.lo: ../../../opcodes/cgen-dis.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-opc.lo: ../../../opcodes/cgen-opc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+dis-buf.lo: ../../../opcodes/dis-buf.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
 
 DEJAGNUTESTS = cpumonkey.exp dhrystone.exp
 check-local: all
index 9fa4811..57ed28b 100644 (file)
@@ -88,6 +88,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 INTLLIBS = @INTLLIBS@
 
@@ -106,14 +107,24 @@ AM_CXXFLAGS = $(TOP_CXXFLAGS)
 AM_MAKEFLAGS = "TOP_CXXFLAGS=$(TOP_CXXFLAGS)"
 MAKEOVERRIDES = 
 
-OPCODES = ../../../opcodes/libopcodes.la
 LIBIBERTY = -L../../../libiberty -liberty
 TRACEDIS = tracedis.c
 
 libcgencpu_la_SOURCES = compCGEN.cxx $(TRACEDIS)
 libcgencpu_la_LDFLAGS = -module -no-undefined
-libcgencpu_la_LIBADD = @cpu_libs@ $(OPCODES) $(INTLLIBS) $(LIBIBERTY)
-libcgencpu_la_DEPENDENCIES = @cpu_libs@
+libcgencpu_la_LIBADD = @cpu_libs@ $(INTLLIBS) $(LIBIBERTY) cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+libcgencpu_la_DEPENDENCIES = @cpu_libs@ cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+       -I../../../opcodes \
+       -I../../../bfd \
+       -I../../../intl \
+       -I$(srcdir)/../../../opcodes \
+       -I$(srcdir)/../../../include \
+       -I$(srcdir)/../../../bfd     \
+       -I$(srcdir)/../../../intl    \
+       -D_GNU_SOURCE 
+
 
 DEJAGNUTESTS = cpumonkey.exp dhrystone.exp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -556,6 +567,18 @@ uninstall-am uninstall all-redirect all-am all installdirs-am \
 installdirs mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
+
+cgen-asm.lo: ../../../opcodes/cgen-asm.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-dis.lo: ../../../opcodes/cgen-dis.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-opc.lo: ../../../opcodes/cgen-opc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+dis-buf.lo: ../../../opcodes/dis-buf.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
 check-local: all
        -(cd ../testsuite ; $(MAKE) check RUNTESTFLAGS="$(RUNTESTFLAGS) $(DEJAGNUTESTS)" )
        for subdir in @cpu_subdirs@; do \
index 7d5e150..e05405b 100644 (file)
@@ -621,7 +621,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -639,6 +639,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -650,6 +651,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -662,6 +664,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -679,6 +682,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index d81091a..c82dd8c 100755 (executable)
@@ -2250,7 +2250,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -2270,6 +2270,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -2280,6 +2281,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -2291,6 +2293,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -2301,7 +2304,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2305: checking ARM family support" >&5
+echo "configure:2308: checking ARM family support" >&5
 
 
 
@@ -2314,8 +2317,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2322: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2319: checking MIPS family support" >&5
+echo "configure:2336: checking MIPS family support" >&5
 
 
 
@@ -2329,7 +2346,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2333: checking M32R family support" >&5
+echo "configure:2350: checking M32R family support" >&5
 
 
 
@@ -2343,7 +2360,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2347: checking M68K family support" >&5
+echo "configure:2364: checking M68K family support" >&5
 
 
 
@@ -2357,7 +2374,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2361: checking PPC family support" >&5
+echo "configure:2378: checking PPC family support" >&5
 
 
 
@@ -2400,7 +2417,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2404: checking for $ac_word" >&5
+echo "configure:2421: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GUILE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2436,7 +2453,7 @@ test -n "$GUILE" || GUILE="false"
 # Extract the first word of "links", so it can be a program name with args.
 set dummy links; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2440: checking for $ac_word" >&5
+echo "configure:2457: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LINKS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2476,7 +2493,7 @@ fi
 # Extract the first word of "xsltproc", so it can be a program name with args.
 set dummy xsltproc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2480: checking for $ac_word" >&5
+echo "configure:2497: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_XSLTPROC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2516,7 +2533,7 @@ fi
 # Extract the first word of "sabcmd", so it can be a program name with args.
 set dummy sabcmd; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2520: checking for $ac_word" >&5
+echo "configure:2537: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_SABLOTRON'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2728,6 +2745,9 @@ s%@EXEEXT@%$EXEEXT%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
index cd8d8c1..f8a9e6d 100644 (file)
@@ -1,3 +1,21 @@
+2001-08-16  graydon hoare  <graydon@redhat.com>
+
+       * Makefile.am: gcc -> $(CC) fix.
+       * Makefile.in: Regenerate.
+
+2001-08-15  graydon hoare  <graydon@redhat.com>
+
+       * m32rbf.cxx (step_insns): Fix for bi-endian
+       disassembly.
+
+2001-08-15  graydon hoare  <graydon@redhat.com>
+
+       * m32rbf.cxx (step_insns): Add disassembly
+       tracing support.
+       * Makefile.am: Add support for building and
+       linking invididual objects from opcodes.
+       * Makefile.in: Regenerate.
+
 2001-08-03  matthew green  <mrg@redhat.com>
 
        * m32rbf.h (dtor): Add throw() specifier.
index 1067e5b..67145ff 100644 (file)
@@ -14,6 +14,32 @@ pkgdata_DATA = hw-cpu-m32r_d.txt
 libm32r_la_SOURCES = m32rbf.cxx \
        m32r-decode.cxx m32r-sem.cxx
 libm32r_la_LDFLAGS =
+libm32r_la_LIBADD = m32r-asm.lo m32r-dis.lo m32r-opc.lo m32r-ibld.lo m32r-desc.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+       -I../../../../opcodes \
+       -I../../../../bfd \
+       -I../../../../intl \
+       -I$(srcdir)/../../../../opcodes \
+       -I$(srcdir)/../../../../include \
+       -I$(srcdir)/../../../../bfd     \
+       -I$(srcdir)/../../../../intl    \
+       -D_GNU_SOURCE 
+
+m32r-asm.lo: ../../../../opcodes/m32r-asm.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-dis.lo: ../../../../opcodes/m32r-dis.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-opc.lo: ../../../../opcodes/m32r-opc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-ibld.lo: ../../../../opcodes/m32r-ibld.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-desc.lo: ../../../../opcodes/m32r-desc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
 
 DEJAGNUTESTS = m32rbsp.exp
 check-local: all
index 3913b85..46d99e3 100644 (file)
@@ -104,6 +104,18 @@ libm32r_la_SOURCES = m32rbf.cxx \
        m32r-decode.cxx m32r-sem.cxx
 
 libm32r_la_LDFLAGS = 
+libm32r_la_LIBADD = m32r-asm.lo m32r-dis.lo m32r-opc.lo m32r-ibld.lo m32r-desc.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+       -I../../../../opcodes \
+       -I../../../../bfd \
+       -I../../../../intl \
+       -I$(srcdir)/../../../../opcodes \
+       -I$(srcdir)/../../../../include \
+       -I$(srcdir)/../../../../bfd     \
+       -I$(srcdir)/../../../../intl    \
+       -D_GNU_SOURCE 
+
 
 DEJAGNUTESTS = m32rbsp.exp
 
@@ -125,7 +137,8 @@ DEFS = @DEFS@ -I. -I$(srcdir)
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-libm32r_la_LIBADD = 
+libm32r_la_DEPENDENCIES =  m32r-asm.lo m32r-dis.lo m32r-opc.lo \
+m32r-ibld.lo m32r-desc.lo
 libm32r_la_OBJECTS =  m32rbf.lo m32r-decode.lo m32r-sem.lo
 CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -448,6 +461,21 @@ uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
+
+m32r-asm.lo: ../../../../opcodes/m32r-asm.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-dis.lo: ../../../../opcodes/m32r-dis.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-opc.lo: ../../../../opcodes/m32r-opc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-ibld.lo: ../../../../opcodes/m32r-ibld.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-desc.lo: ../../../../opcodes/m32r-desc.c
+       /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
 check-local: all
        (cd ../../testsuite ; $(MAKE) check RUNTESTFLAGS="$(RUNTESTFLAGS) $(DEJAGNUTESTS)" )
 .PHONY: cgen-all $(CGEN_ALL)
index 9c1257a..eb09fb8 100644 (file)
@@ -215,6 +215,13 @@ m32rbf_cpu::step_insns ()
       // Execute the instruction  -----------------------------------
       if (this->trace_result_p)
        this->begin_trace (pc, sem->idesc->insn_name);
+      if (trace_disass_p)
+       this->disassemble (pc, print_insn_m32r,
+                          bfd_target_elf_flavour,
+                          bfd_arch_m32r,
+                          (current_endianness() == endian_little ? 
+                           BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG), 
+                          "m32r");
       try
        {
          sem->idesc->execute (this, sem);
index 5e43e73..883fb0d 100755 (executable)
@@ -3216,7 +3216,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -3236,6 +3236,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -3246,6 +3247,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -3257,6 +3259,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -3267,7 +3270,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:3271: checking ARM family support" >&5
+echo "configure:3274: checking ARM family support" >&5
 
 
 
@@ -3280,8 +3283,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:3288: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:3285: checking MIPS family support" >&5
+echo "configure:3302: checking MIPS family support" >&5
 
 
 
@@ -3295,7 +3312,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:3299: checking M32R family support" >&5
+echo "configure:3316: checking M32R family support" >&5
 
 
 
@@ -3309,7 +3326,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:3313: checking M68K family support" >&5
+echo "configure:3330: checking M68K family support" >&5
 
 
 
@@ -3323,7 +3340,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:3327: checking PPC family support" >&5
+echo "configure:3344: checking PPC family support" >&5
 
 
 
@@ -3339,7 +3356,7 @@ echo "$ac_t""$sidtarget_ppc" 1>&6
 
 
 
-subdirs="cfgroot tcl audio cgen-cpu families timers"
+subdirs="bochs cfgroot tcl audio cgen-cpu families timers"
 
 
 
@@ -3448,7 +3465,7 @@ done
 ac_given_srcdir=$srcdir
 ac_given_INSTALL="$INSTALL"
 
-trap 'rm -fr `echo "Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+trap 'rm -fr `echo "Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc    
        cache/Makefile
        consoles/Makefile
        gdb/Makefile
@@ -3549,6 +3566,9 @@ s%@HAVE_SABLOTRON_FALSE@%$HAVE_SABLOTRON_FALSE%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
@@ -3604,7 +3624,7 @@ EOF
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc  
        cache/Makefile
        consoles/Makefile
        gdb/Makefile
@@ -3826,7 +3846,7 @@ if test "$no_recursion" != yes; then
     esac
   done
 
-  for ac_config_dir in cfgroot tcl audio cgen-cpu families timers; do
+  for ac_config_dir in bochs cfgroot tcl audio cgen-cpu families timers; do
 
     # Do not complain, so a configure script can configure whichever
     # parts of a large source tree are present.
index 2fd9c70..843e082 100644 (file)
@@ -90,7 +90,7 @@ dnl cfgroot is here because it's statically linked, and libltdl is its baby.
 dnl tcl is here because it looks for tcl/tk in a too complex way for this file.
 dnl audio is here because it has more host-dependent configuration
 dnl cgen-cpu is here because it has target-dependent configuration
-AC_CONFIG_SUBDIRS([cfgroot tcl audio cgen-cpu families timers])
+AC_CONFIG_SUBDIRS([bochs cfgroot tcl audio cgen-cpu families timers])
 
 
 
@@ -101,7 +101,7 @@ AC_SUBST(make_subdirs)
 
 dnl List all component subdirectory files not covered by AC_CONFIG_SUBDIRS
 dnl that need autoconf @substitution@.
-AC_OUTPUT([Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+AC_OUTPUT([Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc     
        cache/Makefile
        consoles/Makefile
        gdb/Makefile
index f54c228..0291578 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
index 4d4395d..6a72248 100644 (file)
@@ -82,6 +82,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 AUTOMAKE_OPTIONS = foreign
 SUBDIRS = @family_subdirs@
index 9df4499..cdfb12b 100644 (file)
@@ -598,7 +598,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -616,6 +616,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -627,6 +628,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -639,6 +641,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -656,6 +659,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index d5e4b12..58d3212 100755 (executable)
@@ -2163,7 +2163,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -2183,6 +2183,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -2193,6 +2194,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -2204,6 +2206,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -2214,7 +2217,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2218: checking ARM family support" >&5
+echo "configure:2221: checking ARM family support" >&5
 
 
 
@@ -2227,8 +2230,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2235: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2232: checking MIPS family support" >&5
+echo "configure:2249: checking MIPS family support" >&5
 
 
 
@@ -2242,7 +2259,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2246: checking M32R family support" >&5
+echo "configure:2263: checking M32R family support" >&5
 
 
 
@@ -2256,7 +2273,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2260: checking M68K family support" >&5
+echo "configure:2277: checking M68K family support" >&5
 
 
 
@@ -2270,7 +2287,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2274: checking PPC family support" >&5
+echo "configure:2291: checking PPC family support" >&5
 
 
 
@@ -2477,6 +2494,9 @@ s%@EXEEXT@%$EXEEXT%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
index f57095e..c7ec248 100644 (file)
@@ -1,3 +1,10 @@
+2001-10-17  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * sw-debug-gdb.xml: New file.
+       * sw-debug-gdb.txt: New file.
+       * Makefile.am: Add docs support.
+       * Makefile.in: Regenerated.
+
 2001-10-16  Dave Brolley  <brolley@redhat.com>
 
        * gdb.h (target_schedulers_enabled): New vector member of class gdb.
index 9c2d7b5..01cfc35 100644 (file)
@@ -11,4 +11,8 @@ libgdb_la_SOURCES = gdb.cxx \
 
 libgdb_la_LDFLAGS = -module -no-undefined
 
+pkgdata_DATA = sw-debug-gdb.txt
+
+html_stylesheet=$(srcdir)/../component_html.xsl
+include $(srcdir)/../../config/Makefile.docs
 
index 2022b3e..514852d 100644 (file)
 # PARTICULAR PURPOSE.
 
 
+# Makefile.docs -*- Makefile -*-
+# Copyright (C) 2001 Red Hat.
+# This file is part of SID and is licensed under the GPL.
+# See the file COPYING.SID for conditions for redistribution.
+#
+# ... to be included in document-building Makefile.am's
+#
+
+
 SHELL = @SHELL@
 
 srcdir = @srcdir@
@@ -87,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -100,6 +110,12 @@ libgdb_la_SOURCES = gdb.cxx \
 
 
 libgdb_la_LDFLAGS = -module -no-undefined
+
+pkgdata_DATA = sw-debug-gdb.txt
+
+html_stylesheet = $(srcdir)/../component_html.xsl
+
+SUFFIXES = .xml .txt .html
 mkinstalldirs = $(SHELL) $(top_srcdir)/../config/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -123,6 +139,8 @@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CF
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DATA =  $(pkgdata_DATA)
+
 DIST_COMMON =  ChangeLog Makefile.am Makefile.in
 
 
@@ -130,16 +148,18 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/gdb.P .deps/gdbserv-input.P .deps/gdbserv-output.P \
+.deps/gdbserv-state.P .deps/gdbserv-utils.P
 SOURCES = $(libgdb_la_SOURCES)
 OBJECTS = $(libgdb_la_OBJECTS)
 
 all: all-redirect
 .SUFFIXES:
-.SUFFIXES: .S .c .cxx .lo .o .s
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus gdb/Makefile
+.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign gdb/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -169,9 +189,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -188,9 +205,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -214,6 +228,25 @@ libgdb.la: $(libgdb_la_OBJECTS) $(libgdb_la_DEPENDENCIES)
 .cxx.lo:
        $(LTCXXCOMPILE) -c $<
 
+install-pkgdataDATA: $(pkgdata_DATA)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+       @list='$(pkgdata_DATA)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p; \
+         else if test -f $$p; then \
+           echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p"; \
+           $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
+         fi; fi; \
+       done
+
+uninstall-pkgdataDATA:
+       @$(NORMAL_UNINSTALL)
+       list='$(pkgdata_DATA)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkgdatadir)/$$p; \
+       done
+
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
@@ -248,8 +281,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = gdb
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign gdb/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -258,33 +296,82 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
-install-data-am:
+install-data-am: install-pkgdataDATA
 install-data: install-data-am
 
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 install: install-am
-uninstall-am: uninstall-pkglibLTLIBRARIES
+uninstall-am: uninstall-pkglibLTLIBRARIES uninstall-pkgdataDATA
 uninstall: uninstall-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile $(LTLIBRARIES) $(DATA)
 all-redirect: all-am
 install-strip:
        $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
 installdirs:
-       $(mkinstalldirs)  $(DESTDIR)$(pkglibdir)
+       $(mkinstalldirs)  $(DESTDIR)$(pkglibdir) $(DESTDIR)$(pkgdatadir)
 
 
 mostlyclean-generic:
@@ -297,27 +384,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -328,14 +415,26 @@ clean-pkglibLTLIBRARIES maintainer-clean-pkglibLTLIBRARIES \
 uninstall-pkglibLTLIBRARIES install-pkglibLTLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
-clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
-
+clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
+install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@     xsltproc --output $@ $(html_stylesheet) $<
+
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_FALSE@@HAVE_SABLOTRON_TRUE@.xml.html:
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_FALSE@@HAVE_SABLOTRON_TRUE@       sabcmd $(html_stylesheet) $< $@
+
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@.html.txt:
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@        links -dump $< > $@
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@        cp $@ $(srcdir)/$@
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/sid/component/gdb/sw-debug-gdb.txt b/sid/component/gdb/sw-debug-gdb.txt
new file mode 100644 (file)
index 0000000..11523c6
--- /dev/null
@@ -0,0 +1,288 @@
+               sw-debug-gdb (libgdb.la :: gdb_component_library)
+
+Synopsis:
+
+   The gdb component is an implementation of the GDB stub.
+
+     ----------------------------------------------------------------------
+
+Functionality:
+
+  Modelling:
+
+   The gdb component communicates with other components through its pins, and
+   also through four relations: a cpu uni-relation, a gloss uni-relation, a
+   target-schedulers multi-relation and a host-schedulers multi-relation.
+
+   Note that in sid, "turning the target power on or off" means that the gdb
+   component drives its yield pin, sets the target schedulers' enabled?
+   attributes through the target-schedulers relation and sets the host
+   schedulers' yield-host-time? attributes through the host-schedulers
+   relation. See sid-sched for an explanation of these pins.
+
+   Also note that the term "hw-breakpoint" used in a sid context could mean
+   the same thing as the term "software breakpoint" in a gdb context. This is
+   because breakpoints in sid are sometimes implemented as triggerpoints set
+   on the pc register.
+
+   +-------------------------------------------------+
+   |                    Behaviors                    |
+   |-------------------------------------------------|
+   |   initialization | When init is driven, target  |
+   |                  | power is turned off.         |
+   |                  | Basically, this means the    |
+   |                  | target will wait for further |
+   |                  | input from gdb.              |
+   |------------------+------------------------------|
+   |        execution | When the gdb component wants |
+   |                  | the target system to yield,  |
+   |                  | it drives the yield pin.     |
+   |                  | Likewise, it will drive the  |
+   |                  | restart pin to restart the   |
+   |                  | target system. The restart   |
+   |                  | pin is typically connected   |
+   |                  | to a hw-reset                |
+   |                  | hw-glue-sequence component   |
+   |                  | that has connections to any  |
+   |                  | of the target components     |
+   |                  | that need to be reset.       |
+   |                  |                              |
+   |                  | When the start-target pin is |
+   |                  | driven, the target power     |
+   |                  | will be turned on. The       |
+   |                  | start-target pin should be   |
+   |                  | driven by a sid-side         |
+   |                  | component that wants the     |
+   |                  | target cpu to start again.   |
+   |                  | Use this pin with caution;   |
+   |                  | driving it could upset an    |
+   |                  | attached external debugger.  |
+   |                  |                              |
+   |                  | The stop-target pin should   |
+   |                  | be driven from a sid-side    |
+   |                  | component that wants to stop |
+   |                  | the target cpu. This pin     |
+   |                  | will be ignored if there are |
+   |                  | signals pending.             |
+   |                  |                              |
+   |                  | When gdb itself or the gdb   |
+   |                  | component (see the           |
+   |                  | explanation of the           |
+   |                  | enable-Z-packet? attribute)  |
+   |                  | sets a software breakpoint,  |
+   |                  | it puts the cpu's            |
+   |                  | instruction cache out of     |
+   |                  | sync with the actual         |
+   |                  | contents of memory. So the   |
+   |                  | gdb component will drive the |
+   |                  | flush-icache pin when it     |
+   |                  | wants the cpu to invalidate  |
+   |                  | its instruction cache.       |
+   |                  |                              |
+   |                  | As long as gdb is connected  |
+   |                  | to the gdb component, the    |
+   |                  | connected? attribute will be |
+   |                  | true.                        |
+   |------------------+------------------------------|
+   |      system call | When gdb detaches from the   |
+   |        emulation | gdb component, the component |
+   |                  | drives the process-signal    |
+   |                  | pin.                         |
+   |                  |                              |
+   |                  | The gloss-process-signal pin |
+   |                  | is typically driven by a     |
+   |                  | gloss component. It tells    |
+   |                  | the gdb component that the   |
+   |                  | gloss component has          |
+   |                  | processed an exit system     |
+   |                  | call.                        |
+   |                  |                              |
+   |                  | The gdb component's trap pin |
+   |                  | is usually connected to the  |
+   |                  | gloss component's            |
+   |                  | trap-code-chain pin. The     |
+   |                  | gloss component sends any    |
+   |                  | trap code that it cannot     |
+   |                  | handle down the trap code    |
+   |                  | chain (via the               |
+   |                  | trap-code-chain pin), and    |
+   |                  | any debugging-related trap   |
+   |                  | will be handled by the gdb   |
+   |                  | component. If the gdb        |
+   |                  | component knows how to       |
+   |                  | handle the trap code, it     |
+   |                  | will handle it and then      |
+   |                  | drive the trap pin with the  |
+   |                  | cpu_trap_handled value. See  |
+   |                  | sw-gloss-arm_angel and       |
+   |                  | hw-cpu-arm7t for more        |
+   |                  | information on trap and      |
+   |                  | trap-code pins.              |
+   |------------------+------------------------------|
+   |          pin i/o | The remote-rx and remote-tx  |
+   |                  | pins are the pins that the   |
+   |                  | gdb component uses to        |
+   |                  | receive data from and        |
+   |                  | transmit data to gdb. They   |
+   |                  | are typically connected to a |
+   |                  | sid-io-socket's rx and tx    |
+   |                  | pins respectively. gdb       |
+   |                  | connects to this             |
+   |                  | sid-io-socket component via  |
+   |                  | TCP, and can then be used    |
+   |                  | just as if it were debugging |
+   |                  | a normal remote target.      |
+   |                  |                              |
+   |                  | The target-tx pin is used to |
+   |                  | transmit characters coming   |
+   |                  | from the target's standard   |
+   |                  | out back to gdb. These       |
+   |                  | characters are transmitted   |
+   |                  | using an "O" packet.         |
+   |------------------+------------------------------|
+   | deinitialization | When the deinit pin is       |
+   |                  | driven, the gdb component    |
+   |                  | disconnects from gdb.        |
+   |------------------+------------------------------|
+   |          setting | When set to true, the        |
+   |                  | trace-gdbsid? and            |
+   |                  | trace-gdbserv? attributes    |
+   |                  | turn on trace messages for   |
+   |                  | the gdb component member     |
+   |                  | functions and the stub       |
+   |                  | functions respectively.      |
+   |                  | Trace messages are printed   |
+   |                  | to stderr.                   |
+   |                  |                              |
+   |                  | When the exit-on-detach?     |
+   |                  | attribute is true, the gdb   |
+   |                  | component drives its         |
+   |                  | process-signal pin when gdb  |
+   |                  | detaches from the target.    |
+   |                  |                              |
+   |                  | When the enable-Z-packet?    |
+   |                  | attribute is true, the gdb   |
+   |                  | component recognizes Z       |
+   |                  | packets that it receives     |
+   |                  | from gdb, and sets           |
+   |                  | breakpoints according to     |
+   |                  | their contents. If the       |
+   |                  | enable-Z-packet? attribute   |
+   |                  | is false, then gdb sets      |
+   |                  | breakpoints directly using   |
+   |                  | the read memory (m) and      |
+   |                  | write memory (M) packets.    |
+   |                  |                              |
+   |                  | The Z-packet-pc-mask         |
+   |                  | attribute is used when       |
+   |                  | passing Harvard-encoded PC   |
+   |                  | addresses to the gdb         |
+   |                  | component via a Z packet.    |
+   |                  |                              |
+   |                  | When the operating-mode?     |
+   |                  | attribute is true, the gdb   |
+   |                  | component doesn't handle any |
+   |                  | cpu traps except for single  |
+   |                  | stepping.                    |
+   +-------------------------------------------------+
+
+   +-------------------------------------------------+
+   |                 SID Conventions                 |
+   |-------------------------------------------------|
+   |         functional | supported          | -     |
+   |--------------------+--------------------+-------|
+   |       save/restore | not supported      | -     |
+   |--------------------+--------------------+-------|
+   |      triggerpoints | supported          | -     |
+   +-------------------------------------------------+
+
+     ----------------------------------------------------------------------
+
+Environment:
+
+   Related Components
+
+   The gdb component connects to many other sid components:
+     * target memory to inspect and set values there
+     * the cpu to set triggerpoints, and to view register values
+     * a gloss component that sends it trap codes
+     * hw-glue-sequences so that it is initialized and deinitialized at the
+       proper times
+     * schedulers to change control between the target and the host
+     * a sid-io-socket component to interface with gdb via TCP
+
+   Host System
+
+   The gdb component prints error and tracing messages to stderr.
+
+     ----------------------------------------------------------------------
+
+Component Reference:
+
+  Component: sw-debug-gdb
+
+   +-----------------------------------------------------------+
+   |                           pins                            |
+   |-----------------------------------------------------------|
+   |        name        |direction|legalvalues|   behaviors    |
+   |--------------------+---------+-----------+----------------|
+   |init                |in       |any        |initialization  |
+   |--------------------+---------+-----------+----------------|
+   |remote-rx           |in       |any        |pin i/o         |
+   |--------------------+---------+-----------+----------------|
+   |remote-tx           |out      |any        |pin i/o         |
+   |--------------------+---------+-----------+----------------|
+   |target-tx           |in       |any        |pin i/o         |
+   |--------------------+---------+-----------+----------------|
+   |process-signal      |out      |enum values|system call     |
+   |                    |         |           |emulation       |
+   |--------------------+---------+-----------+----------------|
+   |gloss-process-signal|in       |enum values|system call     |
+   |                    |         |           |emulation       |
+   |--------------------+---------+-----------+----------------|
+   |trap                |inout    |enum values|system call     |
+   |                    |         |           |emulation       |
+   |--------------------+---------+-----------+----------------|
+   |trap-code           |in       |various    |system call     |
+   |                    |         |values     |emulation       |
+   |--------------------+---------+-----------+----------------|
+   |yield               |out      |any        |execution       |
+   |--------------------+---------+-----------+----------------|
+   |restart             |out      |any        |execution       |
+   |--------------------+---------+-----------+----------------|
+   |flush-icache        |out      |any        |execution       |
+   |--------------------+---------+-----------+----------------|
+   |stop-target         |in       |any        |execution       |
+   |--------------------+---------+-----------+----------------|
+   |start-target        |in       |any        |execution       |
+   |--------------------+---------+-----------+----------------|
+   |deinit              |in       |any        |deinitialization|
+   +-----------------------------------------------------------+
+
+   +------------------------------------------------------+
+   |                      attributes                      |
+   |------------------------------------------------------|
+   |      name      |category|  legal  |default|behaviors||
+   |                |        | values  | value |         ||
+   |----------------+--------+---------+-------+---------||
+   |trace-gdbserv?  |-       |boolean  |false  |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |trace-gdbsid?   |-       |boolean  |false  |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |exit-on-detach? |-       |boolean  |false  |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |enable-Z-packet?|-       |boolean  |true   |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |Z-packet-pc-mask|-       |number   |0      |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |operating-mode? |-       |boolean  |true   |setting  ||
+   |----------------+--------+---------+-------+---------||
+   |connected?      |-       |boolean, |false  |execution||
+   |                |        |read-only|       |         ||
+   +------------------------------------------------------+
+
+     ----------------------------------------------------------------------
+
+References:
+
+   Debugging with GDB
diff --git a/sid/component/gdb/sw-debug-gdb.xml b/sid/component/gdb/sw-debug-gdb.xml
new file mode 100644 (file)
index 0000000..db6afbe
--- /dev/null
@@ -0,0 +1,221 @@
+<?xml version="1.0" ?>
+<!DOCTYPE defcomplib  
+       PUBLIC "-//Red Hat//DTD Component Library//EN"
+        "http://sources.redhat.com/sid/component.dtd">
+<defcomplib lib="libgdb.la" dlsym="gdb_component_library">
+  <defcomponent name="sw-debug-gdb">
+    <!-- pins -->
+    <defpin name="init" direction="in" legalvalues="any" behaviors="initialization"/>
+    <defpin name="remote-rx" direction="in" legalvalues="any" behaviors="pin i/o"/>
+    <defpin name="remote-tx" direction="out" legalvalues="any" behaviors="pin i/o"/>
+    <defpin name="target-tx" direction="in" legalvalues="any" behaviors="pin i/o"/>
+    <defpin name="process-signal" direction="out" legalvalues="enum values" behaviors="system call emulation"/>
+    <defpin name="gloss-process-signal" direction="in" legalvalues="enum values" behaviors="system call emulation"/>
+    <defpin name="trap" direction="inout" legalvalues="enum values" behaviors="system call emulation"/>
+    <defpin name="trap-code" direction="in" legalvalues="various values" behaviors="system call emulation"/>
+    <defpin name="yield" direction="out" legalvalues="any" behaviors="execution"/>
+    <defpin name="restart" direction="out" legalvalues="any" behaviors="execution"/>
+    <defpin name="flush-icache" direction="out" legalvalues="any" behaviors="execution"/>
+    <defpin name="stop-target" direction="in" legalvalues="any" behaviors="execution"/>
+    <defpin name="start-target" direction="in" legalvalues="any" behaviors="execution"/>
+    <defpin name="deinit" direction="in" legalvalues="any" behaviors="deinitialization"/>
+    <!-- attributes -->
+    <defattribute name="trace-gdbserv?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+    <defattribute name="trace-gdbsid?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+    <defattribute name="exit-on-detach?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+    <defattribute name="enable-Z-packet?" legalvalues="boolean" defaultvalue="true" behaviors="setting"/>
+    <defattribute name="Z-packet-pc-mask" legalvalues="number" defaultvalue="0" behaviors="setting"/>
+    <defattribute name="operating-mode?" legalvalues="boolean" defaultvalue="true" behaviors="setting"/>
+    <defattribute name="connected?" legalvalues="boolean, read-only" defaultvalue="false" behaviors="execution"/>
+  </defcomponent>
+  <synop>
+    <p>
+      The gdb component is an implementation of the <a type="url"
+       href="http://sources.redhat.com/gdb/onlinedocs/gdb_15.html#SEC129">GDB
+       stub</a>.
+    </p>
+  </synop>
+  <func>
+    <modelling>
+      <p>
+       The gdb component communicates with other components
+       through its pins, and also through four relations: a cpu
+       uni-relation, a gloss uni-relation, a target-schedulers
+       multi-relation and a host-schedulers multi-relation.
+      </p>
+      <p>
+       Note that in sid, "turning the target power on or off" means
+       that the gdb component drives its <pin> yield</pin> pin, sets
+       the target schedulers' enabled?  attributes through the
+       target-schedulers relation and sets the host schedulers'
+       yield-host-time? attributes through the host-schedulers
+       relation. See <complib>sid-sched</complib> for an explanation
+       of these pins.
+      </p>
+      <p>
+       Also note that the term "hw-breakpoint" used in a sid context
+       could mean the same thing as the term "software breakpoint" in
+       a gdb context. This is because breakpoints in sid are
+       sometimes implemented as triggerpoints set on the pc register.
+      </p>
+    </modelling>
+    <behavior name="initialization">
+      <p>
+       When <pin> init</pin> is driven, target power is turned
+       off. Basically, this means the target will wait for further
+       input from gdb.
+      </p>
+    </behavior>
+    <behavior name="execution">
+      <p>
+       When the gdb component wants the target system to yield, it
+       drives the <pin> yield</pin> pin. Likewise, it will drive the
+       <pin> restart</pin> pin to restart the target system. The
+       restart pin is typically connected to a hw-reset <complib>
+       hw-glue-sequence</complib> component that has connections to
+       any of the target components that need to be reset.
+      </p>
+      <p>
+       When the <pin> start-target</pin> pin is driven, the target
+       power will be turned on. The <pin> start-target</pin> pin
+       should be driven by a sid-side component that wants the target
+       cpu to start again. Use this pin with caution; driving it
+       could upset an attached external debugger.
+      </p>
+      <p>
+       The <pin> stop-target</pin> pin should be driven from a
+       sid-side component that wants to stop the target cpu. This pin
+       will be ignored if there are signals pending.
+      </p>
+      <p>
+       When gdb itself or the gdb component (see the explanation of
+       the <attribute> enable-Z-packet?</attribute> attribute) sets a
+       software breakpoint, it puts the cpu's instruction cache out
+       of sync with the actual contents of memory. So the gdb
+       component will drive the <pin> flush-icache</pin> pin when it
+       wants the cpu to invalidate its instruction cache.
+      </p>
+      <p>
+       As long as gdb is connected to the gdb component, the
+       <attribute> connected?</attribute> attribute will be true.
+      </p>
+    </behavior>
+    <behavior name="system call emulation">
+      <p>
+       When gdb detaches from the gdb component, the component drives
+       the <pin> process-signal</pin> pin.
+      </p>
+      <p>
+       The <pin> gloss-process-signal</pin> pin is typically driven
+       by a <complib> gloss</complib> component.  It tells the gdb
+       component that the gloss component has processed an exit
+       system call.
+      </p>
+      <p>
+       The gdb component's <pin> trap</pin> pin is usually connected
+       to the gloss component's trap-code-chain pin. The gloss
+       component sends any trap code that it cannot handle down the
+       trap code chain (via the trap-code-chain pin), and any
+       debugging-related trap will be handled by the gdb
+       component. If the gdb component knows how to handle the trap
+       code, it will handle it and then drive the trap pin with the
+       cpu_trap_handled value. See <complib>
+       sw-gloss-arm_angel</complib> and <complib>
+       hw-cpu-arm7t</complib> for more information on trap and
+       trap-code pins.
+      </p>
+    </behavior>
+    <behavior name="pin i/o">
+      <p>
+       The <pin> remote-rx</pin> and <pin> remote-tx</pin> pins are
+       the pins that the gdb component uses to receive data from and
+       transmit data to gdb.  They are typically connected to a
+       <complib> sid-io-socket</complib>'s rx and tx pins
+       respectively. gdb connects to this sid-io-socket component via
+       TCP, and can then be used just as if it were debugging a
+       normal remote target.
+      </p>
+      <p>
+       The <pin> target-tx</pin> pin is used to transmit characters
+       coming from the target's standard out back to gdb. These
+       characters are transmitted using an "O" packet.
+      </p>
+    </behavior>
+    <behavior name="deinitialization">
+      <p>
+       When the <pin> deinit</pin> pin is driven, the gdb component
+       disconnects from gdb.
+      </p>
+    </behavior>
+    <behavior name="setting">
+      <p>
+       When set to true, the <attribute> trace-gdbsid?</attribute>
+       and <attribute> trace-gdbserv?</attribute> attributes turn on
+       trace messages for the gdb component member functions and the
+       stub functions respectively. Trace messages are printed to
+       stderr.
+      </p>
+      <p>
+       When the <attribute> exit-on-detach?</attribute> attribute is
+       true, the gdb component drives its <pin> process-signal</pin>
+       pin when gdb detaches from the target.
+      </p>
+      <p>
+       When the <attribute> enable-Z-packet?</attribute> attribute is
+       true, the gdb component recognizes Z packets that it receives
+       from gdb, and sets breakpoints according to their contents. If
+       the <attribute> enable-Z-packet?</attribute> attribute is
+       false, then gdb sets breakpoints directly using the read
+       memory (m) and write memory (M) packets.
+      </p>
+      <p>
+       The <attribute> Z-packet-pc-mask</attribute> attribute is used
+       when passing Harvard-encoded PC addresses to the gdb component
+       via a Z packet.
+      </p>
+      <p>
+       When the <attribute> operating-mode?</attribute> attribute is
+       true, the gdb component doesn't handle any cpu traps except
+       for single stepping.
+      </p>
+    </behavior>
+    <convention name="functional" supported="true">
+    </convention>
+    <convention name="save/restore" supported="false">
+    </convention>
+    <convention name="triggerpoints" supported="true">
+      This component supports triggerpoints on the PC register.
+    </convention>
+  </func>
+  <env>
+    <title>
+      Related Components </title>
+    <p>
+      The gdb component connects to many other sid components:
+      <ul>
+       <li>
+         target memory to inspect and set values there </li>
+       <li>
+         the cpu to set triggerpoints, and to view register values </li>
+       <li>
+         a gloss component that sends it trap codes </li>
+       <li>
+         hw-glue-sequences so that it is initialized and deinitialized
+         at the proper times </li>
+       <li>
+         schedulers to change control between the target and the host </li>
+       <li>
+         a sid-io-socket component to interface with gdb via TCP </li>
+      </ul>
+    </p>
+    <title>
+      Host System </title>
+    <p>
+      The gdb component prints error and tracing
+      messages to stderr.
+    </p>
+  </env>
+  <refs>
+    <a type="url" href="http://sources.redhat.com/gdb/onlinedocs/gdb.html">Debugging with GDB</a>
+  </refs>
+</defcomplib>
index 0c26b73..4bbddef 100644 (file)
        (gloss32::set_halfword): Likewise.
        (gloss32::do_sys_fstat): Likewise.
 
+2001-08-31  Ben Elliston  <bje@redhat.com>
+
+       * sw-gloss-arm_angel.txt: Regenerate.
+
+2001-08-30  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * gloss.cxx: Add syscall-numbering-scheme setting.
+       * libcygmon.h: New file.  It contains cygmon syscall numbers.
+       * sw-gloss-arm_angel.xml: Add syscall-numbering-scheme documentation.
+
 2001-08-12  Richard Henderson  <rth@redhat.com>
 
        * gloss.cxx (gloss32::read): Fix argument type mismatch for min.
index 78f35b3..6cb9b1f 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -212,6 +213,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/angel.P .deps/compGloss.P .deps/gloss.P \
+.deps/hostops.P .deps/m32r.P .deps/mips.P .deps/newlib.P
 SOURCES = $(libgloss_la_SOURCES)
 OBJECTS = $(libgloss_la_OBJECTS)
 
@@ -219,9 +222,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus gloss/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign gloss/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -251,9 +254,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -270,9 +270,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -349,8 +346,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = gloss
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign gloss/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -359,17 +361,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -399,27 +450,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -432,10 +483,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index a0df97c..1eaa5e5 100644 (file)
@@ -8,6 +8,7 @@
 #include <errno.h>
 #include "gloss.h"
 #include "libgloss.h"
+#include "libcygmon.h"
 // ??? For now.  grep for newlib below.
 #include "newlib.h"
 #ifdef HAVE_TIMES
@@ -42,6 +43,7 @@ gloss32::gloss32() :
   cpu (0),
   cpu_memory_bus (0),
   command_line("<unknown>"),
+  syscall_numbering_scheme("libgloss"),
   max_fds(32),
   verbose_p(false)
 {
@@ -63,8 +65,9 @@ gloss32::gloss32() :
   add_uni_relation("cpu", &this->cpu);
 
   add_attribute("command-line", &this->command_line, "setting");
+  add_attribute("syscall-numbering-scheme", &this->syscall_numbering_scheme, "setting");
   add_attribute("verbose?", &this->verbose_p, "setting");
-
+  
   add_attribute("max-fds", &this->max_fds, "setting");
   host_ops = 0;
   fd_table = 0;
@@ -621,11 +624,53 @@ gloss32::set_error_result(int32 value)
 
 \f
 
-// default syscall conversion routine
+// syscall conversion routine
 int32 
 gloss32::target_to_host_syscall (int32 target_syscall)
 {
-  return target_syscall;
+  if(syscall_numbering_scheme == "cygmon")
+    {
+      switch(target_syscall)
+        {
+        case cygmon::SYS_exit:
+          return libgloss::SYS_exit;
+          break;
+        case cygmon::SYS_open:
+          return libgloss::SYS_open;
+          break;
+        case cygmon::SYS_close:
+          return libgloss::SYS_close;
+          break;
+        case cygmon::SYS_read:
+          return libgloss::SYS_read;
+          break;
+        case cygmon::SYS_write:
+          return libgloss::SYS_write;
+          break;
+        case cygmon::SYS_kill:
+          return libgloss::SYS_kill;
+          break;
+        case cygmon::SYS_time:
+          return libgloss::SYS_time;
+          break;
+        case cygmon::SYS_gettimeofday:
+          return libgloss::SYS_gettimeofday;
+          break;
+        default:
+          return libgloss::SYS_unsupported;
+          break;
+        };
+    }
+  else if (syscall_numbering_scheme == "libgloss")
+    {
+      return target_syscall;
+    }
+  else
+    {
+      cerr << "gloss: unsupported syscall numbering scheme. Assuming default (libgloss)" << endl;
+      syscall_numbering_scheme = "libgloss";
+      return target_syscall;
+    };
 }
 
 // System call support.
index 8992ef3..9f31432 100644 (file)
@@ -194,6 +194,8 @@ protected:
   bool tmpnam (string& filename, int& errcode);
   bool isatty (int fd, bool& result, int& errcode);
 
+  string syscall_numbering_scheme;
+  
   // true -> send various debugging messages to cerr.
   // ??? Would be nice to be able to specify a file.
   bool verbose_p;
diff --git a/sid/component/gloss/libcygmon.h b/sid/component/gloss/libcygmon.h
new file mode 100644 (file)
index 0000000..872914f
--- /dev/null
@@ -0,0 +1,30 @@
+// libcygmon.h - Interface details for Cygnus' cygmon.  -*- C++ -*-
+
+// Copyright (C) 1999, 2000 Red Hat.
+// This file is part of SID and is licensed under the GPL.
+// See the file COPYING.SID for conditions for redistribution.
+
+// System call numbers must be synchronised with:
+//   libgloss/i386/cygmon-syscall.h
+
+#ifndef CYGMON_H
+#define CYGMON_H
+
+class cygmon
+{
+public:
+    
+  enum cygmon_syscall
+  {
+    SYS_exit = 1,
+    SYS_open = 5, 
+    SYS_close = 6, 
+    SYS_read = 3,
+    SYS_write = 4, 
+    SYS_kill = 37,
+    SYS_time = 13,
+    SYS_gettimeofday = 156
+  };
+};
+
+#endif // CYGMON_H
index 281e655..1282b06 100644 (file)
@@ -37,7 +37,8 @@ public:
     SYS_utime = 17,
     SYS_time = 18,
     SYS_gettimeofday = 19,
-    SYS_times = 20
+    SYS_times = 20,
+    SYS_unsupported = 99 // arbitrary syscall number, unsupported by default gloss component
   };
 };
 
index a92b0cb..046ed80 100644 (file)
@@ -74,6 +74,19 @@ Functionality:
    |                | tracing messages will be       |
    |                | printed to stderr during a     |
    |                | system call emulation.         |
+   |                |                                |
+   |                | The syscall-numbering-scheme   |
+   |                | setting causes the gloss       |
+   |                | component to use the system    |
+   |                | call numbering scheme          |
+   |                | specified. The gloss component |
+   |                | may then properly interpret    |
+   |                | non-standard syscall numbers   |
+   |                | that come from target-program  |
+   |                | libgloss routines. Currently,  |
+   |                | the only available             |
+   |                | non-standard numbering scheme  |
+   |                | is cygmon.                     |
    |----------------+--------------------------------|
    | initialization | When the reset pin is driven,  |
    |                | all open files are closed and  |
@@ -186,29 +199,32 @@ Component Reference:
    |debug-rx      |in       |0-255      |stdio         |
    +---------------------------------------------------+
 
-   +-------------------------------------------------------------+
-   |                         attributes                          |
-   |-------------------------------------------------------------|
-   |    name    |category| legal | default value |  behaviors   ||
-   |            |        |values |               |              ||
-   |------------+--------+-------+---------------+--------------||
-   |verbose?    |setting |boolean|false          |system call   ||
-   |            |        |       |               |emulation     ||
-   |------------+--------+-------+---------------+--------------||
-   |heap-base   |setting |number |0x80000        |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |heap-limit  |setting |number |1024           |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |stack-base  |setting |number |0x200000       |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |stack-limit |setting |number |0x200000       |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |command-line|setting |any    |''             |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |max-fds     |setting |number |32             |initialization||
-   |------------+--------+-------+---------------+--------------||
-   |'tk tty'    |gui     |-      |'hw-visual-tty'|component gui ||
-   +-------------------------------------------------------------+
+   +-------------------------------------------------------------------------+
+   |                               attributes                                |
+   |-------------------------------------------------------------------------|
+   |          name          |category| legal | default value |  behaviors   ||
+   |                        |        |values |               |              ||
+   |------------------------+--------+-------+---------------+--------------||
+   |verbose?                |setting |boolean|false          |system call   ||
+   |                        |        |       |               |emulation     ||
+   |------------------------+--------+-------+---------------+--------------||
+   |syscall-numbering-scheme|setting |string |libgloss       |system call   ||
+   |                        |        |       |               |emulation     ||
+   |------------------------+--------+-------+---------------+--------------||
+   |heap-base               |setting |number |0x80000        |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |heap-limit              |setting |number |1024           |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |stack-base              |setting |number |0x200000       |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |stack-limit             |setting |number |0x200000       |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |command-line            |setting |any    |''             |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |max-fds                 |setting |number |32             |initialization||
+   |------------------------+--------+-------+---------------+--------------||
+   |'tk tty'                |gui     |-      |'hw-visual-tty'|component gui ||
+   +-------------------------------------------------------------------------+
 
    +-------------------------------------------------+
    |                    accessors                    |
index 433afe2..c615a1a 100644 (file)
@@ -20,6 +20,7 @@
 
     <!-- attributes -->
     <defattribute name="verbose?" category="setting" legalvalues="boolean" defaultvalue="false" behaviors="system call emulation" />
+    <defattribute name="syscall-numbering-scheme" category="setting" legalvalues="string" defaultvalue="libgloss" behaviors="system call emulation" />
     <defattribute name="heap-base" category="setting" legalvalues="number" defaultvalue="0x80000" behaviors="initialization" />
     <defattribute name="heap-limit" category="setting" legalvalues="number" defaultvalue="1024" behaviors="initialization" />
     <defattribute name="stack-base" category="setting" legalvalues="number" defaultvalue="0x200000" behaviors="initialization" />
@@ -74,7 +75,6 @@
        output pin is driven with an exit code similar to that used by
        UNIX <tt>wait(2)</tt>.  Such conditions include memory faults,
        invalid instructions, etc.
-
       </p>
       <p> See the documentation of <complib>hw-cpu-arm7t</complib> for
       the list of supported trap &amp; trap-code values.
        true value, detailed tracing messages will be printed to
        stderr during a system call emulation.
       </p>
+      <p> The <attribute>syscall-numbering-scheme</attribute> setting causes the gloss component to use the
+          system call numbering scheme specified. The gloss component may then properly interpret non-standard syscall
+          numbers that come from target-program libgloss routines. Currently, the only available non-standard
+          numbering scheme is cygmon.
+      </p>
+
     </behavior>
 
     <behavior name="initialization">
index fa0331f..c809f77 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
index dba6d94..b39b85e 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/compIDE.P
 SOURCES = $(libide_la_SOURCES)
 OBJECTS = $(libide_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus ide/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign ide/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = ide
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign ide/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index 15a45cf..e2db4c6 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -147,6 +148,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/arm.P .deps/cma222.P .deps/components.P
 SOURCES = $(libinterrupt_la_SOURCES)
 OBJECTS = $(libinterrupt_la_OBJECTS)
 
@@ -154,9 +156,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus interrupt/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign interrupt/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -186,9 +188,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -205,9 +204,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -284,8 +280,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = interrupt
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign interrupt/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -294,17 +295,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -334,27 +384,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -367,10 +417,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index e5acffa..cb36879 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -158,6 +159,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/HD44780U.P .deps/T6963C.P .deps/lcd-char-display.P \
+.deps/rom-5X10.P .deps/rom-europe.P .deps/rom-japan.P \
+.deps/rom-t6963c.P .deps/rom.P
 SOURCES = $(libhd44780u_la_SOURCES) $(libt6963c_la_SOURCES) $(liblcd_char_display_la_SOURCES)
 OBJECTS = $(libhd44780u_la_OBJECTS) $(libt6963c_la_OBJECTS) $(liblcd_char_display_la_OBJECTS)
 
@@ -165,9 +169,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus lcd/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign lcd/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -197,9 +201,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -216,9 +217,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -277,7 +275,7 @@ uninstall-pkgdataDATA:
 @SET_MAKE@
 
 all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
 check-recursive installcheck-recursive info-recursive dvi-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
        dot_seen=no; \
@@ -361,8 +359,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = lcd
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign lcd/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -381,17 +384,66 @@ distdir: $(DISTFILES)
              || exit 1; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-recursive
 dvi-am:
 dvi: dvi-recursive
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-recursive
 installcheck-am:
 installcheck: installcheck-recursive
-install-info-am: 
-install-info: install-info-recursive
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-recursive
 
@@ -422,27 +474,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-recursive
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-recursive
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-recursive
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -460,9 +512,10 @@ uninstalldirs-recursive all-recursive check-recursive \
 installcheck-recursive info-recursive dvi-recursive \
 mostlyclean-recursive distclean-recursive clean-recursive \
 maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check-local check check-am installcheck-am installcheck \
-install-info-am install-info install-exec-am install-exec \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
 install-data-am install-data install-am install uninstall-am uninstall \
 all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
 distclean-generic clean-generic maintainer-clean-generic clean \
index 123c728..a6fb4d9 100644 (file)
@@ -13,7 +13,7 @@
        * Makefile.am (all-local): Tolerate $srcdir==$builddir.
 
 2001-03-23  John Healy  <jhealy@redhat.com>
-       
+
        * Makefile.in: Regenerated.
 
 2001-01-15  Frank Ch. Eigler  <fche@redhat.com>
index 19c9371..ad140c5 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
index 41b1e53..c3110ea 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -142,6 +143,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/compLoader.P .deps/elfload.P
 SOURCES = $(libloader_la_SOURCES)
 OBJECTS = $(libloader_la_OBJECTS)
 
@@ -149,9 +151,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus loader/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign loader/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -181,9 +183,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -200,9 +199,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -279,8 +275,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = loader
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign loader/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -289,16 +290,65 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -328,27 +378,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -361,12 +411,13 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
 
 
 @MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
index b4ac6c2..1807c6e 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -148,6 +149,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/compMapper.P
 SOURCES = $(libmapper_la_SOURCES)
 OBJECTS = $(libmapper_la_OBJECTS)
 
@@ -155,9 +157,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus mapper/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign mapper/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -187,9 +189,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -206,9 +205,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -261,7 +257,7 @@ uninstall-pkgdataDATA:
 @SET_MAKE@
 
 all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
 check-recursive installcheck-recursive info-recursive dvi-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
        dot_seen=no; \
@@ -345,8 +341,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = mapper
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mapper/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -365,17 +366,66 @@ distdir: $(DISTFILES)
              || exit 1; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-recursive
 dvi-am:
 dvi: dvi-recursive
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-recursive
 installcheck-am:
 installcheck: installcheck-recursive
-install-info-am: 
-install-info: install-info-recursive
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-recursive
 
@@ -406,27 +456,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-recursive
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-recursive
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-recursive
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -444,9 +494,10 @@ uninstalldirs-recursive all-recursive check-recursive \
 installcheck-recursive info-recursive dvi-recursive \
 mostlyclean-recursive distclean-recursive clean-recursive \
 maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check-local check check-am installcheck-am installcheck \
-install-info-am install-info install-exec-am install-exec \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
 install-data-am install-data install-am install uninstall-am uninstall \
 all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
 distclean-generic clean-generic maintainer-clean-generic clean \
index 2e3d5f8..c540d9e 100644 (file)
@@ -1,3 +1,7 @@
+2001-08-03  matthew green  <mrg@redhat.com>
+
+       * busif.cxx (dtor): Add throw() specifier.
+
 2001-03-23  John Healy  <jhealy@redhat.com>
 
        * Makefile.in: Regenerated.
index a72287b..5aa8d82 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -121,6 +122,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/busif.P
 SOURCES = $(libbusif_la_SOURCES)
 OBJECTS = $(libbusif_la_OBJECTS)
 
@@ -128,9 +130,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .lo .o .s
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus mapper/testsuite/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign mapper/testsuite/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -144,9 +146,6 @@ distclean-noinstLTLIBRARIES:
 
 maintainer-clean-noinstLTLIBRARIES:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -163,9 +162,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -223,8 +219,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = mapper/testsuite
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mapper/testsuite/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -233,16 +234,65 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am:
 install-exec: install-exec-am
 
@@ -271,27 +321,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-noinstLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-noinstLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-noinstLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -302,12 +352,14 @@ clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index cc89708..9af0614 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -150,6 +151,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/am29.P .deps/at29.P .deps/components.P .deps/flash.P \
+.deps/generic.P .deps/ramrom.P
 SOURCES = $(libmemory_la_SOURCES)
 OBJECTS = $(libmemory_la_OBJECTS)
 
@@ -157,9 +160,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus memory/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign memory/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -189,9 +192,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -208,9 +208,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -287,8 +284,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = memory
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign memory/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -297,17 +299,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -337,27 +388,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -370,10 +421,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index 84c625c..1c2ff72 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/armRemap.P
 SOURCES = $(libmmu_la_SOURCES)
 OBJECTS = $(libmmu_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus mmu/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign mmu/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = mmu
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mmu/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index c5cab5a..1721750 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/ps2.P
 SOURCES = $(libparport_la_SOURCES)
 OBJECTS = $(libparport_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus parport/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign parport/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = parport
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign parport/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index e4a0385..5e96685 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/gprof.P
 SOURCES = $(libprof_la_SOURCES)
 OBJECTS = $(libprof_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus profiling/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign profiling/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = profiling
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign profiling/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index dbc46d8..57d2018 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/components.P .deps/ds1x42.P .deps/sidrtc.P
 SOURCES = $(librtc_la_SOURCES)
 OBJECTS = $(librtc_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus rtc/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign rtc/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = rtc
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign rtc/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index 793058a..0de8296 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -144,6 +145,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/compSched.P
 SOURCES = $(libsched_la_SOURCES)
 OBJECTS = $(libsched_la_OBJECTS)
 
@@ -151,9 +153,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus sched/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign sched/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -183,9 +185,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -202,9 +201,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -281,8 +277,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = sched
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign sched/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -291,17 +292,66 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-local
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-am
 
@@ -331,27 +381,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -364,10 +414,11 @@ mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
 install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
 mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
index 41015f6..658568b 100644 (file)
@@ -2,6 +2,7 @@
 // Enumerate available sid component families. 
 
 #define SIDTARGET_ARM @sidtarget_arm@
+#define SIDTARGET_X86 @sidtarget_x86@
 #define SIDTARGET_MIPS @sidtarget_mips@
 #define SIDTARGET_M32R @sidtarget_m32r@
 #define SIDTARGET_M68K @sidtarget_m68k@
index e1e09ce..73e821e 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign dejagnu
@@ -113,9 +114,9 @@ GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus testsuite/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -128,8 +129,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = testsuite
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign testsuite/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -148,10 +154,6 @@ RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
 check-DEJAGNU: site.exp
        srcdir=`cd $(srcdir) && pwd`; export srcdir; \
        EXPECT=$(EXPECT); export EXPECT; \
-       if [ -f $(top_builddir)/../expect/expect ]; then \
-         TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
-         export TCL_LIBRARY; \
-       fi; \
        runtest=$(RUNTEST); \
        if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
          $$runtest $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
@@ -176,13 +178,11 @@ info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am:
+check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am:
 install-exec: install-exec-am
 
@@ -230,11 +230,11 @@ maintainer-clean-am:  maintainer-clean-generic distclean-am
 maintainer-clean: maintainer-clean-am
 
 .PHONY: tags distdir check-DEJAGNU info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 31685a5..3a4e0c7 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 AUTOMAKE_OPTIONS = foreign
 SUBDIRS = @cpu_subdirs@ .
index 7d5e150..e05405b 100644 (file)
@@ -621,7 +621,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -639,6 +639,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -650,6 +651,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -662,6 +664,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -679,6 +682,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index 82a2faa..4f7ce78 100755 (executable)
@@ -2210,7 +2210,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -2230,6 +2230,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -2240,6 +2241,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -2251,6 +2253,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -2261,7 +2264,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2265: checking ARM family support" >&5
+echo "configure:2268: checking ARM family support" >&5
 
 
 
@@ -2274,8 +2277,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2282: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2279: checking MIPS family support" >&5
+echo "configure:2296: checking MIPS family support" >&5
 
 
 
@@ -2289,7 +2306,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2293: checking M32R family support" >&5
+echo "configure:2310: checking M32R family support" >&5
 
 
 
@@ -2303,7 +2320,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2307: checking M68K family support" >&5
+echo "configure:2324: checking M68K family support" >&5
 
 
 
@@ -2317,7 +2334,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2321: checking PPC family support" >&5
+echo "configure:2338: checking PPC family support" >&5
 
 
 
@@ -2356,7 +2373,7 @@ subdirs="$cpu_subdirs"
 # Extract the first word of "links", so it can be a program name with args.
 set dummy links; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2360: checking for $ac_word" >&5
+echo "configure:2377: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LINKS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2396,7 +2413,7 @@ fi
 # Extract the first word of "xsltproc", so it can be a program name with args.
 set dummy xsltproc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2400: checking for $ac_word" >&5
+echo "configure:2417: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_XSLTPROC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2436,7 +2453,7 @@ fi
 # Extract the first word of "sabcmd", so it can be a program name with args.
 set dummy sabcmd; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2440: checking for $ac_word" >&5
+echo "configure:2457: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_SABLOTRON'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2648,6 +2665,9 @@ s%@EXEEXT@%$EXEEXT%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
index 4f58c63..c4a92af 100644 (file)
@@ -96,6 +96,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -143,6 +144,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/Uart.P
 SOURCES = $(libuart_la_SOURCES)
 OBJECTS = $(libuart_la_OBJECTS)
 
@@ -150,9 +152,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus uart/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign uart/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -182,9 +184,6 @@ uninstall-pkglibLTLIBRARIES:
          $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
        done
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -201,9 +200,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -256,7 +252,7 @@ uninstall-pkgdataDATA:
 @SET_MAKE@
 
 all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
 check-recursive installcheck-recursive info-recursive dvi-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
        dot_seen=no; \
@@ -340,8 +336,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = uart
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign uart/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -360,16 +361,65 @@ distdir: $(DISTFILES)
              || exit 1; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 info-am:
 info: info-recursive
 dvi-am:
 dvi: dvi-recursive
-check-am:
+check-am: all-am
 check: check-recursive
 installcheck-am:
 installcheck: installcheck-recursive
-install-info-am: 
-install-info: install-info-recursive
 install-exec-am: install-pkglibLTLIBRARIES
 install-exec: install-exec-recursive
 
@@ -400,27 +450,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-recursive
 
 clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \
-               clean-tags clean-generic mostlyclean-am
+               clean-tags clean-depend clean-generic mostlyclean-am
 
 clean: clean-recursive
 
 distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-recursive
 
 maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -438,13 +488,14 @@ uninstalldirs-recursive all-recursive check-recursive \
 installcheck-recursive info-recursive dvi-recursive \
 mostlyclean-recursive distclean-recursive clean-recursive \
 maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs-am installdirs mostlyclean-generic distclean-generic \
-clean-generic maintainer-clean-generic clean mostlyclean distclean \
-maintainer-clean
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
 
 
 @MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
index da133f2..78e40d8 100644 (file)
@@ -87,6 +87,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 socket_libs = @socket_libs@
 
 AUTOMAKE_OPTIONS = foreign
@@ -128,6 +129,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
+DEP_FILES =  .deps/Devices.P .deps/driver.P
 SOURCES = $(uart_driver_SOURCES)
 OBJECTS = $(uart_driver_OBJECTS)
 
@@ -135,9 +137,9 @@ all: all-redirect
 .SUFFIXES:
 .SUFFIXES: .S .c .cxx .lo .o .s
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --cygnus uart/testsuite/Makefile
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign uart/testsuite/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -151,9 +153,6 @@ distclean-checkPROGRAMS:
 
 maintainer-clean-checkPROGRAMS:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -170,9 +169,6 @@ distclean-compile:
 
 maintainer-clean-compile:
 
-.c.lo:
-       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
 .s.lo:
        $(LIBTOOL) --mode=compile $(COMPILE) -c $<
 
@@ -231,8 +227,13 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = uart/testsuite
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign uart/testsuite/Makefile
        @for file in $(DISTFILES); do \
-         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         d=$(srcdir); \
          if test -d $$d/$$file; then \
            cp -pr $$d/$$file $(distdir)/$$file; \
          else \
@@ -241,6 +242,57 @@ distdir: $(DISTFILES)
            || cp -p $$d/$$file $(distdir)/$$file || :; \
          fi; \
        done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cxx
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
 check-TESTS: $(TESTS)
        @failed=0; all=0; \
        srcdir=$(srcdir); export srcdir; \
@@ -270,13 +322,12 @@ info-am:
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am: $(check_PROGRAMS)
+check-am: all-am
+       $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
        $(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
-install-info-am: 
-install-info: install-info-am
 install-exec-am:
 install-exec: install-exec-am
 
@@ -305,27 +356,27 @@ distclean-generic:
 
 maintainer-clean-generic:
 mostlyclean-am:  mostlyclean-checkPROGRAMS mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-tags \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
                mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
 clean-am:  clean-checkPROGRAMS clean-compile clean-libtool clean-tags \
-               clean-generic mostlyclean-am
+               clean-depend clean-generic mostlyclean-am
 
 clean: clean-am
 
 distclean-am:  distclean-checkPROGRAMS distclean-compile \
-               distclean-libtool distclean-tags distclean-generic \
-               clean-am
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
 maintainer-clean-am:  maintainer-clean-checkPROGRAMS \
                maintainer-clean-compile maintainer-clean-libtool \
-               maintainer-clean-tags maintainer-clean-generic \
-               distclean-am
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
@@ -336,11 +387,12 @@ clean-checkPROGRAMS maintainer-clean-checkPROGRAMS mostlyclean-compile \
 distclean-compile clean-compile maintainer-clean-compile \
 mostlyclean-libtool distclean-libtool clean-libtool \
 maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir check-TESTS info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend check-TESTS \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
index 670fef6..da3c8b3 100644 (file)
@@ -3,6 +3,10 @@
        * libstdc++.m4: Reject shared libstdc++ possibility if g++ replies with
        no path to "--print-file-name=libstdc++.a".
 
+2001-09-14  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * sidtargets.m4: Add x86 support.
+
 2001-07-11  Frank Ch. Eigler  <fche@redhat.com>
 
        * Makefile.docs: Support xsltproc; prefer it to sabcmd.
index 7338093..a1ca573 100644 (file)
@@ -14,6 +14,7 @@ set target_alias "@target@"
 # pull out "--enable-targets"/"--target" settings
 global sidtarget
 set sidtarget(arm) @sidtarget_arm@
+set sidtarget(x86) @sidtarget_x86@
 set sidtarget(mips) @sidtarget_mips@
 set sidtarget(m32r) @sidtarget_m32r@
 set sidtarget(m68k) @sidtarget_m68k@
index dbba78a..28e2f5c 100644 (file)
@@ -19,7 +19,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -37,6 +37,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -48,6 +49,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -60,6 +62,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -77,6 +80,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index 3660480..51ab6fc 100755 (executable)
@@ -1383,7 +1383,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -1403,6 +1403,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -1413,6 +1414,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -1424,6 +1426,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -1434,7 +1437,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:1438: checking ARM family support" >&5
+echo "configure:1441: checking ARM family support" >&5
 
 
 
@@ -1447,8 +1450,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:1455: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:1452: checking MIPS family support" >&5
+echo "configure:1469: checking MIPS family support" >&5
 
 
 
@@ -1462,7 +1479,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:1466: checking M32R family support" >&5
+echo "configure:1483: checking M32R family support" >&5
 
 
 
@@ -1476,7 +1493,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:1480: checking M68K family support" >&5
+echo "configure:1497: checking M68K family support" >&5
 
 
 
@@ -1490,7 +1507,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:1494: checking PPC family support" >&5
+echo "configure:1511: checking PPC family support" >&5
 
 
 
@@ -1506,7 +1523,7 @@ echo "$ac_t""$sidtarget_ppc" 1>&6
 
 
 echo $ac_n "checking whether can build shared SID component libraries""... $ac_c" 1>&6
-echo "configure:1510: checking whether can build shared SID component libraries" >&5
+echo "configure:1527: checking whether can build shared SID component libraries" >&5
 if eval "test \"`echo '$''{'ac_cv_libstdcxx_shared'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1519,7 +1536,7 @@ then
   echo "configure: warning: Cannot test for libstdc++ without g++" 1>&2
 else
   echo $ac_n "checking for libstdc++ {static/shared}""... $ac_c" 1>&6
-echo "configure:1523: checking for libstdc++ {static/shared}" >&5
+echo "configure:1540: checking for libstdc++ {static/shared}" >&5
 
   stlibname=libstdc++.a
   case ${host} in
@@ -1579,6 +1596,7 @@ fi
 
 
 
+
 subdirs="include component main bsp samples demos"
 
 trap '' 1 2 15
@@ -1747,6 +1765,9 @@ s%@CXXCPP@%$CXXCPP%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
index fbfa8a0..693ae89 100644 (file)
@@ -41,5 +41,6 @@ fi
 AC_SUBST(enable_shared)
 AC_SUBST(target)
 
+
 AC_CONFIG_SUBDIRS(include component main bsp samples demos)
 AC_OUTPUT(Makefile config/info.tcl)
index bd3eeae..8f5aa82 100755 (executable)
@@ -2445,7 +2445,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.
index 3a2d867..c84d026 100644 (file)
@@ -1,3 +1,8 @@
+2001-11-15  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * sid-guide/book-sid.sgml: Add example to Using GDB
+       section.
+
 2001-10-16  Frank Ch. Eigler  <fche@redhat.com>
 
        * *-guide/images/*.png: New files, replacing ...
index 2fe41ed..0f40307 100644 (file)
           has a bus named "data-bus" through which it expects to
           receive read/write requests. The scenario is depicted blow.
         </PARA>
-<GRAPHIC FILEREF="images/accessor-bus.png" SCALE="55"></GRAPHIC>
+<GRAPHIC FILEREF="images/accessor-bus.png"></GRAPHIC>
 <PARA>    Recall that the accessor is the <EMPHASIS>sending</EMPHASIS>
           end of the connection we wish to make, and that the bus is
           the <EMPHASIS>receiving</EMPHASIS> end. Some people find the
index adf2a89..c9149aa 100644 (file)
      debug the simulation exactly as if it were a "real" target
      environment.
     </PARA>
-<PARA>Configuring the GDB stub and socket components is somewhat
-     lengthy and verbose, but is performed automatically by the
-     <FILENAME>configrun-sid</FILENAME> command when
-     invoked with the
-     <FILENAME>---gdb=<REPLACEABLE>PORT</REPLACEABLE></FILENAME>
-     option.  For complete details of the connection process, see
+<EXAMPLE>
+<TITLE>Debugging a Program Running in SID</TITLE>
+<SCREEN>
+% <USERINPUT>i386-elf-sid --gdb=2345&</USERINPUT>
+[1] 25135
+% <USERINPUT>i386-elf-gdb -nw hello</USERINPUT>
+GNU gdb 2001-10-12-cvs (MI_OUT)
+Copyright 2001 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB.  Type "show warranty" for details.
+This GDB was configured as "--host=i686-pc-linux-gnu --target=i386-elf"...
+(gdb) <USERINPUT>target remote :2345</USERINPUT>
+Remote debugging using :2345
+0x0000fff0 in ?? ()
+(gdb) <USERINPUT>load</USERINPUT>
+Loading section .text, size 0x5994 lma 0x100000
+Loading section .data, size 0x78c lma 0x1059a0
+Loading section .rodata, size 0x2c9 lma 0x106140
+Start address 0x100000, load size 25577
+Transfer rate: 102308 bits/sec, 97 bytes/write.
+(gdb) <USERINPUT>continue</USERINPUT>
+Continuing.
+Hello, World
+
+Program exited normally.
+(gdb) 
+</SCREEN>
+</EXAMPLE>
+<PARA>Configuring the GDB stub and I/O socket components is
+     somewhat lengthy and verbose, but is performed automatically by
+     the <FILENAME>configrun-sid</FILENAME> command when invoked with
+     the <FILENAME>--gdb=<REPLACEABLE>PORT</REPLACEABLE></FILENAME>
+     option, as in the above example.  For a detailed description of
+     the GDB stub component's pins and attributes, see
      <FILENAME>siddoc sw-debug-gdb</FILENAME>.
     </PARA>
 </SECT2>
index 0d3c7ce..04d27d4 100644 (file)
@@ -5,6 +5,10 @@
        (basic_cpu ctor): Initialize them.
        (cg_profile): New function.
 
+2001-10-12  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * sidcpuutil.h (sidutil): Clarified expedited_regno_list comment.
+
 2001-10-04  Frank Ch. Eigler  <fche@redhat.com>
 
        * sidcpuutil.h (basic_cpu ctor): Initialize those tracing flags.
index 5a93d8d..da7a5bb 100644 (file)
@@ -417,12 +417,13 @@ namespace sidutil
        this->triggerpoint_manager.add_watchable_value ("gdb-register-pc", pc);
        this->add_attribute_ro_value ("gdb-num-registers", count, "debugger");
 
-       // The "expedited" register list string is the list of
+       // The "expedited" register list string is the semi-colon-delimited list of
        // register numbers that should be sent to gdb immediately
        // every time sid stops, rather than let gdb ask for it
        // subsequently.  Usually, the PC, frame and stack pointer,
        // and status register should be included in the list.  It
        // makes gdb step operations much faster.
+        // The register numbering scheme is that decided by gdb. 
 
        this->add_attribute_ro_value ("gdb-exp-registers", expedited_regno_list, "debugger");
        for (sid::host_int_4 i=0; i<count; i++)
index 3471472..b2a99ec 100755 (executable)
@@ -1079,7 +1079,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.
index 00b659e..2a3ac20 100644 (file)
@@ -1,10 +1,15 @@
 2001-10-05  Frank Ch. Eigler  <fche@redhat.com>
 
-        * mainDynamic.cxx (version): New function.  Use SID_VERSION from
-        new version.h file.
-        (main): Support "-v" option to print this information.
-        * Makefile.am (sid_DEPENDENCIES): List version.h.
-        * configure, Makefile.in: Regenerated.
+       * mainDynamic.cxx (version): New function.  Use SID_VERSION from
+       new version.h file.
+       (main): Support "-v" option to print this information.
+       * Makefile.am (sid_DEPENDENCIES): List version.h.
+       * configure, Makefile.in: Regenerated.
+
+2001-09-18  Frank Ch. Eigler  <fche@redhat.com>
+
+       * Makefile.am (NEARBY_LIBS, NEARBY_DEPS_LIBS): Add bochs/libx86.la.
+       * Makefile.in: Regenerated.
 
 2001-07-24  Frank Ch. Eigler  <fche@redhat.com>
 
index 28e0458..9a85a87 100644 (file)
@@ -22,6 +22,7 @@ NEARBY_LIBS = \
        -dlpreopen ../../component/cache/libcache.la \
        -dlpreopen ../../component/cfgroot/libconfig.la \
        -dlpreopen ../../component/cgen-cpu/libcgencpu.la \
+       -dlpreopen ../../component/bochs/libx86.la \
        -dlpreopen ../../component/consoles/libconsoles.la \
        $(ALLFAMLIBS2) \
        -dlpreopen ../../component/gdb/libgdb.la \
@@ -48,6 +49,7 @@ NEARBY_DEPS_LIBS = \
        ../../component/cache/libcache.la \
        ../../component/cfgroot/libconfig.la \
        ../../component/cgen-cpu/libcgencpu.la \
+       ../../component/bochs/libx86.la \
        ../../component/consoles/libconsoles.la \
        $(ALLFAMLIBS) \
        ../../component/gdb/libgdb.la \
index a22a92c..b1e8076 100644 (file)
@@ -81,6 +81,7 @@ sidtarget_m32r = @sidtarget_m32r@
 sidtarget_m68k = @sidtarget_m68k@
 sidtarget_mips = @sidtarget_mips@
 sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
 
 AUTOMAKE_OPTIONS = foreign
 ACLOCAL_AMFLAGS = -I $(srcdir)/../../config
@@ -100,6 +101,7 @@ ALLFAMLIBS2 = $(FAM9LIB2)
 @SID_STATIC_TRUE@      -dlpreopen ../../component/cache/libcache.la \
 @SID_STATIC_TRUE@      -dlpreopen ../../component/cfgroot/libconfig.la \
 @SID_STATIC_TRUE@      -dlpreopen ../../component/cgen-cpu/libcgencpu.la \
+@SID_STATIC_TRUE@      -dlpreopen ../../component/bochs/libx86.la \
 @SID_STATIC_TRUE@      -dlpreopen ../../component/consoles/libconsoles.la \
 @SID_STATIC_TRUE@      $(ALLFAMLIBS2) \
 @SID_STATIC_TRUE@      -dlpreopen ../../component/gdb/libgdb.la \
@@ -127,6 +129,7 @@ ALLFAMLIBS2 = $(FAM9LIB2)
 @SID_STATIC_TRUE@      ../../component/cache/libcache.la \
 @SID_STATIC_TRUE@      ../../component/cfgroot/libconfig.la \
 @SID_STATIC_TRUE@      ../../component/cgen-cpu/libcgencpu.la \
+@SID_STATIC_TRUE@      ../../component/bochs/libx86.la \
 @SID_STATIC_TRUE@      ../../component/consoles/libconsoles.la \
 @SID_STATIC_TRUE@      $(ALLFAMLIBS) \
 @SID_STATIC_TRUE@      ../../component/gdb/libgdb.la \
index 6884df7..317dd8b 100644 (file)
@@ -621,7 +621,7 @@ then
     AC_MSG_WARN(Assuming --enable-targets=all)
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -639,6 +639,7 @@ AC_ARG_ENABLE(targets,
 
 dnl Enumerate known chip families
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -650,6 +651,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -662,6 +664,7 @@ done
 dnl Ensure at least one of these variables is non-zero.
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -679,6 +682,11 @@ AC_SUBST(sidtarget_arm)
 AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
 AC_MSG_RESULT($sidtarget_arm)
 
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
 AC_MSG_CHECKING(MIPS family support)
 AC_SUBST(sidtarget_mips)
 AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
index 28b98e4..afbd810 100755 (executable)
@@ -2122,7 +2122,7 @@ then
     echo "configure: warning: Assuming --enable-targets=all" 1>&2
     all_targets=""
     sidtarget_default=1
-else
+else 
     all_targets="$target"
     sidtarget_default=0
 fi
@@ -2142,6 +2142,7 @@ fi
 
 
 sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
 sidtarget_mips=$sidtarget_default
 sidtarget_m32r=$sidtarget_default
 sidtarget_m68k=$sidtarget_default
@@ -2152,6 +2153,7 @@ do
    case "$targ" in
       arm*)   sidtarget_arm=1 ;;
       thumb*) sidtarget_arm=1 ;;
+      i386*) sidtarget_x86=1 ;;
       mips*)  sidtarget_mips=1 ;;
       m32r*)  sidtarget_m32r=1 ;;
       m68k*)  sidtarget_m68k=1 ;;
@@ -2163,6 +2165,7 @@ done
 
 case 1 in
   ${sidtarget_arm}) ;;
+  ${sidtarget_x86}) ;;
   ${sidtarget_mips}) ;;
   ${sidtarget_m32r}) ;;
   ${sidtarget_m68k}) ;;
@@ -2173,7 +2176,7 @@ esac
 
 
 echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2234: checking ARM family support" >&5
+echo "configure:2180: checking ARM family support" >&5
 
 
 
@@ -2186,8 +2189,22 @@ else
 fi
 echo "$ac_t""$sidtarget_arm" 1>&6
 
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2194: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+  SIDTARGET_X86_TRUE=
+  SIDTARGET_X86_FALSE='#'
+else
+  SIDTARGET_X86_TRUE='#'
+  SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
 echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2264: checking MIPS family support" >&5
+echo "configure:2208: checking MIPS family support" >&5
 
 
 
@@ -2201,7 +2218,7 @@ fi
 echo "$ac_t""$sidtarget_mips" 1>&6
 
 echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2278: checking M32R family support" >&5
+echo "configure:2222: checking M32R family support" >&5
 
 
 
@@ -2215,7 +2232,7 @@ fi
 echo "$ac_t""$sidtarget_m32r" 1>&6
 
 echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2292: checking M68K family support" >&5
+echo "configure:2236: checking M68K family support" >&5
 
 
 
@@ -2229,7 +2246,7 @@ fi
 echo "$ac_t""$sidtarget_m68k" 1>&6
 
 echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2322: checking PPC family support" >&5
+echo "configure:2250: checking PPC family support" >&5
 
 
 
@@ -2424,6 +2441,9 @@ s%@CXXCPP@%$CXXCPP%g
 s%@sidtarget_arm@%$sidtarget_arm%g
 s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
 s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
 s%@sidtarget_mips@%$sidtarget_mips%g
 s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
 s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
@@ -2446,7 +2466,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.
index 0fadd03..e8fe913 100644 (file)
@@ -59,16 +59,19 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 host_alias = @host_alias@
 host_triplet = @host@
+AR = @AR@
 AS = @AS@
 CC = @CC@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
 EXEEXT = @EXEEXT@
+LD = @LD@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+NM = @NM@
 OBJDUMP = @OBJDUMP@
 PACKAGE = @PACKAGE@
 RANLIB = @RANLIB@
index a53db13..a9056f9 100644 (file)
@@ -159,7 +159,7 @@ else
 fi])
 
 
-# serial 40 AC_PROG_LIBTOOL
+# serial 41 AC_PROG_LIBTOOL
 AC_DEFUN(AC_PROG_LIBTOOL,
 [AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
 
@@ -167,12 +167,12 @@ AC_DEFUN(AC_PROG_LIBTOOL,
 AC_CACHE_SAVE
 
 # Actually configure libtool.  ac_aux_dir is where install-sh is found.
-CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
 LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
 LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
 DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
 ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
 || AC_MSG_ERROR([libtool configure failed])
 
 # Reload cache, that may have been modified by ltconfig
@@ -197,13 +197,15 @@ AC_REQUIRE([AC_ENABLE_STATIC])dnl
 AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
 AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-AC_REQUIRE([AC_PROG_RANLIB])dnl
 AC_REQUIRE([AC_PROG_CC])dnl
 AC_REQUIRE([AC_PROG_LD])dnl
 AC_REQUIRE([AC_PROG_NM])dnl
 AC_REQUIRE([AC_PROG_LN_S])dnl
 dnl
 
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
 test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
@@ -220,6 +222,12 @@ AC_ARG_ENABLE(libtool-lock,
 test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
 test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
 
+AC_ARG_WITH(pic,
+  [  --with-pic              try to use only PIC/non-PIC objects [default=use both]],
+     pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case "$host" in
@@ -259,8 +267,30 @@ ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
   AC_CHECK_TOOL(AS, as, false)
   AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+  # recent cygwin and mingw systems supply a stub DllMain which the user
+  # can override, but on older systems we have to supply one
+  AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+    [AC_TRY_LINK([DllMain (0, 0, 0);],
+      [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);],
+      [lt_cv_need_dllmain=yes],[lt_cv_need_dllmain=no])])
+
+  case $host in
+  *-*-cygwin*)
+    # cygwin systems need to pass --dll to the linker, and not link
+    # crt.o which will require a WinMain@16 definition.
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+  *-*-mingw*)
+    # old mingw systems require "-dll" to link a DLL, while more recent ones
+    # require "-mdll"
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mdll"
+    AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+      [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+    CFLAGS="$SAVE_CFLAGS" ;;
+  esac
   ;;
-])
+  ])
 esac
 ])
 
@@ -382,7 +412,13 @@ ac_prog=ld
 if test "$ac_cv_prog_gcc" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by GCC])
-  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
   case "$ac_prog" in
     # Accept absolute paths.
 changequote(,)dnl
@@ -438,6 +474,7 @@ else
   AC_MSG_RESULT(no)
 fi
 test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
 AC_PROG_LD_GNU
 ])
 
@@ -483,6 +520,7 @@ else
 fi])
 NM="$ac_cv_path_NM"
 AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
 ])
 
 # AC_CHECK_LIBM - check for math library
index d7c36b7..916167f 100755 (executable)
@@ -24,6 +24,8 @@ ac_help="$ac_help
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
 ac_help="$ac_help
   --disable-libtool-lock  avoid locking (might break parallel builds)"
+ac_help="$ac_help
+  --with-pic              try to use only PIC/non-PIC objects [default=use both]"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -576,7 +578,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:580: checking for a BSD compatible install" >&5
+echo "configure:582: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -629,7 +631,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:633: checking whether build environment is sane" >&5
+echo "configure:635: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -686,7 +688,7 @@ test "$program_suffix" != NONE &&
 test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:690: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:692: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -732,7 +734,7 @@ EOF
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:736: checking for working aclocal" >&5
+echo "configure:738: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -745,7 +747,7 @@ else
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:749: checking for working autoconf" >&5
+echo "configure:751: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -758,7 +760,7 @@ else
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:762: checking for working automake" >&5
+echo "configure:764: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -771,7 +773,7 @@ else
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:775: checking for working autoheader" >&5
+echo "configure:777: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -784,7 +786,7 @@ else
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:788: checking for working makeinfo" >&5
+echo "configure:790: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -802,7 +804,7 @@ fi
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:806: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:808: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -901,7 +903,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:905: checking host system type" >&5
+echo "configure:907: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -922,7 +924,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:926: checking build system type" >&5
+echo "configure:928: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -939,40 +941,10 @@ build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
 build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$build" 1>&6
 
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:946: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_RANLIB="ranlib"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
-  echo "$ac_t""$RANLIB" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:976: checking for $ac_word" >&5
+echo "configure:948: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1002,7 +974,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1006: checking for $ac_word" >&5
+echo "configure:978: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1053,7 +1025,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1057: checking for $ac_word" >&5
+echo "configure:1029: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1085,7 +1057,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1089: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1061: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1096,12 +1068,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1100 "configure"
+#line 1072 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1127,12 +1099,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1131: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1103: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1136: checking whether we are using GNU C" >&5
+echo "configure:1108: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1141,7 +1113,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1117: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1160,7 +1132,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1164: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1136: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1203,8 +1175,14 @@ ac_prog=ld
 if test "$ac_cv_prog_gcc" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:1207: checking for ld used by GCC" >&5
-  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+echo "configure:1179: checking for ld used by GCC" >&5
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
   case "$ac_prog" in
     # Accept absolute paths.
     [\\/]* | [A-Za-z]:[\\/]*)
@@ -1227,10 +1205,10 @@ echo "configure:1207: checking for ld used by GCC" >&5
   esac
 elif test "$with_gnu_ld" = yes; then
   echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:1231: checking for GNU ld" >&5
+echo "configure:1209: checking for GNU ld" >&5
 else
   echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:1234: checking for non-GNU ld" >&5
+echo "configure:1212: checking for non-GNU ld" >&5
 fi
 if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1264,8 +1242,9 @@ else
   echo "$ac_t""no" 1>&6
 fi
 test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:1269: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:1248: checking if the linker ($LD) is GNU ld" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1281,7 +1260,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
 
 
 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:1285: checking for BSD-compatible nm" >&5
+echo "configure:1264: checking for BSD-compatible nm" >&5
 if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1316,8 +1295,9 @@ fi
 NM="$ac_cv_path_NM"
 echo "$ac_t""$NM" 1>&6
 
+
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1321: checking whether ln -s works" >&5
+echo "configure:1301: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1344,6 +1324,106 @@ else
 fi
 
 
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1331: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="${ac_tool_prefix}ar"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1363: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1395: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  RANLIB=":"
+fi
+fi
+
+
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
 test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
@@ -1362,13 +1442,24 @@ fi
 test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
 test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
 
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case "$host" in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 1371 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:1372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  echo '#line 1462 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       LD="${LD-ld} -32"
@@ -1389,19 +1480,19 @@ case "$host" in
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:1393: checking whether the C compiler needs -belf" >&5
+echo "configure:1484: checking whether the C compiler needs -belf" >&5
 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1398 "configure"
+#line 1489 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   lt_cv_cc_needs_belf=yes
 else
@@ -1424,7 +1515,7 @@ echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
   # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
 set dummy ${ac_tool_prefix}dlltool; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1428: checking for $ac_word" >&5
+echo "configure:1519: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1456,7 +1547,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "dlltool", so it can be a program name with args.
 set dummy dlltool; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1460: checking for $ac_word" >&5
+echo "configure:1551: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1491,7 +1582,7 @@ fi
   # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
 set dummy ${ac_tool_prefix}as; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1495: checking for $ac_word" >&5
+echo "configure:1586: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1523,7 +1614,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "as", so it can be a program name with args.
 set dummy as; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1527: checking for $ac_word" >&5
+echo "configure:1618: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1558,7 +1649,7 @@ fi
   # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
 set dummy ${ac_tool_prefix}objdump; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1562: checking for $ac_word" >&5
+echo "configure:1653: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1590,7 +1681,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "objdump", so it can be a program name with args.
 set dummy objdump; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1594: checking for $ac_word" >&5
+echo "configure:1685: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1622,8 +1713,76 @@ else
 fi
 fi
 
-  ;;
 
+  # recent cygwin and mingw systems supply a stub DllMain which the user
+  # can override, but on older systems we have to supply one
+  echo $ac_n "checking if libtool should supply DllMain function""... $ac_c" 1>&6
+echo "configure:1721: checking if libtool should supply DllMain function" >&5
+if eval "test \"`echo '$''{'lt_cv_need_dllmain'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1726 "configure"
+#include "confdefs.h"
+DllMain (0, 0, 0);
+int main() {
+extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+; return 0; }
+EOF
+if { (eval echo configure:1733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_need_dllmain=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_need_dllmain=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_need_dllmain" 1>&6
+
+  case $host in
+  *-*-cygwin*)
+    # cygwin systems need to pass --dll to the linker, and not link
+    # crt.o which will require a WinMain@16 definition.
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+  *-*-mingw*)
+    # old mingw systems require "-dll" to link a DLL, while more recent ones
+    # require "-mdll"
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mdll"
+    echo $ac_n "checking how to link DLLs""... $ac_c" 1>&6
+echo "configure:1758: checking how to link DLLs" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_dll_switch'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1763 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_dll_switch=-mdll
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_dll_switch=-dll
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_dll_switch" 1>&6
+    CFLAGS="$SAVE_CFLAGS" ;;
+  esac
+  ;;
+  
 esac
 
 
@@ -1677,12 +1836,12 @@ rm -f confcache
 
 
 # Actually configure libtool.  ac_aux_dir is where install-sh is found.
-CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
 LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
 LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
 DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
 ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
 || { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
 
 # Reload cache, that may have been modified by ltconfig
@@ -1707,12 +1866,12 @@ exec 5>>./config.log
 
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:1711: checking for Cygwin environment" >&5
+echo "configure:1870: checking for Cygwin environment" >&5
 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1716 "configure"
+#line 1875 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1723,7 +1882,7 @@ int main() {
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:1727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -1740,19 +1899,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:1744: checking for mingw32 environment" >&5
+echo "configure:1903: checking for mingw32 environment" >&5
 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1749 "configure"
+#line 1908 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:1756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -1771,7 +1930,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1775: checking for executable suffix" >&5
+echo "configure:1934: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1781,7 +1940,7 @@ else
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:1944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
       *.c | *.o | *.obj | *.ilk | *.pdb) ;;
@@ -1806,7 +1965,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1810: checking for $ac_word" >&5
+echo "configure:1969: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1838,7 +1997,7 @@ test -n "$CXX" || CXX="gcc"
 
 
 echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1842: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+echo "configure:2001: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
 
 ac_ext=C
 # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1849,12 +2008,12 @@ cross_compiling=$ac_cv_prog_cxx_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1853 "configure"
+#line 2012 "configure"
 #include "confdefs.h"
 
 int main(){return(0);}
 EOF
-if { (eval echo configure:1858: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cxx_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1880,12 +2039,12 @@ if test $ac_cv_prog_cxx_works = no; then
   { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1884: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2043: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
 cross_compiling=$ac_cv_prog_cxx_cross
 
 echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1889: checking whether we are using GNU C++" >&5
+echo "configure:2048: checking whether we are using GNU C++" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1894,7 +2053,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gxx=yes
 else
   ac_cv_prog_gxx=no
@@ -1913,7 +2072,7 @@ ac_test_CXXFLAGS="${CXXFLAGS+set}"
 ac_save_CXXFLAGS="$CXXFLAGS"
 CXXFLAGS=
 echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1917: checking whether ${CXX-g++} accepts -g" >&5
+echo "configure:2076: checking whether ${CXX-g++} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1945,7 +2104,7 @@ else
 fi
 
 echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
-echo "configure:1949: checking how to run the C++ preprocessor" >&5
+echo "configure:2108: checking how to run the C++ preprocessor" >&5
 if test -z "$CXXCPP"; then
 if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1958,12 +2117,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes
 cross_compiling=$ac_cv_prog_cxx_cross
   CXXCPP="${CXX-g++} -E"
   cat > conftest.$ac_ext <<EOF
-#line 1962 "configure"
+#line 2121 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1967: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1988,7 +2147,7 @@ CXXCPP="$ac_cv_prog_CXXCPP"
 echo "$ac_t""$CXXCPP" 1>&6
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1992: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:2151: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2198,9 +2357,12 @@ s%@build_alias@%$build_alias%g
 s%@build_cpu@%$build_cpu%g
 s%@build_vendor@%$build_vendor%g
 s%@build_os@%$build_os%g
-s%@RANLIB@%$RANLIB%g
 s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
 s%@LN_S@%$LN_S%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
 s%@DLLTOOL@%$DLLTOOL%g
 s%@AS@%$AS%g
 s%@OBJDUMP@%$OBJDUMP%g
@@ -2216,7 +2378,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.