DSPLLE: small cleanup
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4015 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
fea2aa344d
commit
9dc90df0af
|
@ -154,10 +154,6 @@ void DSPCore_Reset()
|
||||||
|
|
||||||
void DSPCore_SetException(u8 level)
|
void DSPCore_SetException(u8 level)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_EXP
|
|
||||||
NOTICE_LOG(DSPLLE, "Set exception %d", level);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_dsp.exceptions |= 1 << level;
|
g_dsp.exceptions |= 1 << level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,58 +161,55 @@ void DSPCore_SetException(u8 level)
|
||||||
void DSPCore_CheckExternalInterrupt()
|
void DSPCore_CheckExternalInterrupt()
|
||||||
{
|
{
|
||||||
// check if there is an external interrupt
|
// check if there is an external interrupt
|
||||||
if (g_dsp.cr & CR_EXTERNAL_INT) {
|
if (! g_dsp.cr & CR_EXTERNAL_INT)
|
||||||
if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE) && g_dsp.exception_in_progress == -1) {
|
return;
|
||||||
#ifdef DEBUG_EXP
|
|
||||||
NOTICE_LOG(DSP_MAIL, "External interrupt fired");
|
if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
|
||||||
#endif
|
return;
|
||||||
// Signal the SPU about new mail
|
|
||||||
DSPCore_SetException(EXP_INT);
|
// Signal the SPU about new mail
|
||||||
|
DSPCore_SetException(EXP_INT);
|
||||||
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
|
||||||
} else {
|
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
||||||
#ifdef DEBUG_EXP
|
|
||||||
ERROR_LOG(DSP_MAIL, "External interrupt failed(masked) by %d", g_dsp.exception_in_progress);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DSPCore_CheckExceptions()
|
void DSPCore_CheckExceptions()
|
||||||
{
|
{
|
||||||
|
if (g_dsp.exceptions == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// it's unclear what to do when there are two exceptions are the same time
|
// it's unclear what to do when there are two exceptions are the same time
|
||||||
// but for sure they should not be called together therefore the
|
// but for sure they should not be called together therefore the
|
||||||
// g_dsp.exception_in_progress_hack
|
// g_dsp.exception_in_progress
|
||||||
if (g_dsp.exceptions != 0) {
|
if (g_dsp.exception_in_progress != -1) {
|
||||||
if (g_dsp.exception_in_progress == -1) {
|
|
||||||
// check exceptions should it be 0..7 or 7..0?
|
|
||||||
for (int i = 7; i >= 0; i--) {
|
|
||||||
// Seems exp int or reset are not masked by sr_int_enable
|
|
||||||
if (g_dsp.exceptions & (1 << i)) {
|
|
||||||
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT && dsp_SR_is_flag_set(SR_EXT_INT_ENABLE)) || i == EXP_RESET) {
|
|
||||||
_assert_msg_(MASTER_LOG, g_dsp.exception_in_progress == -1, "assert %d while exception", g_dsp.exception_in_progress);
|
|
||||||
|
|
||||||
// store pc and sr until RTI
|
|
||||||
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
|
|
||||||
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
|
|
||||||
|
|
||||||
g_dsp.pc = i * 2;
|
|
||||||
g_dsp.exceptions &= ~(1 << i);
|
|
||||||
if (i)
|
|
||||||
g_dsp.exception_in_progress = i;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_EXP
|
#ifdef DEBUG_EXP
|
||||||
ERROR_LOG(DSPLLE, "Firing exception %d failed", i);
|
ERROR_LOG(DSPLLE, "Firing exception %d failed exception %d active", g_dsp.exceptions, g_dsp.exception_in_progress);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 7; i > 0; i--) {
|
||||||
|
// Seems exp int or reset are not masked by sr_int_enable
|
||||||
|
if (g_dsp.exceptions & (1 << i)) {
|
||||||
|
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT)) {
|
||||||
|
|
||||||
|
_assert_msg_(MASTER_LOG, g_dsp.exception_in_progress == -1, "assert %d while exception", g_dsp.exception_in_progress);
|
||||||
|
|
||||||
|
// store pc and sr until RTI
|
||||||
|
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
|
||||||
|
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
|
||||||
|
|
||||||
|
g_dsp.pc = i * 2;
|
||||||
|
g_dsp.exceptions &= ~(1 << i);
|
||||||
|
if (i)
|
||||||
|
g_dsp.exception_in_progress = i;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_EXP
|
||||||
|
ERROR_LOG(DSPLLE, "Firing exception %d failed", i);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_EXP
|
|
||||||
ERROR_LOG(DSPLLE, "Firing exception %d failed exception %d active", g_dsp.exceptions, g_dsp.exception_in_progress);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@
|
||||||
#define SR_10 0x0010 // seem to be set by tst
|
#define SR_10 0x0010 // seem to be set by tst
|
||||||
#define SR_TOP2BITS 0x0020 // if the upper 2 bits are equal
|
#define SR_TOP2BITS 0x0020 // if the upper 2 bits are equal
|
||||||
#define SR_LOGIC_ZERO 0x0040
|
#define SR_LOGIC_ZERO 0x0040
|
||||||
|
#define SR_80 0x0080 // Unknown, set by add
|
||||||
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
|
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
|
||||||
#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_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
|
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
|
||||||
|
@ -162,7 +163,6 @@
|
||||||
#define SR_CMP_MASK 0x3f
|
#define SR_CMP_MASK 0x3f
|
||||||
|
|
||||||
// exceptions vector
|
// exceptions vector
|
||||||
#define EXP_RESET 0 // 0x0000
|
|
||||||
#define EXP_STOVF 1 // 0x0002 stack under/over flow
|
#define EXP_STOVF 1 // 0x0002 stack under/over flow
|
||||||
#define EXP_2 2 // 0x0004
|
#define EXP_2 2 // 0x0004
|
||||||
#define EXP_3 3 // 0x0006
|
#define EXP_3 3 // 0x0006
|
||||||
|
|
Loading…
Reference in New Issue