| 106 | } |
| 107 | extern int branch; |
| 108 | __fi void COP0_UpdatePCCR() |
| 109 | { |
| 110 | // Counting and counter exceptions are not performed if we are currently executing a Level 2 exception (ERL) |
| 111 | // or the counting function is not enabled (CTE) |
| 112 | if (cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE) |
| 113 | { |
| 114 | cpuRegs.lastPERFCycle[0] = cpuRegs.cycle; |
| 115 | cpuRegs.lastPERFCycle[1] = cpuRegs.lastPERFCycle[0]; |
| 116 | return; |
| 117 | } |
| 118 | |
| 119 | // Implemented memory mode check (kernel/super/user) |
| 120 | |
| 121 | if (cpuRegs.PERF.n.pccr.val & ((1 << (cpuRegs.CP0.n.Status.b.KSU + 2)) | (cpuRegs.CP0.n.Status.b.EXL << 1))) |
| 122 | { |
| 123 | // ---------------------------------- |
| 124 | // Update Performance Counter 0 |
| 125 | // ---------------------------------- |
| 126 | |
| 127 | if (PERF_ShouldCountEvent(cpuRegs.PERF.n.pccr.b.Event0)) |
| 128 | { |
| 129 | u32 incr = cpuRegs.cycle - cpuRegs.lastPERFCycle[0]; |
| 130 | if (incr == 0) |
| 131 | incr++; |
| 132 | |
| 133 | // use prev/XOR method for one-time exceptions (but likely less correct) |
| 134 | //u32 prev = cpuRegs.PERF.n.pcr0; |
| 135 | cpuRegs.PERF.n.pcr0 += incr; |
| 136 | //DevCon.Warning("PCR VAL %x", cpuRegs.PERF.n.pccr.val); |
| 137 | //prev ^= (1UL<<31); // XOR is fun! |
| 138 | //if( (prev & cpuRegs.PERF.n.pcr0) & (1UL<<31) ) |
| 139 | if ((cpuRegs.PERF.n.pcr0 & 0x80000000)) |
| 140 | { |
| 141 | // TODO: Vector to the appropriate exception here. |
| 142 | // This code *should* be correct, but is untested (and other parts of the emu are |
| 143 | // not prepared to handle proper Level 2 exception vectors yet) |
| 144 | |
| 145 | //branch == 1 is probably not the best way to check for the delay slot, but it beats nothing! (Refraction) |
| 146 | /* if( branch == 1 ) |
| 147 | { |
| 148 | cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc - 4; |
| 149 | cpuRegs.CP0.n.Cause |= 0x40000000; |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc; |
| 154 | cpuRegs.CP0.n.Cause &= ~0x40000000; |
| 155 | } |
| 156 | |
| 157 | if( cpuRegs.CP0.n.Status.b.DEV ) |
| 158 | { |
| 159 | // Bootstrap vector |
| 160 | cpuRegs.pc = 0xbfc00280; |
| 161 | } |
| 162 | else |
| 163 | { |
| 164 | cpuRegs.pc = 0x80000080; |
| 165 | } |
no test coverage detected