mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
-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
This commit is contained in:
parent
7388d5bd12
commit
e9a84bc89e
@ -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<s32>(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<u32>(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<u64>(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:
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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(1, INT3_LOCAL1_MAPPABLE1);
|
||||
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(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)
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user