From e9a84bc89ebe8b5b79de4726ff84ea9b1ea92935 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sun, 12 May 2019 10:31:37 +0200 Subject: -ioc2: Fixed mappable interrupt checks. Fixes IRIX 6.5 installer hanging on keyboard input. [Ryan Holtz] -r4000: Changed LL/SC behaviour to not use a write tap. Possibly incorrect behaviour, but IRIX 6.5 installer doesn't hang anymore on miniroot creation, nw --- src/devices/cpu/mips/r4000.cpp | 52 ++++---------------------- src/devices/cpu/mips/r4000.h | 2 +- src/mame/machine/hpc3.cpp | 8 ++-- src/mame/machine/ioc2.cpp | 83 +++++++++++++++--------------------------- src/mame/machine/ioc2.h | 5 ++- 5 files changed, 46 insertions(+), 104 deletions(-) diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp index 8b220b2b67f..dac528ee1e6 100644 --- a/src/devices/cpu/mips/r4000.cpp +++ b/src/devices/cpu/mips/r4000.cpp @@ -91,7 +91,7 @@ r4000_base_device::r4000_base_device(const machine_config &mconfig, device_type : cpu_device(mconfig, type, tag, owner, clock) , m_program_config_le("program", ENDIANNESS_LITTLE, 64, 32) , m_program_config_be("program", ENDIANNESS_BIG, 64, 32) - , m_ll_watch(nullptr) + , m_ll_active(false) , m_fcr0(0x00000500U) { m_cp0[CP0_PRId] = prid; @@ -200,11 +200,7 @@ void r4000_base_device::device_reset() m_cp0_timer_zero = total_cycles(); - if (m_ll_watch) - { - m_ll_watch->remove(); - m_ll_watch = nullptr; - } + m_ll_active = false; m_cp0[CP0_WatchLo] = 0; m_cp0[CP0_WatchHi] = 0; @@ -1033,24 +1029,10 @@ void r4000_base_device::cpu_execute(u32 const op) load_linked(ADDR(m_r[RSREG], s16(op)), [this, op](u64 address, s32 data) { - // remove existing tap - if (m_ll_watch) - m_ll_watch->remove(); - m_r[RTREG] = data; m_cp0[CP0_LLAddr] = u32(address >> 4); - // install write tap - // FIXME: physical address truncation - m_ll_watch = space(0).install_write_tap(offs_t(address & ~7), offs_t(address | 7), "ll", - [this, hi(bool(BIT(address, 2)))](offs_t offset, u64 &data, u64 mem_mask) - { - if (hi ? ACCESSING_BITS_32_63 : ACCESSING_BITS_0_31) - { - m_ll_watch->remove(); - m_ll_watch = nullptr; - } - }); + m_ll_active = true; m_ll_addr = ADDR(m_r[RSREG], s16(op)); }); break; @@ -1066,20 +1048,10 @@ void r4000_base_device::cpu_execute(u32 const op) [this, op](u64 address, u64 data) { // remove existing tap - if (m_ll_watch) - m_ll_watch->remove(); - m_r[RTREG] = data; m_cp0[CP0_LLAddr] = u32(address >> 4); - // install write tap - // FIXME: address truncation - m_ll_watch = space(0).install_write_tap(offs_t(address & ~7), offs_t(address | 7), "lld", - [this](offs_t offset, u64 &data, u64 mem_mask) - { - m_ll_watch->remove(); - m_ll_watch = nullptr; - }); + m_ll_active = true; m_ll_addr = ADDR(m_r[RSREG], s16(op)); }); break; @@ -1097,10 +1069,9 @@ void r4000_base_device::cpu_execute(u32 const op) }); break; case 0x38: // SC - if (m_ll_watch && m_ll_addr == ADDR(m_r[RSREG], s16(op))) + if (m_ll_active && m_ll_addr == ADDR(m_r[RSREG], s16(op))) { - m_ll_watch->remove(); - m_ll_watch = nullptr; + m_ll_active = false; store(ADDR(m_r[RSREG], s16(op)), u32(m_r[RTREG])); m_r[RTREG] = 1; @@ -1116,11 +1087,8 @@ void r4000_base_device::cpu_execute(u32 const op) break; //case 0x3b: // * case 0x3c: // SCD - if (m_ll_watch && m_ll_addr == ADDR(m_r[RSREG], s16(op))) + if (m_ll_active && m_ll_addr == ADDR(m_r[RSREG], s16(op))) { - m_ll_watch->remove(); - m_ll_watch = nullptr; - store(ADDR(m_r[RSREG], s16(op)), m_r[RTREG]); m_r[RTREG] = 1; } @@ -1358,11 +1326,7 @@ void r4000_base_device::cp0_execute(u32 const op) SR &= ~SR_EXL; } - if (m_ll_watch) - { - m_ll_watch->remove(); - m_ll_watch = nullptr; - } + m_ll_active = false; break; default: diff --git a/src/devices/cpu/mips/r4000.h b/src/devices/cpu/mips/r4000.h index 217df45ecb6..156af91eb41 100644 --- a/src/devices/cpu/mips/r4000.h +++ b/src/devices/cpu/mips/r4000.h @@ -394,7 +394,7 @@ protected: u64 m_cp0[32]; u64 m_cp0_timer_zero; emu_timer *m_cp0_timer; - memory_passthrough_handler *m_ll_watch; + bool m_ll_active; u64 m_ll_addr; struct tlb_entry_t { diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp index 8cc75dfa594..164c6c933fc 100644 --- a/src/mame/machine/hpc3.cpp +++ b/src/mame/machine/hpc3.cpp @@ -414,11 +414,11 @@ READ32_MEMBER(hpc3_device::pbus4_r) break; case 0x0014/4: ret = m_ioc2->get_map_int_mask(0); - LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 0 Mask Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); break; case 0x0018/4: ret = m_ioc2->get_map_int_mask(1); - LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); + LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 1 Mask Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); break; case 0x0030/4: ret = m_ioc2->get_pit_reg(0); @@ -457,11 +457,11 @@ WRITE32_MEMBER(hpc3_device::pbus4_w) break; case 0x0014/4: m_ioc2->set_map_int_mask(0, data); - LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 0 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); break; case 0x0018/4: m_ioc2->set_map_int_mask(1, data); - LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + LOGMASKED(LOG_PBUS4, "%s: HPC3 INT3 Mapped Interrupt 1 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); break; case 0x0020/4: m_ioc2->set_timer_int_clear(data); diff --git a/src/mame/machine/ioc2.cpp b/src/mame/machine/ioc2.cpp index ff9c9fc80a9..5c5d1b3355b 100644 --- a/src/mame/machine/ioc2.cpp +++ b/src/mame/machine/ioc2.cpp @@ -23,7 +23,7 @@ #define LOG_PIT (1 << 10) #define LOG_IRQS (1 << 11) #define LOG_ALL (LOG_PI1 | LOG_SERIAL | LOG_MOUSEKBD | LOG_PANEL | LOG_SYSID | LOG_READ | LOG_DMA_SEL | LOG_RESET | LOG_WRITE | LOG_INT3 | LOG_PIT | LOG_IRQS) -#define LOG_DEFAULT (LOG_ALL & ~(LOG_SYSID | LOG_MOUSEKBD)) +#define LOG_DEFAULT (LOG_ALL & ~(LOG_SYSID)) #define VERBOSE (0) #include "logmacro.h" @@ -238,23 +238,31 @@ void ioc2_device::set_mappable_int(uint8_t mask, bool state) const uint8_t new0 = m_int3_map_mask_reg[0] & m_int3_map_status_reg; if (old0 ^ new0) { - LOGMASKED(LOG_IRQS, "%sing Mappable interrupt mask %02x, interrupt status was %02x, now %02x, %sing mappable0\n", state ? "Rais" : "Lower", mask, old, - m_int3_map_status_reg, (m_int3_map_mask_reg[0] & m_int3_map_status_reg) ? "rais" : "lower"); - if (m_int3_map_mask_reg[0] & m_int3_map_status_reg) - raise_local_irq(0, INT3_LOCAL0_MAPPABLE0); - else - lower_local_irq(0, INT3_LOCAL0_MAPPABLE0); + check_mappable_interrupt(0); } const uint8_t new1 = m_int3_map_mask_reg[1] & m_int3_map_status_reg; if (old1 ^ new1) { - LOGMASKED(LOG_IRQS, "%sing Mappable interrupt mask %02x, interrupt status was %02x, now %02x, %sing mappable1\n", state ? "Rais" : "Lower", mask, old, - m_int3_map_status_reg, (m_int3_map_mask_reg[0] & m_int3_map_status_reg) ? "rais" : "lower"); - if (m_int3_map_mask_reg[1] & m_int3_map_status_reg) - raise_local_irq(1, INT3_LOCAL1_MAPPABLE1); + check_mappable_interrupt(1); + } +} + +void ioc2_device::check_mappable_interrupt(int channel) +{ + if (channel == 0) + { + if (m_int3_map_mask_reg[channel] & m_int3_map_status_reg) + raise_local_irq(channel, INT3_LOCAL0_MAPPABLE0); + else + lower_local_irq(channel, INT3_LOCAL0_MAPPABLE0); + } + else + { + if (m_int3_map_mask_reg[channel] & m_int3_map_status_reg) + raise_local_irq(channel, INT3_LOCAL1_MAPPABLE1); else - lower_local_irq(1, INT3_LOCAL1_MAPPABLE1); + lower_local_irq(channel, INT3_LOCAL1_MAPPABLE1); } } @@ -330,13 +338,13 @@ READ32_MEMBER(ioc2_device::read) case KBD_MOUSE_REGS1: { - const uint8_t data = m_kbdc->data_r(space, (offset - KBD_MOUSE_REGS1) * 4); + const uint8_t data = m_kbdc->data_r(space, 0); LOGMASKED(LOG_MOUSEKBD, "%s: Read Keyboard/Mouse Register 1: %02x\n", machine().describe_context(), data); return data; } case KBD_MOUSE_REGS2: { - const uint8_t data = m_kbdc->data_r(space, (offset - KBD_MOUSE_REGS1) * 4); + const uint8_t data = m_kbdc->data_r(space, 4); LOGMASKED(LOG_MOUSEKBD, "%s: Read Keyboard/Mouse Register 2: %02x\n", machine().describe_context(), data); return data; } @@ -385,64 +393,44 @@ READ32_MEMBER(ioc2_device::read) return m_write_reg; case INT3_LOCAL0_STATUS_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Local0 Status Register: %02x\n", machine().describe_context(), m_int3_local_status_reg[0]); return m_int3_local_status_reg[0]; - } case INT3_LOCAL0_MASK_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Local0 Mask Register: %02x\n", machine().describe_context(), m_int3_local_mask_reg[0]); return m_int3_local_mask_reg[0]; - } case INT3_LOCAL1_STATUS_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Local1 Status Register: %02x\n", machine().describe_context(), m_int3_local_status_reg[1]); return m_int3_local_status_reg[1]; - } case INT3_LOCAL1_MASK_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Local1 Mask Register: %02x\n", machine().describe_context(), m_int3_local_mask_reg[1]); return m_int3_local_mask_reg[1]; - } case INT3_MAP_STATUS_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Map Status Register: %02x\n", machine().describe_context(), m_int3_map_status_reg); return m_int3_map_status_reg; - } case INT3_MAP_MASK0_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Map Mask0 Register: %02x\n", machine().describe_context(), m_int3_map_mask_reg[0]); return m_int3_map_mask_reg[0]; - } case INT3_MAP_MASK1_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Map Mask1 Register: %02x\n", machine().describe_context(), m_int3_map_mask_reg[1]); return m_int3_map_mask_reg[1]; - } case INT3_MAP_POLARITY_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Map Polarity Register: %02x\n", machine().describe_context(), m_int3_map_pol_reg); return m_int3_map_pol_reg; - } case INT3_TIMER_CLEAR_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Timer Clear (ignored)\n", machine().describe_context()); return 0; - } case INT3_ERROR_STATUS_REG: - { LOGMASKED(LOG_INT3, "%s: Read Interrupt Error Status Register: %02x\n", machine().describe_context(), m_int3_err_status_reg); return m_int3_err_status_reg; - } case TIMER_COUNT0_REG: { @@ -514,28 +502,28 @@ WRITE32_MEMBER( ioc2_device::write ) case SERIAL1_CMD_REG: LOGMASKED(LOG_SERIAL, "%s: Write Serial 1 Command Register: %02x\n", machine().describe_context(), (uint8_t)data); - m_scc->ba_cd_w(space, (offset - SERIAL1_CMD_REG) ^ 3, data & 0xff); + m_scc->ba_cd_w(space, 3, data & 0xff); return; case SERIAL1_DATA_REG: LOGMASKED(LOG_SERIAL, "%s: Write Serial 1 Data Register: %02x\n", machine().describe_context(), (uint8_t)data); - m_scc->ba_cd_w(space, (offset - SERIAL1_CMD_REG) ^ 3, data & 0xff); + m_scc->ba_cd_w(space, 2, data & 0xff); return; case SERIAL2_CMD_REG: LOGMASKED(LOG_SERIAL, "%s: Write Serial 2 Command Register: %02x\n", machine().describe_context(), (uint8_t)data); - m_scc->ba_cd_w(space, (offset - SERIAL1_CMD_REG) ^ 3, data & 0xff); + m_scc->ba_cd_w(space, 1, data & 0xff); return; case SERIAL2_DATA_REG: LOGMASKED(LOG_SERIAL, "%s: Write Serial 2 Data Register: %02x\n", machine().describe_context(), (uint8_t)data); - m_scc->ba_cd_w(space, (offset - SERIAL1_CMD_REG) ^ 3, data & 0xff); + m_scc->ba_cd_w(space, 0, data & 0xff); return; case KBD_MOUSE_REGS1: LOGMASKED(LOG_MOUSEKBD, "%s: Write Keyboard/Mouse Register 1: %02x\n", machine().describe_context(), (uint8_t)data); - m_kbdc->data_w(space, (offset - KBD_MOUSE_REGS1) * 4, data & 0xff); + m_kbdc->data_w(space, 0, data & 0xff); return; case KBD_MOUSE_REGS2: LOGMASKED(LOG_MOUSEKBD, "%s: Write Keyboard/Mouse Register 2: %02x\n", machine().describe_context(), (uint8_t)data); - m_kbdc->data_w(space, (offset - KBD_MOUSE_REGS1) * 4, data & 0xff); + m_kbdc->data_w(space, 4, data & 0xff); return; case PANEL_REG: @@ -575,7 +563,7 @@ WRITE32_MEMBER( ioc2_device::write ) return; case WRITE_REG: - LOGMASKED(LOG_RESET, "%s: Write Write Register: %02x\n", machine().describe_context(), (uint8_t)data); + LOGMASKED(LOG_WRITE, "%s: Write Write Register: %02x\n", machine().describe_context(), (uint8_t)data); m_write_reg = data; return; @@ -587,43 +575,31 @@ WRITE32_MEMBER( ioc2_device::write ) return; case INT3_LOCAL0_MASK_REG: - { LOGMASKED(LOG_INT3, "%s: Write Interrupt Local0 Mask Register: %02x\n", machine().describe_context(), (uint8_t)data); set_local_int_mask(0, data); return; - } - case INT3_LOCAL1_MASK_REG: - { LOGMASKED(LOG_INT3, "%s: Write Interrupt Local1 Mask Register: %02x\n", machine().describe_context(), (uint8_t)data); set_local_int_mask(1, data); return; - } case INT3_MAP_MASK0_REG: - // TODO: Implement mappable interrupts LOGMASKED(LOG_INT3, "%s: Write Interrupt Map Mask0 Register: %02x\n", machine().describe_context(), (uint8_t)data); set_map_int_mask(0, data); return; - case INT3_MAP_MASK1_REG: - // TODO: Implement mappable interrupts LOGMASKED(LOG_INT3, "%s: Write Interrupt Map Mask1 Register: %02x\n", machine().describe_context(), (uint8_t)data); set_map_int_mask(1, data); return; - case INT3_MAP_POLARITY_REG: // TODO: Mappable interrupt polarity select LOGMASKED(LOG_INT3, "%s: Write Interrupt Map Polarity Register: %02x\n", machine().describe_context(), (uint8_t)data); m_int3_map_pol_reg = data; return; - case INT3_TIMER_CLEAR_REG: - { LOGMASKED(LOG_INT3, "%s: Write Interrupt Timer Clear Register: %02x\n", machine().describe_context(), (uint8_t)data); set_timer_int_clear(data); return; - } case TIMER_COUNT0_REG: LOGMASKED(LOG_PIT, "%s: Write Timer Count0 Register: %02x\n", machine().describe_context(), (uint8_t)data); @@ -660,6 +636,7 @@ void ioc2_device::set_local_int_mask(int channel, uint32_t mask) void ioc2_device::set_map_int_mask(int channel, uint32_t mask) { m_int3_map_mask_reg[channel] = (uint8_t)mask; + check_mappable_interrupt(channel); } void ioc2_device::set_timer_int_clear(uint32_t data) diff --git a/src/mame/machine/ioc2.h b/src/mame/machine/ioc2.h index 5e99996e7c6..d53012010dc 100644 --- a/src/mame/machine/ioc2.h +++ b/src/mame/machine/ioc2.h @@ -32,7 +32,7 @@ public: void raise_local_irq(int channel, uint8_t mask); void lower_local_irq(int channel, uint8_t mask); - enum + enum : uint8_t { INT3_LOCAL0_FIFO = 0x01, INT3_LOCAL0_SCSI0 = 0x02, @@ -44,7 +44,7 @@ public: INT3_LOCAL0_MAPPABLE0 = 0x80, }; - enum + enum : uint8_t { INT3_LOCAL1_GP0 = 0x01, INT3_LOCAL1_PANEL = 0x02, @@ -83,6 +83,7 @@ protected: DECLARE_WRITE_LINE_MEMBER(duart_int_w); void set_mappable_int(uint8_t mask, bool state); + void check_mappable_interrupt(int channel); enum { -- cgit v1.2.3