DSPLLE: added lsrnr (based on lordmark and luigi suggestions) Still somethings seems wrong as it didn't fix the zelda problem:(
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3800 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3bc8eb7eaf
commit
90f595bada
|
@ -59,15 +59,14 @@ s16 ADPCM_Step(u32& _rSamplePos)
|
||||||
|
|
||||||
_rSamplePos++;
|
_rSamplePos++;
|
||||||
|
|
||||||
// The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't
|
// The advanced interpolation (linear, polyphase,...) is done by the UCode,
|
||||||
// need to bother with it here.
|
// so we don't need to bother with it here.
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 dsp_read_aram_d3()
|
u16 dsp_read_aram_d3()
|
||||||
{
|
{
|
||||||
// Zelda ucode reads ARAM through 0xffd3.
|
// Zelda ucode reads ARAM through 0xffd3.
|
||||||
|
|
||||||
u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL];
|
u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL];
|
||||||
u8 value = 0;
|
u8 value = 0;
|
||||||
switch (gdsp_ifx_regs[DSP_FORMAT]) {
|
switch (gdsp_ifx_regs[DSP_FORMAT]) {
|
||||||
|
@ -75,7 +74,7 @@ u16 dsp_read_aram_d3()
|
||||||
value = DSPHost_ReadHostMemory(Address);
|
value = DSPHost_ReadHostMemory(Address);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(DSPLLE, "dsp_write_aram_d3: Unseen Format %i", gdsp_ifx_regs[DSP_FORMAT]);
|
ERROR_LOG(DSPLLE, "dsp_read_aram_d3: Unseen Format %i", gdsp_ifx_regs[DSP_FORMAT]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@ -83,9 +82,8 @@ u16 dsp_read_aram_d3()
|
||||||
|
|
||||||
void dsp_write_aram_d3(u16 value)
|
void dsp_write_aram_d3(u16 value)
|
||||||
{
|
{
|
||||||
// Zelda ucode writes a bunch of zeros to ARAM through d3 during initialization.
|
// Zelda ucode writes a bunch of zeros to ARAM through d3 during
|
||||||
// Don't know if it ever does it later, too.
|
// initialization. Don't know if it ever does it later, too.
|
||||||
|
|
||||||
const u32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL];
|
const u32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL];
|
||||||
u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL];
|
u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL];
|
||||||
switch (gdsp_ifx_regs[DSP_FORMAT]) {
|
switch (gdsp_ifx_regs[DSP_FORMAT]) {
|
||||||
|
|
|
@ -161,7 +161,7 @@ void gdsp_ifx_write(u16 addr, u16 val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xd3: // ZeldaUnk (accelerator WRITE)
|
case 0xd3: // ZeldaUnk (accelerator WRITE)
|
||||||
INFO_LOG(DSPLLE, "Write To ZeldaUnk pc=%04x (%04x)", g_dsp.pc, val);
|
NOTICE_LOG(DSPLLE, "Write To ZeldaUnk pc=%04x (%04x)", g_dsp.pc, val);
|
||||||
dsp_write_aram_d3(val);
|
dsp_write_aram_d3(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ u16 gdsp_ifx_read(u16 addr)
|
||||||
return dsp_read_accelerator();
|
return dsp_read_accelerator();
|
||||||
|
|
||||||
case 0xd3:
|
case 0xd3:
|
||||||
ERROR_LOG(DSPLLE, "DSP read aram D3");
|
NOTICE_LOG(DSPLLE, "Read from ZeldaUnk pc=%04x", g_dsp.pc);
|
||||||
return dsp_read_aram_d3();
|
return dsp_read_aram_d3();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -91,7 +91,9 @@ void Step()
|
||||||
ProfilerDump(g_dsp.step_counter);
|
ProfilerDump(g_dsp.step_counter);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// if (g_dsp.pc >= 0x0272 && g_dsp.pc <= 0x0282)
|
||||||
|
// printf("pc %04x acc0 %04x acc1 %04x\n", g_dsp.pc, dsp_get_acc_m(0), dsp_get_acc_m(1));
|
||||||
|
|
||||||
u16 opc = dsp_fetch_code();
|
u16 opc = dsp_fetch_code();
|
||||||
ExecuteInstruction(UDSPInstruction(opc));
|
ExecuteInstruction(UDSPInstruction(opc));
|
||||||
HandleLoop();
|
HandleLoop();
|
||||||
|
|
|
@ -118,6 +118,7 @@ void asl(const UDSPInstruction& opc);
|
||||||
void asr(const UDSPInstruction& opc);
|
void asr(const UDSPInstruction& opc);
|
||||||
void lsrn(const UDSPInstruction& opc);
|
void lsrn(const UDSPInstruction& opc);
|
||||||
void asrn(const UDSPInstruction& opc);
|
void asrn(const UDSPInstruction& opc);
|
||||||
|
void lsrnr(const UDSPInstruction& opc);
|
||||||
void dar(const UDSPInstruction& opc);
|
void dar(const UDSPInstruction& opc);
|
||||||
void iar(const UDSPInstruction& opc);
|
void iar(const UDSPInstruction& opc);
|
||||||
void sbclr(const UDSPInstruction& opc);
|
void sbclr(const UDSPInstruction& opc);
|
||||||
|
|
|
@ -162,7 +162,8 @@ const DSPOPCTemplate opcodes[] =
|
||||||
// discovered by ector!
|
// discovered by ector!
|
||||||
{"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, nop, 1, 0, {}, NULL, NULL},
|
{"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, nop, 1, 0, {}, NULL, NULL},
|
||||||
{"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, nop, 1, 0, {}, NULL, NULL},
|
{"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, nop, 1, 0, {}, NULL, NULL},
|
||||||
|
{"LSRNR", 0x3c80, 0xfeff, DSPInterpreter::lsrnr, nop, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, NULL, NULL},
|
||||||
|
|
||||||
{"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
{"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
||||||
{"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
{"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
||||||
{"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
|
{"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL},
|
||||||
|
@ -269,8 +270,6 @@ const DSPOPCTemplate opcodes[] =
|
||||||
{"XORR", 0x3000, 0xfcff, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"XORR", 0x3000, 0xfcff, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"ANDR", 0x3400, 0xfcff, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"ANDR", 0x3400, 0xfcff, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"ORR", 0x3800, 0xfcff, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"ORR", 0x3800, 0xfcff, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"ANDC", 0x3C00, 0xfeff, DSPInterpreter::andc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
|
|
||||||
{"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
|
|
||||||
|
|
||||||
{"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
|
@ -176,6 +176,7 @@ void orr(const UDSPInstruction& opc)
|
||||||
Update_SR_Register64(acc);
|
Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// ANDC $acD.m, $ac(1-D).m
|
// ANDC $acD.m, $ac(1-D).m
|
||||||
// 0011 110d xxxx xxxx
|
// 0011 110d xxxx xxxx
|
||||||
// Logic AND middle part of accumulator $acD.m with middle part of
|
// Logic AND middle part of accumulator $acD.m with middle part of
|
||||||
|
@ -207,7 +208,7 @@ void orc(const UDSPInstruction& opc)
|
||||||
|
|
||||||
Update_SR_Register64(dsp_get_long_acc(D));
|
Update_SR_Register64(dsp_get_long_acc(D));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void orf(const UDSPInstruction& opc)
|
void orf(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
ERROR_LOG(DSPLLE, "orf not implemented");
|
ERROR_LOG(DSPLLE, "orf not implemented");
|
||||||
|
@ -659,7 +660,7 @@ void asr(const UDSPInstruction& opc)
|
||||||
// (if value negative, becomes left shift).
|
// (if value negative, becomes left shift).
|
||||||
void lsrn(const UDSPInstruction& opc)
|
void lsrn(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
|
s16 shift = dsp_get_acc_m(1);
|
||||||
u64 acc = dsp_get_long_acc(0);
|
u64 acc = dsp_get_long_acc(0);
|
||||||
// Lop off the extraneous sign extension our 64-bit fake accum causes
|
// Lop off the extraneous sign extension our 64-bit fake accum causes
|
||||||
acc &= 0x000000FFFFFFFFFFULL;
|
acc &= 0x000000FFFFFFFFFFULL;
|
||||||
|
@ -679,7 +680,7 @@ void lsrn(const UDSPInstruction& opc)
|
||||||
// (if value negative, becomes left shift).
|
// (if value negative, becomes left shift).
|
||||||
void asrn(const UDSPInstruction& opc)
|
void asrn(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
s16 shift = (s16)g_dsp.r[DSP_REG_ACM1];
|
s16 shift = dsp_get_acc_m(1);
|
||||||
s64 acc = dsp_get_long_acc(0);
|
s64 acc = dsp_get_long_acc(0);
|
||||||
if (shift > 0) {
|
if (shift > 0) {
|
||||||
acc >>= shift;
|
acc >>= shift;
|
||||||
|
@ -690,6 +691,24 @@ void asrn(const UDSPInstruction& opc)
|
||||||
Update_SR_Register64(acc);
|
Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LSRNR $acR
|
||||||
|
// 0011 110d 1100 0000
|
||||||
|
// Logically shifts right accumulator $ACC0 by signed 16-bit value $AC0.M
|
||||||
|
// Not described by Duddie's doc - at least not as a separate instruction.
|
||||||
|
void lsrnr(const UDSPInstruction& opc)
|
||||||
|
{
|
||||||
|
u8 sreg = 1;//Check if it should be (opc.hex >> 8) & 0x1;
|
||||||
|
s16 shift = dsp_get_acc_m(0);
|
||||||
|
u64 acc = dsp_get_long_acc(sreg);
|
||||||
|
acc &= 0x000000FFFFFFFFFFULL;
|
||||||
|
if (shift > 0) {
|
||||||
|
acc <<= shift;
|
||||||
|
} else if (shift < 0) {
|
||||||
|
acc >>= -shift;
|
||||||
|
}
|
||||||
|
dsp_set_long_acc(sreg, acc);
|
||||||
|
Update_SR_Register64(acc);
|
||||||
|
}
|
||||||
|
|
||||||
// CMPAR $acS axR.h
|
// CMPAR $acS axR.h
|
||||||
// 1100 0001 xxxx xxxx
|
// 1100 0001 xxxx xxxx
|
||||||
|
@ -709,6 +728,7 @@ void cmpar(const UDSPInstruction& opc)
|
||||||
Update_SR_Register64(sr - rr);
|
Update_SR_Register64(sr - rr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CMP
|
// CMP
|
||||||
// 1000 0010 xxxx xxxx
|
// 1000 0010 xxxx xxxx
|
||||||
// Compares accumulator $ac0 with accumulator $ac1.
|
// Compares accumulator $ac0 with accumulator $ac1.
|
||||||
|
|
Loading…
Reference in New Issue