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:
parent
bd7419d437
commit
42fed5c111
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue