Shared portion of the branch test, called from both the Interpreter and the recompiler. (moved here to help alleviate redundant code)
| 359 | // Shared portion of the branch test, called from both the Interpreter |
| 360 | // and the recompiler. (moved here to help alleviate redundant code) |
| 361 | __fi void _cpuEventTest_Shared() |
| 362 | { |
| 363 | eeEventTestIsActive = true; |
| 364 | cpuRegs.nextEventCycle = cpuRegs.cycle + eeWaitCycles; |
| 365 | cpuRegs.lastEventCycle = cpuRegs.cycle; |
| 366 | // ---- INTC / DMAC (CPU-level Exceptions) ----------------- |
| 367 | // Done first because exceptions raised during event tests need to be postponed a few |
| 368 | // cycles (fixes Grandia II [PAL], which does a spin loop on a vsync and expects to |
| 369 | // be able to read the value before the exception handler clears it). |
| 370 | |
| 371 | uint mask = intcInterrupt() | dmacInterrupt(); |
| 372 | if (cpuIntsEnabled(mask)) |
| 373 | cpuException(mask, cpuRegs.branch); |
| 374 | |
| 375 | // ---- IOP ------------- |
| 376 | // * It's important to run a iopEventTest before calling ExecuteBlock. This |
| 377 | // is because the IOP does not always perform branch tests before returning |
| 378 | // (during the prev branch) and also so it can act on the state the EE has |
| 379 | // given it before executing any code. |
| 380 | // |
| 381 | // * The IOP cannot always be run. If we run IOP code every time through the |
| 382 | // cpuEventTest, the IOP generally starts to run way ahead of the EE. |
| 383 | |
| 384 | // It's also important to sync up the IOP before updating the timers, since gates will depend on starting/stopping in the right place! |
| 385 | EEsCycle += cpuRegs.cycle - EEoCycle; |
| 386 | EEoCycle = cpuRegs.cycle; |
| 387 | |
| 388 | if (EEsCycle > 0) |
| 389 | iopEventAction = true; |
| 390 | |
| 391 | if (iopEventAction) |
| 392 | { |
| 393 | //if( EEsCycle < -450 ) |
| 394 | // Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle ); |
| 395 | |
| 396 | EEsCycle = psxCpu->ExecuteBlock(EEsCycle); |
| 397 | |
| 398 | iopEventAction = false; |
| 399 | } |
| 400 | |
| 401 | iopEventTest(); |
| 402 | |
| 403 | if (cpuTestCycle(nextStartCounter, nextDeltaCounter)) |
| 404 | { |
| 405 | rcntUpdate(); |
| 406 | _cpuTestPERF(); |
| 407 | } |
| 408 | |
| 409 | _cpuTestTIMR(); |
| 410 | |
| 411 | // ---- Interrupts ------------- |
| 412 | // These are basically just DMAC-related events, which also piggy-back the same bits as |
| 413 | // the PS2's own DMA channel IRQs and IRQ Masks. |
| 414 | |
| 415 | if (cpuRegs.interrupt) |
| 416 | { |
| 417 | // This is a BIOS hack because the coding in the BIOS is terrible but the bug is masked by Data Cache |
| 418 | // where a DMA buffer is overwritten without waiting for the transfer to end, which causes the fonts to get all messed up |
no test coverage detected