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_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
}
}
}

View File

@ -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

View File

@ -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);
}

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.pc = dsp_reg_load_stack(DSP_STACK_C);
g_dsp.exception_in_progress_hack = false;
g_dsp.exception_in_progress = -1;
}
// HALT