mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-27 08:15:37 +00:00
InterruptController: Convert to namespace
This commit is contained in:
parent
db364d0e95
commit
0683b9fa0e
|
@ -1233,13 +1233,13 @@ ALWAYS_INLINE static TickCount DoAccessInterruptController(u32 offset, u32& valu
|
||||||
{
|
{
|
||||||
if constexpr (type == MemoryAccessType::Read)
|
if constexpr (type == MemoryAccessType::Read)
|
||||||
{
|
{
|
||||||
value = g_interrupt_controller.ReadRegister(FIXUP_WORD_OFFSET(size, offset));
|
value = InterruptController::ReadRegister(FIXUP_WORD_OFFSET(size, offset));
|
||||||
value = FIXUP_WORD_READ_VALUE(size, offset, value);
|
value = FIXUP_WORD_READ_VALUE(size, offset, value);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_interrupt_controller.WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value));
|
InterruptController::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1180,7 +1180,7 @@ void CDROM::UpdateInterruptRequest()
|
||||||
if ((s_interrupt_flag_register & s_interrupt_enable_register) == 0)
|
if ((s_interrupt_flag_register & s_interrupt_enable_register) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::CDROM);
|
InterruptController::InterruptRequest(InterruptController::IRQ::CDROM);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDROM::HasPendingDiscEvent()
|
bool CDROM::HasPendingDiscEvent()
|
||||||
|
|
|
@ -430,7 +430,7 @@ void DMA::UpdateIRQ()
|
||||||
if (s_DICR.master_flag)
|
if (s_DICR.master_flag)
|
||||||
{
|
{
|
||||||
Log_TracePrintf("Firing DMA master interrupt");
|
Log_TracePrintf("Firing DMA master interrupt");
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::DMA);
|
InterruptController::InterruptRequest(InterruptController::IRQ::DMA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -898,7 +898,7 @@ void GPU::CRTCTickEvent(TickCount ticks)
|
||||||
if (new_vblank)
|
if (new_vblank)
|
||||||
{
|
{
|
||||||
Log_DebugPrintf("Now in v-blank");
|
Log_DebugPrintf("Now in v-blank");
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::VBLANK);
|
InterruptController::InterruptRequest(InterruptController::IRQ::VBLANK);
|
||||||
|
|
||||||
// flush any pending draws and "scan out" the image
|
// flush any pending draws and "scan out" the image
|
||||||
FlushRender();
|
FlushRender();
|
||||||
|
|
|
@ -210,7 +210,7 @@ bool GPU::HandleInterruptRequestCommand()
|
||||||
if (!m_GPUSTAT.interrupt_request)
|
if (!m_GPUSTAT.interrupt_request)
|
||||||
{
|
{
|
||||||
m_GPUSTAT.interrupt_request = true;
|
m_GPUSTAT.interrupt_request = true;
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::GPU);
|
InterruptController::InterruptRequest(InterruptController::IRQ::GPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fifo.RemoveOne();
|
m_fifo.RemoveOne();
|
||||||
|
|
|
@ -7,11 +7,17 @@
|
||||||
#include "util/state_wrapper.h"
|
#include "util/state_wrapper.h"
|
||||||
Log_SetChannel(InterruptController);
|
Log_SetChannel(InterruptController);
|
||||||
|
|
||||||
InterruptController g_interrupt_controller;
|
namespace InterruptController {
|
||||||
|
|
||||||
InterruptController::InterruptController() = default;
|
static constexpr u32 REGISTER_WRITE_MASK = (u32(1) << NUM_IRQS) - 1;
|
||||||
|
static constexpr u32 DEFAULT_INTERRUPT_MASK = 0; //(u32(1) << NUM_IRQS) - 1;
|
||||||
|
|
||||||
InterruptController::~InterruptController() = default;
|
static void UpdateCPUInterruptRequest();
|
||||||
|
|
||||||
|
static u32 s_interrupt_status_register = 0;
|
||||||
|
static u32 s_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
|
||||||
|
|
||||||
|
} // namespace InterruptController
|
||||||
|
|
||||||
void InterruptController::Initialize()
|
void InterruptController::Initialize()
|
||||||
{
|
{
|
||||||
|
@ -22,22 +28,27 @@ void InterruptController::Shutdown() {}
|
||||||
|
|
||||||
void InterruptController::Reset()
|
void InterruptController::Reset()
|
||||||
{
|
{
|
||||||
m_interrupt_status_register = 0;
|
s_interrupt_status_register = 0;
|
||||||
m_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
|
s_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterruptController::DoState(StateWrapper& sw)
|
bool InterruptController::DoState(StateWrapper& sw)
|
||||||
{
|
{
|
||||||
sw.Do(&m_interrupt_status_register);
|
sw.Do(&s_interrupt_status_register);
|
||||||
sw.Do(&m_interrupt_mask_register);
|
sw.Do(&s_interrupt_mask_register);
|
||||||
|
|
||||||
return !sw.HasError();
|
return !sw.HasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterruptController::GetIRQLineState()
|
||||||
|
{
|
||||||
|
return (s_interrupt_status_register != 0);
|
||||||
|
}
|
||||||
|
|
||||||
void InterruptController::InterruptRequest(IRQ irq)
|
void InterruptController::InterruptRequest(IRQ irq)
|
||||||
{
|
{
|
||||||
const u32 bit = (u32(1) << static_cast<u32>(irq));
|
const u32 bit = (u32(1) << static_cast<u32>(irq));
|
||||||
m_interrupt_status_register |= bit;
|
s_interrupt_status_register |= bit;
|
||||||
UpdateCPUInterruptRequest();
|
UpdateCPUInterruptRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +57,10 @@ u32 InterruptController::ReadRegister(u32 offset)
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0x00: // I_STATUS
|
case 0x00: // I_STATUS
|
||||||
return m_interrupt_status_register;
|
return s_interrupt_status_register;
|
||||||
|
|
||||||
case 0x04: // I_MASK
|
case 0x04: // I_MASK
|
||||||
return m_interrupt_mask_register;
|
return s_interrupt_mask_register;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log_ErrorPrintf("Invalid read at offset 0x%08X", offset);
|
Log_ErrorPrintf("Invalid read at offset 0x%08X", offset);
|
||||||
|
@ -63,10 +74,10 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
|
||||||
{
|
{
|
||||||
case 0x00: // I_STATUS
|
case 0x00: // I_STATUS
|
||||||
{
|
{
|
||||||
if ((m_interrupt_status_register & ~value) != 0)
|
if ((s_interrupt_status_register & ~value) != 0)
|
||||||
Log_DebugPrintf("Clearing bits 0x%08X", (m_interrupt_status_register & ~value));
|
Log_DebugPrintf("Clearing bits 0x%08X", (s_interrupt_status_register & ~value));
|
||||||
|
|
||||||
m_interrupt_status_register = m_interrupt_status_register & (value & REGISTER_WRITE_MASK);
|
s_interrupt_status_register = s_interrupt_status_register & (value & REGISTER_WRITE_MASK);
|
||||||
UpdateCPUInterruptRequest();
|
UpdateCPUInterruptRequest();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -74,7 +85,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
|
||||||
case 0x04: // I_MASK
|
case 0x04: // I_MASK
|
||||||
{
|
{
|
||||||
Log_DebugPrintf("Interrupt mask <- 0x%08X", value);
|
Log_DebugPrintf("Interrupt mask <- 0x%08X", value);
|
||||||
m_interrupt_mask_register = value & REGISTER_WRITE_MASK;
|
s_interrupt_mask_register = value & REGISTER_WRITE_MASK;
|
||||||
UpdateCPUInterruptRequest();
|
UpdateCPUInterruptRequest();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +99,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
|
||||||
void InterruptController::UpdateCPUInterruptRequest()
|
void InterruptController::UpdateCPUInterruptRequest()
|
||||||
{
|
{
|
||||||
// external interrupts set bit 10 only?
|
// external interrupts set bit 10 only?
|
||||||
if ((m_interrupt_status_register & m_interrupt_mask_register) != 0)
|
if ((s_interrupt_status_register & s_interrupt_mask_register) != 0)
|
||||||
CPU::SetExternalInterrupt(2);
|
CPU::SetExternalInterrupt(2);
|
||||||
else
|
else
|
||||||
CPU::ClearExternalInterrupt(2);
|
CPU::ClearExternalInterrupt(2);
|
||||||
|
|
|
@ -6,13 +6,12 @@
|
||||||
|
|
||||||
class StateWrapper;
|
class StateWrapper;
|
||||||
|
|
||||||
class InterruptController final
|
namespace InterruptController {
|
||||||
{
|
|
||||||
public:
|
|
||||||
static constexpr u32 NUM_IRQS = 11;
|
|
||||||
|
|
||||||
enum class IRQ : u32
|
static constexpr u32 NUM_IRQS = 11;
|
||||||
{
|
|
||||||
|
enum class IRQ : u32
|
||||||
|
{
|
||||||
VBLANK = 0, // IRQ0 - VBLANK
|
VBLANK = 0, // IRQ0 - VBLANK
|
||||||
GPU = 1, // IRQ1 - GPU via GP0(1Fh)
|
GPU = 1, // IRQ1 - GPU via GP0(1Fh)
|
||||||
CDROM = 2, // IRQ2 - CDROM
|
CDROM = 2, // IRQ2 - CDROM
|
||||||
|
@ -24,35 +23,21 @@ public:
|
||||||
SIO = 8, // IRQ8 - SIO
|
SIO = 8, // IRQ8 - SIO
|
||||||
SPU = 9, // IRQ9 - SPU
|
SPU = 9, // IRQ9 - SPU
|
||||||
IRQ10 = 10 // IRQ10 - Lightpen interrupt, PIO
|
IRQ10 = 10 // IRQ10 - Lightpen interrupt, PIO
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
InterruptController();
|
|
||||||
~InterruptController();
|
|
||||||
|
|
||||||
void Initialize();
|
|
||||||
void Shutdown();
|
|
||||||
void Reset();
|
|
||||||
bool DoState(StateWrapper& sw);
|
|
||||||
|
|
||||||
// Should mirror CPU state.
|
|
||||||
ALWAYS_INLINE bool GetIRQLineState() const { return (m_interrupt_status_register != 0); }
|
|
||||||
|
|
||||||
// Interupts are edge-triggered, so if it is masked when TriggerInterrupt() is called, it will be lost.
|
|
||||||
void InterruptRequest(IRQ irq);
|
|
||||||
|
|
||||||
// I/O
|
|
||||||
u32 ReadRegister(u32 offset);
|
|
||||||
void WriteRegister(u32 offset, u32 value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr u32 REGISTER_WRITE_MASK = (u32(1) << NUM_IRQS) - 1;
|
|
||||||
static constexpr u32 DEFAULT_INTERRUPT_MASK = 0; //(u32(1) << NUM_IRQS) - 1;
|
|
||||||
|
|
||||||
void UpdateCPUInterruptRequest();
|
|
||||||
|
|
||||||
u32 m_interrupt_status_register = 0;
|
|
||||||
u32 m_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern InterruptController g_interrupt_controller;
|
void Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
void Reset();
|
||||||
|
bool DoState(StateWrapper& sw);
|
||||||
|
|
||||||
|
// Should mirror CPU state.
|
||||||
|
bool GetIRQLineState();
|
||||||
|
|
||||||
|
// Interupts are edge-triggered, so if it is masked when TriggerInterrupt() is called, it will be lost.
|
||||||
|
void InterruptRequest(IRQ irq);
|
||||||
|
|
||||||
|
// I/O
|
||||||
|
u32 ReadRegister(u32 offset);
|
||||||
|
void WriteRegister(u32 offset, u32 value);
|
||||||
|
|
||||||
|
} // namespace InterruptController
|
||||||
|
|
|
@ -594,7 +594,7 @@ void Pad::DoACK()
|
||||||
{
|
{
|
||||||
Log_DebugPrintf("Triggering ACK interrupt");
|
Log_DebugPrintf("Triggering ACK interrupt");
|
||||||
m_JOY_STAT.INTR = true;
|
m_JOY_STAT.INTR = true;
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::IRQ7);
|
InterruptController::InterruptRequest(InterruptController::IRQ::IRQ7);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
|
|
|
@ -1146,7 +1146,7 @@ void SPU::TriggerRAMIRQ()
|
||||||
{
|
{
|
||||||
DebugAssert(IsRAMIRQTriggerable());
|
DebugAssert(IsRAMIRQTriggerable());
|
||||||
s_SPUSTAT.irq9_flag = true;
|
s_SPUSTAT.irq9_flag = true;
|
||||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::SPU);
|
InterruptController::InterruptRequest(InterruptController::IRQ::SPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPU::CheckForLateRAMIRQs()
|
void SPU::CheckForLateRAMIRQs()
|
||||||
|
|
|
@ -1387,7 +1387,7 @@ bool System::Initialize(bool force_software_renderer)
|
||||||
CPU::CodeCache::Initialize();
|
CPU::CodeCache::Initialize();
|
||||||
|
|
||||||
DMA::Initialize();
|
DMA::Initialize();
|
||||||
g_interrupt_controller.Initialize();
|
InterruptController::Initialize();
|
||||||
|
|
||||||
CDROM::Initialize();
|
CDROM::Initialize();
|
||||||
g_pad.Initialize();
|
g_pad.Initialize();
|
||||||
|
@ -1457,7 +1457,7 @@ void System::DestroySystem()
|
||||||
g_pad.Shutdown();
|
g_pad.Shutdown();
|
||||||
CDROM::Shutdown();
|
CDROM::Shutdown();
|
||||||
g_gpu.reset();
|
g_gpu.reset();
|
||||||
g_interrupt_controller.Shutdown();
|
InterruptController::Shutdown();
|
||||||
DMA::Shutdown();
|
DMA::Shutdown();
|
||||||
PGXP::Shutdown();
|
PGXP::Shutdown();
|
||||||
CPU::CodeCache::Shutdown();
|
CPU::CodeCache::Shutdown();
|
||||||
|
@ -1643,7 +1643,7 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
|
||||||
if (!sw.DoMarker("DMA") || !DMA::DoState(sw))
|
if (!sw.DoMarker("DMA") || !DMA::DoState(sw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!sw.DoMarker("InterruptController") || !g_interrupt_controller.DoState(sw))
|
if (!sw.DoMarker("InterruptController") || !InterruptController::DoState(sw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
g_gpu->RestoreGraphicsAPIState();
|
g_gpu->RestoreGraphicsAPIState();
|
||||||
|
@ -1740,7 +1740,7 @@ void System::InternalReset()
|
||||||
|
|
||||||
Bus::Reset();
|
Bus::Reset();
|
||||||
DMA::Reset();
|
DMA::Reset();
|
||||||
g_interrupt_controller.Reset();
|
InterruptController::Reset();
|
||||||
g_gpu->Reset(true);
|
g_gpu->Reset(true);
|
||||||
CDROM::Reset();
|
CDROM::Reset();
|
||||||
g_pad.Reset();
|
g_pad.Reset();
|
||||||
|
|
|
@ -417,7 +417,7 @@ void Timers::UpdateIRQ(u32 index)
|
||||||
|
|
||||||
Log_DebugPrintf("Raising timer %u IRQ", index);
|
Log_DebugPrintf("Raising timer %u IRQ", index);
|
||||||
cs.irq_done = true;
|
cs.irq_done = true;
|
||||||
g_interrupt_controller.InterruptRequest(
|
InterruptController::InterruptRequest(
|
||||||
static_cast<InterruptController::IRQ>(static_cast<u32>(InterruptController::IRQ::TMR0) + index));
|
static_cast<InterruptController::IRQ>(static_cast<u32>(InterruptController::IRQ::TMR0) + index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue