diff --git a/src/devices/cpu/i86/i186.cpp b/src/devices/cpu/i86/i186.cpp index 58fcec3c2161c..cb3ae45f52674 100644 --- a/src/devices/cpu/i86/i186.cpp +++ b/src/devices/cpu/i86/i186.cpp @@ -167,6 +167,9 @@ i80186_cpu_device::i80186_cpu_device(const machine_config &mconfig, device_type , m_irmx_irq_ack(*this) { memcpy(m_timing, m_i80186_timing, sizeof(m_i80186_timing)); + // The Effective Address calculation times are already included in the + // instruction timings for the 80186, so fill the table with zeros. + memset(m_ea_timing, 0, sizeof(m_i80186_ea_timing)); set_irq_acknowledge_callback(*this, FUNC(i80186_cpu_device::inta_callback)); } diff --git a/src/devices/cpu/i86/i186.h b/src/devices/cpu/i86/i186.h index ea15d15c48624..2826e02fcbc72 100644 --- a/src/devices/cpu/i86/i186.h +++ b/src/devices/cpu/i86/i186.h @@ -85,6 +85,7 @@ class i80186_cpu_device : public i8086_common_cpu_device virtual void write_word(uint32_t addr, uint16_t data) override; static const uint8_t m_i80186_timing[200]; + static const uint8_t m_i80186_ea_timing[200]; private: void update_interrupt_state(); diff --git a/src/devices/cpu/i86/i286.cpp b/src/devices/cpu/i86/i286.cpp index bfe4dc7c72831..7ba394b99893e 100644 --- a/src/devices/cpu/i86/i286.cpp +++ b/src/devices/cpu/i86/i286.cpp @@ -114,9 +114,9 @@ const uint8_t i80286_cpu_device::m_i80286_timing[] = 5, 5, 5, 5, /* port reads */ 3, 3, 3, 3, /* port writes */ - 2, 3, 3, /* move, 8-bit */ + 2, 5, 3, /* move, 8-bit */ 2, 3, /* move, 8-bit immediate */ - 2, 3, 3, /* move, 16-bit */ + 2, 5, 3, /* move, 16-bit */ 2, 3, /* move, 16-bit immediate */ 5, 5, 3, 3, /* move, AL/AX memory */ 2, 5, 2, 3, /* move, segment registers */ @@ -164,6 +164,25 @@ const uint8_t i80286_cpu_device::m_i80286_timing[] = 13, /* (80186) BOUND */ }; +// Effective Address calculation takes one extra clock if offset calculation +// requires summing 3 elements. +const uint8_t i80286_cpu_device::m_i80286_ea_timing[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + DEFINE_DEVICE_TYPE(I80286, i80286_cpu_device, "i80286", "Intel 80286") i80286_cpu_device::i80286_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -175,6 +194,7 @@ i80286_cpu_device::i80286_cpu_device(const machine_config &mconfig, const char * , m_out_shutdown_func(*this) { memcpy(m_timing, m_i80286_timing, sizeof(m_i80286_timing)); + memcpy(m_ea_timing, m_i80286_ea_timing, sizeof(m_i80286_ea_timing)); m_amask = 0xffffff; memset(m_sregs, 0x00, sizeof(m_sregs)); m_sregs[CS] = 0xf000; diff --git a/src/devices/cpu/i86/i286.h b/src/devices/cpu/i86/i286.h index cceb66fc931d8..aacd4ed01c2af 100644 --- a/src/devices/cpu/i86/i286.h +++ b/src/devices/cpu/i86/i286.h @@ -150,6 +150,7 @@ class i80286_cpu_device : public i8086_common_cpu_device address_space_config m_opcodes_config; address_space_config m_io_config; static const uint8_t m_i80286_timing[200]; + static const uint8_t m_i80286_ea_timing[200]; enum { FAULT_DE = 0, diff --git a/src/devices/cpu/i86/i86.cpp b/src/devices/cpu/i86/i86.cpp index 846fe02eda96d..fca50dceb7627 100644 --- a/src/devices/cpu/i86/i86.cpp +++ b/src/devices/cpu/i86/i86.cpp @@ -80,6 +80,23 @@ const uint8_t i8086_cpu_device::m_i8086_timing[] = 18, 9,17, /* MOVS 16-bit */ }; +const uint8_t i8086_cpu_device::m_i8086_ea_timing[] = +{ + 7, 8, 8, 7, 5, 5, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 12, 11, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 11, 11, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + /***************************************************************************/ /* cpu state */ /***************************************************************************/ @@ -94,6 +111,7 @@ i8088_cpu_device::i8088_cpu_device(const machine_config &mconfig, const char *ta : i8086_cpu_device(mconfig, I8088, tag, owner, clock, 8) { memcpy(m_timing, m_i8086_timing, sizeof(m_i8086_timing)); + memcpy(m_ea_timing, m_i8086_ea_timing, sizeof(m_i8086_ea_timing)); } i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -1504,28 +1522,28 @@ bool i8086_common_cpu_device::common_op(uint8_t op) m_modrm = fetch(); m_src = RegByte(); PutRMByte(m_src); - CLKM(ALU_RR8,ALU_MR8); + CLKM(MOV_RR8,MOV_MR8); break; case 0x89: // i_mov_wr16 m_modrm = fetch(); m_src = RegWord(); PutRMWord(m_src); - CLKM(ALU_RR16,ALU_MR16); + CLKM(MOV_RR16,MOV_MR16); break; case 0x8a: // i_mov_r8b m_modrm = fetch(); m_src = GetRMByte(); RegByte(m_src); - CLKM(ALU_RR8,ALU_RM8); + CLKM(MOV_RR8,MOV_RM8); break; case 0x8b: // i_mov_r16w m_modrm = fetch(); m_src = GetRMWord(); RegWord(m_src); - CLKM(ALU_RR16,ALU_RM16); + CLKM(MOV_RR16,MOV_RM16); break; case 0x8c: // i_mov_wsreg diff --git a/src/devices/cpu/i86/i86.h b/src/devices/cpu/i86/i86.h index 3ceb94f672d29..50c616c661497 100644 --- a/src/devices/cpu/i86/i86.h +++ b/src/devices/cpu/i86/i86.h @@ -330,6 +330,7 @@ class i8086_common_cpu_device : public cpu_device, public i386_disassembler::con } m_Mod_RM; uint8_t m_timing[200]; + uint8_t m_ea_timing[200]; bool m_halt; bool m_lock; @@ -372,6 +373,7 @@ class i8086_cpu_device : public i8086_common_cpu_device address_space_config m_extra_config; address_space_config m_io_config; static const uint8_t m_i8086_timing[200]; + static const uint8_t m_i8086_ea_timing[200]; devcb_write_line m_out_if_func; devcb_write32 m_esc_opcode_handler; devcb_write32 m_esc_data_handler; diff --git a/src/devices/cpu/i86/i86inline.h b/src/devices/cpu/i86/i86inline.h index fb14cbcdee865..15a3aef2881cd 100644 --- a/src/devices/cpu/i86/i86inline.h +++ b/src/devices/cpu/i86/i86inline.h @@ -76,140 +76,118 @@ inline void i8086_common_cpu_device::CLKM(uint8_t op_reg, uint8_t op_mem) inline uint32_t i8086_common_cpu_device::get_ea(int size, int op) { uint16_t e16; + uint8_t modrm = m_modrm & 0xc7; - switch( m_modrm & 0xc7 ) + switch( modrm ) { case 0x00: - m_icount -= 7; m_eo = m_regs.w[BX] + m_regs.w[SI]; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x01: - m_icount -= 8; m_eo = m_regs.w[BX] + m_regs.w[DI]; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x02: - m_icount -= 8; m_eo = m_regs.w[BP] + m_regs.w[SI]; m_ea = calc_addr(SS, m_eo, size, op); break; case 0x03: - m_icount -= 7; m_eo = m_regs.w[BP] + m_regs.w[DI]; m_ea = calc_addr(SS, m_eo, size, op); break; case 0x04: - m_icount -= 5; m_eo = m_regs.w[SI]; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x05: - m_icount -= 5; m_eo = m_regs.w[DI]; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x06: - m_icount -= 6; m_eo = fetch_word(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x07: - m_icount -= 5; m_eo = m_regs.w[BX]; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x40: - m_icount -= 11; m_eo = m_regs.w[BX] + m_regs.w[SI] + (int8_t)fetch(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x41: - m_icount -= 12; m_eo = m_regs.w[BX] + m_regs.w[DI] + (int8_t)fetch(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x42: - m_icount -= 12; m_eo = m_regs.w[BP] + m_regs.w[SI] + (int8_t)fetch(); m_ea = calc_addr(SS, m_eo, size, op); break; case 0x43: - m_icount -= 11; m_eo = m_regs.w[BP] + m_regs.w[DI] + (int8_t)fetch(); m_ea = calc_addr(SS, m_eo, size, op); break; case 0x44: - m_icount -= 9; m_eo = m_regs.w[SI] + (int8_t)fetch(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x45: - m_icount -= 9; m_eo = m_regs.w[DI] + (int8_t)fetch(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x46: - m_icount -= 9; m_eo = m_regs.w[BP] + (int8_t)fetch(); m_ea = calc_addr(SS, m_eo, size, op); break; case 0x47: - m_icount -= 9; m_eo = m_regs.w[BX] + (int8_t)fetch(); m_ea = calc_addr(DS, m_eo, size, op); break; case 0x80: - m_icount -= 11; e16 = fetch_word(); m_eo = m_regs.w[BX] + m_regs.w[SI] + (int16_t)e16; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x81: - m_icount -= 12; e16 = fetch_word(); m_eo = m_regs.w[BX] + m_regs.w[DI] + (int16_t)e16; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x82: - m_icount -= 11; e16 = fetch_word(); m_eo = m_regs.w[BP] + m_regs.w[SI] + (int16_t)e16; m_ea = calc_addr(SS, m_eo, size, op); break; case 0x83: - m_icount -= 11; e16 = fetch_word(); m_eo = m_regs.w[BP] + m_regs.w[DI] + (int16_t)e16; m_ea = calc_addr(SS, m_eo, size, op); break; case 0x84: - m_icount -= 9; e16 = fetch_word(); m_eo = m_regs.w[SI] + (int16_t)e16; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x85: - m_icount -= 9; e16 = fetch_word(); m_eo = m_regs.w[DI] + (int16_t)e16; m_ea = calc_addr(DS, m_eo, size, op); break; case 0x86: - m_icount -= 9; e16 = fetch_word(); m_eo = m_regs.w[BP] + (int16_t)e16; m_ea = calc_addr(SS, m_eo, size, op); break; case 0x87: - m_icount -= 9; e16 = fetch_word(); m_eo = m_regs.w[BX] + (int16_t)e16; m_ea = calc_addr(DS, m_eo, size, op); break; } + m_icount -= m_ea_timing[modrm]; return m_ea; }