Updates the state of the nextCounter value (if needed) to serve any pending events for the given counter. Call this method after any modifications to the state of a counter.
| 66 | // any pending events for the given counter. |
| 67 | // Call this method after any modifications to the state of a counter. |
| 68 | static __fi void _rcntSet(int cntidx) |
| 69 | { |
| 70 | s32 c; |
| 71 | pxAssume(cntidx <= 4); // rcntSet isn't valid for h/vsync counters. |
| 72 | |
| 73 | const Counter& counter = counters[cntidx]; |
| 74 | |
| 75 | // Stopped or special hsync gate? |
| 76 | if (!rcntCanCount(cntidx) || (counter.mode.ClockSource == 0x3)) |
| 77 | return; |
| 78 | |
| 79 | if (!counter.mode.TargetInterrupt && !counter.mode.OverflowInterrupt && !counter.mode.ZeroReturn) |
| 80 | return; |
| 81 | // check for special cases where the overflow or target has just passed |
| 82 | // (we probably missed it because we're doing/checking other things) |
| 83 | if (counter.count > 0x10000 || counter.count > counter.target) |
| 84 | { |
| 85 | nextDeltaCounter = 4; |
| 86 | return; |
| 87 | } |
| 88 | |
| 89 | // nextCounter is relative to the cpuRegs.cycle when rcntUpdate() was last called. |
| 90 | // However, the current _rcntSet could be called at any cycle count, so we need to take |
| 91 | // that into account. Adding the difference from that cycle count to the current one |
| 92 | // will do the trick! |
| 93 | |
| 94 | c = ((0x10000 - counter.count) * counter.rate) - (cpuRegs.cycle - counter.startCycle); |
| 95 | c += cpuRegs.cycle - nextStartCounter; // adjust for time passed since last rcntUpdate(); |
| 96 | |
| 97 | if (c < nextDeltaCounter) |
| 98 | { |
| 99 | nextDeltaCounter = c; |
| 100 | |
| 101 | cpuSetNextEvent(nextStartCounter, nextDeltaCounter); // Need to update on counter resets/target changes |
| 102 | } |
| 103 | |
| 104 | // Ignore target diff if target is currently disabled. |
| 105 | // (the overflow is all we care about since it goes first, and then the |
| 106 | // target will be turned on afterward, and handled in the next event test). |
| 107 | |
| 108 | if (counter.target & EECNT_FUTURE_TARGET) |
| 109 | { |
| 110 | return; |
| 111 | } |
| 112 | else |
| 113 | { |
| 114 | |
| 115 | c = ((counter.target - counter.count) * counter.rate) - (cpuRegs.cycle - counter.startCycle); |
| 116 | c += cpuRegs.cycle - nextStartCounter; // adjust for time passed since last rcntUpdate(); |
| 117 | |
| 118 | if (c < nextDeltaCounter) |
| 119 | { |
| 120 | nextDeltaCounter = c; |
| 121 | cpuSetNextEvent(nextStartCounter, nextDeltaCounter); // Need to update on counter resets/target changes |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 |
no test coverage detected