DSP: Restore CMPI and its disasm. Attempt a correct implementation but results seem worse, dunno :p (playing around with Hermes' DSP demos). Fix error logging to log pc-1 instead of pc since pc has already been incremented. minor cleanups.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2881 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-04-05 16:58:15 +00:00
parent 4832ffa377
commit 4913912dbb
5 changed files with 51 additions and 38 deletions

View File

@ -32,8 +32,7 @@ namespace DSPInterpreter {
void unknown(const UDSPInstruction& opc) void unknown(const UDSPInstruction& opc)
{ {
//_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception"); //_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
ERROR_LOG(DSPHLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc); ERROR_LOG(DSPHLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc.hex, g_dsp.pc - 1);
/*PanicAlert("LLE: Unrecognized opcode 0x%04x", opc.hex);*/
//g_dsp.pc = g_dsp.err_pc; //g_dsp.pc = g_dsp.err_pc;
} }
@ -602,7 +601,7 @@ void andf(const UDSPInstruction& opc)
} }
// FIXME inside // FIXME inside
void subf(const UDSPInstruction& opc) void cmpi(const UDSPInstruction& opc)
{ {
if (opc.hex & 0xf) if (opc.hex & 0xf)
{ {
@ -610,6 +609,8 @@ void subf(const UDSPInstruction& opc)
ERROR_LOG(DSPHLE, "dsp subf opcode"); ERROR_LOG(DSPHLE, "dsp subf opcode");
} }
#if 1
// Old implementation
u8 reg = 0x1e + ((opc.hex >> 8) & 0x1); u8 reg = 0x1e + ((opc.hex >> 8) & 0x1);
s64 imm = (s16)dsp_fetch_code(); s64 imm = (s16)dsp_fetch_code();
@ -617,6 +618,18 @@ void subf(const UDSPInstruction& opc)
s64 res = val - imm; s64 res = val - imm;
Update_SR_Register64(res); Update_SR_Register64(res);
#else
// Implementation according to docs
int reg = (opc.hex >> 8) & 0x1;
// Immediate is considered to be at M level in the 40-bit accumulator.
s64 imm = (s64)dsp_fetch_code() << 16;
s64 val = dsp_get_long_acc(reg);
s64 res = val - imm;
Update_SR_Register64(res);
#endif
} }
// FIXME inside // FIXME inside

View File

@ -117,7 +117,7 @@ void srbith(const UDSPInstruction& opc);
void andfc(const UDSPInstruction& opc); void andfc(const UDSPInstruction& opc);
void andf(const UDSPInstruction& opc); void andf(const UDSPInstruction& opc);
void subf(const UDSPInstruction& opc); void cmpi(const UDSPInstruction& opc);
void xori(const UDSPInstruction& opc); void xori(const UDSPInstruction& opc);
void andi(const UDSPInstruction& opc); void andi(const UDSPInstruction& opc);
void ori(const UDSPInstruction& opc); void ori(const UDSPInstruction& opc);

View File

@ -56,6 +56,10 @@ jnz, ifs, retlnz
#include "gdsp_ext_op.h" #include "gdsp_ext_op.h"
void nop(const UDSPInstruction& opc) {/*DSPInterpreter::unknown(opc);*/} void nop(const UDSPInstruction& opc) {/*DSPInterpreter::unknown(opc);*/}
// "Unrecognized opcode 0x01a2, pc 0x0165" seems wrong.
// TODO: Fill up the tables with the corresponding instructions // TODO: Fill up the tables with the corresponding instructions
DSPOPCTemplate opcodes[] = DSPOPCTemplate opcodes[] =
@ -171,8 +175,8 @@ DSPOPCTemplate opcodes[] =
{"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, {"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
{"ORF", 0x02e0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // Hermes: ??? (has it commented out) {"ORF", 0x02e0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // Hermes: ??? (has it commented out)
{"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // F|RES: missing S64 {"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, // F|RES: missing S64
{"SUBF", 0x0280, 0xfeff, DSPInterpreter::subf, nop, 1, 2, {{P_REG, 1, 0, 8, 0x0100}}, NULL, NULL}, {"CMPI", 0x0280, 0xfeff, DSPInterpreter::cmpi, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL},
{"ILRR", 0x0210, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL}, {"ILRR", 0x0210, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL},
{"ILRRD", 0x0214, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL}, // Hermes doesn't list this {"ILRRD", 0x0214, 0xfedc, DSPInterpreter::ilrr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL}, // Hermes doesn't list this
@ -317,15 +321,15 @@ dspInstFunc epilogueTable[OPTABLE_SIZE];
void InitInstructionTable() void InitInstructionTable()
{ {
for(u32 i = 0; i < OPTABLE_SIZE; i++) { for (u32 i = 0; i < OPTABLE_SIZE; i++) {
opTable[i] = DSPInterpreter::unknown; opTable[i] = DSPInterpreter::unknown;
prologueTable[i] = NULL; prologueTable[i] = NULL;
epilogueTable[i] = NULL; epilogueTable[i] = NULL;
} }
for(u32 i = 0; i < OPTABLE_SIZE; i++) { for (u32 i = 0; i < OPTABLE_SIZE; i++) {
for(u32 j = 0; j < opcodes_size; j++) for (u32 j = 0; j < opcodes_size; j++)
if((opcodes[j].opcode_mask & i) == opcodes[j].opcode) { if ((opcodes[j].opcode_mask & i) == opcodes[j].opcode) {
if (opTable[i] == DSPInterpreter::unknown) { if (opTable[i] == DSPInterpreter::unknown) {
opTable[i] = opcodes[j].interpFunc; opTable[i] = opcodes[j].interpFunc;
prologueTable[i] = opcodes[j].prologue; prologueTable[i] = opcodes[j].prologue;
@ -339,11 +343,11 @@ void InitInstructionTable()
void ComputeInstruction(const UDSPInstruction& inst) void ComputeInstruction(const UDSPInstruction& inst)
{ {
if(prologueTable[inst.hex]) if (prologueTable[inst.hex])
prologueTable[inst.hex](inst); prologueTable[inst.hex](inst);
opTable[inst.hex](inst); opTable[inst.hex](inst);
if(epilogueTable[inst.hex]) if (epilogueTable[inst.hex])
epilogueTable[inst.hex](inst); epilogueTable[inst.hex](inst);
} }

View File

@ -55,7 +55,7 @@ void (*SDSP::irq_request)() = NULL;
bool SDSP::exception_in_progress_hack = false; // should be replaced with bit9 in SR? bool SDSP::exception_in_progress_hack = false; // should be replaced with bit9 in SR?
// for debugger only // for debugger only
bool SDSP::dump_imem = false; bool SDSP::dump_imem = true;
u32 SDSP::iram_crc = 0; u32 SDSP::iram_crc = 0;
u64 SDSP::step_counter = 0; u64 SDSP::step_counter = 0;

View File

@ -41,15 +41,14 @@
// //
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
inline void dsp_SR_set_flag(u8 flag) inline void dsp_SR_set_flag(int flag)
{ {
g_dsp.r[R_SR] |= (1 << flag); g_dsp.r[R_SR] |= (1 << flag);
} }
inline bool dsp_SR_is_flag_set(int flag)
inline bool dsp_SR_is_flag_set(u8 flag)
{ {
return((g_dsp.r[R_SR] & (1 << flag)) > 0); return (g_dsp.r[R_SR] & (1 << flag)) != 0;
} }
@ -77,7 +76,7 @@ inline u16 dsp_op_read_reg(u8 reg)
break; break;
} }
return(val); return val;
} }
@ -146,7 +145,7 @@ inline void dsp_set_long_prod(s64 val)
// //
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
inline s64 dsp_get_long_acc(u8 reg) inline s64 dsp_get_long_acc(int reg)
{ {
#if PROFILE #if PROFILE
ProfilerAddDelta(g_dsp.err_pc, 1); ProfilerAddDelta(g_dsp.err_pc, 1);
@ -161,11 +160,11 @@ inline s64 dsp_get_long_acc(u8 reg)
low_acc <<= 16; low_acc <<= 16;
low_acc |= g_dsp.r[0x1c + reg]; low_acc |= g_dsp.r[0x1c + reg];
val |= low_acc; val |= low_acc;
return(val); return val;
} }
inline u64 dsp_get_ulong_acc(u8 reg) inline u64 dsp_get_ulong_acc(int reg)
{ {
#if PROFILE #if PROFILE
ProfilerAddDelta(g_dsp.err_pc, 1); ProfilerAddDelta(g_dsp.err_pc, 1);
@ -180,11 +179,11 @@ inline u64 dsp_get_ulong_acc(u8 reg)
low_acc <<= 16; low_acc <<= 16;
low_acc |= g_dsp.r[0x1c + reg]; low_acc |= g_dsp.r[0x1c + reg];
val |= low_acc; val |= low_acc;
return(val); return val;
} }
inline void dsp_set_long_acc(u8 _reg, s64 val) inline void dsp_set_long_acc(int _reg, s64 val)
{ {
#if PROFILE #if PROFILE
ProfilerAddDelta(g_dsp.err_pc, 1); ProfilerAddDelta(g_dsp.err_pc, 1);
@ -199,24 +198,24 @@ inline void dsp_set_long_acc(u8 _reg, s64 val)
} }
inline s16 dsp_get_acc_l(u8 _reg) inline s16 dsp_get_acc_l(int _reg)
{ {
_assert_(_reg < 2); _assert_(_reg < 2);
return(g_dsp.r[0x1c + _reg]); return g_dsp.r[0x1c + _reg];
} }
inline s16 dsp_get_acc_m(u8 _reg) inline s16 dsp_get_acc_m(int _reg)
{ {
_assert_(_reg < 2); _assert_(_reg < 2);
return(g_dsp.r[0x1e + _reg]); return g_dsp.r[0x1e + _reg];
} }
inline s16 dsp_get_acc_h(u8 _reg) inline s16 dsp_get_acc_h(int _reg)
{ {
_assert_(_reg < 2); _assert_(_reg < 2);
return(g_dsp.r[0x10 + _reg]); return g_dsp.r[0x10 + _reg];
} }
@ -227,7 +226,7 @@ inline s16 dsp_get_acc_h(u8 _reg)
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
inline s64 dsp_get_long_acx(u8 _reg) inline s64 dsp_get_long_acx(int _reg)
{ {
#if PROFILE #if PROFILE
ProfilerAddDelta(g_dsp.err_pc, 1); ProfilerAddDelta(g_dsp.err_pc, 1);
@ -238,22 +237,19 @@ inline s64 dsp_get_long_acx(u8 _reg)
val <<= 16; val <<= 16;
s64 low_acc = g_dsp.r[0x18 + _reg]; s64 low_acc = g_dsp.r[0x18 + _reg];
val |= low_acc; val |= low_acc;
return(val); return val;
} }
inline s16 dsp_get_ax_l(int _reg)
inline s16 dsp_get_ax_l(u8 _reg)
{ {
_assert_(_reg < 2); _assert_(_reg < 2);
return(g_dsp.r[0x18 + _reg]); return g_dsp.r[0x18 + _reg];
} }
inline s16 dsp_get_ax_h(int _reg)
inline s16 dsp_get_ax_h(u8 _reg)
{ {
_assert_(_reg < 2); _assert_(_reg < 2);
return(g_dsp.r[0x1a + _reg]); return g_dsp.r[0x1a + _reg];
} }
#endif #endif