OSDN Git Service

[VM][I386][NEWDEV][WIP] Fitting to CSP from MAME 0.208.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 23 Apr 2019 20:42:08 +0000 (05:42 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 23 Apr 2019 20:42:08 +0000 (05:42 +0900)
source/src/vm/libcpu_newdev/i386/cache.h
source/src/vm/libcpu_newdev/i386/i386_device.cpp
source/src/vm/libcpu_newdev/i386/i386_device.h
source/src/vm/libcpu_newdev/i386/i386dasm.cpp
source/src/vm/libcpu_newdev/i386/i386dasm.h
source/src/vm/libcpu_newdev/i386/i386op16.hxx
source/src/vm/libcpu_newdev/i386/i386ops.hxx
source/src/vm/libcpu_newdev/i386/i486ops.hxx

index a04f2ca..371021f 100644 (file)
@@ -42,35 +42,35 @@ public:
        // Reset the cache
        void reset();
        // Find the cacheline containing data at address
-       template <int ReadWrite> u8* search(u32 address);
+       template <int ReadWrite> uint8_t* search(uint32_t address);
        // Allocate a cacheline for data at address
-       template <int ReadWrite> bool allocate(u32 address, u8 **data);
+       template <int ReadWrite> bool allocate(uint32_t address, uint8_t **data);
        // Get the address where the cacheline data should be written back to
-       u32 old();
+       uint32_t old();
        // Get the address of the first byte of the cacheline that contains data at address
-       u32 base(u32 address);
+       uint32_t base(uint32_t address);
        // Compose the cacheline parameters into an address
-       u32 address(u32 tag, u32 set, u32 offset);
+       uint32_t address(uint32_t tag, uint32_t set, uint32_t offset);
        // Get the data of the first cacheline marked as dirty
-       u8* first_dirty(u32 &base, bool clean);
+       uint8_t* first_dirty(uint32_t &base, bool clean);
        // Get the data of the next cacheline marked as dirty
-       u8* next_dirty(u32 &base, bool clean);
+       uint8_t* next_dirty(uint32_t &base, bool clean);
 
 private:
        static const int Ways = 1 << WayBits;
        static const int LineBytes = 1 << LineBits;
        static const int Sets = 1 << SetBits;
-       static const u32 LineMask = (1 << LineBits) - 1;
-       static const u32 SetMask = ((1 << SetBits) - 1) << LineBits;
-       static const u32 WayMask = (1 << WayBits) - 1;
+       static const uint32_t LineMask = (1 << LineBits) - 1;
+       static const uint32_t SetMask = ((1 << SetBits) - 1) << LineBits;
+       static const uint32_t WayMask = (1 << WayBits) - 1;
        static const int TagShift = LineBits + SetBits;
 
        struct cacheline {
-               u8 data[LineBytes];
+               uint8_t data[LineBytes];
                bool allocated;
                bool dirty;
-               u32 tag;
-               u32 debug_address;
+               uint32_t tag;
+               uint32_t debug_address;
        };
 
        struct cacheset {
@@ -79,7 +79,7 @@ private:
        };
 
        cacheset sets[Sets];
-       u32 writeback_base;
+       uint32_t writeback_base;
        int last_set;
        int last_way;
 };
@@ -107,7 +107,7 @@ void cpucache<TagBits, SetBits, WayBits, LineBits>::reset()
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
 template<int ReadWrite>
-u8* cpucache<TagBits, SetBits, WayBits, LineBits>::search(u32 address)
+uint8_t* cpucache<TagBits, SetBits, WayBits, LineBits>::search(uint32_t address)
 {
        const int addresset = (address & SetMask) >> LineBits;
        const int addrestag = address >> TagShift;
@@ -124,7 +124,7 @@ u8* cpucache<TagBits, SetBits, WayBits, LineBits>::search(u32 address)
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
 template<int ReadWrite>
-bool cpucache<TagBits, SetBits, WayBits, LineBits>::allocate(u32 address, u8 **data)
+bool cpucache<TagBits, SetBits, WayBits, LineBits>::allocate(uint32_t address, uint8_t **data)
 {
        const int addresset = (address & SetMask) >> LineBits;
        const int addrestag = address >> TagShift;
@@ -151,25 +151,25 @@ bool cpucache<TagBits, SetBits, WayBits, LineBits>::allocate(u32 address, u8 **d
 }
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
-u32 cpucache<TagBits, SetBits, WayBits, LineBits>::old()
+uint32_t cpucache<TagBits, SetBits, WayBits, LineBits>::old()
 {
        return writeback_base;
 }
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
-u32 cpucache<TagBits, SetBits, WayBits, LineBits>::base(u32 address)
+uint32_t cpucache<TagBits, SetBits, WayBits, LineBits>::base(uint32_t address)
 {
        return address & ~LineMask;
 }
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
-u32 cpucache<TagBits, SetBits, WayBits, LineBits>::address(u32 tag, u32 set, u32 offset)
+uint32_t cpucache<TagBits, SetBits, WayBits, LineBits>::address(uint32_t tag, uint32_t set, uint32_t offset)
 {
        return (tag << TagShift) | (set << LineBits) | offset;
 }
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
-u8* cpucache<TagBits, SetBits, WayBits, LineBits>::first_dirty(u32 &base, bool clean)
+uint8_t* cpucache<TagBits, SetBits, WayBits, LineBits>::first_dirty(uint32_t &base, bool clean)
 {
        for (int s = 0; s < Sets; s++)
                for (int w = 0; w < Ways; w++)
@@ -186,7 +186,7 @@ u8* cpucache<TagBits, SetBits, WayBits, LineBits>::first_dirty(u32 &base, bool c
 }
 
 template<int TagBits, int SetBits, int WayBits, int LineBits>
-u8* cpucache<TagBits, SetBits, WayBits, LineBits>::next_dirty(u32 &base, bool clean)
+uint8_t* cpucache<TagBits, SetBits, WayBits, LineBits>::next_dirty(uint32_t &base, bool clean)
 {
        if (last_set < 0)
                return nullptr;
@@ -218,15 +218,15 @@ u8* cpucache<TagBits, SetBits, WayBits, LineBits>::next_dirty(u32 &base, bool cl
 
 /* To test it outside of Mame
 const int memorysize = 256 * 1024;
-u8 memory[memorysize];
+uint8_t memory[memorysize];
 
-void readline(u8 *data, u32 address)
+void readline(uint8_t *data, uint32_t address)
 {
     for (int n = 0; n < 64; n++)
         data[n] = memory[address + n];
 }
 
-void writeline(u8 *data, u32 address)
+void writeline(uint8_t *data, uint32_t address)
 {
     for (int n = 0; n < 64; n++)
         memory[address + n] = data[n];
@@ -236,9 +236,9 @@ void cache_tester()
 {
     cpucache<18, 8, 6, 2> cache;
     bool r;
-    u8 *data;
+    uint8_t *data;
     int address;
-    u8 value;
+    uint8_t value;
 
     for (int n = 0; n < memorysize; n++)
         memory[n] = 0xaa ^ n;
index f372dba..f017204 100644 (file)
 */
 
 #include "emu.h"
-#include "i386.h"
-#include "i386priv.h"
-#include "x87priv.h"
-#include "cycles.h"
-#include "i386ops.h"
+#include "vm_template.h"
+#include "./i386_device.h"
+#include "./i386priv.h"
+#include "./x87priv.h"
+#include "./cycles.h"
+#include "./i386ops.h"
 
 #include "debugger.h"
 #include "debug/debugcpu.h"
@@ -31,6 +32,7 @@
 /* seems to be defined on mingw-gcc */
 #undef i386
 
+/*
 DEFINE_DEVICE_TYPE(I386,        i386_device,        "i386",        "Intel I386")
 DEFINE_DEVICE_TYPE(I386SX,      i386sx_device,      "i386sx",      "Intel I386SX")
 DEFINE_DEVICE_TYPE(I486,        i486_device,        "i486",        "Intel I486")
@@ -43,106 +45,124 @@ DEFINE_DEVICE_TYPE(PENTIUM2,    pentium2_device,    "pentium2",    "Intel Pentiu
 DEFINE_DEVICE_TYPE(PENTIUM3,    pentium3_device,    "pentium3",    "Intel Pentium III")
 DEFINE_DEVICE_TYPE(ATHLONXP,    athlonxp_device,    "athlonxp",    "Amd Athlon XP")
 DEFINE_DEVICE_TYPE(PENTIUM4,    pentium4_device,    "pentium4",    "Intel Pentium 4")
+*/
 
-
-i386_device::i386_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : i386_device(mconfig, I386, tag, owner, clock, 32, 32, 32)
-{
-}
-
-
-i386_device::i386_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_data_width, int program_addr_width, int io_data_width)
-       : cpu_device(mconfig, type, tag, owner, clock)
-       , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
-       , m_program_config("program", ENDIANNESS_LITTLE, program_data_width, program_addr_width, 0, 32, 12)
-       , m_io_config("io", ENDIANNESS_LITTLE, io_data_width, 16, 0)
-       , m_smiact(*this)
-       , m_ferr_handler(*this)
+i386_device::i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : DEVICE(parent_vm, parent_emu)
 {
        // 32 unified
-       set_vtlb_dynamic_entries(32);
-}
-
-i386sx_device::i386sx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : i386_device(mconfig, I386SX, tag, owner, clock, 16, 24, 16)
-{
+       d_vtlb = new device_vtlb_interface(parent_vm, parent_emu, this, AS_PROGRAM);
+       m_smiact = this;
+       m_ferr_handler = this;
+       m_smiact_enabled = false;
+
+       initialize_output_signals(&outputs_reset);
+       d_debugger = NULL;
+       d_dma = NULL;
+       d_mem = NULL;
+       d_io = NULL;
+       d_bios = NULL;
+       d_pic = NULL;
+       d_program_stored = NULL;
+       d_io_stored = NULL;
+       
+       d_vtlb->set_vtlb_dynamic_entries(32);
+       d_vtlb->set_vtlb_page_shift(12);
+       d_vtlb->set_vtlb_addr_width(32);
+
+       m_ferr_err_value = 0;
+       data_width = 32;
+       set_device_name(_T("i386 DX CPU"));
+
+       
 }
 
-i486_device::i486_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : i486_device(mconfig, I486, tag, owner, clock)
+i386_device::~i386_device()
 {
+       if(d_vtlb != NULL) delete d_vtlb;
 }
 
-i486_device::i486_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
-       : i386_device(mconfig, type, tag, owner, clock, 32, 32, 32)
+i386sx_device::i386sx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : i386_device(parent_vm, parent_emu)
 {
+       data_width = 16;
+       set_device_name(_T("i386 SX CPU"));
 }
 
-i486dx4_device::i486dx4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : i486_device(mconfig, I486DX4, tag, owner, clock)
+i486_device::i486_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : i386_device(parent_vm, parent_emu)
 {
+       set_device_name(_T("Intel i486"));
 }
 
-pentium_device::pentium_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_device(mconfig, PENTIUM, tag, owner, clock)
+i486dx4_device::i486dx4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : i486_device(parent_vm, parent_emu)
 {
+       set_device_name(_T("Intel i486 DX4"));
 }
 
-pentium_device::pentium_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
-       : i386_device(mconfig, type, tag, owner, clock, 32, 32, 32)
+pentium_device::pentium_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : i386_device(parent_vm, parent_emu)
 {
        // 64 dtlb small, 8 dtlb large, 32 itlb
-       set_vtlb_dynamic_entries(96);
+       d_vtlb->set_vtlb_dynamic_entries(96);
+       set_device_name(_T("Intel Pentium(i586)"));
 }
 
-mediagx_device::mediagx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : i386_device(mconfig, MEDIAGX, tag, owner, clock, 32, 32, 32)
+mediagx_device::mediagx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : i386_device(parent_vm, parent_emu)
 {
+       set_device_name(_T("Cyrix MediaGX"));
 }
 
-pentium_pro_device::pentium_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_pro_device(mconfig, PENTIUM_PRO, tag, owner, clock)
-{
-}
 
-pentium_pro_device::pentium_pro_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_device(mconfig, type, tag, owner, clock)
+pentium_pro_device::pentium_pro_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_device(parent_vm, parent_emu)
 {
+       set_device_name(_T("Intel Pentium Pro(i686)"));
 }
 
-pentium_mmx_device::pentium_mmx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_device(mconfig, PENTIUM_MMX, tag, owner, clock)
+pentium_mmx_device::pentium_mmx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_device(parent_vm, parent_emu)
 {
        // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
-       set_vtlb_dynamic_entries(96);
+       d_vtlb->set_vtlb_dynamic_entries(96);
+       set_device_name(_T("Intel Pentium MMX"));
 }
 
-pentium2_device::pentium2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_pro_device(mconfig, PENTIUM2, tag, owner, clock)
+pentium2_device::pentium2_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_pro_device(parent_vm, parent_emu)
 {
        // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
-       set_vtlb_dynamic_entries(96);
+       d_vtlb->set_vtlb_dynamic_entries(96);
+       set_device_name(_T("Intel Pentium2"));
 }
 
-pentium3_device::pentium3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_pro_device(mconfig, PENTIUM3, tag, owner, clock)
+pentium3_device::pentium3_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_pro_device(parent_vm, parent_emu)
 {
        // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
-       set_vtlb_dynamic_entries(96);
+       d_vtlb->set_vtlb_dynamic_entries(96);
+       set_device_name(_T("Intel Pentium3"));
 }
 
-athlonxp_device::athlonxp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_device(mconfig, ATHLONXP, tag, owner, clock)
+// ToDo: AthlonXP
+#if 0
+athlonxp_device::athlonxp_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_device(parent_vm, parent_emu)
 {
        // TODO: put correct value
-       set_vtlb_dynamic_entries(256);
+       d_vtlb->set_vtlb_dynamic_entries(256);
+       set_device_name(_T("AMD AthlonXP"));
 }
+#endif
 
-pentium4_device::pentium4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-       : pentium_device(mconfig, PENTIUM4, tag, owner, clock)
+pentium4_device::pentium4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
+       : pentium_device(parent_vm, parent_emu)
 {
        // 128 dtlb, 64 itlb
-       set_vtlb_dynamic_entries(196);
+       d_vtlb->set_vtlb_dynamic_entries(196);
+       set_device_name(_T("Intel Pentium4"));
 }
 
 device_memory_interface::space_config_vector i386_device::memory_space_config() const
@@ -280,7 +300,7 @@ bool i386_device::translate_address(int pl, int type, uint32_t *address, uint32_
        if (!(m_cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
                return true;
 
-       const vtlb_entry *table = vtlb_table();
+       const vtlb_entry *table = d_vtlb->vtlb_table();
        uint32_t index = *address >> 12;
        vtlb_entry entry = table[index];
        if (type == TRANSLATE_FETCH)
@@ -300,7 +320,7 @@ bool i386_device::translate_address(int pl, int type, uint32_t *address, uint32_
                                *error |= 1;
                        return false;
                }
-               vtlb_dynload(index, *address, entry);
+               d_vtlb->vtlb_dynload(index, *address, entry);
                return true;
        }
        if (!(entry & (1 << type)))
@@ -949,7 +969,10 @@ void i386_device::i386_trap(int irq, int irq_gate, int trap_level)
                if(trap_level >= 3)
                {
                        logerror("IRQ: Triple fault. CPU reset.\n");
-                       pulse_input_line(INPUT_LINE_RESET, attotime::zero);
+                       //pulse_input_line(INPUT_LINE_RESET, attotime::zero);
+                       m_shutdown = true;
+                       write_signals(&outputs_reset, 0xffffffff);
+                       reset();
                        return;
                }
 
@@ -1274,11 +1297,51 @@ void i386_device::i386_trap(int irq, int irq_gate, int trap_level)
                        m_IF = 0;
                m_TF = 0;
                m_NT = 0;
+               m_eflags = get_flags();
+#if 0
+               if((irq >= 0x10) && (irq_gate == 1) && (m_ext == 0)) {
+                       // Try to call pseudo bios
+                       i386_load_segment_descriptor(CS);
+                       uint32_t tmp_pc = i386_translate(CS, m_eip, -1, 1 );
+                       int stat = 0;
+                       bios_trap_x86(tmp_pc, stat);
+                       if(stat != 0) { // HIT
+                               try     {
+                                       // this is ugly but the alternative is worse
+                                       if(/*type != 0x0e && type != 0x0f*/ (type & 0x08) == 0)  // if not 386 interrupt or trap gate
+                                       {
+                                               m_eip = POP16();
+                                               m_sreg[CS].selector = POP16();
+                                               UINT32 __flags = POP16();
+                                               m_eflags = (get_flags() & 0xffff0000) | (__flags & 0x0000ffff);
+                                               set_flags(m_eflags);
+                                       }
+                                       else
+                                       {
+                                               m_eip = POP32();
+                                               UINT32 sel;
+                                               sel = POP32();
+                                               m_sreg[CS].selector = sel; // ToDo: POP32SEG()
+                                               UINT32 __flags = POP32();
+                                               m_eflags = (get_flags() & 0xff000000) | (__flags & 0x00ffffff);
+                                               set_flags(m_eflags);
+                                       }
+                               }
+                               catch(UINT64 e)
+                               {
+                                       REG32(ESP) = tempSP;
+                                       //logerror("THROWN EXCEPTION %08X at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", e, irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
+                                       throw e;
+                               }
+                               return;
+                       }
+                       CHANGE_PC(m_eip);
+                       return;
+               }
+#endif
        }
-
        i386_load_segment_descriptor(CS);
        CHANGE_PC(m_eip);
-
 }
 
 void i386_device::i386_trap_with_error(int irq, int irq_gate, int trap_level, uint32_t error)
@@ -1516,7 +1579,7 @@ void i386_device::i386_task_switch(uint16_t selector, uint8_t nested)
        }
        m_cr[3] = READ32(tss+0x1c);  // CR3 (PDBR)
        if(oldcr3 != m_cr[3])
-               vtlb_flush_dynamic();
+               d_vtlb->vtlb_flush_dynamic();
 
        /* Set the busy bit in the new task's descriptor */
        if(selector & 0x0004)
@@ -1548,10 +1611,101 @@ void i386_device::i386_check_irq_line()
        if ( (m_irq_state) && m_IF )
        {
                m_cycles -= 2;
-               i386_trap(standard_irq_callback(0), 1, 0);
+               int irqnum = d_pic->get_intr_ack();
+               try {
+                       i386_trap(irqnum, 1, 0);
+               } catch(uint64_t e) {
+                       //logdebug("EXCEPTION %08X VIA INTERRUPT/TRAP HANDLING IRQ=%02Xh(%d) ADDR=%08X\n", e, irqnum, irqnum, m_pc);
+               }
+               m_irq_state = 0;
        }
 }
 
+bool i386_device::bios_int_x86(int num)
+{
+       if(d_bios == NULL) return false;
+       uint16_t regs[10], sregs[4]; // ToDo: Full calling
+       regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); 
+       regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI);
+       regs[8] = 0x0000; regs[9] = 0x0000;                                                     
+       sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector;
+       sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector;
+       int32_t ZeroFlag = m_ZF, CarryFlag = m_CF;
+       if(d_bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { 
+               REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; 
+               REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; 
+               m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; 
+               CYCLES(CYCLES_IRET);                                                    
+               if((regs[8] != 0x0000) || (regs[9] != 0x0000)) {                
+                       uint32_t hi = regs[9];                                                          
+                       uint32_t lo = regs[8];                                                          
+                       uint32_t addr = (hi << 16) | lo;                                        
+                       m_eip = addr;                                                           
+               }                                                                                                               
+               return true;                                                                                                    
+       }
+       return false;
+}              
+
+
+bool i386_device::bios_call_far_x86(uint32_t address)
+{
+       if(d_bios == NULL) return false;
+       if(((m_cr[0] & 0x0001) != 0) && (m_VM == 0)) return false; // Return if (!(VM8086) && (Protected))
+       
+       uint16_t regs[10], sregs[4]; // ToDo: Full calling
+       regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); 
+       regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI);
+       regs[8] = 0x0000; regs[9] = 0x0000;                                                     
+       sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector;
+       sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector;
+       int32_t ZeroFlag = m_ZF, CarryFlag = m_CF;
+       if(d_bios->bios_call_far_i86(address, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { 
+               REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; 
+               REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; 
+               m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; 
+               CYCLES(CYCLES_RET_INTERSEG);                                                    
+               if((regs[8] != 0x0000) || (regs[9] != 0x0000)) {                
+                       uint32_t hi = regs[9];                                                          
+                       uint32_t lo = regs[8];                                                          
+                       uint32_t addr = (hi << 16) | lo;                                        
+                       m_eip = addr;                                                           
+               }                                                                                                               
+               return true;                                                                                                    
+       }
+       return false;
+}              
+
+bool i386_device::bios_trap_x86(uint32_t address, int &stat)
+{
+       if(d_bios == NULL) return false;
+       if(((m_cr[0] & 0x0001) != 0) && (m_VM == 0)) return false; // Return if (!(VM8086) && (Protected))
+       
+       uint16_t regs[10], sregs[4]; // ToDo: Full calling
+       regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); 
+       regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI);
+       regs[8] = 0x0000; regs[9] = 0x0000;                                                     
+       sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector;
+       sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector;
+       int32_t ZeroFlag = m_ZF, CarryFlag = m_CF;
+       stat = 0;
+       if(d_bios->bios_call_far_i86(address, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { 
+               REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; 
+               REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; 
+               m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; 
+               CYCLES(CYCLES_RET_INTERSEG);                                                    
+               if((regs[8] != 0x0000) || (regs[9] != 0x0000)) {                
+                       uint32_t hi = regs[9];                                                          
+                       uint32_t lo = regs[8];                                                          
+                       uint32_t addr = (hi << 16) | lo;                                        
+                       m_eip = addr;                                                           
+               }
+               stat = 1;
+               return true;                                                                                                    
+       }
+       return false;
+}              
+
 void i386_device::i386_protected_mode_jump(uint16_t seg, uint32_t off, int indirect, int operand32)
 {
        I386_SREG desc;
@@ -3337,6 +3491,7 @@ void i386_device::i386_postload()
 
 void i386_device::i386_common_init()
 {
+       DEVICE::initialize();
        int i, j;
        static const int regs8[8] = {AL,CL,DL,BL,AH,CH,DH,BH};
        static const int regs16[8] = {AX,CX,DX,BX,SP,BP,SI,DI};
@@ -3366,7 +3521,7 @@ void i386_device::i386_common_init()
        }
 
        m_program = &space(AS_PROGRAM);
-       if(m_program->data_width() == 16) {
+       if(data_width == 16) {
                // for the 386sx
                macache16 = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
        } else {
@@ -3380,104 +3535,21 @@ void i386_device::i386_common_init()
 
        zero_state();
 
-       save_item(NAME(m_reg.d));
-       save_item(NAME(m_sreg[ES].selector));
-       save_item(NAME(m_sreg[ES].base));
-       save_item(NAME(m_sreg[ES].limit));
-       save_item(NAME(m_sreg[ES].flags));
-       save_item(NAME(m_sreg[ES].d));
-       save_item(NAME(m_sreg[CS].selector));
-       save_item(NAME(m_sreg[CS].base));
-       save_item(NAME(m_sreg[CS].limit));
-       save_item(NAME(m_sreg[CS].flags));
-       save_item(NAME(m_sreg[CS].d));
-       save_item(NAME(m_sreg[SS].selector));
-       save_item(NAME(m_sreg[SS].base));
-       save_item(NAME(m_sreg[SS].limit));
-       save_item(NAME(m_sreg[SS].flags));
-       save_item(NAME(m_sreg[SS].d));
-       save_item(NAME(m_sreg[DS].selector));
-       save_item(NAME(m_sreg[DS].base));
-       save_item(NAME(m_sreg[DS].limit));
-       save_item(NAME(m_sreg[DS].flags));
-       save_item(NAME(m_sreg[DS].d));
-       save_item(NAME(m_sreg[FS].selector));
-       save_item(NAME(m_sreg[FS].base));
-       save_item(NAME(m_sreg[FS].limit));
-       save_item(NAME(m_sreg[FS].flags));
-       save_item(NAME(m_sreg[FS].d));
-       save_item(NAME(m_sreg[GS].selector));
-       save_item(NAME(m_sreg[GS].base));
-       save_item(NAME(m_sreg[GS].limit));
-       save_item(NAME(m_sreg[GS].flags));
-       save_item(NAME(m_sreg[GS].d));
-       save_item(NAME(m_eip));
-       save_item(NAME(m_prev_eip));
-
-       save_item(NAME(m_CF));
-       save_item(NAME(m_DF));
-       save_item(NAME(m_SF));
-       save_item(NAME(m_OF));
-       save_item(NAME(m_ZF));
-       save_item(NAME(m_PF));
-       save_item(NAME(m_AF));
-       save_item(NAME(m_IF));
-       save_item(NAME(m_TF));
-       save_item(NAME(m_IOP1));
-       save_item(NAME(m_IOP2));
-       save_item(NAME(m_NT));
-       save_item(NAME(m_RF));
-       save_item(NAME(m_VM));
-       save_item(NAME(m_AC));
-       save_item(NAME(m_VIF));
-       save_item(NAME(m_VIP));
-       save_item(NAME(m_ID));
-
-       save_item(NAME(m_CPL));
-
-       save_item(NAME(m_performed_intersegment_jump));
-
-       save_item(NAME(m_cr));
-       save_item(NAME(m_dr));
-       save_item(NAME(m_tr));
-
-       save_item(NAME(m_idtr.base));
-       save_item(NAME(m_idtr.limit));
-       save_item(NAME(m_gdtr.base));
-       save_item(NAME(m_gdtr.limit));
-       save_item(NAME(m_task.base));
-       save_item(NAME(m_task.segment));
-       save_item(NAME(m_task.limit));
-       save_item(NAME(m_task.flags));
-       save_item(NAME(m_ldtr.base));
-       save_item(NAME(m_ldtr.segment));
-       save_item(NAME(m_ldtr.limit));
-       save_item(NAME(m_ldtr.flags));
-
-       save_item(NAME(m_segment_override));
-
-       save_item(NAME(m_irq_state));
-       save_item(NAME(m_a20_mask));
-
-       save_item(NAME(m_mxcsr));
-
-       save_item(NAME(m_smm));
-       save_item(NAME(m_smi));
-       save_item(NAME(m_smi_latched));
-       save_item(NAME(m_nmi_masked));
-       save_item(NAME(m_nmi_latched));
-       save_item(NAME(m_smbase));
-       save_item(NAME(m_lock));
-       machine().save().register_postload(save_prepost_delegate(FUNC(i386_device::i386_postload), this));
-
-       m_smiact.resolve_safe();
-       m_ferr_handler.resolve_safe();
-       m_ferr_handler(0);
 
+       //m_smiact.resolve_safe();
+       //m_ferr_handler.resolve_safe();
+       m_ferr_err_value =0;
+
+       if((d_debugger != NULL) && (osd->check_feature(USE_DEBUGGER))) {
+               d_program_stored = d_mem;
+               d_io_stored = d_io;
+       } else {
+               d_debugger = NULL;
+       }
        set_icountptr(m_cycles);
 }
 
-void i386_device::device_start()
+void i386_device::initialize()
 {
        i386_common_init();
 
@@ -3485,133 +3557,275 @@ void i386_device::device_start()
        m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_I386].get();
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_I386].get();
 
-       register_state_i386();
-}
-
-void i386_device::register_state_i386()
-{
-       state_add( I386_PC,         "PC", m_pc).formatstr("%08X");
-       state_add( I386_EIP,        "EIP", m_eip).callimport().formatstr("%08X");
-       state_add( I386_AL,         "~AL", REG8(AL)).formatstr("%02X");
-       state_add( I386_AH,         "~AH", REG8(AH)).formatstr("%02X");
-       state_add( I386_BL,         "~BL", REG8(BL)).formatstr("%02X");
-       state_add( I386_BH,         "~BH", REG8(BH)).formatstr("%02X");
-       state_add( I386_CL,         "~CL", REG8(CL)).formatstr("%02X");
-       state_add( I386_CH,         "~CH", REG8(CH)).formatstr("%02X");
-       state_add( I386_DL,         "~DL", REG8(DL)).formatstr("%02X");
-       state_add( I386_DH,         "~DH", REG8(DH)).formatstr("%02X");
-       state_add( I386_AX,         "~AX", REG16(AX)).formatstr("%04X");
-       state_add( I386_BX,         "~BX", REG16(BX)).formatstr("%04X");
-       state_add( I386_CX,         "~CX", REG16(CX)).formatstr("%04X");
-       state_add( I386_DX,         "~DX", REG16(DX)).formatstr("%04X");
-       state_add( I386_SI,         "~SI", REG16(SI)).formatstr("%04X");
-       state_add( I386_DI,         "~DI", REG16(DI)).formatstr("%04X");
-       state_add( I386_BP,         "~BP", REG16(BP)).formatstr("%04X");
-       state_add( I386_SP,         "~SP", REG16(SP)).formatstr("%04X");
-       state_add( I386_IP,         "~IP", m_debugger_temp).mask(0xffff).callimport().callexport().formatstr("%04X");
-       state_add( I386_EAX,        "EAX", m_reg.d[EAX]).formatstr("%08X");
-       state_add( I386_EBX,        "EBX", m_reg.d[EBX]).formatstr("%08X");
-       state_add( I386_ECX,        "ECX", m_reg.d[ECX]).formatstr("%08X");
-       state_add( I386_EDX,        "EDX", m_reg.d[EDX]).formatstr("%08X");
-       state_add( I386_EBP,        "EBP", m_reg.d[EBP]).formatstr("%08X");
-       state_add( I386_ESP,        "ESP", m_reg.d[ESP]).formatstr("%08X");
-       state_add( I386_ESI,        "ESI", m_reg.d[ESI]).formatstr("%08X");
-       state_add( I386_EDI,        "EDI", m_reg.d[EDI]).formatstr("%08X");
-       state_add( I386_EFLAGS,     "EFLAGS", m_eflags).formatstr("%08X");
-       state_add( I386_CS,         "CS", m_sreg[CS].selector).callimport().formatstr("%04X");
-       state_add( I386_CS_BASE,    "CSBASE", m_sreg[CS].base).formatstr("%08X");
-       state_add( I386_CS_LIMIT,   "CSLIMIT", m_sreg[CS].limit).formatstr("%08X");
-       state_add( I386_CS_FLAGS,   "CSFLAGS", m_sreg[CS].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_SS,         "SS", m_sreg[SS].selector).callimport().formatstr("%04X");
-       state_add( I386_SS_BASE,    "SSBASE", m_sreg[SS].base).formatstr("%08X");
-       state_add( I386_SS_LIMIT,   "SSLIMIT", m_sreg[SS].limit).formatstr("%08X");
-       state_add( I386_SS_FLAGS,   "SSFLAGS", m_sreg[SS].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_DS,         "DS", m_sreg[DS].selector).callimport().formatstr("%04X");
-       state_add( I386_DS_BASE,    "DSBASE", m_sreg[DS].base).formatstr("%08X");
-       state_add( I386_DS_LIMIT,   "DSLIMIT", m_sreg[DS].limit).formatstr("%08X");
-       state_add( I386_DS_FLAGS,   "DSFLAGS", m_sreg[DS].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_ES,         "ES", m_sreg[ES].selector).callimport().formatstr("%04X");
-       state_add( I386_ES_BASE,    "ESBASE", m_sreg[ES].base).formatstr("%08X");
-       state_add( I386_ES_LIMIT,   "ESLIMIT", m_sreg[ES].limit).formatstr("%08X");
-       state_add( I386_ES_FLAGS,   "ESFLAGS", m_sreg[ES].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_FS,         "FS", m_sreg[FS].selector).callimport().formatstr("%04X");
-       state_add( I386_FS_BASE,    "FSBASE", m_sreg[FS].base).formatstr("%08X");
-       state_add( I386_FS_LIMIT,   "FSLIMIT", m_sreg[FS].limit).formatstr("%08X");
-       state_add( I386_FS_FLAGS,   "FSFLAGS", m_sreg[FS].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_GS,         "GS", m_sreg[GS].selector).callimport().formatstr("%04X");
-       state_add( I386_GS_BASE,    "GSBASE", m_sreg[GS].base).formatstr("%08X");
-       state_add( I386_GS_LIMIT,   "GSLIMIT", m_sreg[GS].limit).formatstr("%08X");
-       state_add( I386_GS_FLAGS,   "GSFLAGS", m_sreg[GS].flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_CR0,        "CR0", m_cr[0]).formatstr("%08X");
-       state_add( I386_CR1,        "CR1", m_cr[1]).formatstr("%08X");
-       state_add( I386_CR2,        "CR2", m_cr[2]).formatstr("%08X");
-       state_add( I386_CR3,        "CR3", m_cr[3]).formatstr("%08X");
-       state_add( I386_CR4,        "CR4", m_cr[4]).formatstr("%08X");
-       state_add( I386_DR0,        "DR0", m_dr[0]).formatstr("%08X");
-       state_add( I386_DR1,        "DR1", m_dr[1]).formatstr("%08X");
-       state_add( I386_DR2,        "DR2", m_dr[2]).formatstr("%08X");
-       state_add( I386_DR3,        "DR3", m_dr[3]).formatstr("%08X");
-       state_add( I386_DR4,        "DR4", m_dr[4]).formatstr("%08X");
-       state_add( I386_DR5,        "DR5", m_dr[5]).formatstr("%08X");
-       state_add( I386_DR6,        "DR6", m_dr[6]).formatstr("%08X");
-       state_add( I386_DR7,        "DR7", m_dr[7]).formatstr("%08X");
-       state_add( I386_TR6,        "TR6", m_tr[6]).formatstr("%08X");
-       state_add( I386_TR7,        "TR7", m_tr[7]).formatstr("%08X");
-       state_add( I386_GDTR_BASE,  "GDTRBASE", m_gdtr.base).formatstr("%08X");
-       state_add( I386_GDTR_LIMIT, "GDTRLIMIT", m_gdtr.limit).formatstr("%04X");
-       state_add( I386_IDTR_BASE,  "IDTRBASE", m_idtr.base).formatstr("%08X");
-       state_add( I386_IDTR_LIMIT, "IDTRLIMIT", m_idtr.limit).formatstr("%04X");
-       state_add( I386_LDTR,       "LDTR", m_ldtr.segment).formatstr("%04X");
-       state_add( I386_LDTR_BASE,  "LDTRBASE", m_ldtr.base).formatstr("%08X");
-       state_add( I386_LDTR_LIMIT, "LDTRLIMIT", m_ldtr.limit).formatstr("%08X");
-       state_add( I386_LDTR_FLAGS, "LDTRFLAGS", m_ldtr.flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_TR,         "TR", m_task.segment).formatstr("%04X");
-       state_add( I386_TR_BASE,    "TRBASE", m_task.base).formatstr("%08X");
-       state_add( I386_TR_LIMIT,   "TRLIMIT", m_task.limit).formatstr("%08X");
-       state_add( I386_TR_FLAGS,   "TRFLAGS", m_task.flags).mask(0xf0ff).formatstr("%04X");
-       state_add( I386_CPL,        "CPL", m_CPL).formatstr("%01X");
-
-       state_add( STATE_GENPC, "GENPC", m_pc).noshow();
-       state_add( STATE_GENPCBASE, "CURPC", m_pc).noshow();
-       state_add( STATE_GENFLAGS, "GENFLAGS", m_debugger_temp).formatstr("%8s").noshow();
-       state_add( STATE_GENSP, "GENSP", REG32(ESP)).noshow();
-}
-
-void i386_device::register_state_i386_x87()
-{
-       register_state_i386();
-
-       state_add( X87_CTRL,   "x87_CW", m_x87_cw).formatstr("%04X");
-       state_add( X87_STATUS, "x87_SW", m_x87_sw).formatstr("%04X");
-       state_add( X87_TAG,    "x87_TAG", m_x87_tw).formatstr("%04X");
-       state_add( X87_ST0,    "ST0", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST1,    "ST1", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST2,    "ST2", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST3,    "ST3", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST4,    "ST4", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST5,    "ST5", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST6,    "ST6", m_debugger_temp ).formatstr("%15s");
-       state_add( X87_ST7,    "ST7", m_debugger_temp ).formatstr("%15s");
-}
-
-void i386_device::register_state_i386_x87_xmm()
-{
-       register_state_i386_x87();
-
-       state_add( SSE_XMM0, "XMM0", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM1, "XMM1", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM2, "XMM2", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM3, "XMM3", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM4, "XMM4", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM5, "XMM5", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM6, "XMM6", m_debugger_temp ).formatstr("%32s");
-       state_add( SSE_XMM7, "XMM7", m_debugger_temp ).formatstr("%32s");
-
-}
-
-void i386_device::state_import(const device_state_entry &entry)
-{
-       switch (entry.index())
+//     register_state_i386();
+}
+
+#define STATE_VERSION 6
+
+bool i386_device::process_state_segment(int num, FILEIO* state_fio, bool loading)
+{
+       state_fio->StateValue(m_sreg[num].selector);
+       state_fio->StateValue(m_sreg[num].base);
+       state_fio->StateValue(m_sreg[num].limit);
+       state_fio->StateValue(m_sreg[num].flags);
+
+       return true;
+}
+
+bool i386_device::process_state_i386(FILEIO* state_fio, bool loading)
+{
+       state_fio->StateValue(m_pc);
+       state_fio->StateValue(m_eip);
+       state_fio->StateValue(m_prev_eip);
+       state_fio->StateValue(m_reg.d[EAX]); 
+       state_fio->StateValue(m_reg.d[EBX]); 
+       state_fio->StateValue(m_reg.d[ECX]); 
+       state_fio->StateValue(m_reg.d[EDX]); 
+       state_fio->StateValue(m_reg.d[EBP]); 
+       state_fio->StateValue(m_reg.d[ESP]); 
+       state_fio->StateValue(m_reg.d[ESI]); 
+       state_fio->StateValue(m_reg.d[EDI]);
+       
+       state_fio->StateValue(m_eflags);
+       state_fio->StateValue(m_eflags_mask);
+       
+       process_state_segment(CS, state_fio, loading); 
+       process_state_segment(SS, state_fio, loading); 
+       process_state_segment(DS, state_fio, loading); 
+       process_state_segment(ES, state_fio, loading); 
+       process_state_segment(FS, state_fio, loading); 
+       process_state_segment(GS, state_fio, loading);
+       state_fio->StateArray(m_cr, sizeof(m_cr), 1);
+       state_fio->StateArray(m_dr, sizeof(m_dr), 1);
+       state_fio->StateArray(m_tr, sizeof(m_tr), 1);
+
+       state_fio->StateValue(m_gdtr.base);
+       state_fio->StateValue(m_gdtr.limit);
+       
+       state_fio->StateValue(m_idtr.base);
+       state_fio->StateValue(m_idtr.limit);
+       
+       state_fio->StateValue(m_ldtr.segment);
+       state_fio->StateValue(m_ldtr.base);
+       state_fio->StateValue(m_ldtr.limit);
+       state_fio->StateValue(m_ldtr.flags);
+       
+       state_fio->StateValue(m_task.segment);
+       state_fio->StateValue(m_task.base);
+       state_fio->StateValue(m_task.limit);
+       state_fio->StateValue(m_task.flags);
+
+       state_fio->StateValue(m_CF);
+       state_fio->StateValue(m_DF);
+       state_fio->StateValue(m_SF);
+       state_fio->StateValue(m_OF);
+       state_fio->StateValue(m_ZF);
+       state_fio->StateValue(m_PF);
+       state_fio->StateValue(m_AF);
+       state_fio->StateValue(m_IF);
+       state_fio->StateValue(m_TF);
+       state_fio->StateValue(m_IOP1);
+       state_fio->StateValue(m_IOP2);
+       state_fio->StateValue(m_NT);
+       state_fio->StateValue(m_RF);
+       state_fio->StateValue(m_VM);
+       state_fio->StateValue(m_AC);
+       state_fio->StateValue(m_VIF);
+       state_fio->StateValue(m_VIP);
+       state_fio->StateValue(m_ID);
+       
+       state_fio->StateValue(m_CPL);
+       
+       state_fio->StateValue(m_performed_intersegment_jump);
+       
+       state_fio->StateValue(m_segment_override);
+       state_fio->StateValue(m_irq_state);
+       state_fio->StateValue(m_a20_mask);
+       state_fio->StateValue(m_shutdown);
+       state_fio->StateValue(m_halted);
+       state_fio->StateValue(m_busreq);
+       
+       state_fio->StateValue(m_cycles);
+       state_fio->StateValue(extra_cycles);
+       state_fio->StateValue(total_cycles);
+       state_fio->StateValue(m_tsc);
+                                                 
+       state_fio->StateValue(m_mxcsr);
+       state_fio->StateValue(m_smm);
+       state_fio->StateValue(m_smi);
+       state_fio->StateValue(m_smi_latched);
+       state_fio->StateValue(m_nmi_masked);
+       state_fio->StateValue(m_nmi_latched);
+       state_fio->StateValue(m_smbase);
+       state_fio->StateValue(m_lock);
+       state_fio->StateValue(m_ferr_err_value);
+       state_fio->StateValue(m_smiact_enabled);
+       
+       state_fio->StateValue(m_operand_size);
+
+       state_fio->StateValue(icount);
+       if(loading) {
+               i386_postload();
+               prev_total_cycles = total_cycles;
+       }
+
+       //m_smiact.resolve_safe();
+       //m_ferr_handler.resolve_safe();
+
+//     state_add( STATE_GENPC, "GENPC", m_pc).noshow();
+//     state_add( STATE_GENPCBASE, "CURPC", m_pc).noshow();
+//     state_add( STATE_GENFLAGS, "GENFLAGS", m_debugger_temp).formatstr("%8s").noshow();
+//     state_add( STATE_GENSP, "GENSP", REG32(ESP)).noshow();
+       return true;
+}
+
+bool i386_device::process_state_i386_x87(FILEIO* state_fio, bool loading)
+{
+       if(!process_state_i386(state_fio, loading)) {
+               return false;
+       }
+       state_fio->StateValue(m_x87_cw);
+       state_fio->StateValue(m_x87_sw);
+       state_fio->StateValue(m_x87_tw);
+       state_fio->StateValue(m_x87_data_ptr);
+       state_fio->StateValue(m_x87_inst_ptr);
+       state_fio->StateValue(m_x87_opcode);
+       state_fio->StateValue(m_x87_operand_size);
+       for(int i = 0; i < 8; i++) {
+               state_fio->StateValue(m_x87_reg[i].high);
+               state_fio->StateValue(m_x87_reg[i].low);
+       }
+       return true;
+}
+
+bool i386_device::process_state_i386_x87_xmm(FILEIO* state_fio, bool loading)
+{
+       if(!process_state_i386_x87(state_fio, loading)) {
+               return false;
+       }
+       for(int i = 0; i < 8; i++) {
+               for(int j = 0; j < 4; j++) {
+                       state_fio->StateValue(m_sse_reg[i].d[j]);
+               }
+       }
+       state_fio->StateValue(m_xmm_operand_size);
+       return true;
+}
+
+bool i386_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386(state_fio, loading);
+}
+
+bool i486_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool pentium_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool mediagx_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool pentium_pro_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool pentium_mmx_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool pentium2_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87(state_fio, loading);
+}
+
+bool pentium3_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87_xmm(state_fio, loading);
+}
+
+bool pentium4_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87_xmm(state_fio, loading);
+}
+
+#if 0
+bool athlonxp_device::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       return process_state_i386_x87_xmm(state_fio, loading);
+}
+#endif
+void i386_device::state_import(int index)
+{
+       switch (index)
        {
                case I386_EIP:
                        CHANGE_PC(m_eip);
@@ -3641,9 +3855,9 @@ void i386_device::state_import(const device_state_entry &entry)
        }
 }
 
-void i386_device::state_export(const device_state_entry &entry)
+void i386_device::state_export(int index)
 {
-       switch (entry.index())
+       switch (index())
        {
                case I386_IP:
                        m_debugger_temp = m_eip & 0xffff;
@@ -3651,65 +3865,6 @@ void i386_device::state_export(const device_state_entry &entry)
        }
 }
 
-void i386_device::state_string_export(const device_state_entry &entry, std::string &str) const
-{
-       switch (entry.index())
-       {
-               case STATE_GENFLAGS:
-                       str = string_format("%08X", get_flags());
-                       break;
-               case X87_ST0:
-                       str = string_format("%f", fx80_to_double(ST(0)));
-                       break;
-               case X87_ST1:
-                       str = string_format("%f", fx80_to_double(ST(1)));
-                       break;
-               case X87_ST2:
-                       str = string_format("%f", fx80_to_double(ST(2)));
-                       break;
-               case X87_ST3:
-                       str = string_format("%f", fx80_to_double(ST(3)));
-                       break;
-               case X87_ST4:
-                       str = string_format("%f", fx80_to_double(ST(4)));
-                       break;
-               case X87_ST5:
-                       str = string_format("%f", fx80_to_double(ST(5)));
-                       break;
-               case X87_ST6:
-                       str = string_format("%f", fx80_to_double(ST(6)));
-                       break;
-               case X87_ST7:
-                       str = string_format("%f", fx80_to_double(ST(7)));
-                       break;
-               case SSE_XMM0:
-                       str = string_format("%08x%08x%08x%08x", XMM(0).d[3], XMM(0).d[2], XMM(0).d[1], XMM(0).d[0]);
-                       break;
-               case SSE_XMM1:
-                       str = string_format("%08x%08x%08x%08x", XMM(1).d[3], XMM(1).d[2], XMM(1).d[1], XMM(1).d[0]);
-                       break;
-               case SSE_XMM2:
-                       str = string_format("%08x%08x%08x%08x", XMM(2).d[3], XMM(2).d[2], XMM(2).d[1], XMM(2).d[0]);
-                       break;
-               case SSE_XMM3:
-                       str = string_format("%08x%08x%08x%08x", XMM(3).d[3], XMM(3).d[2], XMM(3).d[1], XMM(3).d[0]);
-                       break;
-               case SSE_XMM4:
-                       str = string_format("%08x%08x%08x%08x", XMM(4).d[3], XMM(4).d[2], XMM(4).d[1], XMM(4).d[0]);
-                       break;
-               case SSE_XMM5:
-                       str = string_format("%08x%08x%08x%08x", XMM(5).d[3], XMM(5).d[2], XMM(5).d[1], XMM(5).d[0]);
-                       break;
-               case SSE_XMM6:
-                       str = string_format("%08x%08x%08x%08x", XMM(6).d[3], XMM(6).d[2], XMM(6).d[1], XMM(6).d[0]);
-                       break;
-               case SSE_XMM7:
-                       str = string_format("%08x%08x%08x%08x", XMM(7).d[3], XMM(7).d[2], XMM(7).d[1], XMM(7).d[0]);
-                       break;
-       }
-       float_exception_flags = 0; // kill any float exceptions that occur here
-}
-
 void i386_device::build_opcode_table(uint32_t features)
 {
        int i;
@@ -3842,6 +3997,7 @@ void i386_device::zero_state()
        memset( &m_ldtr, 0, sizeof(m_ldtr) );
        m_ext = 0;
        m_halted = 0;
+       m_busreq = 0;
        m_operand_size = 0;
        m_xmm_operand_size = 0;
        m_address_size = 0;
@@ -3854,6 +4010,7 @@ void i386_device::zero_state()
        m_opcode = 0;
        m_irq_state = 0;
        m_a20_mask = 0;
+       m_shutdown = false;
        m_cpuid_max_input_value_eax = 0;
        m_cpuid_id0 = 0;
        m_cpuid_id1 = 0;
@@ -3861,6 +4018,9 @@ void i386_device::zero_state()
        m_cpu_version = 0;
        m_feature_flags = 0;
        m_tsc = 0;
+       total_cycles = 0;
+       prev_total_cycles = 0;
+       extra_cycles = 0;
        m_perfctr[0] = m_perfctr[1] = 0;
        memset( m_x87_reg, 0, sizeof(m_x87_reg) );
        m_x87_cw = 0;
@@ -3882,7 +4042,7 @@ void i386_device::zero_state()
        m_opcode_bytes_length = 0;
 }
 
-void i386_device::device_reset()
+void i386_device::reset()
 {
        zero_state();
 
@@ -3935,8 +4095,8 @@ void i386_device::pentium_smi()
 
        m_cr[0] &= ~(0x8000000d);
        set_flags(2);
-       if(!m_smiact.isnull())
-               m_smiact(true);
+       if(m_smiact != NULL) 
+               m_smiact_enabled = true;
        m_smm = true;
        m_smi_latched = false;
 
@@ -4078,67 +4238,205 @@ void i386_device::i386_set_a20_line(int state)
                m_a20_mask = ~(1 << 20);
        }
        // TODO: how does A20M and the tlb interact
-       vtlb_flush_dynamic();
+       d_vtlb->vtlb_flush_dynamic();
 }
 
-void i386_device::execute_run()
+void i386_device::write_signal(int id, uint32_t data, uint32_t mask)
+{
+       if(id == SIG_CPU_NMI) {
+               i386_set_irq_line(INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE);
+       } else if(id == SIG_CPU_IRQ) {
+               i386_set_irq_line(INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
+       } else if(id == SIG_CPU_BUSREQ) {
+               m_busreq = (data & mask) ? 1 : 0;
+       } else if(id == SIG_I386_A20) {
+               i386_set_a20_line(data & mask);
+       }
+}
+
+int i386_device::run(int clocks)
 {
        int cycles = m_cycles;
        m_base_cycles = cycles;
        CHANGE_PC(m_eip);
 
-       if (m_halted)
+       if ((m_halted) || (m_busreq))
        {
-               m_tsc += cycles;
-               m_cycles = 0;
-               return;
+               if(d_dma != NULL) {
+                       d_dma->do_dma();
+               }
+               if(clocks < 0) {
+                       int passed_cycles = max(1, extra_cycles);
+                       extra_cycles = 0;
+                       tsc += passed_cycles;
+                       total_cycles += passed_cycles;
+                       return passed_cycles;
+               } else {
+                       m_cycles += clocks;
+                       m_cycles -= extra_cycles;
+                       extra_cycles = 0;
+                       /* if busreq is raised, spin cpu while remained clock */
+                       if(m_cycles > 0) {
+                               m_cycles = 0;
+                       }
+                       int passed_cycles = m_base_cycles - m_cycles;
+                       tsc += passed_cycles;
+//#ifdef USE_DEBUGGER
+                       total_cycles += passed_cycles;
+//#endif
+                       return passed_cycles;
+               }
        }
 
-       while( m_cycles > 0 )
+       if(clocks < 0) {
+               m_cycles = 1;
+       } else {
+               m_cycles += clocks;
+       }
+       m_base_cycles = m_cycles;
+       total_cycles += extra_cycles;
+       m_cycles -= extra_cycles;
+       extra_cycles - 0;
+       
+       while( (m_cycles > 0) && !(m_busreq) )
        {
-               i386_check_irq_line();
-               m_operand_size = m_sreg[CS].d;
-               m_xmm_operand_size = 0;
-               m_address_size = m_sreg[CS].d;
-               m_operand_prefix = 0;
-               m_address_prefix = 0;
+               bool now_debugging = false;
+               if((d_debugger != NULL) && (d_emu != NULL)){
+                       now_debugging = d_debugger->now_debugging;
+               }
+               if(now_debugging) {
+                       d_debugger->check_break_points(m_pc);
+                       if(d_debugger->now_suspended) {
+                               d_debugger->now_waiting = true;
+                               emu->start_waiting_in_debugger();
+                               while(d_debugger->now_debugging && d_debugger->now_suspended) {
+                                       emu->process_waiting_in_debugger();
+                               }
+                               emu->finish_waiting_in_debugger();
+                               d_debugger->now_waiting = false;
+                       }
+                       if(d_debugger->now_debugging) {
+                               d_mem = d_io = d_debugger;
+                       } else {
+                               now_debugging = false;
+                       }
+                       int first_cycles = m_cycles;
+                       i386_check_irq_line();
+                       m_operand_size = m_sreg[CS].d;
+                       m_xmm_operand_size = 0;
+                       m_address_size = m_sreg[CS].d;
+                       m_operand_prefix = 0;
+                       m_address_prefix = 0;
+
+                       m_ext = 1;
+                       int old_tf = m_TF;
 
-               m_ext = 1;
-               int old_tf = m_TF;
+                       d_debugger->add_cpu_trace(m_pc);
+                       m_segment_prefix = 0;
+                       m_prev_eip = m_eip;
+                       m_prev_pc = m_pc;
 
-               m_segment_prefix = 0;
-               m_prev_eip = m_eip;
+                       if(m_delayed_interrupt_enable != 0)
+                       {
+                               m_IF = 1;
+                               m_delayed_interrupt_enable = 0;
+                       }
+#ifdef DEBUG_MISSING_OPCODE
+                       m_opcode_bytes_length = 0;
+                       m_opcode_pc = m_pc;
+#endif
+                       try
+                       {
+                               i386_decode_opcode();
+                               if(m_TF && old_tf)
+                               {
+                                       m_prev_eip = m_eip;
+                                       m_ext = 1;
+                                       i386_trap(1,0,0);
+                               }
+                               if(m_lock && (m_opcode != 0xf0))
+                                       m_lock = false;
+                       }
+                       catch(uint64_t e)
+                       {
+                               m_ext = 1;
+                               //logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, e >> 32); 
+                               i386_trap_with_error(e&0xffffffff,0,0,e>>32, 1);
+                       }
+                       
+//#ifdef SINGLE_MODE_DMA
+                       if(d_dma != NULL) {
+                               d_dma->do_dma();
+                       }
+//#endif
+                       /* adjust for any interrupts that came in */
+                       m_cycles -= extra_cycles;
+                       extra_cycles = 0;
+                       total_cycles += first_cycles - m_cycles;
+                       
+                       if(now_debugging) {
+                               if(!d_debugger->now_going) {
+                                       d_debugger->now_suspended = true;
+                               }
+                               d_mem = d_program_stored;
+                               d_io = d_io_stored;
+                       }
+               } else {
+                       int first_cycles = m_cycles;
 
-               debugger_instruction_hook(m_pc);
+                       i386_check_irq_line();
+                       m_operand_size = m_sreg[CS].d;
+                       m_xmm_operand_size = 0;
+                       m_address_size = m_sreg[CS].d;
+                       m_operand_prefix = 0;
+                       m_address_prefix = 0;
 
-               if(m_delayed_interrupt_enable != 0)
-               {
-                       m_IF = 1;
-                       m_delayed_interrupt_enable = 0;
-               }
+                       m_ext = 1;
+                       int old_tf = m_TF;
+
+                       m_segment_prefix = 0;
+                       m_prev_eip = m_eip;
+
+                       debugger_instruction_hook(m_pc);
+
+                       if(m_delayed_interrupt_enable != 0)
+                       {
+                               m_IF = 1;
+                               m_delayed_interrupt_enable = 0;
+                       }
 #ifdef DEBUG_MISSING_OPCODE
-               m_opcode_bytes_length = 0;
-               m_opcode_pc = m_pc;
+                       m_opcode_bytes_length = 0;
+                       m_opcode_pc = m_pc;
 #endif
-               try
-               {
-                       i386_decode_opcode();
-                       if(m_TF && old_tf)
+                       try
+                       {
+                               i386_decode_opcode();
+                               if(m_TF && old_tf)
+                               {
+                                       m_prev_eip = m_eip;
+                                       m_ext = 1;
+                                       i386_trap(1,0,0);
+                               }
+                               if(m_lock && (m_opcode != 0xf0))
+                                       m_lock = false;
+                       }
+                       catch(uint64_t e)
                        {
-                               m_prev_eip = m_eip;
                                m_ext = 1;
-                               i386_trap(1,0,0);
+                               i386_trap_with_error(e&0xffffffff,0,0,e>>32);
+                       }
+                       if(d_dma != NULL) {
+                               d_dma->do_dma();
                        }
-                       if(m_lock && (m_opcode != 0xf0))
-                               m_lock = false;
                }
-               catch(uint64_t e)
-               {
-                       m_ext = 1;
-                       i386_trap_with_error(e&0xffffffff,0,0,e>>32);
+               if ((m_cycles > 0) && (m_busreq)) {
+                       total_cycles += m_cycles;
+                       m_cycles = 0;
                }
        }
-       m_tsc += (cycles - m_cycles);
+       int passed_cycles = m_base_cycles - m_cycles;
+       m_tsc += passed_cycles;
+       return passed_cycles;
 }
 
 /*************************************************************************/
@@ -4152,6 +4450,100 @@ bool i386_device::memory_translate(int spacenum, int intention, offs_t &address)
        return ret;
 }
 
+void i386_device::set_intr_line(bool line, bool pending, uint32_t bit)
+{
+       i386_set_irq_line(INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE);
+}
+
+void i386_device::set_extra_clock(int cycles)
+{
+       extra_cycles += cycles;
+}
+
+int i386_device::get_extra_clock()
+{
+       return extra_cycles;
+}
+
+uint32_t i386_device::get_pc()
+{
+       return m_prev_pc;
+}
+
+uint32_t i386_device::get_next_pc()
+{
+       return m_pc;
+}
+
+void i386_device::write_debug_data8(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_mem->write_data8w(addr, data, &wait);
+}
+
+void i386_device::write_debug_data16(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_mem->write_data16w(addr, data, &wait);
+}
+
+void i386_device::write_debug_data32(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_mem->write_data32w(addr, data, &wait);
+}
+
+uint32_t i386_device::read_debug_data8(uint32_t addr)
+{
+       int wait;
+       return d_mem->read_data8w(addr, &wait);
+}
+
+uint32_t i386_device::read_debug_data16(uint32_t addr)
+{
+       int wait;
+       return d_mem->read_data16w(addr, &wait);
+}
+
+uint32_t i386_device::read_debug_data32(uint32_t addr)
+{
+       int wait;
+       return d_mem->read_data32w(addr, &wait);
+}
+
+void i386_device::write_debug_io8(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_io->write_io8w(addr, data, &wait);
+}
+
+uint32_t i386_device::read_debug_io8(uint32_t addr) {
+       int wait;
+       return d_io->read_io8w(addr, &wait);
+}
+
+void i386_device::write_debug_io16(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_io->write_io16w(addr, data, &wait);
+}
+
+uint32_t i386_device::read_debug_io16(uint32_t addr) {
+       int wait;
+       return d_io->read_io16w(addr, &wait);
+}
+
+void i386_device::write_debug_io32(uint32_t addr, uint32_t data)
+{
+       int wait;
+       d_io->write_io32w(addr, data, &wait);
+}
+
+uint32_t i386_device::read_debug_io32(uint32_t addr) {
+       int wait;
+       return d_io->read_io32w(addr, &wait);
+}
+
 int i386_device::get_mode() const
 {
        return m_sreg[CS].d ? 32 : 16;
@@ -4184,7 +4576,7 @@ void i386_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
 /* Intel 486 */
 
 
-void i486_device::device_start()
+void i486_device::initialize()
 {
        i386_common_init();
 
@@ -4193,10 +4585,10 @@ void i486_device::device_start()
        m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_I486].get();
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_I486].get();
 
-       register_state_i386_x87();
+//     register_state_i386_x87();
 }
 
-void i486_device::device_reset()
+void i486_device::reset()
 {
        zero_state();
 
@@ -4236,9 +4628,9 @@ void i486_device::device_reset()
        CHANGE_PC(m_eip);
 }
 
-void i486dx4_device::device_reset()
+void i486dx4_device::reset()
 {
-       i486_device::device_reset();
+       i486_device::reset();
        m_cpuid_id0 = 0x756e6547;   // Genu
        m_cpuid_id1 = 0x49656e69;   // ineI
        m_cpuid_id2 = 0x6c65746e;   // ntel
@@ -4251,10 +4643,10 @@ void i486dx4_device::device_reset()
 /* Pentium */
 
 
-void pentium_device::device_start()
+void pentium_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87();
+//     register_state_i386_x87();
 
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM);
        build_x87_opcode_table();
@@ -4262,7 +4654,7 @@ void pentium_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();
 }
 
-void pentium_device::device_reset()
+void pentium_device::reset()
 {
        zero_state();
 
@@ -4323,10 +4715,10 @@ void pentium_device::device_reset()
 /* Cyrix MediaGX */
 
 
-void mediagx_device::device_start()
+void mediagx_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87();
+//     register_state_i386_x87();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_CYRIX);
@@ -4334,7 +4726,7 @@ void mediagx_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_MEDIAGX].get();
 }
 
-void mediagx_device::device_reset()
+void mediagx_device::reset()
 {
        zero_state();
 
@@ -4386,10 +4778,10 @@ void mediagx_device::device_reset()
 /*****************************************************************************/
 /* Intel Pentium Pro */
 
-void pentium_pro_device::device_start()
+void pentium_pro_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87();
+//     register_state_i386_x87();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO);
@@ -4397,7 +4789,7 @@ void pentium_pro_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void pentium_pro_device::device_reset()
+void pentium_pro_device::reset()
 {
        zero_state();
 
@@ -4459,10 +4851,10 @@ void pentium_pro_device::device_reset()
 /*****************************************************************************/
 /* Intel Pentium MMX */
 
-void pentium_mmx_device::device_start()
+void pentium_mmx_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87();
+//     register_state_i386_x87();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_MMX);
@@ -4470,7 +4862,7 @@ void pentium_mmx_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void pentium_mmx_device::device_reset()
+void pentium_mmx_device::reset()
 {
        zero_state();
 
@@ -4530,10 +4922,10 @@ void pentium_mmx_device::device_reset()
 /*****************************************************************************/
 /* Intel Pentium II */
 
-void pentium2_device::device_start()
+void pentium2_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87();
+//     register_state_i386_x87();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX);
@@ -4541,7 +4933,7 @@ void pentium2_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void pentium2_device::device_reset()
+void pentium2_device::reset()
 {
        zero_state();
 
@@ -4595,10 +4987,10 @@ void pentium2_device::device_reset()
 /*****************************************************************************/
 /* Intel Pentium III */
 
-void pentium3_device::device_start()
+void pentium3_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87_xmm();
+//     register_state_i386_x87_xmm();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE);
@@ -4606,7 +4998,7 @@ void pentium3_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void pentium3_device::device_reset()
+void pentium3_device::reset()
 {
        zero_state();
 
@@ -4658,7 +5050,7 @@ void pentium3_device::device_reset()
 
        CHANGE_PC(m_eip);
 }
-
+#if 0
 /*****************************************************************************/
 /* AMD Athlon XP
    Model: Athlon XP 2400+
@@ -4667,10 +5059,10 @@ void pentium3_device::device_reset()
    Date code: 0240MPMW
 */
 
-void athlonxp_device::device_start()
+void athlonxp_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87_xmm();
+//     register_state_i386_x87_xmm();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE);
@@ -4678,7 +5070,7 @@ void athlonxp_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void athlonxp_device::device_reset()
+void athlonxp_device::reset()
 {
        zero_state();
 
@@ -4793,30 +5185,30 @@ dt athlonxp_device::opcode_read_cache(offs_t address)
                                offs_t old_address = cache.old();
 
                                for (int w = 0; w < 64; w += 4)
-                                       macache32->write_dword(old_address + w, *(u32 *)(data + w));
+                                       macache32->write_data32(old_address + w, *(u32 *)(data + w));
                        }
                        for (int r = 0; r < 64; r += 4)
-                               *(u32 *)(data + r) = macache32->read_dword(address + r);
+                               *(u32 *)(data + r) = macache32->read_data32(address + r);
                        return *(dt *)(data + offset);
                }
                else
                {
                        if (sizeof(dt) == 1)
-                               return macache32->read_byte(address);
+                               return macache32->read_data8(address);
                        else if (sizeof(dt) == 2)
-                               return macache32->read_word(address);
+                               return macache32->read_data16(address);
                        else
-                               return macache32->read_dword(address);
+                               return macache32->read_data32(address);
                }
        }
        else
        {
                if (sizeof(dt) == 1)
-                       return macache32->read_byte(address);
+                       return macache32->read_data8(address);
                else if (sizeof(dt) == 2)
-                       return macache32->read_word(address);
+                       return macache32->read_data16(address);
                else
-                       return macache32->read_dword(address);
+                       return macache32->read_data32(address);
        }
 }
 
@@ -4954,15 +5346,15 @@ void athlonxp_device::opcode_wbinvd()
 {
        invalidate_cache(true);
 }
-
+#endif
 
 /*****************************************************************************/
 /* Intel Pentium 4 */
 
-void pentium4_device::device_start()
+void pentium4_device::initialize()
 {
        i386_common_init();
-       register_state_i386_x87_xmm();
+//     register_state_i386_x87_xmm();
 
        build_x87_opcode_table();
        build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE | OP_SSE2);
@@ -4970,7 +5362,7 @@ void pentium4_device::device_start()
        m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();  // TODO: generate own cycle tables
 }
 
-void pentium4_device::device_reset()
+void pentium4_device::reset()
 {
        zero_state();
 
@@ -5023,3 +5415,201 @@ void pentium4_device::device_reset()
 
        CHANGE_PC(m_eip);
 }
+
+bool i386_device::write_debug_reg(const _TCHAR *reg, uint32_t data)
+{
+       if(_tcsicmp(reg, _T("IP")) == 0) {
+               m_eip = data & 0xffff;
+               CHANGE_PC(m_eip);
+       } else if(_tcsicmp(reg, _T("EIP")) == 0) {
+               m_eip = data;
+               CHANGE_PC(m_eip);
+       } else if(_tcsicmp(reg, _T("EAX")) == 0) {
+               REG32(EAX) = data;
+       } else if(_tcsicmp(reg, _T("EBX")) == 0) {
+               REG32(EBX) = data;
+       } else if(_tcsicmp(reg, _T("ECX")) == 0) {
+               REG32(ECX) = data;
+       } else if(_tcsicmp(reg, _T("EDX")) == 0) {
+               REG32(EDX) = data;
+       } else if(_tcsicmp(reg, _T("ESP")) == 0) {
+               REG32(ESP) = data;
+       } else if(_tcsicmp(reg, _T("EBP")) == 0) {
+               REG32(EBP) = data;
+       } else if(_tcsicmp(reg, _T("ESI")) == 0) {
+               REG32(ESI) = data;
+       } else if(_tcsicmp(reg, _T("EDI")) == 0) {
+               REG32(EDI) = data;
+       } else if(_tcsicmp(reg, _T("AX")) == 0) {
+               REG16(AX) = data;
+       } else if(_tcsicmp(reg, _T("BX")) == 0) {
+               REG16(BX) = data;
+       } else if(_tcsicmp(reg, _T("CX")) == 0) {
+               REG16(CX) = data;
+       } else if(_tcsicmp(reg, _T("DX")) == 0) {
+               REG16(DX) = data;
+       } else if(_tcsicmp(reg, _T("SP")) == 0) {
+               REG16(SP) = data;
+       } else if(_tcsicmp(reg, _T("BP")) == 0) {
+               REG16(BP) = data;
+       } else if(_tcsicmp(reg, _T("SI")) == 0) {
+               REG16(SI) = data;
+       } else if(_tcsicmp(reg, _T("DI")) == 0) {
+               REG16(DI) = data;
+       } else if(_tcsicmp(reg, _T("AL")) == 0) {
+               REG8(AL) = data;
+       } else if(_tcsicmp(reg, _T("AH")) == 0) {
+               REG8(AH) = data;
+       } else if(_tcsicmp(reg, _T("BL")) == 0) {
+               REG8(BL) = data;
+       } else if(_tcsicmp(reg, _T("BH")) == 0) {
+               REG8(BH) = data;
+       } else if(_tcsicmp(reg, _T("CL")) == 0) {
+               REG8(CL) = data;
+       } else if(_tcsicmp(reg, _T("CH")) == 0) {
+               REG8(CH) = data;
+       } else if(_tcsicmp(reg, _T("DL")) == 0) {
+               REG8(DL) = data;
+       } else if(_tcsicmp(reg, _T("DH")) == 0) {
+               REG8(DH) = data;
+       } else {
+               return false;
+       }
+       return true;
+}
+
+uint32_t i386_device::read_debug_reg(const _TCHAR *reg)
+{
+       if(_tcsicmp(reg, _T("EIP")) == 0) {
+               return m_eip;
+       } else if(_tcsicmp(reg, _T("IP")) == 0) {
+               return m_eip & 0xffff;
+       }  else if(_tcsicmp(reg, _T("EAX")) == 0) {
+               return REG32(EAX);
+       } else if(_tcsicmp(reg, _T("EBX")) == 0) {
+               return REG32(EBX);
+       } else if(_tcsicmp(reg, _T("ECX")) == 0) {
+               return REG32(ECX);
+       } else if(_tcsicmp(reg, _T("EDX")) == 0) {
+               return REG32(EDX);
+       } else if(_tcsicmp(reg, _T("ESP")) == 0) {
+               return REG32(ESP);
+       } else if(_tcsicmp(reg, _T("EBP")) == 0) {
+               return REG32(EBP);
+       } else if(_tcsicmp(reg, _T("ESI")) == 0) {
+               return REG32(ESI);
+       } else if(_tcsicmp(reg, _T("EDI")) == 0) {
+               return REG32(EDI);
+       } else if(_tcsicmp(reg, _T("AX")) == 0) {
+               return REG16(AX);
+       } else if(_tcsicmp(reg, _T("BX")) == 0) {
+               return REG16(BX);
+       } else if(_tcsicmp(reg, _T("CX")) == 0) {
+               return REG16(CX);
+       } else if(_tcsicmp(reg, _T("DX")) == 0) {
+               return REG16(DX);
+       } else if(_tcsicmp(reg, _T("SP")) == 0) {
+               return REG16(SP);
+       } else if(_tcsicmp(reg, _T("BP")) == 0) {
+               return REG16(BP);
+       } else if(_tcsicmp(reg, _T("SI")) == 0) {
+               return REG16(SI);
+       } else if(_tcsicmp(reg, _T("DI")) == 0) {
+               return REG16(DI);
+       } else if(_tcsicmp(reg, _T("AL")) == 0) {
+               return REG8(AL);
+       } else if(_tcsicmp(reg, _T("AH")) == 0) {
+               return REG8(AH);
+       } else if(_tcsicmp(reg, _T("BL")) == 0) {
+               return REG8(BL);
+       } else if(_tcsicmp(reg, _T("BH")) == 0) {
+               return REG8(BH);
+       } else if(_tcsicmp(reg, _T("CL")) == 0) {
+               return REG8(CL);
+       } else if(_tcsicmp(reg, _T("CH")) == 0) {
+               return REG8(CH);
+       } else if(_tcsicmp(reg, _T("DL")) == 0) {
+               return REG8(DL);
+       } else if(_tcsicmp(reg, _T("DH")) == 0) {
+               return REG8(DH);
+       }
+       return 0;
+}
+
+void i386_device::dump_segs(_TCHAR *buffer, _TCHAR* label, int segnum, size_t len)
+{
+       if((segnum < 0) || (segnum >= 6)) {
+               memset(buffer, 0x00, len);
+               return;
+       }
+       snprintf_s(buffer, len, "%s:%04X BASE=%08X LIMIT=%08X D=%d FLAGS=%04X VALID=%s\n",
+                          label,
+                          m_sreg[segnum].selector, m_sreg[segnum].base, m_sreg[segnum].limit,
+                          m_sreg[segnum].d, m_sreg[segnum].flags, (m_sreg[segnum].valid) ? "YES" : "NO");
+}
+       
+void i386_device::dump_regs(_TCHAR *buffer, size_t len)
+{
+       _TCHAR minibuffer[512];
+       snprintf(minibuffer, 512, "PC=%08X EIP=%08X ", m_pc, m_eip);
+       strncat(buffer, minibuffer, len); 
+       snprintf(minibuffer, 512, "PREV_PC=%08X PREV_EIP=%08X \n", m_prev_pc, m_prev_eip);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "CS", CS, 512);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "SS", SS, 512);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "DS", DS, 512);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "ES", ES, 512);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "FS", FS, 512);
+       strncat(buffer, minibuffer, len);
+       dump_segs(minibuffer, "GS", GS, 512);
+       strncat(buffer, minibuffer, len);
+       
+       snprintf(minibuffer, 512, "IOPL=%d CPL=%d EFLAGS=%08X EFLAGS_MASK=%08X\n", ((m_IOP1) | (m_IOP2 << 1)), m_CPL, m_eflags, m_eflags_mask); 
+       strncat(buffer, minibuffer, len);
+       snprintf(minibuffer, 512, "FLAGS: %s%s%s%s %s%s%s%s\n      %s%s%s%s %s%s%s%s\n",
+                        (m_CF == 0) ? "--" : "CF", (m_DF == 0) ? "--" : "CF", (m_SF == 0) ? "--" : "SF", (m_OF == 0) ? "--" : "OF",
+                        (m_ZF == 0) ? "-- " : "ZF ", (m_PF == 0) ? "-- " : "PF ", (m_AF == 0) ? "-- " : "AF ", (m_IF == 0) ? "-- " : "IF ",
+                        (m_TF == 0) ? "--" : "TF", (m_NT == 0) ? "--" : "NT", (m_RF == 0) ? "--" : "RF", (m_VM == 0) ? "--" : "VM",
+                        (m_AC == 0) ? "-- " : "AC ",
+                        (m_VIF == 0) ? "---" : "VIF", (m_VIP == 0) ? "---" : "VIP", (m_ID == 0) ? "-- " : "ID ");
+       strncat(buffer, minibuffer, len);
+
+       snprintf(minibuffer, 512, "EAX=%08X ECX=%08X EDX=%08X EBX=%08X\n", REG32(EAX), REG32(ECX), REG32(EDX), REG32(EBX));
+       strncat(buffer, minibuffer, len);
+       
+       snprintf(minibuffer, 512, "ESP=%08X EBP=%08X ESI=%08X EDI=%08X\n", REG32(ESP), REG32(EBP), REG32(ESI), REG32(EDI));
+       strncat(buffer, minibuffer, len);
+}
+
+bool i386_device::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
+{
+       if(buffer == NULL) return false;
+       if(buffer_len <= 0) return false;
+       memset(buffer, 0x00, buffer_len * sizeof(_TCHAR));
+       // ToDo: XMM, x87
+       dump_regs(buffer, buffer_len);
+       if(buffer[buffer_len - 1] != '\0') return false;
+       return true;
+}
+
+const UINT32 DASMFLAG_LENGTHMASK    = 0x0000ffff;   // the low 16-bits contain the actual length
+
+int I386::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
+{
+//     UINT64 eip = pc - sreg[CS].base;
+//     UINT8 ops[16];
+//     for(int i = 0; i < 16; i++) {
+//             int wait;
+//             ops[i] = d_mem->read_data8w(pc + i, &wait);
+//     }
+//     UINT8 *oprom = ops;
+       if(d_dasm == NULL) return 0;
+       if((buffer == NULL) || (buffer_len <= 0)) return 0;
+       int reply =  d_dasm->disassemble(pc, buffer, buffer_len, this);
+       reply = reply & DASMFLAG_LENGTHMASK;
+       return reply;
+}
index 90aab9f..badd42b 100644 (file)
 // SoftFloat 2 lacks an include guard
 #ifndef softfloat_h
 #define softfloat_h 1
-#include "softfloat/milieu.h"
-#include "softfloat/softfloat.h"
+#include "../softfloat/milieu.h"
+#include "../softfloat/softfloat.h"
 #endif
 
 #include "debug/debugcpu.h"
-#include "divtlb.h"
+#include "./divtlb.h"
 
-#include "i386dasm.h"
-#include "cache.h"
+#include "./i386dasm.h"
+#include "./cache.h"
 
 #define INPUT_LINE_A20      1
 #define INPUT_LINE_SMI      2
 
+typedef u8 uint8_t;
+typedef u16 uint16_t;
+typedef u32 uint32_t;
+typedef u64 uint64_t;
 
 // mingw has this defined for 32-bit compiles
 #undef i386
 
 #define X86_NUM_CPUS        4
 
-class i386_device : public cpu_device, public device_vtlb_interface, public i386_disassembler::config
+enum address_spacenum
 {
+       AS_0,                           // first address space
+       AS_1,                           // second address space
+       AS_2,                           // third address space
+       AS_3,                           // fourth address space
+       ADDRESS_SPACES,                 // maximum number of address spaces
+
+       // alternate address space names for common use
+       AS_PROGRAM = AS_0,              // program address space
+       AS_DATA = AS_1,                 // data address space
+       AS_IO = AS_2                    // I/O address space
+};
+
+class VM_TEMPLATE;
+class EMU;
+class DEBUGGER;
+class i386_device : public DEVICE
+{
+protected:
+       outpust_t outputs_reset;
+       DEVICE* d_mem;
+       DEVICE* d_io;
+       DEVICE* d_dma;
+       DEVICE* d_pic;
+       DEVICE* d_bios;
+       
+       DEBUGGER* d_debugger;
+       DEVICE* d_program_stored, d_io_stored;
 public:
        // construction/destruction
-       i386_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
+       i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       ~i386_device();
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
+       void set_address_mask(uint32_t mask)
+       {
+               m_a20_mask = mask;
+               d_vtlb->vtlb_flush_dynamic();
+       }
+       uint32_t get_address_mask()
+       {
+               return m_a20_mask;
+       }
+       void set_shutdown_flag(int shutdown)
+       {
+               m_shutdown = (shutdown != 0) ? true : false;
+       }
+       int set_shutdown_flag()
+       {
+               return (m_shutdown) ? 1 : 0;
+       }
+       
+       void set_context_mem(DEVICE* device)
+       {
+               d_mem = device;
+       }
+       void set_context_io(DEVICE* device)
+       {
+               d_io = device;
+       }
+       void set_context_intr(DEVICE* device)
+       {
+               d_pic = device;
+       }
+       void set_context_bios(DEVICE* device)
+       {
+               d_bios = device;
+       }
+       void set_context_dma(DEVICE* device)
+       {
+               d_dma = device;
+       }
+       void set_context_debugger(DEBUGGER* device)
+       {
+               d_debugger = device;
+       }
+       void set_reset_line(DEVICE* dev, int id, uint32_t mask)
+       {
+               register_output_signal(&outputs_reset, dev, id, mask);
+       }
+       
        // configuration helpers
-       auto smiact() { return m_smiact.bind(); }
-       auto ferr() { return m_ferr_handler.bind(); }
 
        uint64_t debug_segbase(symbol_table &table, int params, const uint64_t *param);
        uint64_t debug_seglimit(symbol_table &table, int params, const uint64_t *param);
@@ -43,11 +122,17 @@ public:
        uint64_t debug_virttophys(symbol_table &table, int params, const uint64_t *param);
 
 protected:
-       i386_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_data_width, int program_addr_width, int io_data_width);
+       device_vtlb_interface* d_vtlb;
+       bool process_state_segment(int num, FILEIO* state_fio, bool loading);
+       bool process_state_i386(FILEIO* state_fio, bool loading);
+       bool process_state_i386_x87(FILEIO* state_fio, bool loading);
+       bool process_state_i386_xmm(FILEIO* state_fio, bool loading);
+       
+       bool bios_int_x86(int num);
+       bool bios_call_far_x86(uint32_t address);
+       bool bios_trap_x86(uint32_t address, int &stat);
 
        // device-level overrides
-       virtual void device_start() override;
-       virtual void device_reset() override;
        virtual void device_debug_setup() override;
 
        // device_execute_interface overrides
@@ -80,17 +165,30 @@ protected:
        virtual void opcode_wbinvd() {}
 
        // routine to access memory
-       virtual u8 mem_pr8(offs_t address) { return macache32->read_byte(address); }
-       virtual u16 mem_pr16(offs_t address) { return macache32->read_word(address); }
-       virtual u32 mem_pr32(offs_t address) { return macache32->read_dword(address); }
-
-       virtual u8 mem_prd8(offs_t address) { return m_program->read_byte(address); }
-       virtual u16 mem_prd16(offs_t address) { return m_program->read_word(address); }
-       virtual u32 mem_prd32(offs_t address) { return m_program->read_dword(address); }
-       virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_byte(address, data); }
-       virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_word(address, data); }
-       virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_dword(address, data); }
-
+       // ToDo: Memory cache
+#if 1
+       virtual u8 mem_pr8(offs_t address) { return m_program->read_data8(address); }
+       virtual u16 mem_pr16(offs_t address) { return m_program->read_data16(address); }
+       virtual u32 mem_pr32(offs_t address) { return m_program->read_data32(address); }
+
+       virtual u8 mem_prd8(offs_t address) { return m_program->read_data8(address); }
+       virtual u16 mem_prd16(offs_t address) { return m_program->read_data16(address); }
+       virtual u32 mem_prd32(offs_t address) { return m_program->read_data32(address); }
+       virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_data8(address, data); }
+       virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_data16(address, data); }
+       virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_data32(address, data); }
+#else
+       virtual u8 mem_pr8(offs_t address) { return macache32->read_data8(address); }
+       virtual u16 mem_pr16(offs_t address) { return macache32->read_data16(address); }
+       virtual u32 mem_pr32(offs_t address) { return macache32->read_data32(address); }
+
+       virtual u8 mem_prd8(offs_t address) { return m_program->read_data8(address); }
+       virtual u16 mem_prd16(offs_t address) { return m_program->read_data16(address); }
+       virtual u32 mem_prd32(offs_t address) { return m_program->read_data32(address); }
+       virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_data8(address, data); }
+       virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_data16(address, data); }
+       virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_data32(address, data); }
+#endif 
        address_space_config m_program_config;
        address_space_config m_io_config;
 
@@ -279,6 +377,7 @@ protected:
        uint8_t m_ext;  // external interrupt
 
        int m_halted;
+       int m_busreq;
 
        int m_operand_size;
        int m_xmm_operand_size;
@@ -291,14 +390,20 @@ protected:
 
        int m_cycles;
        int m_base_cycles;
+       int64_t total_cycles;
+       int64_t prev_total_cycles;
+       int extra_cycles;
+       
        uint8_t m_opcode;
 
        uint8_t m_irq_state;
-       address_space *m_program;
-       address_space *m_io;
+       DEVICE *m_program;
+       DEVICE *m_io;
        uint32_t m_a20_mask;
-       memory_access_cache<1, 0, ENDIANNESS_LITTLE> *macache16;
-       memory_access_cache<2, 0, ENDIANNESS_LITTLE> *macache32;
+       bool m_shutdown;
+       // ToDo: Memory Cache.
+       //memory_access_cache<1, 0, ENDIANNESS_LITTLE> *macache16;
+       //memory_access_cache<2, 0, ENDIANNESS_LITTLE> *macache32;
 
        int m_cpuid_max_input_value_eax; // Highest CPUID standard function available
        uint32_t m_cpuid_id0, m_cpuid_id1, m_cpuid_id2;
@@ -366,8 +471,10 @@ protected:
        bool m_nmi_masked;
        bool m_nmi_latched;
        uint32_t m_smbase;
-       devcb_write_line m_smiact;
-       devcb_write_line m_ferr_handler;
+       DEVICE* m_smiact;
+       DEVICE* m_ferr_handler;
+       bool m_smiact_enabled;
+       int  m_ferr_err_value;
        bool m_lock;
 
        // bytes in current opcode, debug only
@@ -1508,35 +1615,38 @@ class i386sx_device : public i386_device
 {
 public:
        // construction/destruction
-       i386sx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       i386sx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
 
 protected:
-       virtual u8 mem_pr8(offs_t address) override { return macache16->read_byte(address); };
-       virtual u16 mem_pr16(offs_t address) override { return macache16->read_word(address); };
-       virtual u32 mem_pr32(offs_t address) override { return macache16->read_dword(address); };
+#if 0
+       virtual u8 mem_pr8(offs_t address) override { return macache16->read_data8(address); };
+       virtual u16 mem_pr16(offs_t address) override { return macache16->read_data16(address); };
+       virtual u32 mem_pr32(offs_t address) override { return macache16->read_data32(address); };
+#else
+       virtual u8 mem_pr8(offs_t address) override { return m_program->read_data8(address); };
+       virtual u16 mem_pr16(offs_t address) override { return m_program->read_data16(address); };
+       virtual u32 mem_pr32(offs_t address) override { return m_program->read_data32(address); };
+#endif 
 };
 
 class i486_device : public i386_device
 {
 public:
        // construction/destruction
-       i486_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       i486_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 
-protected:
-       i486_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
-       virtual void device_start() override;
-       virtual void device_reset() override;
 };
 
 class i486dx4_device : public i486_device
 {
 public:
        // construction/destruction
-       i486dx4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       i486dx4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual void reset() override;
 
-protected:
-       virtual void device_reset() override;
 };
 
 
@@ -1544,17 +1654,17 @@ class pentium_device : public i386_device
 {
 public:
        // construction/destruction
-       pentium_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       pentium_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 
 protected:
-       pentium_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
 
        virtual bool execute_input_edge_triggered(int inputnum) const override { return inputnum == INPUT_LINE_NMI || inputnum == INPUT_LINE_SMI; }
        virtual void execute_set_input(int inputnum, int state) override;
        virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
        virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
-       virtual void device_start() override;
-       virtual void device_reset() override;
 };
 
 
@@ -1562,11 +1672,10 @@ class pentium_mmx_device : public pentium_device
 {
 public:
        // construction/destruction
-       pentium_mmx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
-       virtual void device_start() override;
-       virtual void device_reset() override;
+       pentium_mmx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 };
 
 
@@ -1574,11 +1683,10 @@ class mediagx_device : public i386_device
 {
 public:
        // construction/destruction
-       mediagx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
-       virtual void device_start() override;
-       virtual void device_reset() override;
+       mediagx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 };
 
 
@@ -1586,15 +1694,14 @@ class pentium_pro_device : public pentium_device
 {
 public:
        // construction/destruction
-       pentium_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       pentium_pro_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 
 protected:
-       pentium_pro_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
        virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
        virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
-       virtual void device_start() override;
-       virtual void device_reset() override;
 };
 
 
@@ -1602,11 +1709,10 @@ class pentium2_device : public pentium_pro_device
 {
 public:
        // construction/destruction
-       pentium2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
-       virtual void device_start() override;
-       virtual void device_reset() override;
+       pentium2_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 };
 
 
@@ -1614,19 +1720,21 @@ class pentium3_device : public pentium_pro_device
 {
 public:
        // construction/destruction
-       pentium3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
-       virtual void device_start() override;
-       virtual void device_reset() override;
+       pentium3_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 };
 
-
+#if 0
 class athlonxp_device : public pentium_device
 {
 public:
        // construction/destruction
-       athlonxp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       athlonxp_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 
 protected:
        virtual void opcode_cpuid() override;
@@ -1634,8 +1742,6 @@ protected:
        virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
        virtual void opcode_invd() override;
        virtual void opcode_wbinvd() override;
-       virtual void device_start() override;
-       virtual void device_reset() override;
 
        virtual u8 mem_pr8(offs_t address) override { return opcode_read_cache<u8, NATIVE_ENDIAN_VALUE_LE_BE(0, 3)>(address);   }
        virtual u16 mem_pr16(offs_t address) override { return opcode_read_cache<u16, NATIVE_ENDIAN_VALUE_LE_BE(0, 2)>(address); }
@@ -1661,22 +1767,23 @@ private:
        uint8_t m_memory_ranges_1m[1024 / 4];
        cpucache<17, 9, Cache2Way, CacheLineBytes64> cache; // 512 sets, 2 ways (cachelines per set), 64 bytes per cacheline
 };
-
+#endif
 
 class pentium4_device : public pentium_device
 {
 public:
        // construction/destruction
-       pentium4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+       pentium4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
+       virtual bool process_state(FILEIO* state_fio, bool loading);
+       virtual void initialize() override;
+       virtual void reset() override;
 
 protected:
        virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
        virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
-       virtual void device_start() override;
-       virtual void device_reset() override;
 };
 
-
+/*
 DECLARE_DEVICE_TYPE(I386,        i386_device)
 DECLARE_DEVICE_TYPE(I386SX,      i386sx_device)
 DECLARE_DEVICE_TYPE(I486,        i486_device)
@@ -1689,5 +1796,5 @@ DECLARE_DEVICE_TYPE(PENTIUM2,    pentium2_device)
 DECLARE_DEVICE_TYPE(PENTIUM3,    pentium3_device)
 DECLARE_DEVICE_TYPE(ATHLONXP,    athlonxp_device)
 DECLARE_DEVICE_TYPE(PENTIUM4,    pentium4_device)
-
+*/
 #endif // MAME_CPU_I386_I386_H
index 374f2a2..1f7199a 100644 (file)
@@ -1867,46 +1867,46 @@ const char *const i386_disassembler::i386_reg8[8] = {"al", "cl", "dl", "bl", "ah
 const char *const i386_disassembler::i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"};
 const char *const i386_disassembler::i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"};
 
-inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        if ((pc - base_pc) + 1 > max_length)
                return 0xff;
-       uint8_t d = opcodes.r8(pc);
+       uint8_t d = parent->read_debug_data8(pc);
        pc++;
        return d;
 }
 
-inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        if ((pc - base_pc) + 2 > max_length)
                return 0xffff;
-       uint16_t d = opcodes.r16(pc);
+       uint16_t d = parent->read_debug_data16(pc);
        pc += 2;
        return d;
 }
 
-inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        if ((pc - base_pc) + 4 > max_length)
                return 0xffffffff;
-       uint32_t d = opcodes.r32(pc);
+       uint32_t d = parent->read_debug_data32(pc);
        pc += 4;
        return d;
 }
 
-inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
-       return FETCH(base_pc, pc, opcodes);
+       return FETCH(base_pc, pc, parent);
 }
 
-inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
-       return FETCH16(base_pc, pc, opcodes);
+       return FETCH16(base_pc, pc, parent);
 }
 
-inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, i386_device* parent)
 {
-       return FETCH32(base_pc, pc, opcodes);
+       return FETCH32(base_pc, pc, parent);
 }
 
 char *i386_disassembler::hexstring(uint32_t value, int digits)
@@ -1951,37 +1951,46 @@ char *i386_disassembler::shexstring(uint32_t value, int digits, bool always)
        return buffer;
 }
 
-void i386_disassembler::handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::add_snprintf(_TCHAR* buffer, size_t len, const char *format, ...)
+{
+       va_list ap;
+       va_start(ap, format);
+       int result = vsnprintf(buffer, len, format, ap);
+       va_end(ap);
+       return result;
+}
+
+void i386_disassembler::handle_sib_byte(_TCHAR* buffer, size_t len, uint8_t mod, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        uint32_t i32;
        uint8_t scale, i, base;
-       uint8_t sib = FETCHD(base_pc, pc, opcodes);
+       uint8_t sib = FETCHD(base_pc, pc, parent);
 
        scale = (sib >> 6) & 0x3;
        i = ((sib >> 3) & 0x7) | sibex;
        base = (sib & 0x7) | rmex;
 
        if (base == 5 && mod == 0) {
-               i32 = FETCHD32(base_pc, pc, opcodes);
-               util::stream_format(stream, "%s", hexstring(i32, 0));
+               i32 = FETCHD32(base_pc, pc, parent);
+               add_snprintf(buffer, len, "%s", hexstring(i32, 0));
        } else if (base != 5 || mod != 3)
-               util::stream_format(stream, "%s", i386_reg[address_size][base]);
+               add_snprintf(buffer, len, "%s", i386_reg[address_size][base]);
 
        if ( i != 4 ) {
-               util::stream_format(stream, "+%s", i386_reg[address_size][i]);
+               add_snprintf(buffer, len, "+%s", i386_reg[address_size][i]);
                if (scale)
-                       util::stream_format(stream, "*%d", 1 << scale);
+                       add_snprintf(buffer, len, "*%d", 1 << scale);
        }
 }
 
-void i386_disassembler::handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::handle_modrm(_TCHAR *buffer, size_t len, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        int8_t disp8;
        int16_t disp16;
        int32_t disp32;
        uint8_t mod, rm;
 
-       modrm = FETCHD(base_pc, pc, opcodes);
+       modrm = FETCHD(base_pc, pc, parent);
        mod = (modrm >> 6) & 0x3;
        rm = (modrm & 0x7) | rmex;
 
@@ -1990,92 +1999,90 @@ void i386_disassembler::handle_modrm(std::ostream &stream, offs_t base_pc, offs_
 
        switch(segment)
        {
-               case SEG_CS: util::stream_format(stream, "cs:"); break;
-               case SEG_DS: util::stream_format(stream, "ds:"); break;
-               case SEG_ES: util::stream_format(stream, "es:"); break;
-               case SEG_FS: util::stream_format(stream, "fs:"); break;
-               case SEG_GS: util::stream_format(stream, "gs:"); break;
-               case SEG_SS: util::stream_format(stream, "ss:"); break;
+               case SEG_CS: add_snprintf(buffer, len, "cs:"); break;
+               case SEG_DS: add_snprintf(buffer, len, "ds:"); break;
+               case SEG_ES: add_snprintf(buffer, len, "es:"); break;
+               case SEG_FS: add_snprintf(buffer, len, "fs:"); break;
+               case SEG_GS: add_snprintf(buffer, len, "gs:"); break;
+               case SEG_SS: add_snprintf(buffer, len, "ss:"); break;
        }
 
-       util::stream_format(stream, "[" );
+       add_snprintf(buffer, len, "[" );
        if( address_size == 2 ) {
                if ((rm & 7) == 4)
-                       handle_sib_byte(stream, mod, base_pc, pc, opcodes);
+                       handle_sib_byte(buffer, len, mod, base_pc, pc, parent);
                else if ((rm & 7) == 5 && mod == 0) {
-                       disp32 = FETCHD32(base_pc, pc, opcodes);
-                       util::stream_format(stream, "rip%s", shexstring(disp32, 0, true));
+                       disp32 = FETCHD32(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "rip%s", shexstring(disp32, 0, true));
                } else
-                       util::stream_format(stream, "%s", i386_reg[2][rm]);
+                       add_snprintf(buffer, len, "%s", i386_reg[2][rm]);
                if( mod == 1 ) {
-                       disp8 = FETCHD(base_pc, pc, opcodes);
+                       disp8 = FETCHD(base_pc, pc, parent);
                        if (disp8 != 0)
-                               util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) );
                } else if( mod == 2 ) {
-                       disp32 = FETCHD32(base_pc, pc, opcodes);
+                       disp32 = FETCHD32(base_pc, pc, oparent);
                        if (disp32 != 0)
-                               util::stream_format(stream, "%s", shexstring(disp32, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring(disp32, 0, true) );
                }
        } else if (address_size == 1) {
                if ((rm & 7) == 4)
-                       handle_sib_byte(stream, mod, base_pc, pc, opcodes);
+                       handle_sib_byte(buffer, len, mod, base_pc, pc, parent);
                else if ((rm & 7) == 5 && mod == 0) {
-                       disp32 = FETCHD32(base_pc, pc, opcodes);
+                       disp32 = FETCHD32(base_pc, pc, parent);
                        if (m_config->get_mode() == 64)
-                               util::stream_format(stream, "eip%s", shexstring(disp32, 0, true) );
+                               add_snprintf(buffer, len, "eip%s", shexstring(disp32, 0, true) );
                        else
-                               util::stream_format(stream, "%s", hexstring(disp32, 0) );
+                               add_snprintf(buffer, len, "%s", hexstring(disp32, 0) );
                } else
-                       util::stream_format(stream, "%s", i386_reg[1][rm]);
+                       add_snprintf(buffer, len, "%s", i386_reg[1][rm]);
                if( mod == 1 ) {
-                       disp8 = FETCHD(base_pc, pc, opcodes);
+                       disp8 = FETCHD(base_pc, pc, parent);
                        if (disp8 != 0)
-                               util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) );
                } else if( mod == 2 ) {
-                       disp32 = FETCHD32(base_pc, pc, opcodes);
+                       disp32 = FETCHD32(base_pc, pc, parent);
                        if (disp32 != 0)
-                               util::stream_format(stream, "%s", shexstring(disp32, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring(disp32, 0, true) );
                }
        } else {
                switch( rm )
                {
-                       case 0: util::stream_format(stream, "bx+si" ); break;
-                       case 1: util::stream_format(stream, "bx+di" ); break;
-                       case 2: util::stream_format(stream, "bp+si" ); break;
-                       case 3: util::stream_format(stream, "bp+di" ); break;
-                       case 4: util::stream_format(stream, "si" ); break;
-                       case 5: util::stream_format(stream, "di" ); break;
+                       case 0: add_snprintf(buffer, len, "bx+si" ); break;
+                       case 1: add_snprintf(buffer, len, "bx+di" ); break;
+                       case 2: add_snprintf(buffer, len, "bp+si" ); break;
+                       case 3: add_snprintf(buffer, len, "bp+di" ); break;
+                       case 4: add_snprintf(buffer, len, "si" ); break;
+                       case 5: add_snprintf(buffer, len, "di" ); break;
                        case 6:
                                if( mod == 0 ) {
-                                       disp16 = FETCHD16(base_pc, pc, opcodes);
-                                       util::stream_format(stream, "%s", hexstring((unsigned) (uint16_t) disp16, 0) );
+                                       disp16 = FETCHD16(base_pc, pc, parent);
+                                       add_snprintf(buffer, len, "%s", hexstring((unsigned) (uint16_t) disp16, 0) );
                                } else {
-                                       util::stream_format(stream, "bp" );
+                                       add_snprintf(buffer, len, "bp" );
                                }
                                break;
-                       case 7: util::stream_format(stream, "bx" ); break;
+                       case 7: add_snprintf(buffer, len, "bx" ); break;
                }
                if( mod == 1 ) {
-                       disp8 = FETCHD(base_pc, pc, opcodes);
+                       disp8 = FETCHD(base_pc, pc, parent);
                        if (disp8 != 0)
-                               util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) );
                } else if( mod == 2 ) {
-                       disp16 = FETCHD16(base_pc, pc, opcodes);
+                       disp16 = FETCHD16(base_pc, pc, parent);
                        if (disp16 != 0)
-                               util::stream_format(stream, "%s", shexstring((int32_t)disp16, 0, true) );
+                               add_snprintf(buffer, len, "%s", shexstring((int32_t)disp16, 0, true) );
                }
        }
-       util::stream_format(stream, "]" );
+       add_snprintf(buffer, len, "]" );
 }
 
-void i386_disassembler::handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::handle_modrm(_TCHAR *buffer, size_t len, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
-       std::stringstream stream;
-       handle_modrm(stream, base_pc, pc, opcodes);
-       buffer = stream.str();
+       handle_modrm(buffer, len, base_pc, pc, parent);
 }
 
-void i386_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::handle_param(_TCHAR *buffer, size_t len, uint32_t param, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        uint8_t i8;
        uint16_t i16;
@@ -2089,308 +2096,308 @@ void i386_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_
        switch(param)
        {
                case PARAM_REG:
-                       util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1() | regex] );
+                       add_snprintf(buffer, len, "%s", i386_reg[operand_size][MODRM_REG1() | regex] );
                        break;
 
                case PARAM_REG8:
-                       util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] );
+                       add_snprintf(buffer, len, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] );
                        break;
 
                case PARAM_REG16:
-                       util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1() | regex] );
+                       add_snprintf(buffer, len, "%s", i386_reg[0][MODRM_REG1() | regex] );
                        break;
 
                case PARAM_REG32:
-                       util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1() | regex] );
+                       add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG1() | regex] );
                        break;
 
                case PARAM_REG3264:
-                       util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
+                       add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
                        break;
 
                case PARAM_MMX:
                        if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
-                               util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
+                               add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex );
                        else
-                               util::stream_format(stream, "mm%d", MODRM_REG1() | regex );
+                               add_snprintf(buffer, len, "mm%d", MODRM_REG1() | regex );
                        break;
 
                case PARAM_MMX2:
                        if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
-                               util::stream_format(stream, "xmm%d", MODRM_REG2() | regex );
+                               add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | regex );
                        else
-                               util::stream_format(stream, "mm%d", MODRM_REG2() | regex );
+                               add_snprintf(buffer, len, "mm%d", MODRM_REG2() | regex );
                        break;
 
                case PARAM_XMM:
-                       util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
+                       add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex );
                        break;
 
                case PARAM_REGORXMM:
                        if (pre0f != 0xf2 && pre0f != 0xf3)
-                               util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
+                               add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex );
                        else
-                               util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
+                               add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
                        break;
 
                case PARAM_REG2_32:
-                       util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] );
+                       add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG2() | rmex] );
                        break;
 
                case PARAM_RM:
                case PARAM_RMPTR:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] );
+                               add_snprintf(buffer, len, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] );
                        } else {
                                if (param == PARAM_RMPTR)
                                {
                                        if( operand_size == 2 )
-                                               util::stream_format(stream, "qword ptr " );
+                                               add_snprintf(buffer, len, "qword ptr " );
                                        else if (operand_size == 1)
-                                               util::stream_format(stream, "dword ptr " );
+                                               add_snprintf(buffer, len, "dword ptr " );
                                        else
-                                               util::stream_format(stream, "word ptr " );
+                                               add_snprintf(buffer, len, "word ptr " );
                                }
-                               util::stream_format(stream, "%s", modrm_string );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_RM8:
                case PARAM_RMPTR8:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] );
+                               add_snprintf(buffer, len, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] );
                        } else {
                                if (param == PARAM_RMPTR8)
-                                       util::stream_format(stream, "byte ptr " );
-                               util::stream_format(stream, "%s", modrm_string );
+                                       add_snprintf(buffer, len, "byte ptr " );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_RM16:
                case PARAM_RMPTR16:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2() | rmex] );
+                               add_snprintf(buffer, len, "%s", i386_reg[0][MODRM_REG2() | rmex] );
                        } else {
                                if (param == PARAM_RMPTR16)
-                                       util::stream_format(stream, "word ptr " );
-                               util::stream_format(stream, "%s", modrm_string );
+                                       add_snprintf(buffer, len, "word ptr " );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_RM32:
                case PARAM_RMPTR32:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] );
+                               add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG2() | rmex] );
                        } else {
                                if (param == PARAM_RMPTR32)
-                                       util::stream_format(stream, "dword ptr " );
-                               util::stream_format(stream, "%s", modrm_string );
+                                       add_snprintf(buffer, len, "dword ptr " );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_RMXMM:
                        if( modrm >= 0xc0 ) {
                                if (pre0f != 0xf2 && pre0f != 0xf3)
-                                       util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
+                                       add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex );
                                else
-                                       util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] );
+                                       add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] );
                        } else {
                                if (param == PARAM_RMPTR32)
-                                       util::stream_format(stream, "dword ptr " );
-                               util::stream_format(stream, "%s", modrm_string );
+                                       add_snprintf(buffer, len, "dword ptr " );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_M64:
                case PARAM_M64PTR:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "???" );
+                               add_snprintf(buffer, len, "???" );
                        } else {
                                if (param == PARAM_M64PTR)
-                                       util::stream_format(stream, "qword ptr " );
-                               util::stream_format(stream, "%s", modrm_string );
+                                       add_snprintf(buffer, len, "qword ptr " );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_MMXM:
                        if( modrm >= 0xc0 ) {
                                if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
-                                       util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
+                                       add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex );
                                else
-                                       util::stream_format(stream, "mm%d", MODRM_REG2() | rmex );
+                                       add_snprintf(buffer, len, "mm%d", MODRM_REG2() | rmex );
                        } else {
-                               util::stream_format(stream, "%s", modrm_string );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_XMMM:
                        if( modrm >= 0xc0 ) {
-                               util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
+                               add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex );
                        } else {
-                               util::stream_format(stream, "%s", modrm_string );
+                               add_snprintf(buffer, len, "%s", modrm_string );
                        }
                        break;
 
                case PARAM_I4:
-                       i8 = FETCHD(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%d", i8 & 0x0f );
+                       i8 = FETCHD(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%d", i8 & 0x0f );
                        break;
 
                case PARAM_I8:
-                       i8 = FETCHD(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%s", shexstring((int8_t)i8, 0, false) );
+                       i8 = FETCHD(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%s", shexstring((int8_t)i8, 0, false) );
                        break;
 
                case PARAM_I16:
-                       i16 = FETCHD16(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%s", shexstring((int16_t)i16, 0, false) );
+                       i16 = FETCHD16(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%s", shexstring((int16_t)i16, 0, false) );
                        break;
 
                case PARAM_UI8:
-                       i8 = FETCHD(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%s", shexstring((uint8_t)i8, 0, false) );
+                       i8 = FETCHD(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%s", shexstring((uint8_t)i8, 0, false) );
                        break;
 
                case PARAM_UI16:
-                       i16 = FETCHD16(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%s", shexstring((uint16_t)i16, 0, false) );
+                       i16 = FETCHD16(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%s", shexstring((uint16_t)i16, 0, false) );
                        break;
 
                case PARAM_IMM64:
                        if (operand_size == 2) {
-                               uint32_t lo32 = FETCHD32(base_pc, pc, opcodes);
-                               i32 = FETCHD32(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstring64(lo32, i32) );
+                               uint32_t lo32 = FETCHD32(base_pc, pc, parent);
+                               i32 = FETCHD32(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstring64(lo32, i32) );
                        } else if( operand_size ) {
-                               i32 = FETCHD32(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstring(i32, 0) );
+                               i32 = FETCHD32(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstring(i32, 0) );
                        } else {
-                               i16 = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstring(i16, 0) );
+                               i16 = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstring(i16, 0) );
                        }
                        break;
 
                case PARAM_IMM:
                        if( operand_size ) {
-                               i32 = FETCHD32(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstring(i32, 0) );
+                               i32 = FETCHD32(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstring(i32, 0) );
                        } else {
-                               i16 = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstring(i16, 0) );
+                               i16 = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstring(i16, 0) );
                        }
                        break;
 
                case PARAM_ADDR:
                        if( operand_size ) {
-                               addr = FETCHD32(base_pc, pc, opcodes);
-                               ptr = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s:", hexstring(ptr, 4) );
-                               util::stream_format(stream, "%s", hexstring(addr, 0) );
+                               addr = FETCHD32(base_pc, pc, parent);
+                               ptr = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s:", hexstring(ptr, 4) );
+                               add_snprintf(buffer, len, "%s", hexstring(addr, 0) );
                        } else {
-                               addr = FETCHD16(base_pc, pc, opcodes);
-                               ptr = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s:", hexstring(ptr, 4) );
-                               util::stream_format(stream, "%s", hexstring(addr, 0) );
+                               addr = FETCHD16(base_pc, pc, parent);
+                               ptr = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s:", hexstring(ptr, 4) );
+                               add_snprintf(buffer, len, "%s", hexstring(addr, 0) );
                        }
                        break;
 
                case PARAM_REL:
                        if( operand_size ) {
-                               d32 = FETCHD32(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstringpc(pc + d32) );
+                               d32 = FETCHD32(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstringpc(pc + d32) );
                        } else {
                                /* make sure to keep the relative offset within the segment */
-                               d16 = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) );
+                               d16 = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) );
                        }
                        break;
 
                case PARAM_REL8:
-                       d8 = FETCHD(base_pc, pc, opcodes);
-                       util::stream_format(stream, "%s", hexstringpc(pc + d8) );
+                       d8 = FETCHD(base_pc, pc, parent);
+                       add_snprintf(buffer, len, "%s", hexstringpc(pc + d8) );
                        break;
 
                case PARAM_MEM_OFFS:
                        switch(segment)
                        {
-                               case SEG_CS: util::stream_format(stream, "cs:" ); break;
-                               case SEG_DS: util::stream_format(stream, "ds:" ); break;
-                               case SEG_ES: util::stream_format(stream, "es:" ); break;
-                               case SEG_FS: util::stream_format(stream, "fs:" ); break;
-                               case SEG_GS: util::stream_format(stream, "gs:" ); break;
-                               case SEG_SS: util::stream_format(stream, "ss:" ); break;
+                               case SEG_CS: add_snprintf(buffer, len, "cs:" ); break;
+                               case SEG_DS: add_snprintf(buffer, len, "ds:" ); break;
+                               case SEG_ES: add_snprintf(buffer, len, "es:" ); break;
+                               case SEG_FS: add_snprintf(buffer, len, "fs:" ); break;
+                               case SEG_GS: add_snprintf(buffer, len, "gs:" ); break;
+                               case SEG_SS: add_snprintf(buffer, len, "ss:" ); break;
                        }
 
                        if( address_size ) {
-                               i32 = FETCHD32(base_pc, pc, opcodes);
-                               util::stream_format(stream, "[%s]", hexstring(i32, 0) );
+                               i32 = FETCHD32(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "[%s]", hexstring(i32, 0) );
                        } else {
-                               i16 = FETCHD16(base_pc, pc, opcodes);
-                               util::stream_format(stream, "[%s]", hexstring(i16, 0) );
+                               i16 = FETCHD16(base_pc, pc, parent);
+                               add_snprintf(buffer, len, "[%s]", hexstring(i16, 0) );
                        }
                        break;
 
                case PARAM_PREIMP:
                        switch(segment)
                        {
-                               case SEG_CS: util::stream_format(stream, "cs:" ); break;
-                               case SEG_DS: util::stream_format(stream, "ds:" ); break;
-                               case SEG_ES: util::stream_format(stream, "es:" ); break;
-                               case SEG_FS: util::stream_format(stream, "fs:" ); break;
-                               case SEG_GS: util::stream_format(stream, "gs:" ); break;
-                               case SEG_SS: util::stream_format(stream, "ss:" ); break;
+                               case SEG_CS: add_snprintf(buffer, len, "cs:" ); break;
+                               case SEG_DS: add_snprintf(buffer, len, "ds:" ); break;
+                               case SEG_ES: add_snprintf(buffer, len, "es:" ); break;
+                               case SEG_FS: add_snprintf(buffer, len, "fs:" ); break;
+                               case SEG_GS: add_snprintf(buffer, len, "gs:" ); break;
+                               case SEG_SS: add_snprintf(buffer, len, "ss:" ); break;
                        }
                        break;
 
                case PARAM_SREG:
-                       util::stream_format(stream, "%s", i386_sreg[MODRM_REG1()] );
+                       add_snprintf(buffer, len, "%s", i386_sreg[MODRM_REG1()] );
                        break;
 
                case PARAM_CREG:
-                       util::stream_format(stream, "cr%d", MODRM_REG1() | regex );
+                       add_snprintf(buffer, len, "cr%d", MODRM_REG1() | regex );
                        break;
 
                case PARAM_TREG:
-                       util::stream_format(stream, "tr%d", MODRM_REG1() | regex );
+                       add_snprintf(buffer, len, "tr%d", MODRM_REG1() | regex );
                        break;
 
                case PARAM_DREG:
-                       util::stream_format(stream, "dr%d", MODRM_REG1() | regex );
+                       add_snprintf(buffer, len, "dr%d", MODRM_REG1() | regex );
                        break;
 
                case PARAM_1:
-                       util::stream_format(stream, "1" );
+                       add_snprintf(buffer, len, "1" );
                        break;
 
                case PARAM_DX:
-                       util::stream_format(stream, "dx" );
+                       add_snprintf(buffer, len, "dx" );
                        break;
 
                case PARAM_XMM0:
-                       util::stream_format(stream, "xmm0" );
+                       add_snprintf(buffer, len, "xmm0" );
                        break;
 
-               case PARAM_AL: util::stream_format(stream, "al" ); break;
-               case PARAM_CL: util::stream_format(stream, "cl" ); break;
-               case PARAM_DL: util::stream_format(stream, "dl" ); break;
-               case PARAM_BL: util::stream_format(stream, "bl" ); break;
-               case PARAM_AH: util::stream_format(stream, "ah" ); break;
-               case PARAM_CH: util::stream_format(stream, "ch" ); break;
-               case PARAM_DH: util::stream_format(stream, "dh" ); break;
-               case PARAM_BH: util::stream_format(stream, "bh" ); break;
-
-               case PARAM_EAX: util::stream_format(stream, "%s", i386_reg[operand_size][0 | rmex] ); break;
-               case PARAM_ECX: util::stream_format(stream, "%s", i386_reg[operand_size][1 | rmex] ); break;
-               case PARAM_EDX: util::stream_format(stream, "%s", i386_reg[operand_size][2 | rmex] ); break;
-               case PARAM_EBX: util::stream_format(stream, "%s", i386_reg[operand_size][3 | rmex] ); break;
-               case PARAM_ESP: util::stream_format(stream, "%s", i386_reg[operand_size][4 | rmex] ); break;
-               case PARAM_EBP: util::stream_format(stream, "%s", i386_reg[operand_size][5 | rmex] ); break;
-               case PARAM_ESI: util::stream_format(stream, "%s", i386_reg[operand_size][6 | rmex] ); break;
-               case PARAM_EDI: util::stream_format(stream, "%s", i386_reg[operand_size][7 | rmex] ); break;
+               case PARAM_AL: add_snprintf(buffer, len, "al" ); break;
+               case PARAM_CL: add_snprintf(buffer, len, "cl" ); break;
+               case PARAM_DL: add_snprintf(buffer, len, "dl" ); break;
+               case PARAM_BL: add_snprintf(buffer, len, "bl" ); break;
+               case PARAM_AH: add_snprintf(buffer, len, "ah" ); break;
+               case PARAM_CH: add_snprintf(buffer, len, "ch" ); break;
+               case PARAM_DH: add_snprintf(buffer, len, "dh" ); break;
+               case PARAM_BH: add_snprintf(buffer, len, "bh" ); break;
+
+               case PARAM_EAX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][0 | rmex] ); break;
+               case PARAM_ECX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][1 | rmex] ); break;
+               case PARAM_EDX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][2 | rmex] ); break;
+               case PARAM_EBX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][3 | rmex] ); break;
+               case PARAM_ESP: add_snprintf(buffer, len, "%s", i386_reg[operand_size][4 | rmex] ); break;
+               case PARAM_EBP: add_snprintf(buffer, len, "%s", i386_reg[operand_size][5 | rmex] ); break;
+               case PARAM_ESI: add_snprintf(buffer, len, "%s", i386_reg[operand_size][6 | rmex] ); break;
+               case PARAM_EDI: add_snprintf(buffer, len, "%s", i386_reg[operand_size][7 | rmex] ); break;
        }
 }
 
-void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::handle_fpu(_TCHAR *buffer, size_t len, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        switch (op1 & 0x7)
        {
@@ -2399,31 +2406,31 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fadd    dword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fmul    dword ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "fcom    dword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fcomp   dword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fsub    dword ptr %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fsubr   dword ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fdiv    dword ptr %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fdivr   dword ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fadd    dword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fmul    dword ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "fcom    dword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fcomp   dword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fsub    dword ptr %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fsubr   dword ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fdiv    dword ptr %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fdivr   dword ptr %s", modrm_string); break;
                                }
                        }
                        else
                        {
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fadd    st(0),st(%d)", op2 & 0x7); break;
-                                       case 1: util::stream_format(stream, "fmul    st(0),st(%d)", op2 & 0x7); break;
-                                       case 2: util::stream_format(stream, "fcom    st(0),st(%d)", op2 & 0x7); break;
-                                       case 3: util::stream_format(stream, "fcomp   st(0),st(%d)", op2 & 0x7); break;
-                                       case 4: util::stream_format(stream, "fsub    st(0),st(%d)", op2 & 0x7); break;
-                                       case 5: util::stream_format(stream, "fsubr   st(0),st(%d)", op2 & 0x7); break;
-                                       case 6: util::stream_format(stream, "fdiv    st(0),st(%d)", op2 & 0x7); break;
-                                       case 7: util::stream_format(stream, "fdivr   st(0),st(%d)", op2 & 0x7); break;
+                                       case 0: add_snprintf(buffer, len, "fadd    st(0),st(%d)", op2 & 0x7); break;
+                                       case 1: add_snprintf(buffer, len, "fmul    st(0),st(%d)", op2 & 0x7); break;
+                                       case 2: add_snprintf(buffer, len, "fcom    st(0),st(%d)", op2 & 0x7); break;
+                                       case 3: add_snprintf(buffer, len, "fcomp   st(0),st(%d)", op2 & 0x7); break;
+                                       case 4: add_snprintf(buffer, len, "fsub    st(0),st(%d)", op2 & 0x7); break;
+                                       case 5: add_snprintf(buffer, len, "fsubr   st(0),st(%d)", op2 & 0x7); break;
+                                       case 6: add_snprintf(buffer, len, "fdiv    st(0),st(%d)", op2 & 0x7); break;
+                                       case 7: add_snprintf(buffer, len, "fdivr   st(0),st(%d)", op2 & 0x7); break;
                                }
                        }
                        break;
@@ -2434,17 +2441,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fld     dword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "??? (FPU)"); break;
-                                       case 2: util::stream_format(stream, "fst     dword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fstp    dword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fldenv  word ptr %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fldcw   word ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fstenv  word ptr %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fstcw   word ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fld     dword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "??? (FPU)"); break;
+                                       case 2: add_snprintf(buffer, len, "fst     dword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fstp    dword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fldenv  word ptr %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fldcw   word ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fstenv  word ptr %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fstcw   word ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2452,41 +2459,41 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "fld     st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fld     st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-                                               util::stream_format(stream, "fxch    st(0),st(%d)", op2 & 0x7); break;
-
-                                       case 0x10: util::stream_format(stream, "fnop"); break;
-                                       case 0x20: util::stream_format(stream, "fchs"); break;
-                                       case 0x21: util::stream_format(stream, "fabs"); break;
-                                       case 0x24: util::stream_format(stream, "ftst"); break;
-                                       case 0x25: util::stream_format(stream, "fxam"); break;
-                                       case 0x28: util::stream_format(stream, "fld1"); break;
-                                       case 0x29: util::stream_format(stream, "fldl2t"); break;
-                                       case 0x2a: util::stream_format(stream, "fldl2e"); break;
-                                       case 0x2b: util::stream_format(stream, "fldpi"); break;
-                                       case 0x2c: util::stream_format(stream, "fldlg2"); break;
-                                       case 0x2d: util::stream_format(stream, "fldln2"); break;
-                                       case 0x2e: util::stream_format(stream, "fldz"); break;
-                                       case 0x30: util::stream_format(stream, "f2xm1"); break;
-                                       case 0x31: util::stream_format(stream, "fyl2x"); break;
-                                       case 0x32: util::stream_format(stream, "fptan"); break;
-                                       case 0x33: util::stream_format(stream, "fpatan"); break;
-                                       case 0x34: util::stream_format(stream, "fxtract"); break;
-                                       case 0x35: util::stream_format(stream, "fprem1"); break;
-                                       case 0x36: util::stream_format(stream, "fdecstp"); break;
-                                       case 0x37: util::stream_format(stream, "fincstp"); break;
-                                       case 0x38: util::stream_format(stream, "fprem"); break;
-                                       case 0x39: util::stream_format(stream, "fyl2xp1"); break;
-                                       case 0x3a: util::stream_format(stream, "fsqrt"); break;
-                                       case 0x3b: util::stream_format(stream, "fsincos"); break;
-                                       case 0x3c: util::stream_format(stream, "frndint"); break;
-                                       case 0x3d: util::stream_format(stream, "fscale"); break;
-                                       case 0x3e: util::stream_format(stream, "fsin"); break;
-                                       case 0x3f: util::stream_format(stream, "fcos"); break;
-
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                               add_snprintf(buffer, len, "fxch    st(0),st(%d)", op2 & 0x7); break;
+
+                                       case 0x10: add_snprintf(buffer, len, "fnop"); break;
+                                       case 0x20: add_snprintf(buffer, len, "fchs"); break;
+                                       case 0x21: add_snprintf(buffer, len, "fabs"); break;
+                                       case 0x24: add_snprintf(buffer, len, "ftst"); break;
+                                       case 0x25: add_snprintf(buffer, len, "fxam"); break;
+                                       case 0x28: add_snprintf(buffer, len, "fld1"); break;
+                                       case 0x29: add_snprintf(buffer, len, "fldl2t"); break;
+                                       case 0x2a: add_snprintf(buffer, len, "fldl2e"); break;
+                                       case 0x2b: add_snprintf(buffer, len, "fldpi"); break;
+                                       case 0x2c: add_snprintf(buffer, len, "fldlg2"); break;
+                                       case 0x2d: add_snprintf(buffer, len, "fldln2"); break;
+                                       case 0x2e: add_snprintf(buffer, len, "fldz"); break;
+                                       case 0x30: add_snprintf(buffer, len, "f2xm1"); break;
+                                       case 0x31: add_snprintf(buffer, len, "fyl2x"); break;
+                                       case 0x32: add_snprintf(buffer, len, "fptan"); break;
+                                       case 0x33: add_snprintf(buffer, len, "fpatan"); break;
+                                       case 0x34: add_snprintf(buffer, len, "fxtract"); break;
+                                       case 0x35: add_snprintf(buffer, len, "fprem1"); break;
+                                       case 0x36: add_snprintf(buffer, len, "fdecstp"); break;
+                                       case 0x37: add_snprintf(buffer, len, "fincstp"); break;
+                                       case 0x38: add_snprintf(buffer, len, "fprem"); break;
+                                       case 0x39: add_snprintf(buffer, len, "fyl2xp1"); break;
+                                       case 0x3a: add_snprintf(buffer, len, "fsqrt"); break;
+                                       case 0x3b: add_snprintf(buffer, len, "fsincos"); break;
+                                       case 0x3c: add_snprintf(buffer, len, "frndint"); break;
+                                       case 0x3d: add_snprintf(buffer, len, "fscale"); break;
+                                       case 0x3e: add_snprintf(buffer, len, "fsin"); break;
+                                       case 0x3f: add_snprintf(buffer, len, "fcos"); break;
+
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2497,17 +2504,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fiadd   dword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fimul   dword ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "ficom   dword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "ficomp  dword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fisub   dword ptr %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fisubr  dword ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fidiv   dword ptr %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fidivr  dword ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fiadd   dword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fimul   dword ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "ficom   dword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "ficomp  dword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fisub   dword ptr %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fisubr  dword ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fidiv   dword ptr %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fidivr  dword ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2515,20 +2522,20 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "fcmovb  st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovb  st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-                                               util::stream_format(stream, "fcmove  st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmove  st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-                                               util::stream_format(stream, "fcmovbe st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovbe st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-                                               util::stream_format(stream, "fcmovu  st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovu  st(0),st(%d)", op2 & 0x7); break;
                                        case 0x29:
-                                               util::stream_format(stream, "fucompp"); break;
+                                               add_snprintf(buffer, len, "fucompp"); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
 
                                }
                        }
@@ -2540,17 +2547,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fild    dword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fisttp  dword ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "fist    dword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fistp   dword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "??? (FPU)"); break;
-                                       case 5: util::stream_format(stream, "fld     tword ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "??? (FPU)"); break;
-                                       case 7: util::stream_format(stream, "fstp    tword ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fild    dword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fisttp  dword ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "fist    dword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fistp   dword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "??? (FPU)"); break;
+                                       case 5: add_snprintf(buffer, len, "fld     tword ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "??? (FPU)"); break;
+                                       case 7: add_snprintf(buffer, len, "fstp    tword ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2558,27 +2565,27 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "fcmovnb st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovnb st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-                                               util::stream_format(stream, "fcmovne st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovne st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-                                               util::stream_format(stream, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-                                               util::stream_format(stream, "fcmovnu st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcmovnu st(0),st(%d)", op2 & 0x7); break;
 
-                                       case 0x22: util::stream_format(stream, "fclex"); break;
-                                       case 0x23: util::stream_format(stream, "finit"); break;
+                                       case 0x22: add_snprintf(buffer, len, "fclex"); break;
+                                       case 0x23: add_snprintf(buffer, len, "finit"); break;
 
                                        case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-                                               util::stream_format(stream, "fucomi  st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fucomi  st(0),st(%d)", op2 & 0x7); break;
 
                                        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
-                                               util::stream_format(stream, "fcomi   st(0),st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcomi   st(0),st(%d)", op2 & 0x7); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2589,17 +2596,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fadd    qword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fmul    qword ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "fcom    qword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fcomp   qword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fsub    qword ptr %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fsubr   qword ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fdiv    qword ptr %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fdivr   qword ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fadd    qword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fmul    qword ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "fcom    qword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fcomp   qword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fsub    qword ptr %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fsubr   qword ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fdiv    qword ptr %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fdivr   qword ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2607,24 +2614,24 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "fadd    st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fadd    st(%d),st(0)", op2 & 0x7); break;
 
                                        case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-                                               util::stream_format(stream, "fmul    st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fmul    st(%d),st(0)", op2 & 0x7); break;
 
                                        case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
-                                               util::stream_format(stream, "fsubr   st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fsubr   st(%d),st(0)", op2 & 0x7); break;
 
                                        case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-                                               util::stream_format(stream, "fsub    st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fsub    st(%d),st(0)", op2 & 0x7); break;
 
                                        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
-                                               util::stream_format(stream, "fdivr   st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fdivr   st(%d),st(0)", op2 & 0x7); break;
 
                                        case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-                                               util::stream_format(stream, "fdiv    st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fdiv    st(%d),st(0)", op2 & 0x7); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2635,17 +2642,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fld     qword ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fisttp  qword ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "fst     qword ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fstp    qword ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "frstor  %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "??? (FPU)"); break;
-                                       case 6: util::stream_format(stream, "fsave   %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fstsw   word ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fld     qword ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fisttp  qword ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "fst     qword ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fstp    qword ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "frstor  %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "??? (FPU)"); break;
+                                       case 6: add_snprintf(buffer, len, "fsave   %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fstsw   word ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2653,21 +2660,21 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "ffree   st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "ffree   st(%d)", op2 & 0x7); break;
 
                                        case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-                                               util::stream_format(stream, "fst     st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fst     st(%d)", op2 & 0x7); break;
 
                                        case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-                                               util::stream_format(stream, "fstp    st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fstp    st(%d)", op2 & 0x7); break;
 
                                        case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
-                                               util::stream_format(stream, "fucom   st(%d), st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fucom   st(%d), st(0)", op2 & 0x7); break;
 
                                        case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-                                               util::stream_format(stream, "fucomp  st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fucomp  st(%d)", op2 & 0x7); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2678,17 +2685,17 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fiadd   word ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fimul   word ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "ficom   word ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "ficomp  word ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fisub   word ptr %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fisubr  word ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fidiv   word ptr %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fidivr  word ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fiadd   word ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fimul   word ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "ficom   word ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "ficomp  word ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fisub   word ptr %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fisubr  word ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fidiv   word ptr %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fidivr  word ptr %s", modrm_string); break;
                                }
                        }
                        else
@@ -2696,26 +2703,26 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                                switch (op2 & 0x3f)
                                {
                                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
-                                               util::stream_format(stream, "faddp   st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "faddp   st(%d)", op2 & 0x7); break;
 
                                        case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-                                               util::stream_format(stream, "fmulp   st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fmulp   st(%d)", op2 & 0x7); break;
 
-                                       case 0x19: util::stream_format(stream, "fcompp"); break;
+                                       case 0x19: add_snprintf(buffer, len, "fcompp"); break;
 
                                        case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
-                                               util::stream_format(stream, "fsubrp  st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fsubrp  st(%d)", op2 & 0x7); break;
 
                                        case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-                                               util::stream_format(stream, "fsubp   st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fsubp   st(%d)", op2 & 0x7); break;
 
                                        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
-                                               util::stream_format(stream, "fdivrp  st(%d), st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fdivrp  st(%d), st(0)", op2 & 0x7); break;
 
                                        case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-                                               util::stream_format(stream, "fdivp   st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fdivp   st(%d)", op2 & 0x7); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2726,32 +2733,32 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
                        if (op2 < 0xc0)
                        {
                                pc--;       // adjust fetch pointer, so modrm byte read again
-                               handle_modrm(modrm_string, base_pc, pc, opcodes);
+                               handle_modrm(modrm_string, base_pc, pc, parent);
                                switch ((op2 >> 3) & 0x7)
                                {
-                                       case 0: util::stream_format(stream, "fild    word ptr %s", modrm_string); break;
-                                       case 1: util::stream_format(stream, "fisttp  word ptr %s", modrm_string); break;
-                                       case 2: util::stream_format(stream, "fist    word ptr %s", modrm_string); break;
-                                       case 3: util::stream_format(stream, "fistp   word ptr %s", modrm_string); break;
-                                       case 4: util::stream_format(stream, "fbld    %s", modrm_string); break;
-                                       case 5: util::stream_format(stream, "fild    qword ptr %s", modrm_string); break;
-                                       case 6: util::stream_format(stream, "fbstp   %s", modrm_string); break;
-                                       case 7: util::stream_format(stream, "fistp   qword ptr %s", modrm_string); break;
+                                       case 0: add_snprintf(buffer, len, "fild    word ptr %s", modrm_string); break;
+                                       case 1: add_snprintf(buffer, len, "fisttp  word ptr %s", modrm_string); break;
+                                       case 2: add_snprintf(buffer, len, "fist    word ptr %s", modrm_string); break;
+                                       case 3: add_snprintf(buffer, len, "fistp   word ptr %s", modrm_string); break;
+                                       case 4: add_snprintf(buffer, len, "fbld    %s", modrm_string); break;
+                                       case 5: add_snprintf(buffer, len, "fild    qword ptr %s", modrm_string); break;
+                                       case 6: add_snprintf(buffer, len, "fbstp   %s", modrm_string); break;
+                                       case 7: add_snprintf(buffer, len, "fistp   qword ptr %s", modrm_string); break;
                                }
                        }
                        else
                        {
                                switch (op2 & 0x3f)
                                {
-                                       case 0x20: util::stream_format(stream, "fstsw   ax"); break;
+                                       case 0x20: add_snprintf(buffer, len, "fstsw   ax"); break;
 
                                        case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-                                               util::stream_format(stream, "fucomip st(%d)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fucomip st(%d)", op2 & 0x7); break;
 
                                        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
-                                               util::stream_format(stream, "fcomip  st(%d),st(0)", op2 & 0x7); break;
+                                               add_snprintf(buffer, len, "fcomip  st(%d),st(0)", op2 & 0x7); break;
 
-                                       default: util::stream_format(stream, "??? (FPU)"); break;
+                                       default: add_snprintf(buffer, len, "??? (FPU)"); break;
                                }
                        }
                        break;
@@ -2759,7 +2766,7 @@ void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op
        }
 }
 
-void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
+void i386_disassembler::decode_opcode(_TCHAR *buffer, size_t len, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, i386_device* parent)
 {
        int i;
        uint8_t op2;
@@ -2777,8 +2784,8 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                                regex = (op1 << 1) & 8;
                                sibex = (op1 << 2) & 8;
                                rmex = (op1 << 3) & 8;
-                               op2 = FETCH(base_pc, pc, opcodes);
-                               decode_opcode(stream, &i386_opcode_table1[op2], op1, base_pc, pc, opcodes);
+                               op2 = FETCH(base_pc, pc, parent);
+                               decode_opcode(buffer, len, &i386_opcode_table1[op2], op1, base_pc, pc, parent);
                                return;
                        }
                        break;
@@ -2790,8 +2797,8 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                                operand_size ^= 1;
                                operand_prefix = 1;
                        }
-                       op2 = FETCH(base_pc, pc, opcodes);
-                       decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
+                       op2 = FETCH(base_pc, pc, parent);
+                       decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent);
                        return;
 
                case ADDR_SIZE:
@@ -2804,23 +2811,23 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                                        address_size ^= 3;
                                address_prefix = 1;
                        }
-                       op2 = FETCH(base_pc, pc, opcodes);
-                       decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
+                       op2 = FETCH(base_pc, pc, parent);
+                       decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent);
                        return;
 
                case TWO_BYTE:
                        if (pc - 2 >= base_pc)
-                               pre0f = opcodes.r8(pc-2);
-                       op2 = FETCHD(base_pc, pc, opcodes);
-                       decode_opcode(stream, &i386_opcode_table2[op2], op1, base_pc, pc, opcodes);
+                               pre0f = parent.r8(pc-2);
+                       op2 = FETCHD(base_pc, pc, parent);
+                       decode_opcode(buffer, len, &i386_opcode_table2[op2], op1, base_pc, pc, parent);
                        return;
 
                case THREE_BYTE:
-                       op2 = FETCHD(base_pc, pc, opcodes);
-                       if (opcodes.r8(pc-2) == 0x38)
-                               decode_opcode(stream, &i386_opcode_table0F38[op2], op1, base_pc, pc, opcodes);
+                       op2 = FETCHD(base_pc, pc, parent);
+                       if (parent.r8(pc-2) == 0x38)
+                               decode_opcode(buffer, len, &i386_opcode_table0F38[op2], op1, base_pc, pc, parent);
                        else
-                               decode_opcode(stream, &i386_opcode_table0F3A[op2], op1, base_pc, pc, opcodes);
+                               decode_opcode(buffer, len, &i386_opcode_table0F3A[op2], op1, base_pc, pc, parent);
                        return;
 
                case SEG_CS:
@@ -2831,40 +2838,40 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                case SEG_SS:
                        rex = regex = sibex = rmex = 0;
                        segment = op->flags;
-                       op2 = FETCH(base_pc, pc, opcodes);
-                       decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
+                       op2 = FETCH(base_pc, pc, parent);
+                       decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent);
                        return;
 
                case PREFIX:
-                       op2 = FETCH(base_pc, pc, opcodes);
+                       op2 = FETCH(base_pc, pc, parent);
                        if ((op2 != 0x0f) && (op2 != 0x90))
-                               util::stream_format(stream, "%-7s ", op->mnemonic );
+                               add_snprintf(buffer, len, "%-7s ", op->mnemonic );
                        if ((op2 == 0x90) && !pre0f)
                                pre0f = op1;
-                       decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
+                       decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent);
                        dasm_flags |= op->dasm_flags;
                        return;
 
                case GROUP:
-                       handle_modrm(modrm_string, base_pc, pc, opcodes);
+                       handle_modrm(modrm_string, base_pc, pc, parent);
                        for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
                                if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) {
                                        if (op->flags & GROUP_MOD)
-                                               decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, opcodes);
+                                               decode_opcode(buffer, len, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, parent);
                                        else
-                                               decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, opcodes);
+                                               decode_opcode(buffer, len, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, parent);
                                        return;
                                }
                        }
                        goto handle_unknown;
 
                case FPU:
-                       op2 = FETCHD(base_pc, pc, opcodes);
-                       handle_fpu(stream, op1, op2, base_pc, pc, opcodes);
+                       op2 = FETCHD(base_pc, pc, parent);
+                       handle_fpu(buffer, len, op1, op2, base_pc, pc, parent);
                        return;
 
                case MODRM:
-                       handle_modrm(modrm_string, base_pc, pc, opcodes);
+                       handle_modrm(modrm_string, base_pc, pc, parent);
                        break;
        }
 
@@ -2876,7 +2883,7 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                const char *mnemonic = op->mnemonic + strlen(op->mnemonic) + 1;
                if (operand_size == 2)
                        mnemonic += strlen(mnemonic) + 1;
-               util::stream_format(stream, "%-7s ", mnemonic );
+               add_snprintf(buffer, len, "%-7s ", mnemonic );
        }
        else if (op->flags & VAR_NAME4)
        {
@@ -2884,34 +2891,34 @@ void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *o
                int which = (pre0f == 0xf3) ? 3 : (pre0f == 0xf2) ? 2 : (pre0f == 0x66) ? 1 : 0;
                while (which--)
                        mnemonic += strlen(mnemonic) + 1;
-               util::stream_format(stream, "%-7s ", mnemonic );
+               add_snprintf(buffer, len, "%-7s ", mnemonic );
        }
        else
-               util::stream_format(stream, "%-7s ", op->mnemonic );
+               add_snprintf(buffer, len, "%-7s ", op->mnemonic );
        dasm_flags = op->dasm_flags;
 
        if( op->param1 != 0 ) {
-               handle_param(stream, op->param1, base_pc, pc, opcodes);
+               handle_param(buffer, len, op->param1, base_pc, pc, parent);
        }
 
        if( op->param2 != 0 ) {
-               util::stream_format(stream, "," );
-               handle_param(stream, op->param2, base_pc, pc, opcodes);
+               add_snprintf(buffer, len, "," );
+               handle_param(buffer, len, op->param2, base_pc, pc, parent);
        }
 
        if( op->param3 != 0 ) {
-               util::stream_format(stream, "," );
-               handle_param(stream, op->param3, base_pc, pc, opcodes);
+               add_snprintf(buffer, len, "," );
+               handle_param(buffer, len, op->param3, base_pc, pc, parent);
        }
        return;
 
 handle_unknown:
-       util::stream_format(stream, "???");
+       add_snprintf(buffer, len, "???");
 }
 
-offs_t i386_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+uint32_t i386_disassembler::disassemble(_TCHAR* buffer, size_t len, uint32_t pc,  i386_device* parent)
 {
-       offs_t base_pc = pc;
+       uint32_t base_pc = pc;
        uint8_t op;
 
        switch(m_config->get_mode())
@@ -2949,10 +2956,10 @@ offs_t i386_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
        address_prefix = 0;
        operand_prefix = 0;
 
-       op = FETCH(base_pc, pc, opcodes);
+       op = FETCH(base_pc, pc, parent);
 
-       decode_opcode( stream, &i386_opcode_table1[op], op, base_pc, pc, opcodes);
-       return (pc-base_pc) | dasm_flags | SUPPORTED;
+       decode_opcode(buffer, len, &i386_opcode_table1[op], op, base_pc, pc, parent);
+       return (pc-base_pc) | dasm_flags | DASMFLAG_SUPPORTED;
 }
 
 i386_disassembler::i386_disassembler(config *conf) : m_config(conf)
index 25f5ec0..fa2210b 100644 (file)
@@ -18,7 +18,7 @@ public:
        i386_disassembler(config *conf);
 
        virtual u32 opcode_alignment() const override;
-       virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+       virtual offs_t disassemble(uint32_t pc, const data_buffer &opcodes, const data_buffer &params) override;
 
 private:
        enum
index cfaa990..83a41ac 100644 (file)
@@ -504,6 +504,14 @@ void i386_device::i386_call_abs16()        // Opcode 0x9a
                m_performed_intersegment_jump = 1;
                m_eip = offset;
                i386_load_segment_descriptor(CS);
+               //uint8_t IOPL = (m_IOP1 & 1) | ((m_IOP2 & 1) << 1);
+               if(bios_call_far_x86(( (((uint32_t)ptr) << 4) + ((uint32_t)offset)) & m_a20_mask)) {
+                       m_eip = POP16();
+                       m_sreg[CS].selector = POP16();
+                       i386_load_segment_descriptor(CS);
+                       CYCLES(CYCLES_CALL_INTERSEG + CYCLES_RET_INTERSEG);      /* TODO: Timing = 17 + m */
+                       return;
+               }
        }
        CYCLES(CYCLES_CALL_INTERSEG);      /* TODO: Timing = 17 + m */
        CHANGE_PC(m_eip);
@@ -3045,6 +3053,13 @@ void i386_device::i386_groupFF_16()        // Opcode 0xff
                                                m_sreg[CS].selector = selector;
                                                m_performed_intersegment_jump = 1;
                                                i386_load_segment_descriptor(CS );
+                                               if(bios_call_far_x86(( (((uint32_t)ptr) << 4) + ((uint32_t)offset)) & m_a20_mask)) {
+                                                       m_eip = POP16();
+                                                       m_sreg[CS].selector = POP16();
+                                                       i386_load_segment_descriptor(CS);
+                                                       CYCLES(CYCLES_CALL_INTERSEG + CYCLES_RET_INTERSEG);      /* TODO: Timing = 17 + m */
+                                                       return;
+                                               }
                                                m_eip = address;
                                                CHANGE_PC(m_eip);
                                        }
index 5b9d21a..58bef3c 100644 (file)
@@ -703,7 +703,7 @@ void i386_device::i386_mov_cr_r32()        // Opcode 0x0f 22
                case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
                case 3:
                        CYCLES(CYCLES_MOV_REG_CR3);
-                       vtlb_flush_dynamic();
+                       d_vtlb->vtlb_flush_dynamic();
                        break;
                case 4: CYCLES(1); break; // TODO
                default:
@@ -2333,6 +2333,10 @@ void i386_device::i386_int()               // Opcode 0xcd
        int interrupt = FETCH();
        CYCLES(CYCLES_INT);
        m_ext = 0; // not an external interrupt
+       if(bios_int_x86(interrupt)) {
+               m_ext = 1;
+               return;
+       }
        i386_trap(interrupt, 1, 0);
        m_ext = 1;
 }
index 6946e46..052fdf4 100644 (file)
@@ -329,7 +329,7 @@ void i386_device::i486_group0F01_16()      // Opcode 0x0f 01
                                }
                                ea = GetEA(modrm,-1);
                                CYCLES(25); // TODO: add to cycles.h
-                               vtlb_flush_address(ea);
+                               d_vtlb->vtlb_flush_address(ea);
                                break;
                        }
                default:
@@ -447,7 +447,7 @@ void i386_device::i486_group0F01_32()      // Opcode 0x0f 01
                                }
                                ea = GetEA(modrm,-1);
                                CYCLES(25); // TODO: add to cycles.h
-                               vtlb_flush_address(ea);
+                               d_vtlb->vtlb_flush_address(ea);
                                break;
                        }
                default:
@@ -517,14 +517,14 @@ void i386_device::i486_mov_cr_r32()        // Opcode 0x0f 22
                case 0:
                        CYCLES(CYCLES_MOV_REG_CR0);
                        if((oldcr ^ m_cr[cr]) & 0x80010000)
-                               vtlb_flush_dynamic();
+                               d_vtlb->vtlb_flush_dynamic();
                        if (PROTECTED_MODE != BIT(data, 0))
                                debugger_privilege_hook();
                        break;
                case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
                case 3:
                        CYCLES(CYCLES_MOV_REG_CR3);
-                       vtlb_flush_dynamic();
+                       d_vtlb->vtlb_flush_dynamic();
                        break;
                case 4: CYCLES(1); break; // TODO
                default: