static void I486OP(cmpxchg_rm16_r16)(i386_state *cpustate) // Opcode 0x0f b1 { UINT8 modrm = FETCH(cpustate); if( modrm >= 0xc0 ) { UINT16 dst = LOAD_RM16(modrm); UINT16 src = LOAD_REG16(modrm); if( REG16(AX) == dst ) { STORE_RM16(modrm, src); cpustate->ZF = 1; CYCLES(cpustate,CYCLES_CMPXCHG_REG_REG_T); } else { REG16(AX) = dst; cpustate->ZF = 0; CYCLES(cpustate,CYCLES_CMPXCHG_REG_REG_F); } } else { UINT32 ea = GetEA(cpustate,modrm); UINT16 dst = READ16(cpustate,ea); UINT16 src = LOAD_REG16(modrm); if( REG16(AX) == dst ) { WRITE16(cpustate,modrm, src); cpustate->ZF = 1; CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_T); } else { REG16(AX) = dst; cpustate->ZF = 0; CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_F); } } }
void i386_device::i486_cmpxchg_rm16_r16() // Opcode 0x0f b1 { UINT8 modrm = FETCH(); if( modrm >= 0xc0 ) { UINT16 dst = LOAD_RM16(modrm); UINT16 src = LOAD_REG16(modrm); if( REG16(AX) == dst ) { STORE_RM16(modrm, src); m_ZF = 1; CYCLES(CYCLES_CMPXCHG_REG_REG_T); } else { REG16(AX) = dst; m_ZF = 0; CYCLES(CYCLES_CMPXCHG_REG_REG_F); } } else { UINT32 ea = GetEA(modrm,0); UINT16 dst = READ16(ea); UINT16 src = LOAD_REG16(modrm); if( REG16(AX) == dst ) { WRITE16(ea, src); m_ZF = 1; CYCLES(CYCLES_CMPXCHG_REG_MEM_T); } else { REG16(AX) = dst; m_ZF = 0; CYCLES(CYCLES_CMPXCHG_REG_MEM_F); } } }
static void I486OP(xadd_rm16_r16)(i386_state *cpustate) // Opcode 0x0f c1 { UINT8 modrm = FETCH(cpustate); if( modrm >= 0xc0 ) { UINT16 dst = LOAD_RM16(modrm); UINT16 src = LOAD_REG16(modrm); STORE_RM16(modrm, dst + src); STORE_REG16(modrm, dst); CYCLES(cpustate,CYCLES_XADD_REG_REG); } else { UINT32 ea = GetEA(cpustate,modrm); UINT16 dst = READ16(cpustate,ea); UINT16 src = LOAD_REG16(modrm); WRITE16(cpustate,ea, dst + src); STORE_REG16(modrm, dst); CYCLES(cpustate,CYCLES_XADD_REG_MEM); } }
static void I486OP(xadd_rm8_r8)(i386_state *cpustate) // Opcode 0x0f c0 { UINT8 modrm = FETCH(cpustate); if( modrm >= 0xc0 ) { UINT8 dst = LOAD_RM8(modrm); UINT8 src = LOAD_REG8(modrm); STORE_RM16(modrm, dst + src); STORE_REG16(modrm, dst); CYCLES(cpustate,CYCLES_XADD_REG_REG); } else { UINT32 ea = GetEA(cpustate,modrm,1); UINT8 dst = READ8(cpustate,ea); UINT8 src = LOAD_REG8(modrm); WRITE8(cpustate,ea, dst + src); STORE_REG8(modrm, dst); CYCLES(cpustate,CYCLES_XADD_REG_MEM); } }
void i386_device::i486_xadd_rm16_r16() // Opcode 0x0f c1 { UINT8 modrm = FETCH(); if( modrm >= 0xc0 ) { UINT16 dst = LOAD_RM16(modrm); UINT16 src = LOAD_REG16(modrm); STORE_REG16(modrm, dst); STORE_RM16(modrm, dst + src); CYCLES(CYCLES_XADD_REG_REG); } else { UINT32 ea = GetEA(modrm,1); UINT16 dst = READ16(ea); UINT16 src = LOAD_REG16(modrm); WRITE16(ea, dst + src); STORE_REG16(modrm, dst); CYCLES(CYCLES_XADD_REG_MEM); } }
static void I486OP(group0F01_16)(i386_state *cpustate) // Opcode 0x0f 01 { UINT8 modrm = FETCH(cpustate); UINT16 address; UINT32 ea; switch( (modrm >> 3) & 0x7 ) { case 0: /* SGDT */ { if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address ); } else { ea = GetEA(cpustate,modrm); } WRITE16(cpustate,ea, cpustate->gdtr.limit); WRITE32(cpustate,ea + 2, cpustate->gdtr.base & 0xffffff); CYCLES(cpustate,CYCLES_SGDT); break; } case 1: /* SIDT */ { if (modrm >= 0xc0) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address ); } else { ea = GetEA(cpustate,modrm); } WRITE16(cpustate,ea, cpustate->idtr.limit); WRITE32(cpustate,ea + 2, cpustate->idtr.base & 0xffffff); CYCLES(cpustate,CYCLES_SIDT); break; } case 2: /* LGDT */ { if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address ); } else { ea = GetEA(cpustate,modrm); } cpustate->gdtr.limit = READ16(cpustate,ea); cpustate->gdtr.base = READ32(cpustate,ea + 2) & 0xffffff; CYCLES(cpustate,CYCLES_LGDT); break; } case 3: /* LIDT */ { if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address ); } else { ea = GetEA(cpustate,modrm); } cpustate->idtr.limit = READ16(cpustate,ea); cpustate->idtr.base = READ32(cpustate,ea + 2) & 0xffffff; CYCLES(cpustate,CYCLES_LIDT); break; } case 4: /* SMSW */ { if( modrm >= 0xc0 ) { STORE_RM16(modrm, cpustate->cr[0]); CYCLES(cpustate,CYCLES_SMSW_REG); } else { ea = GetEA(cpustate,modrm); WRITE16(cpustate,ea, cpustate->cr[0]); CYCLES(cpustate,CYCLES_SMSW_MEM); } break; } case 6: /* LMSW */ { // TODO: Check for protection fault UINT8 b; if( modrm >= 0xc0 ) { b = LOAD_RM8(modrm); CYCLES(cpustate,CYCLES_LMSW_REG); } else { ea = GetEA(cpustate,modrm); CYCLES(cpustate,CYCLES_LMSW_MEM); b = READ8(cpustate,ea); } cpustate->cr[0] &= ~0x03; cpustate->cr[0] |= b & 0x03; break; } case 7: /* INVLPG */ { // Nothing to do ? break; } default: fatalerror("i486: unimplemented opcode 0x0f 01 /%d at %08X", (modrm >> 3) & 0x7, cpustate->eip - 2); break; } }
void i386_device::i486_group0F01_16() // Opcode 0x0f 01 { UINT8 modrm = FETCH(); UINT16 address; UINT32 ea; switch( (modrm >> 3) & 0x7 ) { case 0: /* SGDT */ { if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( CS, address, 1 ); } else { ea = GetEA(modrm,1); } WRITE16(ea, m_gdtr.limit); WRITE32(ea + 2, m_gdtr.base & 0xffffff); CYCLES(CYCLES_SGDT); break; } case 1: /* SIDT */ { if (modrm >= 0xc0) { address = LOAD_RM16(modrm); ea = i386_translate( CS, address, 1 ); } else { ea = GetEA(modrm,1); } WRITE16(ea, m_idtr.limit); WRITE32(ea + 2, m_idtr.base & 0xffffff); CYCLES(CYCLES_SIDT); break; } case 2: /* LGDT */ { if(PROTECTED_MODE && m_CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( CS, address, 0 ); } else { ea = GetEA(modrm,0); } m_gdtr.limit = READ16(ea); m_gdtr.base = READ32(ea + 2) & 0xffffff; CYCLES(CYCLES_LGDT); break; } case 3: /* LIDT */ { if(PROTECTED_MODE && m_CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( CS, address, 0 ); } else { ea = GetEA(modrm,0); } m_idtr.limit = READ16(ea); m_idtr.base = READ32(ea + 2) & 0xffffff; CYCLES(CYCLES_LIDT); break; } case 4: /* SMSW */ { if( modrm >= 0xc0 ) { STORE_RM16(modrm, m_cr[0]); CYCLES(CYCLES_SMSW_REG); } else { ea = GetEA(modrm,1); WRITE16(ea, m_cr[0]); CYCLES(CYCLES_SMSW_MEM); } break; } case 6: /* LMSW */ { UINT16 b; if(PROTECTED_MODE && m_CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { b = LOAD_RM16(modrm); CYCLES(CYCLES_LMSW_REG); } else { ea = GetEA(modrm,0); CYCLES(CYCLES_LMSW_MEM); b = READ16(ea); } if(PROTECTED_MODE) b |= 0x0001; // cannot return to real mode using this instruction. m_cr[0] &= ~0x0000000f; m_cr[0] |= b & 0x0000000f; break; } case 7: /* INVLPG */ { if(PROTECTED_MODE && m_CPL) FAULT(FAULT_GP,0) if(modrm >= 0xc0) { logerror("i486: invlpg with modrm %02X\n", modrm); FAULT(FAULT_UD,0) } ea = GetEA(modrm,-1); CYCLES(25); // TODO: add to cycles.h vtlb_flush_address(m_vtlb, ea); break; } default: report_invalid_modrm("group0F01_16", modrm); break; }
static void I486OP(group0F01_16)(i386_state *cpustate) // Opcode 0x0f 01 { UINT8 modrm = FETCH(cpustate); UINT16 address; UINT32 ea; switch( (modrm >> 3) & 0x7 ) { case 0: /* SGDT */ { if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address, 1 ); } else { ea = GetEA(cpustate,modrm,1); } WRITE16(cpustate,ea, cpustate->gdtr.limit); WRITE32(cpustate,ea + 2, cpustate->gdtr.base & 0xffffff); CYCLES(cpustate,CYCLES_SGDT); break; } case 1: /* SIDT */ { if (modrm >= 0xc0) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address, 1 ); } else { ea = GetEA(cpustate,modrm,1); } WRITE16(cpustate,ea, cpustate->idtr.limit); WRITE32(cpustate,ea + 2, cpustate->idtr.base & 0xffffff); CYCLES(cpustate,CYCLES_SIDT); break; } case 2: /* LGDT */ { if(PROTECTED_MODE && cpustate->CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address, 0 ); } else { ea = GetEA(cpustate,modrm,0); } cpustate->gdtr.limit = READ16(cpustate,ea); cpustate->gdtr.base = READ32(cpustate,ea + 2) & 0xffffff; CYCLES(cpustate,CYCLES_LGDT); break; } case 3: /* LIDT */ { if(PROTECTED_MODE && cpustate->CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { address = LOAD_RM16(modrm); ea = i386_translate( cpustate, CS, address, 0 ); } else { ea = GetEA(cpustate,modrm,0); } cpustate->idtr.limit = READ16(cpustate,ea); cpustate->idtr.base = READ32(cpustate,ea + 2) & 0xffffff; CYCLES(cpustate,CYCLES_LIDT); break; } case 4: /* SMSW */ { if( modrm >= 0xc0 ) { STORE_RM16(modrm, cpustate->cr[0]); CYCLES(cpustate,CYCLES_SMSW_REG); } else { ea = GetEA(cpustate,modrm,1); WRITE16(cpustate,ea, cpustate->cr[0]); CYCLES(cpustate,CYCLES_SMSW_MEM); } break; } case 6: /* LMSW */ { UINT16 b; if(PROTECTED_MODE && cpustate->CPL) FAULT(FAULT_GP,0) if( modrm >= 0xc0 ) { b = LOAD_RM16(modrm); CYCLES(cpustate,CYCLES_LMSW_REG); } else { ea = GetEA(cpustate,modrm,0); CYCLES(cpustate,CYCLES_LMSW_MEM); b = READ16(cpustate,ea); } if(PROTECTED_MODE) b |= 0x0001; // cannot return to real mode using this instruction. cpustate->cr[0] &= ~0x0000000f; cpustate->cr[0] |= b & 0x0000000f; break; } case 7: /* INVLPG */ { // Nothing to do ? break; } default: fatalerror("i486: unimplemented opcode 0x0f 01 /%d at %08X", (modrm >> 3) & 0x7, cpustate->eip - 2); break; } }