mirror of
https://github.com/n64dev/cen64.git
synced 2024-05-12 01:15:33 -04:00
87ebca00b5
1) Setting SP_PC was not resetting the pipeline. This caused that changing the PC within a HALT/UNHALT sequence was still causing previous instructions in the pipeline (at the old address) to be executed. This is not how the hardware works: SP_PC is immediate and discards the whole pipeline. 2) BREAK did not correctly halt the processor at the right instruction, which in turn caused resumption after HALT to execute the wrong set of instructions. This was caused by the fact that the SP_STATUS change was written into the EXDF latch, which in turn takes 3 cycles to reach completion. Instead, we now use the DFWB latch, and we cause it to abort the RSP cycle if the processor is halted. This happens at the beginning of next cycle, which is the correct moment. 2bis) Since we are at it, use rsp_status_write to modify the RSP in this case, rather than a direct write to the register. This change fixes a race condition: SP_STATUS must be accessed atomically when cen64 runs in multithreaded mode. To use rsp_status_write, we need to introduce a nonexisting SP_SET_BROKE bit: we use the MSB, but then mask it out in MTC0 to avoid some code to inadvertently have that bit set. 3) When unhalting after BREAK, it's important to keep the correct PC which comes from the EX stage (the one that was going to be executed if BREAK didn't occur). Before, it was using the IF PC (fetch) which is farther in the future. Fixes #155 |
||
---|---|---|
.. | ||
cp0.c | ||
cp0.h | ||
cp2.c | ||
cp2.h | ||
cpu.c | ||
cpu.h | ||
decoder.c | ||
decoder.h | ||
functions.c | ||
interface.c | ||
interface.h | ||
opcodes.c | ||
opcodes.h | ||
opcodes.md | ||
opcodes_priv.h | ||
pipeline.c | ||
pipeline.h | ||
registers.md | ||
vector_opcodes.md | ||
vfunctions.c |