summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore
diff options
context:
space:
mode:
authornakeee <nakeee@gmail.com>2009-07-10 11:19:47 +0000
committernakeee <nakeee@gmail.com>2009-07-10 11:19:47 +0000
commit42fed5c111d983e421a461e5cf8d052abe52a4c4 (patch)
tree0335cebfdebbab902c5b2a4d428e054c6ad3e9eb /Source/Core/DSPCore
parentbd7419d4377d88697abb9070549f3d10249d5d4d (diff)
DSPLLE: exception work, please review/test/-1
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3731 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore')
-rw-r--r--Source/Core/DSPCore/Src/DSPCore.cpp67
-rw-r--r--Source/Core/DSPCore/Src/DSPCore.h4
-rw-r--r--Source/Core/DSPCore/Src/DSPHWInterface.cpp6
-rw-r--r--Source/Core/DSPCore/Src/DspIntBranch.cpp2
4 files changed, 43 insertions, 36 deletions
diff --git a/Source/Core/DSPCore/Src/DSPCore.cpp b/Source/Core/DSPCore/Src/DSPCore.cpp
index 1758c70bde..92d399cd4e 100644
--- a/Source/Core/DSPCore/Src/DSPCore.cpp
+++ b/Source/Core/DSPCore/Src/DSPCore.cpp
@@ -116,6 +116,7 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename)
g_dsp.r[DSP_REG_SR] |= SR_INT_ENABLE;
g_dsp.r[DSP_REG_SR] |= SR_EXT_INT_ENABLE;
+ g_dsp.exception_in_progress = -1;
g_dsp.cr = 0x804;
gdsp_ifx_init();
@@ -125,7 +126,7 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename)
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
DSPAnalyzer::Analyze();
step_event.Init();
-
+
return true;
}
@@ -140,19 +141,22 @@ void DSPCore_Shutdown()
void DSPCore_Reset()
{
- _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception");
+ _assert_msg_(MASTER_LOG, g_dsp.exception_in_progress == -1, "reset while exception");
g_dsp.pc = DSP_RESET_VECTOR;
- g_dsp.exception_in_progress_hack = false;
+ g_dsp.exception_in_progress = -1;
g_dsp.r[DSP_REG_WR0] = 0xffff;
g_dsp.r[DSP_REG_WR1] = 0xffff;
g_dsp.r[DSP_REG_WR2] = 0xffff;
g_dsp.r[DSP_REG_WR3] = 0xffff;
-
}
void DSPCore_SetException(u8 level)
{
+#ifdef DEBUG_EXP
+ NOTICE_LOG(DSPLLE, "Firing exception %d", g_dsp.exceptions);
+#endif
+
g_dsp.exceptions |= 1 << level;
}
@@ -160,56 +164,57 @@ void DSPCore_SetException(u8 level)
void DSPCore_CheckExternalInterrupt()
{
// check if there is an external interrupt
- if (g_dsp.cr & CR_EXTERNAL_INT && !g_dsp.exception_in_progress_hack)
- {
+ if (g_dsp.cr & CR_EXTERNAL_INT) {
+ if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE) && g_dsp.exception_in_progress < 1) {
#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "Firing external interrupt");
+ NOTICE_LOG(DSP_MAIL, "External interrupt fired");
#endif
- if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
- {
// Signal the SPU about new mail
DSPCore_SetException(EXP_INT);
g_dsp.cr &= ~CR_EXTERNAL_INT;
} else {
#ifdef DEBUG_EXP
- ERROR_LOG(DSPLLE, "External interrupt firing failed");
+ ERROR_LOG(DSP_MAIL, "External interrupt failed(masked)");
#endif
}
-
}
}
+
void DSPCore_CheckExceptions()
{
// 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
// g_dsp.exception_in_progress_hack
- if (g_dsp.exceptions != 0 && !g_dsp.exception_in_progress_hack) {
-#ifdef DEBUG_EXP
- NOTICE_LOG(DSPLLE, "Firing exception %d", g_dsp.exceptions);
-#endif
- // check exceptions should it be 0..7 or 7..0?
- for (int i = 0; i < 8; 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 || i == EXP_RESET) {
- _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
+ if (g_dsp.exceptions != 0) {
+ 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 || 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);
- g_dsp.exception_in_progress_hack = true;
- break;
- } else {
+ // 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);
+ g_dsp.exception_in_progress = i;
+ break;
+ } else {
#ifdef DEBUG_EXP
- ERROR_LOG(DSPLLE, "Firing exception %d failed");
+ ERROR_LOG(DSPLLE, "Firing exception %d failed", g_dsp.exceptions);
#endif
+ }
}
}
+ } else {
+#ifdef DEBUG_EXP
+ ERROR_LOG(DSPLLE, "Firing exception %d failed exception active", g_dsp.exceptions);
+#endif
}
}
}
diff --git a/Source/Core/DSPCore/Src/DSPCore.h b/Source/Core/DSPCore/Src/DSPCore.h
index 0a3385970a..29a0ab44c0 100644
--- a/Source/Core/DSPCore/Src/DSPCore.h
+++ b/Source/Core/DSPCore/Src/DSPCore.h
@@ -186,8 +186,8 @@ struct SDSP
u16 cr;
u8 reg_stack_ptr[4];
- u8 exceptions; // pending exceptions?
- bool exception_in_progress_hack; // is this the same as "exception enabled"?
+ u8 exceptions; // pending exceptions
+ int exception_in_progress; // inside exp flag
// Let's make stack depth 32 for now. The real DSP has different depths
// for the different stacks, but it would be strange if any ucode relied on stack
diff --git a/Source/Core/DSPCore/Src/DSPHWInterface.cpp b/Source/Core/DSPCore/Src/DSPHWInterface.cpp
index f5fbf6844f..bf77f4b6a1 100644
--- a/Source/Core/DSPCore/Src/DSPHWInterface.cpp
+++ b/Source/Core/DSPCore/Src/DSPHWInterface.cpp
@@ -136,6 +136,8 @@ void gdsp_ifx_write(u16 addr, u16 val)
case 0xfb: // DIRQ
if (val & 0x1)
DSPHost_InterruptRequest();
+ else
+ ERROR_LOG(DSPLLE, "Unknown Interrupt Request pc=%04x (%04x)", g_dsp.pc, val);
break;
case 0xfc: // DMBH
@@ -244,12 +246,12 @@ void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size)
}
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
- INFO_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc);
+ NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc);
g_dsp.iram_crc = DSPHost_CodeLoaded(g_dsp.cpu_ram + (addr & 0x0fffffff), size);
DSPAnalyzer::Analyze();
// This calls the reset functions, but it get some games stuck
// uncomment it to help with debugging
- // DSPCore_SetException(EXP_RESET);
+ DSPCore_SetException(EXP_RESET);
}
diff --git a/Source/Core/DSPCore/Src/DspIntBranch.cpp b/Source/Core/DSPCore/Src/DspIntBranch.cpp
index c2679a9f3e..3d4becc61d 100644
--- a/Source/Core/DSPCore/Src/DspIntBranch.cpp
+++ b/Source/Core/DSPCore/Src/DspIntBranch.cpp
@@ -126,7 +126,7 @@ void rti(const UDSPInstruction& opc)
g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
- g_dsp.exception_in_progress_hack = false;
+ g_dsp.exception_in_progress = -1;
}
// HALT