InterruptController: Convert to namespace

This commit is contained in:
Connor McLaughlin 2023-01-11 19:01:20 +10:00
parent db364d0e95
commit 0683b9fa0e
11 changed files with 71 additions and 75 deletions

View file

@ -1233,13 +1233,13 @@ ALWAYS_INLINE static TickCount DoAccessInterruptController(u32 offset, u32& valu
{
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);
return 2;
}
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;
}
}

View file

@ -1180,7 +1180,7 @@ void CDROM::UpdateInterruptRequest()
if ((s_interrupt_flag_register & s_interrupt_enable_register) == 0)
return;
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::CDROM);
InterruptController::InterruptRequest(InterruptController::IRQ::CDROM);
}
bool CDROM::HasPendingDiscEvent()

View file

@ -430,7 +430,7 @@ void DMA::UpdateIRQ()
if (s_DICR.master_flag)
{
Log_TracePrintf("Firing DMA master interrupt");
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::DMA);
InterruptController::InterruptRequest(InterruptController::IRQ::DMA);
}
}

View file

@ -898,7 +898,7 @@ void GPU::CRTCTickEvent(TickCount ticks)
if (new_vblank)
{
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
FlushRender();

View file

@ -210,7 +210,7 @@ bool GPU::HandleInterruptRequestCommand()
if (!m_GPUSTAT.interrupt_request)
{
m_GPUSTAT.interrupt_request = true;
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::GPU);
InterruptController::InterruptRequest(InterruptController::IRQ::GPU);
}
m_fifo.RemoveOne();

View file

@ -7,11 +7,17 @@
#include "util/state_wrapper.h"
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()
{
@ -22,22 +28,27 @@ void InterruptController::Shutdown() {}
void InterruptController::Reset()
{
m_interrupt_status_register = 0;
m_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
s_interrupt_status_register = 0;
s_interrupt_mask_register = DEFAULT_INTERRUPT_MASK;
}
bool InterruptController::DoState(StateWrapper& sw)
{
sw.Do(&m_interrupt_status_register);
sw.Do(&m_interrupt_mask_register);
sw.Do(&s_interrupt_status_register);
sw.Do(&s_interrupt_mask_register);
return !sw.HasError();
}
bool InterruptController::GetIRQLineState()
{
return (s_interrupt_status_register != 0);
}
void InterruptController::InterruptRequest(IRQ irq)
{
const u32 bit = (u32(1) << static_cast<u32>(irq));
m_interrupt_status_register |= bit;
s_interrupt_status_register |= bit;
UpdateCPUInterruptRequest();
}
@ -46,10 +57,10 @@ u32 InterruptController::ReadRegister(u32 offset)
switch (offset)
{
case 0x00: // I_STATUS
return m_interrupt_status_register;
return s_interrupt_status_register;
case 0x04: // I_MASK
return m_interrupt_mask_register;
return s_interrupt_mask_register;
default:
Log_ErrorPrintf("Invalid read at offset 0x%08X", offset);
@ -63,10 +74,10 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
{
case 0x00: // I_STATUS
{
if ((m_interrupt_status_register & ~value) != 0)
Log_DebugPrintf("Clearing bits 0x%08X", (m_interrupt_status_register & ~value));
if ((s_interrupt_status_register & ~value) != 0)
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();
}
break;
@ -74,7 +85,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
case 0x04: // I_MASK
{
Log_DebugPrintf("Interrupt mask <- 0x%08X", value);
m_interrupt_mask_register = value & REGISTER_WRITE_MASK;
s_interrupt_mask_register = value & REGISTER_WRITE_MASK;
UpdateCPUInterruptRequest();
}
break;
@ -88,7 +99,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value)
void InterruptController::UpdateCPUInterruptRequest()
{
// 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);
else
CPU::ClearExternalInterrupt(2);

View file

@ -6,53 +6,38 @@
class StateWrapper;
class InterruptController final
namespace InterruptController {
static constexpr u32 NUM_IRQS = 11;
enum class IRQ : u32
{
public:
static constexpr u32 NUM_IRQS = 11;
enum class IRQ : u32
{
VBLANK = 0, // IRQ0 - VBLANK
GPU = 1, // IRQ1 - GPU via GP0(1Fh)
CDROM = 2, // IRQ2 - CDROM
DMA = 3, // IRQ3 - DMA
TMR0 = 4, // IRQ4 - TMR0 - Sysclk or Dotclk
TMR1 = 5, // IRQ5 - TMR1 - Sysclk Hblank
TMR2 = 6, // IRQ6 - TMR2 - Sysclk or Sysclk / 8
IRQ7 = 7, // IRQ7 - Controller and Memory Card Byte Received
SIO = 8, // IRQ8 - SIO
SPU = 9, // IRQ9 - SPU
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;
VBLANK = 0, // IRQ0 - VBLANK
GPU = 1, // IRQ1 - GPU via GP0(1Fh)
CDROM = 2, // IRQ2 - CDROM
DMA = 3, // IRQ3 - DMA
TMR0 = 4, // IRQ4 - TMR0 - Sysclk or Dotclk
TMR1 = 5, // IRQ5 - TMR1 - Sysclk Hblank
TMR2 = 6, // IRQ6 - TMR2 - Sysclk or Sysclk / 8
IRQ7 = 7, // IRQ7 - Controller and Memory Card Byte Received
SIO = 8, // IRQ8 - SIO
SPU = 9, // IRQ9 - SPU
IRQ10 = 10 // IRQ10 - Lightpen interrupt, PIO
};
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

View file

@ -594,7 +594,7 @@ void Pad::DoACK()
{
Log_DebugPrintf("Triggering ACK interrupt");
m_JOY_STAT.INTR = true;
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::IRQ7);
InterruptController::InterruptRequest(InterruptController::IRQ::IRQ7);
}
EndTransfer();

View file

@ -1146,7 +1146,7 @@ void SPU::TriggerRAMIRQ()
{
DebugAssert(IsRAMIRQTriggerable());
s_SPUSTAT.irq9_flag = true;
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::SPU);
InterruptController::InterruptRequest(InterruptController::IRQ::SPU);
}
void SPU::CheckForLateRAMIRQs()

View file

@ -1387,7 +1387,7 @@ bool System::Initialize(bool force_software_renderer)
CPU::CodeCache::Initialize();
DMA::Initialize();
g_interrupt_controller.Initialize();
InterruptController::Initialize();
CDROM::Initialize();
g_pad.Initialize();
@ -1457,7 +1457,7 @@ void System::DestroySystem()
g_pad.Shutdown();
CDROM::Shutdown();
g_gpu.reset();
g_interrupt_controller.Shutdown();
InterruptController::Shutdown();
DMA::Shutdown();
PGXP::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))
return false;
if (!sw.DoMarker("InterruptController") || !g_interrupt_controller.DoState(sw))
if (!sw.DoMarker("InterruptController") || !InterruptController::DoState(sw))
return false;
g_gpu->RestoreGraphicsAPIState();
@ -1740,7 +1740,7 @@ void System::InternalReset()
Bus::Reset();
DMA::Reset();
g_interrupt_controller.Reset();
InterruptController::Reset();
g_gpu->Reset(true);
CDROM::Reset();
g_pad.Reset();

View file

@ -417,7 +417,7 @@ void Timers::UpdateIRQ(u32 index)
Log_DebugPrintf("Raising timer %u IRQ", index);
cs.irq_done = true;
g_interrupt_controller.InterruptRequest(
InterruptController::InterruptRequest(
static_cast<InterruptController::IRQ>(static_cast<u32>(InterruptController::IRQ::TMR0) + index));
}