summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i386/i386.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i386/i386.cpp')
-rw-r--r--src/devices/cpu/i386/i386.cpp209
1 files changed, 205 insertions, 4 deletions
diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp
index 06fbfca3fb5..9952755dc22 100644
--- a/src/devices/cpu/i386/i386.cpp
+++ b/src/devices/cpu/i386/i386.cpp
@@ -99,26 +99,31 @@ mediagx_device::mediagx_device(const machine_config &mconfig, const char *tag, d
}
pentium_pro_device::pentium_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pentium_device(mconfig, PENTIUM_PRO, tag, owner, 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_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_pro_device(mconfig, PENTIUM_MMX, tag, owner, clock)
{
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
set_vtlb_dynamic_entries(96);
}
pentium2_device::pentium2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pentium_device(mconfig, PENTIUM2, tag, owner, clock)
+ : pentium_pro_device(mconfig, PENTIUM2, tag, owner, clock)
{
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
set_vtlb_dynamic_entries(96);
}
pentium3_device::pentium3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pentium_device(mconfig, PENTIUM3, tag, owner, clock)
+ : pentium_pro_device(mconfig, PENTIUM3, tag, owner, clock)
{
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
set_vtlb_dynamic_entries(96);
@@ -4039,6 +4044,24 @@ std::unique_ptr<util::disasm_interface> i386_device::create_disassembler()
return std::make_unique<i386_disassembler>(this);
}
+void i386_device::opcode_cpuid()
+{
+ logerror("CPUID called with unsupported EAX=%08x at %08x!\n", REG32(EAX), m_eip);
+}
+
+uint64_t i386_device::opcode_rdmsr(bool &valid_msr)
+{
+ valid_msr = false;
+ logerror("RDMSR called with unsupported ECX=%08x at %08x!\n", REG32(ECX), m_eip);
+ return -1;
+}
+
+void i386_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
+{
+ valid_msr = false;
+ logerror("WRMSR called with unsupported ECX=%08x (%08x%08x) at %08x!\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_eip);
+}
+
/*****************************************************************************/
/* Intel 486 */
@@ -4177,6 +4200,98 @@ void pentium_device::device_reset()
CHANGE_PC(m_eip);
}
+uint64_t pentium_device::opcode_rdmsr(bool &valid_msr)
+{
+ uint32_t offset = REG32(ECX);
+
+ switch (offset)
+ {
+ // Machine Check Exception (TODO)
+ case 0x00:
+ valid_msr = true;
+ popmessage("RDMSR: Reading P5_MC_ADDR");
+ return 0;
+ case 0x01:
+ valid_msr = true;
+ popmessage("RDMSR: Reading P5_MC_TYPE");
+ return 0;
+ // Time Stamp Counter
+ case 0x10:
+ valid_msr = true;
+ popmessage("RDMSR: Reading TSC");
+ return m_tsc;
+ // Event Counters (TODO)
+ case 0x11: // CESR
+ valid_msr = true;
+ popmessage("RDMSR: Reading CESR");
+ return 0;
+ case 0x12: // CTR0
+ valid_msr = true;
+ return m_perfctr[0];
+ case 0x13: // CTR1
+ valid_msr = true;
+ return m_perfctr[1];
+ default:
+ if (!(offset & ~0xf)) // 2-f are test registers
+ {
+ valid_msr = true;
+ logerror("RDMSR: Reading test MSR %x", offset);
+ return 0;
+ }
+ logerror("RDMSR: invalid P5 MSR read %08x at %08x\n", offset, m_pc - 2);
+ valid_msr = false;
+ return 0;
+ }
+ return -1;
+}
+
+void pentium_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
+{
+ uint32_t offset = REG32(ECX);
+
+ switch (offset)
+ {
+ // Machine Check Exception (TODO)
+ case 0x00:
+ popmessage("WRMSR: Writing P5_MC_ADDR");
+ valid_msr = true;
+ break;
+ case 0x01:
+ popmessage("WRMSR: Writing P5_MC_TYPE");
+ valid_msr = true;
+ break;
+ // Time Stamp Counter
+ case 0x10:
+ m_tsc = data;
+ popmessage("WRMSR: Writing to TSC");
+ valid_msr = true;
+ break;
+ // Event Counters (TODO)
+ case 0x11: // CESR
+ popmessage("WRMSR: Writing to CESR");
+ valid_msr = true;
+ break;
+ case 0x12: // CTR0
+ m_perfctr[0] = data;
+ valid_msr = true;
+ break;
+ case 0x13: // CTR1
+ m_perfctr[1] = data;
+ valid_msr = true;
+ break;
+ default:
+ if (!(offset & ~0xf)) // 2-f are test registers
+ {
+ valid_msr = true;
+ logerror("WRMSR: Writing test MSR %x", offset);
+ break;
+ }
+ logerror("WRMSR: invalid MSR write %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
+ valid_msr = false;
+ break;
+ }
+}
+
/*****************************************************************************/
/* Cyrix MediaGX */
@@ -4314,6 +4429,69 @@ void pentium_pro_device::device_reset()
CHANGE_PC(m_eip);
}
+uint64_t pentium_pro_device::opcode_rdmsr(bool &valid_msr)
+{
+ uint32_t offset = REG32(ECX);
+
+ switch (offset)
+ {
+ // Machine Check Exception (TODO)
+ case 0x00:
+ valid_msr = true;
+ popmessage("RDMSR: Reading P5_MC_ADDR");
+ return 0;
+ case 0x01:
+ valid_msr = true;
+ popmessage("RDMSR: Reading P5_MC_TYPE");
+ return 0;
+ // Time Stamp Counter
+ case 0x10:
+ valid_msr = true;
+ popmessage("RDMSR: Reading TSC");
+ return m_tsc;
+ // Performance Counters (TODO)
+ case 0xc1: // PerfCtr0
+ valid_msr = true;
+ return m_perfctr[0];
+ case 0xc2: // PerfCtr1
+ valid_msr = true;
+ return m_perfctr[1];
+ default:
+ logerror("RDMSR: unimplemented register called %08x at %08x\n", offset, m_pc - 2);
+ valid_msr = true;
+ return 0;
+ }
+ return -1;
+}
+
+void pentium_pro_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
+{
+ uint32_t offset = REG32(ECX);
+
+ switch (offset)
+ {
+ // Time Stamp Counter
+ case 0x10:
+ m_tsc = data;
+ popmessage("WRMSR: Writing to TSC");
+ valid_msr = true;
+ break;
+ // Performance Counters (TODO)
+ case 0xc1: // PerfCtr0
+ m_perfctr[0] = data;
+ valid_msr = true;
+ break;
+ case 0xc2: // PerfCtr1
+ m_perfctr[1] = data;
+ valid_msr = true;
+ break;
+ default:
+ logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
+ valid_msr = true;
+ break;
+ }
+}
+
/*****************************************************************************/
/* Intel Pentium MMX */
@@ -4655,3 +4833,26 @@ void pentium4_device::device_reset()
CHANGE_PC(m_eip);
}
+
+uint64_t pentium4_device::opcode_rdmsr(bool &valid_msr)
+{
+ switch (REG32(ECX))
+ {
+ default:
+ logerror("RDMSR: unimplemented register called %08x at %08x\n", REG32(ECX), m_pc - 2);
+ valid_msr = true;
+ return 0;
+ }
+ return -1;
+}
+
+void pentium4_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
+{
+ switch (REG32(ECX))
+ {
+ default:
+ logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
+ valid_msr = true;
+ break;
+ }
+}