// 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 {
};
cacheset sets[Sets];
- u32 writeback_base;
+ uint32_t writeback_base;
int last_set;
int last_way;
};
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;
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;
}
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++)
}
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;
/* 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];
{
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;
*/
#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"
/* 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")
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
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)
*error |= 1;
return false;
}
- vtlb_dynload(index, *address, entry);
+ d_vtlb->vtlb_dynload(index, *address, entry);
return true;
}
if (!(entry & (1 << type)))
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;
}
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)
}
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)
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;
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};
}
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 {
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();
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);
}
}
-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;
}
}
-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;
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;
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;
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;
m_opcode_bytes_length = 0;
}
-void i386_device::device_reset()
+void i386_device::reset()
{
zero_state();
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;
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;
}
/*************************************************************************/
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;
/* Intel 486 */
-void i486_device::device_start()
+void i486_device::initialize()
{
i386_common_init();
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();
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
/* 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();
m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get();
}
-void pentium_device::device_reset()
+void pentium_device::reset()
{
zero_state();
/* 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);
m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_MEDIAGX].get();
}
-void mediagx_device::device_reset()
+void mediagx_device::reset()
{
zero_state();
/*****************************************************************************/
/* 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);
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();
/*****************************************************************************/
/* 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);
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();
/*****************************************************************************/
/* 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);
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();
/*****************************************************************************/
/* 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);
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();
CHANGE_PC(m_eip);
}
-
+#if 0
/*****************************************************************************/
/* AMD Athlon XP
Model: Athlon XP 2400+
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);
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();
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);
}
}
{
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);
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();
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;
+}
// 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);
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
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;
uint8_t m_ext; // external interrupt
int m_halted;
+ int m_busreq;
int m_operand_size;
int m_xmm_operand_size;
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;
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
{
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;
};
{
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;
};
{
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;
};
{
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;
};
{
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;
};
{
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;
};
{
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;
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); }
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)
DECLARE_DEVICE_TYPE(PENTIUM3, pentium3_device)
DECLARE_DEVICE_TYPE(ATHLONXP, athlonxp_device)
DECLARE_DEVICE_TYPE(PENTIUM4, pentium4_device)
-
+*/
#endif // MAME_CPU_I386_I386_H
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)
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;
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;
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)
{
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;
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
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;
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
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;
}
}
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
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;
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
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;
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
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;
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
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;
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;
}
}
-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;
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;
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:
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:
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;
}
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)
{
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 ¶ms)
+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())
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)
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 ¶ms) override;
+ virtual offs_t disassemble(uint32_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
private:
enum
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);
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);
}
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:
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;
}
}
ea = GetEA(modrm,-1);
CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(ea);
+ d_vtlb->vtlb_flush_address(ea);
break;
}
default:
}
ea = GetEA(modrm,-1);
CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(ea);
+ d_vtlb->vtlb_flush_address(ea);
break;
}
default:
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: