Ah, I might have forgotten something.
In RunRSP you applied this:
Code:
void RunRSP()
{
unsigned int TaskType;
// clear all registers
memset(&RspRegs, 0, sizeof(RspRegs));
...
Again, I have no HLE-in-the-plugins experience here, but this raises a couple questions to me.
First, most of the RSP registers are powered on to a randomized/undefined state and value. The exceptions include the 8 RSP accumulator segments and some bits of the system control (CP0) registers and status flags.
The game software is always responsible for initializing these registers after system startup, or else their value is undefined (not necessarily zero'd).
So is it really necessary to zero the memory for RspRegs every time there is an RSP task to execute?
--------
Second, I'm not sure whether this check is really necessary.
Code:
TaskType = *((unsigned int *)(RSP.DMEM + 0xFC0));
if (TaskType == 2)
run_microcode();
When the CPU host knows there is a SP task, it tells the RSP plugin first.
If the RSP plugin judges it to be a audio task, it can request your audio plugin to HLE it.
So you're checking here to make sure it's an audio task in case the RSP plugin was wrong about it being an audio task.
This is stable and safe and fine, but slower because your if() causes an extra branch every time we want to run something in HLE.
The branch frame could be worked around like this:
Code:
if (TaskType != 2)
// MessageBoxA(NULL, "RSP thought this task was aud?", NULL, 0x00000030);
return;
else
run_microcode(); // Rename this to `run_task()` for my next release
Some of that other code (clear SP_STATUS_HALT, reset the program counter) might also be obsolete/redundant since the main CPU (pj64) or indirectly the RSP plugin itself is responsible for maintaining that security, but again you might keep it there just to be safe.