summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/emu/cpu/i386/i386.h7
-rw-r--r--src/emu/cpu/i386/i386ops.h10
-rw-r--r--src/emu/cpu/i386/pentops.inc268
-rw-r--r--src/mame/drivers/pinball2k.c28
4 files changed, 311 insertions, 2 deletions
diff --git a/src/emu/cpu/i386/i386.h b/src/emu/cpu/i386/i386.h
index e994a7aa006..b2bcd3c0056 100644
--- a/src/emu/cpu/i386/i386.h
+++ b/src/emu/cpu/i386/i386.h
@@ -962,6 +962,7 @@ struct I386_CALL_GATE
void pentium_cmovg_r32_rm32();
void pentium_movnti_m16_r16();
void pentium_movnti_m32_r32();
+ void i386_cyrix_special();
void i386_cyrix_unknown();
void pentium_cmpxchg8b_m64();
void pentium_movntq_m64_r64();
@@ -1004,6 +1005,12 @@ struct I386_CALL_GATE
void mmx_paddw_r64_rm64();
void mmx_paddd_r64_rm64();
void mmx_emms();
+ void i386_cyrix_svdc();
+ void i386_cyrix_rsdc();
+ void i386_cyrix_svldt();
+ void i386_cyrix_rsldt();
+ void i386_cyrix_svts();
+ void i386_cyrix_rsts();
void mmx_movd_r64_rm32();
void mmx_movq_r64_rm64();
void mmx_movd_rm32_r64();
diff --git a/src/emu/cpu/i386/i386ops.h b/src/emu/cpu/i386/i386ops.h
index 6523dafd144..c540a7d3c16 100644
--- a/src/emu/cpu/i386/i386ops.h
+++ b/src/emu/cpu/i386/i386ops.h
@@ -329,6 +329,10 @@ const i386_device::X86_OPCODE i386_device::s_x86_opcode_table[] =
{ 0x32, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_rdmsr, &i386_device::pentium_rdmsr, false},
{ 0x38, OP_2BYTE|OP_PENTIUM, &i386_device::i386_decode_three_byte38, &i386_device::i386_decode_three_byte38,false},
{ 0x3A, OP_2BYTE|OP_PENTIUM, &i386_device::i386_decode_three_byte3a, &i386_device::i386_decode_three_byte3a,false},
+ { 0x3A, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false},
+ { 0x3B, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false},
+ { 0x3C, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false},
+ { 0x3D, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false},
{ 0x40, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovo_r16_rm16, &i386_device::pentium_cmovo_r32_rm32, false},
{ 0x41, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovno_r16_rm16, &i386_device::pentium_cmovno_r32_rm32, false},
{ 0x42, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovb_r16_rm16, &i386_device::pentium_cmovb_r32_rm32, false},
@@ -384,6 +388,12 @@ const i386_device::X86_OPCODE i386_device::s_x86_opcode_table[] =
{ 0x75, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpeqw_r64_rm64, &i386_device::mmx_pcmpeqw_r64_rm64, false},
{ 0x76, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpeqd_r64_rm64, &i386_device::mmx_pcmpeqd_r64_rm64, false},
{ 0x77, OP_2BYTE|OP_MMX, &i386_device::mmx_emms, &i386_device::mmx_emms, false},
+ { 0x78, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svdc, &i386_device::i386_cyrix_svdc, false},
+ { 0x79, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsdc, &i386_device::i386_cyrix_rsdc, false},
+ { 0x7a, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svldt, &i386_device::i386_cyrix_svldt, false},
+ { 0x7b, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsldt, &i386_device::i386_cyrix_rsldt, false},
+ { 0x7c, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svts, &i386_device::i386_cyrix_svts, false},
+ { 0x7d, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsts, &i386_device::i386_cyrix_rsts, false},
{ 0x7e, OP_2BYTE|OP_MMX, &i386_device::mmx_movd_rm32_r64, &i386_device::mmx_movd_rm32_r64, false},
{ 0x7f, OP_2BYTE|OP_MMX, &i386_device::mmx_movq_rm64_r64, &i386_device::mmx_movq_rm64_r64, false},
{ 0x80, OP_2BYTE|OP_I386, &i386_device::i386_jo_rel16, &i386_device::i386_jo_rel32, false},
diff --git a/src/emu/cpu/i386/pentops.inc b/src/emu/cpu/i386/pentops.inc
index 348bd71becd..c7a341d9ba7 100644
--- a/src/emu/cpu/i386/pentops.inc
+++ b/src/emu/cpu/i386/pentops.inc
@@ -1062,6 +1062,18 @@ void i386_device::pentium_movnti_m32_r32() // Opcode 0f c3
}
}
+void i386_device::i386_cyrix_special() // Opcode 0x0f 3a-3d
+{
+/*
+0f 3a BB0_RESET (set BB0 pointer = base)
+0f 3b BB1_RESET (set BB1 pointer = base)
+0f 3c CPU_WRITE (write special CPU memory-mapped register, [ebx] = eax)
+0f 3d CPU_READ (read special CPU memory-mapped register, eax, = [ebx])
+*/
+
+ CYCLES(1);
+}
+
void i386_device::i386_cyrix_unknown() // Opcode 0x0f 74
{
logerror("Unemulated 0x0f 0x74 opcode called\n");
@@ -1970,6 +1982,262 @@ void i386_device::mmx_emms() // Opcode 0f 77
CYCLES(1); // TODO: correct cycle count
}
+void i386_device::i386_cyrix_svdc() // Opcode 0f 78
+{
+ UINT8 modrm = FETCH();
+
+ if( modrm < 0xc0 ) {
+ UINT32 ea = GetEA(modrm,0);
+ int index = (modrm >> 3) & 7;
+ int limit;
+ switch (index)
+ {
+ case 0:
+ {
+ index = ES;
+ break;
+ }
+
+ case 2:
+ {
+ index = SS;
+ break;
+ }
+
+ case 3:
+ {
+ index = DS;
+ break;
+ }
+
+ case 4:
+ {
+ index = FS;
+ break;
+ }
+
+ case 5:
+ {
+ index = GS;
+ break;
+ }
+
+ default:
+ {
+ i386_trap(6, 0, 0);
+ }
+ }
+
+ limit = m_sreg[index].limit;
+
+ if (m_sreg[index].flags & 0x8000) //G bit
+ {
+ limit >>= 12;
+ }
+
+ WRITE16(ea + 0, limit);
+ WRITE32(ea + 2, m_sreg[index].base);
+ WRITE16(ea + 5, m_sreg[index].flags); //replace top 8 bits of base
+ WRITE8(ea + 7, m_sreg[index].base >> 24);
+ WRITE16(ea + 8, m_sreg[index].selector);
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ CYCLES(1); // TODO: correct cycle count
+}
+
+void i386_device::i386_cyrix_rsdc() // Opcode 0f 79
+{
+ UINT8 modrm = FETCH();
+
+ if( modrm < 0xc0 ) {
+ UINT32 ea = GetEA(modrm,0);
+ int index = (modrm >> 3) & 7;
+ UINT16 flags;
+ UINT32 base;
+ UINT32 limit;
+ switch (index)
+ {
+ case 0:
+ {
+ index = ES;
+ break;
+ }
+
+ case 2:
+ {
+ index = SS;
+ break;
+ }
+
+ case 3:
+ {
+ index = DS;
+ break;
+ }
+
+ case 4:
+ {
+ index = FS;
+ break;
+ }
+
+ case 5:
+ {
+ index = GS;
+ break;
+ }
+
+ default:
+ {
+ i386_trap(6, 0, 0);
+ }
+ }
+
+ base = (READ32(ea + 2) & 0x00ffffff) | (READ8(ea + 7) << 24);
+ flags = READ16(ea + 5);
+ limit = READ16(ea + 0) | ((flags & 3) << 16);
+
+ if (flags & 0x8000) //G bit
+ {
+ limit = (limit << 12) | 0xfff;
+ }
+
+ m_sreg[index].selector = READ16(ea + 8);
+ m_sreg[index].flags = flags;
+ m_sreg[index].base = base;
+ m_sreg[index].limit = limit;
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ CYCLES(1); // TODO: correct cycle count
+}
+
+void i386_device::i386_cyrix_svldt() // Opcode 0f 7a
+{
+ if ( PROTECTED_MODE && !V8086_MODE )
+ {
+ UINT8 modrm = FETCH();
+
+ if( !(modrm & 0xf8) ) {
+ UINT32 ea = GetEA(modrm,0);
+ UINT32 limit = m_ldtr.limit;
+
+ if (m_ldtr.flags & 0x8000) //G bit
+ {
+ limit >>= 12;
+ }
+
+ WRITE16(ea + 0, limit);
+ WRITE32(ea + 2, m_ldtr.base);
+ WRITE16(ea + 5, m_ldtr.flags); //replace top 8 bits of base
+ WRITE8(ea + 7, m_ldtr.base >> 24);
+ WRITE16(ea + 8, m_ldtr.segment);
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ CYCLES(1); // TODO: correct cycle count
+}
+
+void i386_device::i386_cyrix_rsldt() // Opcode 0f 7b
+{
+ if ( PROTECTED_MODE && !V8086_MODE )
+ {
+ if(m_CPL)
+ FAULT(FAULT_GP,0)
+
+ UINT8 modrm = FETCH();
+
+ if( !(modrm & 0xf8) ) {
+ UINT32 ea = GetEA(modrm,0);
+ UINT16 flags = READ16(ea + 5);
+ UINT32 base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24);
+ UINT32 limit = READ16(ea + 0) | ((flags & 3) << 16);
+ I386_SREG seg;
+
+ if (flags & 0x8000) //G bit
+ {
+ limit = (limit << 12) | 0xfff;
+ }
+
+ memset(&seg, 0, sizeof(seg));
+ seg.selector = READ16(ea + 8);
+ i386_load_protected_mode_segment(&seg,NULL);
+ m_ldtr.limit = limit;
+ m_ldtr.base = base;
+ m_ldtr.flags = flags;
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ CYCLES(1); // TODO: correct cycle count
+}
+
+void i386_device::i386_cyrix_svts() // Opcode 0f 7c
+{
+ if ( PROTECTED_MODE )
+ {
+ UINT8 modrm = FETCH();
+
+ if( !(modrm & 0xf8) ) {
+ UINT32 ea = GetEA(modrm,0);
+ UINT32 limit = m_task.limit;
+
+ if (m_task.flags & 0x8000) //G bit
+ {
+ limit >>= 12;
+ }
+
+ WRITE16(ea + 0, limit);
+ WRITE32(ea + 2, m_task.base);
+ WRITE16(ea + 5, m_task.flags); //replace top 8 bits of base
+ WRITE8(ea + 7, m_task.base >> 24);
+ WRITE16(ea + 8, m_task.segment);
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ } else {
+ i386_trap(6, 0, 0);
+ }
+}
+
+void i386_device::i386_cyrix_rsts() // Opcode 0f 7d
+{
+ if ( PROTECTED_MODE )
+ {
+ if(m_CPL)
+ FAULT(FAULT_GP,0)
+
+ UINT8 modrm = FETCH();
+
+ if( !(modrm & 0xf8) ) {
+ UINT32 ea = GetEA(modrm,0);
+ UINT16 flags = READ16(ea + 5);
+ UINT32 base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24);
+ UINT32 limit = READ16(ea + 0) | ((flags & 3) << 16);
+
+ if (flags & 0x8000) //G bit
+ {
+ limit = (limit << 12) | 0xfff;
+ }
+ m_task.segment = READ16(ea + 8);
+ m_task.limit = limit;
+ m_task.base = base;
+ m_task.flags = flags;
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ } else {
+ i386_trap(6, 0, 0);
+ }
+ CYCLES(1); // TODO: correct cycle count
+}
+
void i386_device::mmx_movd_r64_rm32() // Opcode 0f 6e
{
MMXPROLOG();
diff --git a/src/mame/drivers/pinball2k.c b/src/mame/drivers/pinball2k.c
index 71c16c3f2b1..6cdb658cc34 100644
--- a/src/mame/drivers/pinball2k.c
+++ b/src/mame/drivers/pinball2k.c
@@ -9,8 +9,8 @@
- MediaGX features should be moved out to machine/ and shared with mediagx.c once we know what these games need
Hardware:
- - Cyrix MediaGX processor/VGA
- - Cyrix CX5520 northbridge?
+ - Cyrix MediaGX processor/VGA (northbridge)
+ - Cyrix CX5520 (southbridge)
- VS9824AG SuperI/O standard PC I/O chip
- 1 ISA, 2 PCI slots, 2 IDE headers
- "Prism" PCI card with PLX PCI9052 PCI-to-random stuff bridge
@@ -83,6 +83,10 @@ public:
DECLARE_WRITE32_MEMBER(ad1847_w);
DECLARE_READ8_MEMBER(io20_r);
DECLARE_WRITE8_MEMBER(io20_w);
+ DECLARE_READ32_MEMBER(port400_r);
+ DECLARE_WRITE32_MEMBER(port400_w);
+ DECLARE_READ32_MEMBER(port800_r);
+ DECLARE_WRITE32_MEMBER(port800_w);
DECLARE_DRIVER_INIT(pinball2k);
virtual void machine_start();
virtual void machine_reset();
@@ -415,6 +419,24 @@ WRITE8_MEMBER(pinball2k_state::io20_w)
}
}
+READ32_MEMBER(pinball2k_state::port400_r)
+{
+ return 0x8000;
+}
+
+WRITE32_MEMBER(pinball2k_state::port400_w)
+{
+}
+
+READ32_MEMBER(pinball2k_state::port800_r)
+{
+ return 0x80;
+}
+
+WRITE32_MEMBER(pinball2k_state::port800_w)
+{
+}
+
READ32_MEMBER(pinball2k_state::parallel_port_r)
{
UINT32 r = 0;
@@ -467,6 +489,8 @@ static ADDRESS_MAP_START(mediagx_io, AS_IO, 32, pinball2k_state )
AM_IMPORT_FROM(pcat32_io_common)
AM_RANGE(0x00e8, 0x00eb) AM_NOP // I/O delay port
AM_RANGE(0x0378, 0x037b) AM_READWRITE(parallel_port_r, parallel_port_w)
+ AM_RANGE(0x0400, 0x0403) AM_READWRITE(port400_r, port400_w)
+ AM_RANGE(0x0800, 0x0803) AM_READWRITE(port800_r, port800_w)
AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write)
ADDRESS_MAP_END