mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-25 15:41:11 +00:00
dsplle - prevent crashing, if there is unknown opcode (interpreter, only important for tests and certain homebrew ucodes), more cleaning, removal of obsolete TODO-s
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7399 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
723c115813
commit
47c81bf0e8
@ -164,9 +164,9 @@
|
|||||||
#define SR_400 0x0400 // unknown
|
#define SR_400 0x0400 // unknown
|
||||||
#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
|
#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
|
||||||
#define SR_1000 0x1000 // unknown
|
#define SR_1000 0x1000 // unknown
|
||||||
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
|
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2) (Free mul by 2)
|
||||||
#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums and data saturation for stores from mid accums.
|
#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums and data saturation for stores from mid accums.
|
||||||
#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats ax?.l as unsigned.
|
#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats ax?.l as unsigned (MULX family only).
|
||||||
|
|
||||||
// This should be the bits affected by CMP. Does not include logic zero.
|
// This should be the bits affected by CMP. Does not include logic zero.
|
||||||
#define SR_CMP_MASK 0x3f
|
#define SR_CMP_MASK 0x3f
|
||||||
|
@ -221,7 +221,6 @@ static void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size)
|
|||||||
u8* dst = ((u8*)g_dsp.iram);
|
u8* dst = ((u8*)g_dsp.iram);
|
||||||
for (u32 i = 0; i < size; i += 2)
|
for (u32 i = 0; i < size; i += 2)
|
||||||
{
|
{
|
||||||
// TODO : this may be different on Wii.
|
|
||||||
*(u16*)&dst[dsp_addr + i] = Common::swap16(*(const u16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]);
|
*(u16*)&dst[dsp_addr + i] = Common::swap16(*(const u16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]);
|
||||||
}
|
}
|
||||||
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
|
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
|
||||||
|
@ -35,10 +35,8 @@ namespace DSPInterpreter {
|
|||||||
|
|
||||||
volatile u32 gdsp_running;
|
volatile u32 gdsp_running;
|
||||||
|
|
||||||
// NOTE: These have nothing to do with g_dsp.r[DSP_REG_CR].
|
// NOTE: These have nothing to do with g_dsp.r.cr !
|
||||||
|
|
||||||
// Hm, should instructions that change CR use this? Probably not (but they
|
|
||||||
// should call UpdateCachedCR())
|
|
||||||
void WriteCR(u16 val)
|
void WriteCR(u16 val)
|
||||||
{
|
{
|
||||||
// reset
|
// reset
|
||||||
@ -52,8 +50,9 @@ void WriteCR(u16 val)
|
|||||||
{
|
{
|
||||||
// this looks like a hack! OSInitAudioSystem ucode
|
// this looks like a hack! OSInitAudioSystem ucode
|
||||||
// should send this mail - not dsp core itself
|
// should send this mail - not dsp core itself
|
||||||
gdsp_mbox_write_h(GDSP_MBOX_DSP, 0x8054);
|
// this doesnt work anymore
|
||||||
gdsp_mbox_write_l(GDSP_MBOX_DSP, 0x4348);
|
//gdsp_mbox_write_h(GDSP_MBOX_DSP, 0x8054);
|
||||||
|
//gdsp_mbox_write_l(GDSP_MBOX_DSP, 0x4348);
|
||||||
val |= 0x800;
|
val |= 0x800;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +60,6 @@ void WriteCR(u16 val)
|
|||||||
g_dsp.cr = val;
|
g_dsp.cr = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hm, should instructions that read CR use this? (Probably not).
|
|
||||||
u16 ReadCR()
|
u16 ReadCR()
|
||||||
{
|
{
|
||||||
if (g_dsp.pc & 0x8000)
|
if (g_dsp.pc & 0x8000)
|
||||||
|
@ -45,7 +45,6 @@ u16 ReadCR();
|
|||||||
typedef void (*DSPInterpreterFunc)(const UDSPInstruction opc);
|
typedef void (*DSPInterpreterFunc)(const UDSPInstruction opc);
|
||||||
|
|
||||||
// All the opcode functions.
|
// All the opcode functions.
|
||||||
void unknown(const UDSPInstruction opc);
|
|
||||||
void call(const UDSPInstruction opc);
|
void call(const UDSPInstruction opc);
|
||||||
void callr(const UDSPInstruction opc);
|
void callr(const UDSPInstruction opc);
|
||||||
void ifcc(const UDSPInstruction opc);
|
void ifcc(const UDSPInstruction opc);
|
||||||
|
@ -27,8 +27,9 @@
|
|||||||
void nop(const UDSPInstruction opc)
|
void nop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
// The real nop is 0. Anything else is bad.
|
// The real nop is 0. Anything else is bad.
|
||||||
if (opc)
|
if (opc) {
|
||||||
DSPInterpreter::unknown(opc);
|
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x", opc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DSPOPCTemplate opcodes[] =
|
const DSPOPCTemplate opcodes[] =
|
||||||
@ -300,7 +301,7 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DSPOPCTemplate cw =
|
const DSPOPCTemplate cw =
|
||||||
{"CW", 0x0000, 0x0000, NULL, NULL, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, false, false, false, false, false};
|
{"CW", 0x0000, 0x0000, nop, NULL, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, false, false, false, false, false};
|
||||||
|
|
||||||
// extended opcodes
|
// extended opcodes
|
||||||
|
|
||||||
|
@ -750,7 +750,6 @@ void abs(const UDSPInstruction opc)
|
|||||||
// 0110 0srd xxxx xxxx
|
// 0110 0srd xxxx xxxx
|
||||||
// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
|
// Moves register $axS.R (sign extended) to middle accumulator $acD.hm.
|
||||||
// Sets $acD.l to 0.
|
// Sets $acD.l to 0.
|
||||||
// TODO: Check what happens to acD.h.
|
|
||||||
//
|
//
|
||||||
// flags out: --xx xx00
|
// flags out: --xx xx00
|
||||||
void movr(const UDSPInstruction opc)
|
void movr(const UDSPInstruction opc)
|
||||||
|
@ -142,50 +142,33 @@ void sbset(const UDSPInstruction opc)
|
|||||||
g_dsp.r.sr |= (1 << bit);
|
g_dsp.r.sr |= (1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a bunch of flag setters, flipping bits in SR. So far so good,
|
// This is a bunch of flag setters, flipping bits in SR.
|
||||||
// but it's harder to know exactly what effect they have.
|
|
||||||
void srbith(const UDSPInstruction opc)
|
void srbith(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
zeroWriteBackLog();
|
zeroWriteBackLog();
|
||||||
switch ((opc >> 8) & 0xf)
|
switch ((opc >> 8) & 0xf)
|
||||||
{
|
{
|
||||||
// M0/M2 change the multiplier mode (it can multiply by 2 for free).
|
|
||||||
case 0xa: // M2
|
case 0xa: // M2
|
||||||
g_dsp.r.sr &= ~SR_MUL_MODIFY;
|
g_dsp.r.sr &= ~SR_MUL_MODIFY;
|
||||||
break;
|
break;
|
||||||
case 0xb: // M0
|
case 0xb: // M0
|
||||||
g_dsp.r.sr |= SR_MUL_MODIFY;
|
g_dsp.r.sr |= SR_MUL_MODIFY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// If set, treat multiplicands as unsigned.
|
|
||||||
// If clear, treat them as signed.
|
|
||||||
case 0xc: // CLR15
|
case 0xc: // CLR15
|
||||||
g_dsp.r.sr &= ~SR_MUL_UNSIGNED;
|
g_dsp.r.sr &= ~SR_MUL_UNSIGNED;
|
||||||
break;
|
break;
|
||||||
case 0xd: // SET15
|
case 0xd: // SET15
|
||||||
g_dsp.r.sr |= SR_MUL_UNSIGNED;
|
g_dsp.r.sr |= SR_MUL_UNSIGNED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Automatic 40-bit sign extension when loading ACx.M.
|
|
||||||
// SET40 changes something very important: see the LRI instruction above.
|
|
||||||
case 0xe: // SET16 (CLR40)
|
case 0xe: // SET16 (CLR40)
|
||||||
g_dsp.r.sr &= ~SR_40_MODE_BIT;
|
g_dsp.r.sr &= ~SR_40_MODE_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf: // SET40
|
case 0xf: // SET40
|
||||||
g_dsp.r.sr |= SR_40_MODE_BIT;
|
g_dsp.r.sr |= SR_40_MODE_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
|
||||||
|
|
||||||
void unknown(const UDSPInstruction opc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(DSPLLE, "LLE: Unrecognized opcode 0x%04x, pc 0x%04x", opc, g_dsp.pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user