mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-16 12:58:33 +02:00
DSPLLE - flags&stuff,xar->subarn,0x80 kinda figured out,... (experimental)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5174 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -25,12 +25,6 @@
|
||||
|
||||
namespace DSPInterpreter {
|
||||
|
||||
void unknown(const UDSPInstruction& opc)
|
||||
{
|
||||
//_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
|
||||
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
|
||||
}
|
||||
|
||||
// MRR $D, $S
|
||||
// 0001 11dd ddds ssss
|
||||
// Move value from register $S to register $D.
|
||||
@ -50,7 +44,7 @@ void mrr(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 S40 mode if loaded to AC0.M: The
|
||||
// value gets sign extended to the whole accumulator! This does not happen in
|
||||
@ -75,45 +69,21 @@ void lris(const UDSPInstruction& opc)
|
||||
dsp_conditional_extend_accum(reg);
|
||||
}
|
||||
|
||||
|
||||
// TSTAXL $acR
|
||||
// 1000 r001 xxxx xxxx
|
||||
// r specifies one of the main accumulators.
|
||||
// Definitely not a test instruction - it changes the accums.
|
||||
// Not affected by m0/m2. Not affected by s16/s40.
|
||||
void tstaxl(const UDSPInstruction& opc)
|
||||
{
|
||||
// This is probably all wrong.
|
||||
//u8 reg = (opc.hex >> 8) & 0x1;
|
||||
//s16 val = dsp_get_ax_l(reg);
|
||||
//Update_SR_Register16(val);
|
||||
}
|
||||
|
||||
// ADDARN $arD, $ixS
|
||||
// 0000 0000 0001 ssdd
|
||||
// Adds indexing register $ixS to an addressing register $arD.
|
||||
void addarn(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 dreg = opc.hex & 0x3;
|
||||
u8 sreg = (opc.hex >> 2) & 0x3;
|
||||
|
||||
g_dsp.r[dreg] = 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.
|
||||
}
|
||||
//----
|
||||
|
||||
// NX
|
||||
// 1000 -000 xxxx xxxx
|
||||
// No operation, but can be extended with extended opcode.
|
||||
// This opcode is supposed to do nothing - it's used if you want to use
|
||||
// an opcode extension but not do anything. At least according to duddie.
|
||||
void nx(const UDSPInstruction& opc)
|
||||
{
|
||||
zeroWriteBackLog();
|
||||
// This opcode is supposed to do nothing - it's used if you want to use
|
||||
// an opcode extension but not do anything. At least according to duddie.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// DAR $arD ?
|
||||
//----
|
||||
|
||||
// DAR $arD
|
||||
// 0000 0000 0000 01dd
|
||||
// Decrement address register $arD.
|
||||
void dar(const UDSPInstruction& opc)
|
||||
@ -121,7 +91,7 @@ void dar(const UDSPInstruction& opc)
|
||||
g_dsp.r[opc.hex & 0x3] = dsp_decrement_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
// IAR $arD ?
|
||||
// IAR $arD
|
||||
// 0000 0000 0000 10dd
|
||||
// Increment address register $arD.
|
||||
void iar(const UDSPInstruction& opc)
|
||||
@ -129,37 +99,49 @@ void iar(const UDSPInstruction& opc)
|
||||
g_dsp.r[opc.hex & 0x3] = dsp_increment_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
// XAR $arD ?
|
||||
// SUBARN $arD
|
||||
// 0000 0000 0000 11dd
|
||||
// $arD result somehow depends on $wrD
|
||||
// unknown atm
|
||||
// used in IPL ucode
|
||||
void xar(const UDSPInstruction& opc)
|
||||
// Subtract indexing register $ixD from an addressing register $arD.
|
||||
// used only in IPL-NTSC ucode
|
||||
void subarn(const UDSPInstruction& opc)
|
||||
{
|
||||
// u8 dreg = opc.hex & 0x3;
|
||||
u8 dreg = opc.hex & 0x3;
|
||||
g_dsp.r[dreg] = dsp_decrease_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
|
||||
}
|
||||
|
||||
// ADDARN $arD, $ixS
|
||||
// 0000 0000 0001 ssdd
|
||||
// Adds indexing register $ixS to an addressing register $arD.
|
||||
// It is critical for the Zelda ucode that this one wraps correctly.
|
||||
void addarn(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 dreg = opc.hex & 0x3;
|
||||
u8 sreg = (opc.hex >> 2) & 0x3;
|
||||
g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
|
||||
}
|
||||
|
||||
//----
|
||||
|
||||
// SBCLR #I
|
||||
// 0001 0011 0000 0iii
|
||||
// 0001 0011 aaaa aiii
|
||||
// bit of status register $sr. Bit number is calculated by adding 6 to
|
||||
// immediate value I.
|
||||
void sbclr(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 bit = (opc.hex & 0xff) + 6;
|
||||
u8 bit = (opc.hex & 0x7) + 6;
|
||||
g_dsp.r[DSP_REG_SR] &= ~(1 << bit);
|
||||
}
|
||||
|
||||
// SBSET #I
|
||||
// 0001 0010 0000 0iii
|
||||
// 0001 0010 aaaa aiii
|
||||
// Set bit of status register $sr. Bit number is calculated by adding 6 to
|
||||
// immediate value I.
|
||||
void sbset(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 bit = (opc.hex & 0xff) + 6;
|
||||
u8 bit = (opc.hex & 0x7) + 6;
|
||||
g_dsp.r[DSP_REG_SR] |= (1 << bit);
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
void srbith(const UDSPInstruction& opc)
|
||||
@ -199,4 +181,11 @@ void srbith(const UDSPInstruction& opc)
|
||||
}
|
||||
}
|
||||
|
||||
//----
|
||||
|
||||
void unknown(const UDSPInstruction& opc)
|
||||
{
|
||||
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user