mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-05-02 14:58:03 +03:00
DSP: make all logical operations set the logical SR_LOGIC_ZERO flag instead of the arithmetic flags
assumed 0x20 is a mistake and suppose to be the logical zero flag Couldn't see any change whatsoever. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2975 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
20be60f9b9
commit
99e29c82fd
5 changed files with 72 additions and 62 deletions
|
@ -35,14 +35,6 @@ void unknown(const UDSPInstruction& opc)
|
||||||
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
|
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test register and updates SR accordingly
|
|
||||||
void tsta(int reg)
|
|
||||||
{
|
|
||||||
s64 acc = dsp_get_long_acc(reg);
|
|
||||||
|
|
||||||
Update_SR_Register64(acc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic call implementation
|
// Generic call implementation
|
||||||
// CALLcc addressA
|
// CALLcc addressA
|
||||||
// 0000 0010 1011 cccc
|
// 0000 0010 1011 cccc
|
||||||
|
@ -669,7 +661,10 @@ void cmp(const UDSPInstruction& opc)
|
||||||
// Test accumulator %acR.
|
// Test accumulator %acR.
|
||||||
void tst(const UDSPInstruction& opc)
|
void tst(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
tsta((opc.hex >> 11) & 0x1);
|
s8 reg = (opc.hex >> 11) & 0x1;
|
||||||
|
s64 acc = dsp_get_long_acc(reg);
|
||||||
|
|
||||||
|
Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDAXL $acD, $axS.l
|
// ADDAXL $acD, $axS.l
|
||||||
|
@ -767,7 +762,10 @@ void xorr(const UDSPInstruction& opc)
|
||||||
|
|
||||||
g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg];
|
g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg];
|
||||||
|
|
||||||
tsta(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
|
|
||||||
|
Update_SR_LZ(acc);
|
||||||
|
// tsta(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANDR $acD.m, $axS.h
|
// ANDR $acD.m, $axS.h
|
||||||
|
@ -781,7 +779,10 @@ void andr(const UDSPInstruction& opc)
|
||||||
|
|
||||||
g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg];
|
g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg];
|
||||||
|
|
||||||
tsta(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
|
|
||||||
|
Update_SR_LZ(acc);
|
||||||
|
// tsta(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ORR $acD.m, $axS.h
|
// ORR $acD.m, $axS.h
|
||||||
|
@ -796,7 +797,11 @@ void orr(const UDSPInstruction& opc)
|
||||||
|
|
||||||
g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg];
|
g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg];
|
||||||
|
|
||||||
tsta(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
|
|
||||||
|
Update_SR_LZ(acc);
|
||||||
|
|
||||||
|
// tsta(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANDC $acD.m, $ac(1-D).m
|
// ANDC $acD.m, $ac(1-D).m
|
||||||
|
@ -812,21 +817,25 @@ void andc(const UDSPInstruction& opc)
|
||||||
|
|
||||||
dsp_set_long_acc(D, ac1 & ac2);
|
dsp_set_long_acc(D, ac1 & ac2);
|
||||||
|
|
||||||
if ((ac1 & ac2) == 0)
|
Update_SR_LZ(dsp_get_long_acc(D));
|
||||||
{
|
// Update_SR_Register64(dsp_get_long_acc(D));
|
||||||
g_dsp.r[DSP_REG_SR] |= 0x20; // 0x40?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_dsp.r[DSP_REG_SR] &= ~0x20; // 0x40?
|
|
||||||
}
|
|
||||||
|
|
||||||
Update_SR_Register64(dsp_get_long_acc(D));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ORC $acD.m, $ac(1-D).m
|
||||||
|
// 0011 111d xxxx xxxx
|
||||||
|
// Logic OR middle part of accumulator $acD.m with middle part of
|
||||||
|
// accumulator $ax(1-D).m.
|
||||||
void orc(const UDSPInstruction& opc)
|
void orc(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
ERROR_LOG(DSPLLE, "orc not implemented");
|
u8 D = (opc.hex >> 8) & 0x1;
|
||||||
|
|
||||||
|
u16 ac1 = dsp_get_acc_m(D);
|
||||||
|
u16 ac2 = dsp_get_acc_m(1 - D);
|
||||||
|
|
||||||
|
dsp_set_long_acc(D, ac1 | ac2);
|
||||||
|
|
||||||
|
Update_SR_LZ(dsp_get_long_acc(D));
|
||||||
|
// Update_SR_Register64(dsp_get_long_acc(D));
|
||||||
}
|
}
|
||||||
|
|
||||||
void orf(const UDSPInstruction& opc)
|
void orf(const UDSPInstruction& opc)
|
||||||
|
@ -849,21 +858,14 @@ void nx(const UDSPInstruction& opc)
|
||||||
// 0000 001r 1100 0000
|
// 0000 001r 1100 0000
|
||||||
// iiii iiii iiii iiii
|
// iiii iiii iiii iiii
|
||||||
// Set logic zero (LZ) flag in status register $sr if result of logic AND of
|
// Set logic zero (LZ) flag in status register $sr if result of logic AND of
|
||||||
// accumulator mid part $acD.m with immediate value I is equal zero.
|
// accumulator mid part $acD.m with immediate value I is equal I.
|
||||||
void andfc(const UDSPInstruction& opc)
|
void andcf(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc.hex >> 8) & 0x1;
|
u8 reg = (opc.hex >> 8) & 0x1;
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
u16 val = dsp_get_acc_m(reg);
|
u16 val = dsp_get_acc_m(reg);
|
||||||
|
|
||||||
if ((val & imm) == imm)
|
Update_SR_LZ(((val & imm) == imm)?0:1);
|
||||||
{
|
|
||||||
g_dsp.r[DSP_REG_SR] |= 0x40;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_dsp.r[DSP_REG_SR] &= ~0x40;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hermes switched andf and andcf, so check to make sure they are still correct
|
// Hermes switched andf and andcf, so check to make sure they are still correct
|
||||||
|
@ -873,7 +875,7 @@ void andfc(const UDSPInstruction& opc)
|
||||||
// iiii iiii iiii iiii
|
// iiii iiii iiii iiii
|
||||||
// Set logic zero (LZ) flag in status register $sr if result of logical AND
|
// Set logic zero (LZ) flag in status register $sr if result of logical AND
|
||||||
// operation of accumulator mid part $acD.m with immediate value I is equal
|
// operation of accumulator mid part $acD.m with immediate value I is equal
|
||||||
// immediate value I.
|
// immediate value 0.
|
||||||
void andf(const UDSPInstruction& opc)
|
void andf(const UDSPInstruction& opc)
|
||||||
{
|
{
|
||||||
u8 reg;
|
u8 reg;
|
||||||
|
@ -884,14 +886,7 @@ void andf(const UDSPInstruction& opc)
|
||||||
imm = dsp_fetch_code();
|
imm = dsp_fetch_code();
|
||||||
val = g_dsp.r[reg];
|
val = g_dsp.r[reg];
|
||||||
|
|
||||||
if ((val & imm) == 0)
|
Update_SR_LZ(((val & imm) == 0)?0:1);
|
||||||
{
|
|
||||||
g_dsp.r[DSP_REG_SR] |= 0x40;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_dsp.r[DSP_REG_SR] &= ~0x40;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMPI $amD, #I
|
// CMPI $amD, #I
|
||||||
|
@ -922,7 +917,8 @@ void xori(const UDSPInstruction& opc)
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[reg] ^= imm;
|
g_dsp.r[reg] ^= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[reg]);
|
Update_SR_LZ(g_dsp.r[reg]);
|
||||||
|
// Update_SR_Register16((s16)g_dsp.r[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANDI $acD.m, #I
|
// ANDI $acD.m, #I
|
||||||
|
@ -935,7 +931,8 @@ void andi(const UDSPInstruction& opc)
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[reg] &= imm;
|
g_dsp.r[reg] &= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[reg]);
|
Update_SR_LZ(g_dsp.r[reg]);
|
||||||
|
// Update_SR_Register16((s16)g_dsp.r[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -950,7 +947,8 @@ void ori(const UDSPInstruction& opc)
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[reg] |= imm;
|
g_dsp.r[reg] |= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[reg]);
|
Update_SR_LZ(g_dsp.r[reg]);
|
||||||
|
// Update_SR_Register16((s16)g_dsp.r[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
|
@ -1258,8 +1256,8 @@ void lsl16(const UDSPInstruction& opc)
|
||||||
s64 acc = dsp_get_long_acc(areg);
|
s64 acc = dsp_get_long_acc(areg);
|
||||||
acc <<= 16;
|
acc <<= 16;
|
||||||
dsp_set_long_acc(areg, acc);
|
dsp_set_long_acc(areg, acc);
|
||||||
|
Update_SR_LZ(acc);
|
||||||
Update_SR_Register64(acc);
|
// Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MADD $axS.l, $axS.h
|
// MADD $axS.l, $axS.h
|
||||||
|
@ -1306,8 +1304,8 @@ void lsr16(const UDSPInstruction& opc)
|
||||||
|
|
||||||
acc >>= 16;
|
acc >>= 16;
|
||||||
dsp_set_long_acc(areg, acc);
|
dsp_set_long_acc(areg, acc);
|
||||||
|
Update_SR_LZ(acc);
|
||||||
Update_SR_Register64(acc);
|
// Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASR16 $acR
|
// ASR16 $acR
|
||||||
|
@ -1335,8 +1333,8 @@ void lsl(const UDSPInstruction& opc)
|
||||||
|
|
||||||
acc <<= shift;
|
acc <<= shift;
|
||||||
dsp_set_long_acc(opc.areg, acc);
|
dsp_set_long_acc(opc.areg, acc);
|
||||||
|
Update_SR_LZ(acc);
|
||||||
Update_SR_Register64(acc);
|
// Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LSR $acR, #I
|
// LSR $acR, #I
|
||||||
|
@ -1351,8 +1349,8 @@ void lsr(const UDSPInstruction& opc)
|
||||||
acc &= 0x000000FFFFFFFFFFULL;
|
acc &= 0x000000FFFFFFFFFFULL;
|
||||||
acc >>= shift;
|
acc >>= shift;
|
||||||
dsp_set_long_acc(opc.areg, (s64)acc);
|
dsp_set_long_acc(opc.areg, (s64)acc);
|
||||||
|
Update_SR_LZ(acc);
|
||||||
Update_SR_Register64(acc);
|
// Update_SR_Register64(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASL $acR, #I
|
// ASL $acR, #I
|
||||||
|
|
|
@ -129,7 +129,7 @@ void ilrr(const UDSPInstruction& opc);
|
||||||
void ilrrd(const UDSPInstruction& opc);
|
void ilrrd(const UDSPInstruction& opc);
|
||||||
void ilrri(const UDSPInstruction& opc);
|
void ilrri(const UDSPInstruction& opc);
|
||||||
void ilrrn(const UDSPInstruction& opc);
|
void ilrrn(const UDSPInstruction& opc);
|
||||||
void andfc(const UDSPInstruction& opc);
|
void andcf(const UDSPInstruction& opc);
|
||||||
void andf(const UDSPInstruction& opc);
|
void andf(const UDSPInstruction& opc);
|
||||||
void xori(const UDSPInstruction& opc);
|
void xori(const UDSPInstruction& opc);
|
||||||
void andi(const UDSPInstruction& opc);
|
void andi(const UDSPInstruction& opc);
|
||||||
|
|
|
@ -176,7 +176,7 @@ const DSPOPCTemplate opcodes[] =
|
||||||
{"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
|
{"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
|
||||||
{"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
|
{"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, NULL, NULL},
|
||||||
{"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
|
{"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
|
||||||
{"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andfc, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
|
{"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL,},
|
||||||
|
|
||||||
{"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
{"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
||||||
{"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
{"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
|
||||||
|
@ -225,8 +225,6 @@ const DSPOPCTemplate opcodes[] =
|
||||||
// calculations or something? Or clamp?
|
// calculations or something? Or clamp?
|
||||||
// SET15/CLR15 is commonly used around MULXAC in Zeldas.
|
// SET15/CLR15 is commonly used around MULXAC in Zeldas.
|
||||||
// SET16 is done around complicated loops with many madds etc.
|
// SET16 is done around complicated loops with many madds etc.
|
||||||
// It seems SET16 come in all cases found with either CR or IR (almost always with AR3)
|
|
||||||
// Set40 also comes with CR and AR3, but it's not common enough to see the connection.
|
|
||||||
{"CLR15", 0x8c00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"CLR15", 0x8c00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"SET15", 0x8d00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"SET15", 0x8d00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"SET40", 0x8e00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"SET40", 0x8e00, 0xffff, DSPInterpreter::srbith, nop, 1 | P_EXT, 0, {}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Update_SR_Register64(s64 _Value)
|
||||||
// weird
|
// weird
|
||||||
if ((_Value >> 62) == 0)
|
if ((_Value >> 62) == 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= 0x20;
|
Update_SR_LZ(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,23 @@ void Update_SR_Register16(s16 _Value)
|
||||||
// weird
|
// weird
|
||||||
if ((_Value >> 14) == 0)
|
if ((_Value >> 14) == 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= 0x20;
|
Update_SR_LZ(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Update_SR_LZ(s64 value) {
|
||||||
|
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// If this always returns 1, Hermes' demo sounds better.
|
// If this always returns 1, Hermes' demo sounds better.
|
||||||
// However, most AX games are negatively affected.
|
// However, most AX games are negatively affected.
|
||||||
int GetMultiplyModifier()
|
int GetMultiplyModifier()
|
||||||
|
@ -133,13 +146,13 @@ bool CheckCondition(u8 _Condition)
|
||||||
|
|
||||||
case 0xc: // LNZ - LOGIC NOT ZERO
|
case 0xc: // LNZ - LOGIC NOT ZERO
|
||||||
|
|
||||||
if (!(g_dsp.r[DSP_REG_SR] & 0x40))
|
if (!(g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO))
|
||||||
taken = true;
|
taken = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xd: // LZ - LOGIC ZERO
|
case 0xd: // LZ - LOGIC ZERO
|
||||||
|
|
||||||
if (g_dsp.r[DSP_REG_SR] & 0x40)
|
if (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO)
|
||||||
taken = true;
|
taken = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ int GetMultiplyModifier();
|
||||||
|
|
||||||
void Update_SR_Register16(s16 _Value);
|
void Update_SR_Register16(s16 _Value);
|
||||||
void Update_SR_Register64(s64 _Value);
|
void Update_SR_Register64(s64 _Value);
|
||||||
|
void Update_SR_LZ(s64 value);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue