DSP: Comment some new discoveries.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3001 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-04-18 20:44:42 +00:00
parent 1e10c567ff
commit 10989fda06
2 changed files with 24 additions and 24 deletions

View File

@ -448,6 +448,10 @@ void ilrrn(const UDSPInstruction& opc)
// iiii iiii iiii iiii
// 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 S16 mode if loaded to AC0.M: The value gets sign extended
// to the whole accumulator! This does not happen in s40 mode.
void lri(const UDSPInstruction& opc)
{
u8 reg = opc.hex & DSP_REG_MASK;
@ -1437,15 +1441,15 @@ void sbset(const UDSPInstruction& opc)
// FIXME inside
// This seem to be a bunch of bit setters, possibly flippig bits in SR.
// These bits may have effects on the operation of the multiplier or
// accumulators.
// Hermes' demo sets the following defaults, hence that's the most important
// mode to explore for the moment:
// SET40
// CLR15
// 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
// Gonna be fun to explore all 8 possible combinations .. ugh.
void srbith(const UDSPInstruction& opc)
{
switch ((opc.hex >> 8) & 0xf)
@ -1454,37 +1458,32 @@ void srbith(const UDSPInstruction& opc)
// 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.
case 0xa: // M2
case 0xa: // M2
g_dsp.r[DSP_REG_SR] &= ~SR_MUL_MODIFY;
break;
// FIXME: Both of these appear in the beginning of the Wind Waker
case 0xb: // M0
case 0xb: // M0
g_dsp.r[DSP_REG_SR] |= SR_MUL_MODIFY;
break;
// 15-bit precision? clamping? no idea :(
// CLR15 seems to be the default.
// nakee: It seems to come around mul operation, and it explains what sets the mul bit. But if so why not set/clr14?
case 0xc: // CLR15
case 0xc: // CLR15
g_dsp.r[DSP_REG_SR] &= ~SR_TOP_BIT_UNK;
//ERROR_LOG(DSPLLE, "CLR15");
break;
case 0xd: // SET15
case 0xd: // SET15
g_dsp.r[DSP_REG_SR] |= SR_TOP_BIT_UNK;
//ERROR_LOG(DSPLLE, "SET15");
break;
// 40-bit precision? clamping? no idea :(
// 40 seems to be the default.
case 0xe: // SET40 (really, clear SR's 0x4000?) something about "set 40-bit operation"?
//g_dsp.r[DSP_REG_SR] &= ~(1 << 14);
//ERROR_LOG(DSPLLE, "SET40");
// Confirmed these by using DSPSpy and copying the value of SR to R00 after setting.
case 0xe: // SET40 (really, clear SR's 0x4000) something about "set 40-bit operation"?
g_dsp.r[DSP_REG_SR] &= ~SR_16_BIT;
break;
case 0xf: // SET16 (really, set SR's 0x4000?) something about "set 16-bit operation"?
// that doesnt happen on a real console << what does this comment mean?
//g_dsp.r[DSP_REG_SR] |= (1 << 14);
//ERROR_LOG(DSPLLE, "SET16");
case 0xf: // SET16 (really, set SR's 0x4000) something about "set 16-bit operation"?
g_dsp.r[DSP_REG_SR] |= SR_16_BIT;
break;
default:

View File

@ -99,8 +99,9 @@
#define SR_TOP2BITS 0x0020 // this is an odd one.
#define SR_LOGIC_ZERO 0x0040 // ?? duddie's doc sometimes say & 1<<6 (0x40), sometimes 1<<14 (0x4000), while we have 0x20 .. eh
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2
#define SR_TOP_BIT_UNK 0x8000 // 1 = normal. 0 = x2
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
#define SR_TOP_BIT_UNK 0x8000 // 1 = normal. 0 = x2 (CLR15, SET15)
#define SR_16_BIT 0x4000 // 1 = "16", 0 = "40" (SET40, SET16) .. actually, seems it's the reverse. Controls sign extension when loading mid accums.
void dsp_reg_store_stack(u8 stack_reg, u16 val);
u16 dsp_reg_load_stack(u8 stack_reg);