Working towards making Interrupt support more generic/less NV2A specific

This commit is contained in:
Luke Usher 2017-08-09 21:19:26 +01:00 committed by PatrickvL
parent 147b293c8c
commit a1048d0042
1 changed files with 14 additions and 33 deletions

View File

@ -490,8 +490,6 @@ struct {
uint32_t regs[NV_PGRAPH_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PGRAPH_SIZE / sizeof(uint32_t)]; // TODO : union
} pgraph; } pgraph;
bool interruptsUpdated = false;
static void update_irq() static void update_irq()
{ {
/* PFIFO */ /* PFIFO */
@ -531,7 +529,13 @@ static void update_irq()
pmc.pending_interrupts &= ~NV_PMC_INTR_0_SOFTWARE; pmc.pending_interrupts &= ~NV_PMC_INTR_0_SOFTWARE;
} */ } */
interruptsUpdated = true; if (pmc.pending_interrupts && pmc.enabled_interrupts) {
HalSystemInterrupts[3].Assert(true);
} else {
HalSystemInterrupts[3].Assert(false);
}
SwitchToThread();
} }
@ -2652,6 +2656,7 @@ static void nv2a_vblank_thread()
} }
} }
// TODO: Move this into the kernel
static unsigned int WINAPI EmuNV2A_InterruptThread(PVOID param) static unsigned int WINAPI EmuNV2A_InterruptThread(PVOID param)
{ {
EmuGenerateFS(CxbxKrnl_TLS, CxbxKrnl_TLSData); EmuGenerateFS(CxbxKrnl_TLS, CxbxKrnl_TLSData);
@ -2660,39 +2665,15 @@ static unsigned int WINAPI EmuNV2A_InterruptThread(PVOID param)
_controlfp(_RC_NEAR, _MCW_RC); // Set Rounding control to near (unsure about this) _controlfp(_RC_NEAR, _MCW_RC); // Set Rounding control to near (unsure about this)
while (true) { while (true) {
__try { for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) {
// If interrupts need processing, service the NV2A interrupt // If the interrupt is pending, pending and connected, process it
// TODO: Move this into the kernel/make this generic, not NV2A specific if (HalSystemInterrupts[i].IsPending() && EmuInterruptList[i]->Connected) {
// An interrupt thread should exist in the kernel which iterates through HalSystemInterrupts[i].Trigger(EmuInterruptList[i]);
// EmuInterruptList and calls and pending interrupts!
// Note: This is implemented here as currently only NV2A generates
// interrupts, and we have no mechanism for telling the kernel an
// interrupt needs to be fired!
if (interruptsUpdated) {
interruptsUpdated = false;
if (pmc.pending_interrupts && pmc.enabled_interrupts) {
// If GPU Interrupt is connected, call the interrupt service routine
if (EmuInterruptList[3]->Connected) {
// Get a function pointer to the service routine
BOOLEAN(__stdcall *ServiceRoutine)(xboxkrnl::PKINTERRUPT, void*) = (BOOLEAN(__stdcall *)(xboxkrnl::PKINTERRUPT, void*))EmuInterruptList[3]->ServiceRoutine;
// Call the routine, passing the service context and interrupt object
BOOLEAN result = ServiceRoutine(EmuInterruptList[3], EmuInterruptList[3]->ServiceContext);
// TODO: What is the result for?
}
}
else {
// TODO: Cancel IRQ
// EmuWarning("NV2A update_irq() : Cancel IRQ Not Implemented");
} }
} }
SwitchToThread(); SwitchToThread();
} }
__except (EmuException(GetExceptionInformation()))
{
EmuWarning("Problem with ExceptionFilter!");
}
}
return 0; return 0;
} }