mode - 0 means hblank source, 8 means vblank source.
| 790 | |
| 791 | // mode - 0 means hblank source, 8 means vblank source. |
| 792 | static __fi void rcntStartGate(bool isVblank, u64 sCycle) |
| 793 | { |
| 794 | for (int i = 0; i < 4; i++) |
| 795 | { |
| 796 | if (!isVblank && (counters[i].mode.ClockSource == 3) && rcntCanCount(i)) |
| 797 | { |
| 798 | // Update counters using the hblank as the clock. This keeps the hblank source |
| 799 | // nicely in sync with the counters and serves as an optimization also, since these |
| 800 | // counter won't receive special rcntUpdate scheduling. |
| 801 | // Note: Target and overflow tests must be done here since they won't be done |
| 802 | // currectly by rcntUpdate (since it's not being scheduled for these counters) |
| 803 | counters[i].count += HBLANK_COUNTER_SPEED; |
| 804 | _cpuTestOverflow(i); |
| 805 | _cpuTestTarget(i); |
| 806 | } |
| 807 | |
| 808 | if (!counters[i].mode.EnableGate) |
| 809 | continue; |
| 810 | |
| 811 | if ((!!counters[i].mode.GateSource) != isVblank) |
| 812 | continue; |
| 813 | |
| 814 | switch (counters[i].mode.GateMode) |
| 815 | { |
| 816 | case 0x0: // Count When Signal is low (V_RENDER ONLY) |
| 817 | |
| 818 | // Just set the start cycle -- counting will be done as needed |
| 819 | // for events (overflows, targets, mode changes, and the gate off below) |
| 820 | rcntSyncCounter(i); |
| 821 | counters[i].startCycle = sCycle & ~((u64)counters[i].rate - 1); |
| 822 | EECNT_LOG("EE Counter[%d] %s StartGate Type0, count = %x", i, |
| 823 | isVblank ? "vblank" : "hblank", counters[i].count); |
| 824 | break; |
| 825 | case 0x2: // Reset on Vsync end |
| 826 | // This is the vsync start so do nothing. |
| 827 | break; |
| 828 | case 0x1: // Reset on Vsync start |
| 829 | case 0x3: // Reset on Vsync start and end |
| 830 | rcntSyncCounter(i); |
| 831 | counters[i].count = 0; |
| 832 | counters[i].target &= 0xffff; |
| 833 | counters[i].startCycle = sCycle & ~((u64)counters[i].rate - 1); |
| 834 | EECNT_LOG("EE Counter[%d] %s StartGate Type%d, count = %x", i, |
| 835 | isVblank ? "vblank" : "hblank", counters[i].mode.GateMode, counters[i].count); |
| 836 | break; |
| 837 | } |
| 838 | } |
| 839 | |
| 840 | // No need to update actual counts here. Counts are calculated as needed by reads to |
| 841 | // rcntRcount(). And so long as sCycleT is set properly, any targets or overflows |
| 842 | // will be scheduled and handled. |
| 843 | |
| 844 | // Note: No need to set counters here. They'll get set when control returns to |
| 845 | // rcntUpdate, since we're being called from there anyway. |
| 846 | } |
| 847 | |
| 848 | // mode - 0 means hblank signal, 8 means vblank signal. |
| 849 | static __fi void rcntEndGate(bool isVblank, u64 sCycle) |
no test coverage detected