diff --git a/Source/Core/DSPCore/Src/DspIntMisc.cpp b/Source/Core/DSPCore/Src/DspIntMisc.cpp index 3b9deee559..ee7cbe2972 100644 --- a/Source/Core/DSPCore/Src/DspIntMisc.cpp +++ b/Source/Core/DSPCore/Src/DspIntMisc.cpp @@ -42,6 +42,7 @@ void mrr(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_op_write_reg(dreg, val); + dsp_conditional_extend_accum(dreg); } // LRI $D, #I @@ -50,9 +51,10 @@ void mrr(const UDSPInstruction& opc) // Load immediate value I to register $D. // FIXME: Perform additional operation depending on destination register. -// DSPSpy discovery: This, and possibly other instructions that load a register, -// has a different behaviour in S40 mode if loaded to AC0.M: The value gets sign extended -// to the whole accumulator! This does not happen in S16 mode. +// DSPSpy discovery: This, and possibly other instructions that load a +// register, has a different behaviour in S40 mode if loaded to AC0.M: The +// value gets sign extended to the whole accumulator! This does not happen in +// S16 mode. void lri(const UDSPInstruction& opc) { u8 reg = opc.hex & DSP_REG_MASK; @@ -95,8 +97,6 @@ void addarn(const UDSPInstruction& opc) u8 dreg = opc.hex & 0x3; u8 sreg = (opc.hex >> 2) & 0x3; - // g_dsp.r[dreg] += (s16)g_dsp.r[DSP_REG_IX0 + sreg]; - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); // It is critical for the Zelda ucode that this one wraps correctly. @@ -149,24 +149,13 @@ void sbset(const UDSPInstruction& opc) } -// FIXME inside // This is a bunch of flag setters, flipping bits in SR. So far so good, // but it's harder to know exactly what effect they have. -// M0/M2 change the multiplier mode (it can multiply by 2 for free). -// -// SET16 changes something very important: see the LRI instruction above. -// Hermes' demo sets the following defaults: -// SET40 -// CLR15 -// M0 void srbith(const UDSPInstruction& opc) { switch ((opc.hex >> 8) & 0xf) { - // M0 seems to be the default. M2 is used in functions in Zelda - // and then reset with M0 at the end. Like the other bits here, it's - // done around loops with lots of multiplications. - // I've confirmed with DSPSpy that they flip this bit. + // M0/M2 change the multiplier mode (it can multiply by 2 for free). case 0xa: // M2 g_dsp.r[DSP_REG_SR] &= ~SR_MUL_MODIFY; break; @@ -184,13 +173,12 @@ void srbith(const UDSPInstruction& opc) break; // Automatic 40-bit sign extension when loading ACx.M. - // 40 seems to be the default. - // Confirmed these by using DSPSpy and copying the value of SR to R00 after setting. - case 0xe: // SET16 (really, clear SR's 0x4000) + // SET40 changes something very important: see the LRI instruction above. + case 0xe: // SET16 (CLR40) g_dsp.r[DSP_REG_SR] &= ~SR_40_MODE_BIT; break; - case 0xf: // SET40 (really, set SR's 0x4000) + case 0xf: // SET40 g_dsp.r[DSP_REG_SR] |= SR_40_MODE_BIT; break;