mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
SPU MFC: Fix SN interrupts
This commit is contained in:
parent
81684919f5
commit
4405f46aec
@ -112,11 +112,7 @@ void spu_interpreter::set_interrupt_status(spu_thread& spu, spu_opcode_t op)
|
|||||||
spu.set_interrupt_status(false);
|
spu.set_interrupt_status(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spu.interrupts_enabled && (spu.ch_event_mask & spu.ch_event_stat & SPU_EVENT_INTR_IMPLEMENTED) > 0)
|
spu.check_mfc_interrupts(spu.pc);
|
||||||
{
|
|
||||||
spu.interrupts_enabled = false;
|
|
||||||
spu.srr0 = std::exchange(spu.pc, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1865,6 +1865,27 @@ void spu_thread::do_mfc(bool wait)
|
|||||||
ch_tag_upd = 0;
|
ch_tag_upd = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_mfc_interrupts(pc + 4))
|
||||||
|
{
|
||||||
|
spu_runtime::g_escape(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spu_thread::check_mfc_interrupts(u32 next_pc)
|
||||||
|
{
|
||||||
|
if (interrupts_enabled && (ch_event_mask & ch_event_stat & SPU_EVENT_INTR_IMPLEMENTED) > 0)
|
||||||
|
{
|
||||||
|
interrupts_enabled.release(false);
|
||||||
|
srr0 = next_pc;
|
||||||
|
|
||||||
|
// Test for BR/BRA instructions (they are equivalent at zero pc)
|
||||||
|
const u32 br = _ref<u32>(0);
|
||||||
|
pc = (br & 0xfd80007f) == 0x30000000 ? (br >> 5) & 0x3fffc : 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 spu_thread::get_mfc_completed()
|
u32 spu_thread::get_mfc_completed()
|
||||||
@ -2190,6 +2211,11 @@ bool spu_thread::process_mfc_cmd()
|
|||||||
mfc_barrier |= utils::rol32(1, cmd.tag);
|
mfc_barrier |= utils::rol32(1, cmd.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_mfc_interrupts(pc + 4))
|
||||||
|
{
|
||||||
|
spu_runtime::g_escape(this);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,6 +669,7 @@ public:
|
|||||||
u32 get_events(bool waiting = false);
|
u32 get_events(bool waiting = false);
|
||||||
void set_events(u32 mask);
|
void set_events(u32 mask);
|
||||||
void set_interrupt_status(bool enable);
|
void set_interrupt_status(bool enable);
|
||||||
|
bool check_mfc_interrupts(u32 nex_pc);
|
||||||
u32 get_ch_count(u32 ch);
|
u32 get_ch_count(u32 ch);
|
||||||
s64 get_ch_value(u32 ch);
|
s64 get_ch_value(u32 ch);
|
||||||
bool set_ch_value(u32 ch, u32 value);
|
bool set_ch_value(u32 ch, u32 value);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user