DSPLLE: exception work, please review/test/-1

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3731 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-07-10 11:19:47 +00:00
parent bd7419d437
commit 42fed5c111
4 changed files with 43 additions and 36 deletions

View File

@ -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_INT_ENABLE;
g_dsp.r[DSP_REG_SR] |= SR_EXT_INT_ENABLE; g_dsp.r[DSP_REG_SR] |= SR_EXT_INT_ENABLE;
g_dsp.exception_in_progress = -1;
g_dsp.cr = 0x804; g_dsp.cr = 0x804;
gdsp_ifx_init(); 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); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
DSPAnalyzer::Analyze(); DSPAnalyzer::Analyze();
step_event.Init(); step_event.Init();
return true; return true;
} }
@ -140,19 +141,22 @@ void DSPCore_Shutdown()
void DSPCore_Reset() 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.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_WR0] = 0xffff;
g_dsp.r[DSP_REG_WR1] = 0xffff; g_dsp.r[DSP_REG_WR1] = 0xffff;
g_dsp.r[DSP_REG_WR2] = 0xffff; g_dsp.r[DSP_REG_WR2] = 0xffff;
g_dsp.r[DSP_REG_WR3] = 0xffff; g_dsp.r[DSP_REG_WR3] = 0xffff;
} }
void DSPCore_SetException(u8 level) void DSPCore_SetException(u8 level)
{ {
#ifdef DEBUG_EXP
NOTICE_LOG(DSPLLE, "Firing exception %d", g_dsp.exceptions);
#endif
g_dsp.exceptions |= 1 << level; g_dsp.exceptions |= 1 << level;
} }
@ -160,56 +164,57 @@ 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 && !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 #ifdef DEBUG_EXP
NOTICE_LOG(DSPLLE, "Firing external interrupt"); NOTICE_LOG(DSP_MAIL, "External interrupt fired");
#endif #endif
if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
{
// Signal the SPU about new mail // Signal the SPU about new mail
DSPCore_SetException(EXP_INT); DSPCore_SetException(EXP_INT);
g_dsp.cr &= ~CR_EXTERNAL_INT; g_dsp.cr &= ~CR_EXTERNAL_INT;
} else { } else {
#ifdef DEBUG_EXP #ifdef DEBUG_EXP
ERROR_LOG(DSPLLE, "External interrupt firing failed"); ERROR_LOG(DSP_MAIL, "External interrupt failed(masked)");
#endif #endif
} }
} }
} }
void DSPCore_CheckExceptions() void DSPCore_CheckExceptions()
{ {
// 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_hack
if (g_dsp.exceptions != 0 && !g_dsp.exception_in_progress_hack) { if (g_dsp.exceptions != 0) {
#ifdef DEBUG_EXP if (g_dsp.exception_in_progress < 1) {
NOTICE_LOG(DSPLLE, "Firing exception %d", g_dsp.exceptions); // check exceptions should it be 0..7 or 7..0?
#endif for (int i = 7; i >= 0; i--) {
// check exceptions should it be 0..7 or 7..0? // Seems exp int or reset are not masked by sr_int_enable
for (int i = 0; i < 8; i++) { if (g_dsp.exceptions & (1 << i)) {
// Seems exp int or reset are not masked by sr_int_enable if (dsp_SR_is_flag_set(SR_INT_ENABLE) || i == EXP_INT || i == EXP_RESET) {
if (g_dsp.exceptions & (1 << i)) { _assert_msg_(MASTER_LOG, g_dsp.exception_in_progress == -1, "assert %d while exception", g_dsp.exception_in_progress);
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");
// store pc and sr until RTI // store pc and sr until RTI
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]); dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
g_dsp.pc = i * 2; g_dsp.pc = i * 2;
g_dsp.exceptions &= ~(1 << i); g_dsp.exceptions &= ~(1 << i);
g_dsp.exception_in_progress_hack = true; g_dsp.exception_in_progress = i;
break; break;
} else { } else {
#ifdef DEBUG_EXP #ifdef DEBUG_EXP
ERROR_LOG(DSPLLE, "Firing exception %d failed"); ERROR_LOG(DSPLLE, "Firing exception %d failed", g_dsp.exceptions);
#endif #endif
}
} }
} }
} else {
#ifdef DEBUG_EXP
ERROR_LOG(DSPLLE, "Firing exception %d failed exception active", g_dsp.exceptions);
#endif
} }
} }
} }

View File

@ -186,8 +186,8 @@ struct SDSP
u16 cr; u16 cr;
u8 reg_stack_ptr[4]; u8 reg_stack_ptr[4];
u8 exceptions; // pending exceptions? u8 exceptions; // pending exceptions
bool exception_in_progress_hack; // is this the same as "exception enabled"? int exception_in_progress; // inside exp flag
// Let's make stack depth 32 for now. The real DSP has different depths // 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 // for the different stacks, but it would be strange if any ucode relied on stack

View File

@ -136,6 +136,8 @@ void gdsp_ifx_write(u16 addr, u16 val)
case 0xfb: // DIRQ case 0xfb: // DIRQ
if (val & 0x1) if (val & 0x1)
DSPHost_InterruptRequest(); DSPHost_InterruptRequest();
else
ERROR_LOG(DSPLLE, "Unknown Interrupt Request pc=%04x (%04x)", g_dsp.pc, val);
break; break;
case 0xfc: // DMBH 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); 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); g_dsp.iram_crc = DSPHost_CodeLoaded(g_dsp.cpu_ram + (addr & 0x0fffffff), size);
DSPAnalyzer::Analyze(); DSPAnalyzer::Analyze();
// This calls the reset functions, but it get some games stuck // This calls the reset functions, but it get some games stuck
// uncomment it to help with debugging // uncomment it to help with debugging
// DSPCore_SetException(EXP_RESET); DSPCore_SetException(EXP_RESET);
} }

View File

@ -126,7 +126,7 @@ void rti(const UDSPInstruction& opc)
g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D); 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.pc = dsp_reg_load_stack(DSP_STACK_C);
g_dsp.exception_in_progress_hack = false; g_dsp.exception_in_progress = -1;
} }
// HALT // HALT