DSPLLE: comments and logging clean up
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3693 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
45771c8614
commit
c44dabfe8b
|
@ -16,10 +16,13 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
// AID / AUDIO_DMA controls pushing audio out to the SRC and then the speakers.
|
// AID / AUDIO_DMA controls pushing audio out to the SRC and then the speakers.
|
||||||
// The audio DMA pushes audio through a small FIFO 32 bytes at a time, as needed.
|
// The audio DMA pushes audio through a small FIFO 32 bytes at a time, as
|
||||||
|
// needed.
|
||||||
|
|
||||||
// The SRC behind the fifo eats stereo 16-bit data at a sample rate of 32khz,
|
// The SRC behind the fifo eats stereo 16-bit data at a sample rate of 32khz,
|
||||||
// that is, 4 bytes at 32 khz, which is 32 bytes at 4 khz. We thereforce schedule an
|
// that is, 4 bytes at 32 khz, which is 32 bytes at 4 khz. We thereforce
|
||||||
// event that runs at 4khz, that eats audio from the fifo. Thus, we have homebrew audio.
|
// schedule an event that runs at 4khz, that eats audio from the fifo. Thus, we
|
||||||
|
// have homebrew audio.
|
||||||
|
|
||||||
// The AID interrupt is set when the fifo STARTS a transfer. It latches address
|
// The AID interrupt is set when the fifo STARTS a transfer. It latches address
|
||||||
// and count into internal registers and starts copying. This means that the
|
// and count into internal registers and starts copying. This means that the
|
||||||
|
@ -236,9 +239,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
}
|
}
|
||||||
switch (_iAddress & 0xFFFF)
|
switch (_iAddress & 0xFFFF)
|
||||||
{
|
{
|
||||||
// ==================================================================================
|
|
||||||
// AI_REGS 0x5000+
|
// AI_REGS 0x5000+
|
||||||
// ==================================================================================
|
|
||||||
case DSP_MAIL_TO_DSP_HI:
|
case DSP_MAIL_TO_DSP_HI:
|
||||||
_uReturnValue = dsp_plugin->DSP_ReadMailboxHigh(true);
|
_uReturnValue = dsp_plugin->DSP_ReadMailboxHigh(true);
|
||||||
return;
|
return;
|
||||||
|
@ -260,9 +262,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
(dsp_plugin->DSP_ReadControlRegister() & DSP_CONTROL_MASK);
|
(dsp_plugin->DSP_ReadControlRegister() & DSP_CONTROL_MASK);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// ==================================================================================
|
|
||||||
// AR_REGS 0x501x+
|
// AR_REGS 0x501x+
|
||||||
// ==================================================================================
|
|
||||||
case 0x5012:
|
case 0x5012:
|
||||||
_uReturnValue = g_AR_MODE;
|
_uReturnValue = g_AR_MODE;
|
||||||
return;
|
return;
|
||||||
|
@ -282,11 +282,10 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
case AR_DMA_CNT_H: _uReturnValue = g_arDMA.Cnt.Hex >> 16; return;
|
case AR_DMA_CNT_H: _uReturnValue = g_arDMA.Cnt.Hex >> 16; return;
|
||||||
case AR_DMA_CNT_L: _uReturnValue = g_arDMA.Cnt.Hex & 0xFFFF; return;
|
case AR_DMA_CNT_L: _uReturnValue = g_arDMA.Cnt.Hex & 0xFFFF; return;
|
||||||
|
|
||||||
// ==================================================================================
|
|
||||||
// DMA_REGS 0x5030+
|
// DMA_REGS 0x5030+
|
||||||
// ==================================================================================
|
|
||||||
case AUDIO_DMA_BYTES_LEFT:
|
case AUDIO_DMA_BYTES_LEFT:
|
||||||
// Hmm. Would be stupid to ask for bytes left. Assume it wants blocks left.
|
// Hmm. Would be stupid to ask for bytes left. Assume it wants
|
||||||
|
// blocks left.
|
||||||
_uReturnValue = g_audioDMA.BlocksLeft;
|
_uReturnValue = g_audioDMA.BlocksLeft;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -320,10 +319,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
|
|
||||||
switch(_Address & 0xFFFF)
|
switch(_Address & 0xFFFF)
|
||||||
{
|
{
|
||||||
// ==================================================================================
|
|
||||||
// DSP Regs 0x5000+
|
|
||||||
// ==================================================================================
|
|
||||||
|
|
||||||
|
// DSP Regs 0x5000+
|
||||||
case DSP_MAIL_TO_DSP_HI:
|
case DSP_MAIL_TO_DSP_HI:
|
||||||
dsp_plugin->DSP_WriteMailboxHigh(true, _Value);
|
dsp_plugin->DSP_WriteMailboxHigh(true, _Value);
|
||||||
break;
|
break;
|
||||||
|
@ -340,9 +337,7 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
_dbg_assert_msg_(DSPINTERFACE, 0, "W16: DSP_MAIL_FROM_DSP_LO");
|
_dbg_assert_msg_(DSPINTERFACE, 0, "W16: DSP_MAIL_FROM_DSP_LO");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ==================================================================================
|
|
||||||
// Control Register
|
// Control Register
|
||||||
// ==================================================================================
|
|
||||||
case DSP_CONTROL:
|
case DSP_CONTROL:
|
||||||
{
|
{
|
||||||
UDSPControl tmpControl;
|
UDSPControl tmpControl;
|
||||||
|
@ -380,11 +375,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ==================================================================================
|
|
||||||
// AR_REGS 0x501x+
|
// AR_REGS 0x501x+
|
||||||
// DMA back and forth between ARAM and RAM
|
// DMA back and forth between ARAM and RAM
|
||||||
// ==================================================================================
|
|
||||||
|
|
||||||
case 0x5012:
|
case 0x5012:
|
||||||
g_AR_MODE = _Value;
|
g_AR_MODE = _Value;
|
||||||
break;
|
break;
|
||||||
|
@ -418,10 +410,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
Update_ARAM_DMA();
|
Update_ARAM_DMA();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ==================================================================================
|
|
||||||
// Audio DMA_REGS 0x5030+
|
// Audio DMA_REGS 0x5030+
|
||||||
// This is the DMA that goes straight out the speaker.
|
// This is the DMA that goes straight out the speaker.
|
||||||
// ==================================================================================
|
|
||||||
case AUDIO_DMA_START_HI:
|
case AUDIO_DMA_START_HI:
|
||||||
g_audioDMA.SourceAddress = (g_audioDMA.SourceAddress & 0xFFFF) | (_Value<<16);
|
g_audioDMA.SourceAddress = (g_audioDMA.SourceAddress & 0xFFFF) | (_Value<<16);
|
||||||
break;
|
break;
|
||||||
|
@ -459,25 +449,27 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
void UpdateAudioDMA()
|
void UpdateAudioDMA()
|
||||||
{
|
{
|
||||||
if (g_audioDMA.AudioDMAControl.Enabled && g_audioDMA.BlocksLeft) {
|
if (g_audioDMA.AudioDMAControl.Enabled && g_audioDMA.BlocksLeft) {
|
||||||
// Read audio at g_audioDMA.ReadAddress in RAM and push onto an external audio fifo in the emulator,
|
// Read audio at g_audioDMA.ReadAddress in RAM and push onto an
|
||||||
// to be mixed with the disc streaming output. If that audio queue fills up, we delay the emulator.
|
// external audio fifo in the emulator, to be mixed with the disc
|
||||||
|
// streaming output. If that audio queue fills up, we delay the
|
||||||
|
// emulator.
|
||||||
// TO RESTORE OLD BEHAVIOUR, COMMENT OUT THIS LINE
|
// TO RESTORE OLD BEHAVIOUR, COMMENT OUT THIS LINE
|
||||||
dsp_plugin->DSP_SendAIBuffer(g_audioDMA.ReadAddress, AudioInterface::GetDSPSampleRate());
|
dsp_plugin->DSP_SendAIBuffer(g_audioDMA.ReadAddress, AudioInterface::GetDSPSampleRate());
|
||||||
|
|
||||||
g_audioDMA.ReadAddress += 32;
|
g_audioDMA.ReadAddress += 32;
|
||||||
g_audioDMA.BlocksLeft--;
|
g_audioDMA.BlocksLeft--;
|
||||||
if (!g_audioDMA.BlocksLeft) {
|
if (!g_audioDMA.BlocksLeft) {
|
||||||
// No need to turn off the DMA - we can only get here if we had blocks left when we
|
// No need to turn off the DMA - we can only get here if we had
|
||||||
// entered this function, and no longer have any.
|
// blocks left when we entered this function, and no longer have
|
||||||
// Latch new parameters
|
// any. Latch new parameters
|
||||||
g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
|
g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
|
||||||
g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
|
g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
|
||||||
// DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress);
|
// DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress);
|
||||||
GenerateDSPInterrupt(DSP::INT_AID);
|
GenerateDSPInterrupt(DSP::INT_AID);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Send silence. Yeah, it's a bit of a waste to sample rate convert silence.
|
// Send silence. Yeah, it's a bit of a waste to sample rate convert
|
||||||
// or hm. Maybe we shouldn't do this :)
|
// silence. or hm. Maybe we shouldn't do this :)
|
||||||
// dsp->DSP_SendAIBuffer(0, AudioInterface::GetDSPSampleRate());
|
// dsp->DSP_SendAIBuffer(0, AudioInterface::GetDSPSampleRate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,10 +496,8 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
|
|
||||||
switch (_iAddress & 0xFFFF)
|
switch (_iAddress & 0xFFFF)
|
||||||
{
|
{
|
||||||
// ==================================================================================
|
|
||||||
// AR_REGS - i dont know why they are accessed 32 bit too ...
|
|
||||||
// ==================================================================================
|
|
||||||
|
|
||||||
|
// AR_REGS - i dont know why they are accessed 32 bit too ...
|
||||||
case AR_DMA_MMADDR_H:
|
case AR_DMA_MMADDR_H:
|
||||||
g_arDMA.MMAddr = _iValue;
|
g_arDMA.MMAddr = _iValue;
|
||||||
break;
|
break;
|
||||||
|
@ -528,9 +518,8 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________________________________________________________________________________________________
|
|
||||||
// UpdateInterrupts
|
// UpdateInterrupts
|
||||||
//
|
|
||||||
void UpdateInterrupts()
|
void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
if ((g_dspState.DSPControl.AID & g_dspState.DSPControl.AID_mask) ||
|
if ((g_dspState.DSPControl.AID & g_dspState.DSPControl.AID_mask) ||
|
||||||
|
@ -613,21 +602,21 @@ void Update_ARAM_DMA()
|
||||||
GenerateDSPInterrupt(INT_ARAM);
|
GenerateDSPInterrupt(INT_ARAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
|
||||||
// This is how it works: The game has written sound to RAM, the DSP will read it with
|
// This is how it works: The game has written sound to RAM, the DSP will read
|
||||||
// this function. SamplePos in the plugin is double the value given here because it
|
// it with this function. SamplePos in the plugin is double the value given
|
||||||
// works on a nibble level. In Wii addresses can eather be for MEM1 or MEM2, when it wants
|
// here because it works on a nibble level. In Wii addresses can eather be for
|
||||||
// to read from MEM2 it adds 0x2000000 (in nibble terms) to get up to the MEM2 hardware
|
// MEM1 or MEM2, when it wants to read from MEM2 it adds 0x2000000 (in nibble
|
||||||
// address. But in our case we use a second pointer and adjust the value down to 0x00...
|
// terms) to get up to the MEM2 hardware address. But in our case we use a
|
||||||
// -------------------
|
// second pointer and adjust the value down to 0x00...
|
||||||
u8 ReadARAM(u32 _iAddress)
|
u8 ReadARAM(u32 _iAddress)
|
||||||
{
|
{
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x", _iAddress);
|
//DEBUG_LOG(DSPINTERFACE, 0, "ARAM (r) 0x%08x", _iAddress);
|
||||||
|
|
||||||
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||||
{
|
{
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
//DEBUG_LOG(DSPINTERFACE, 0, "ARAM (r) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
||||||
|
|
||||||
// Does this make any sense?
|
// Does this make any sense?
|
||||||
if (_iAddress > WII_MASK)
|
if (_iAddress > WII_MASK)
|
||||||
|
@ -649,7 +638,7 @@ void WriteARAM(u8 value, u32 _uAddress)
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||||
{
|
{
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (w) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
//DEBUG_LOG(DSPINTERFACE, 0, "ARAM (w) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
||||||
|
|
||||||
// Does this make any sense?
|
// Does this make any sense?
|
||||||
if (_uAddress > WII_MASK)
|
if (_uAddress > WII_MASK)
|
||||||
|
@ -686,4 +675,4 @@ void WriteARAM(u8 _iValue, u32 _iAddress)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
} // end of namespace DSP
|
} // end of namespace DSP
|
||||||
// ===================
|
|
||||||
|
|
|
@ -106,12 +106,12 @@ u16 dsp_read_accelerator()
|
||||||
|
|
||||||
u16 val;
|
u16 val;
|
||||||
|
|
||||||
// let's do the "hardware" decode
|
// let's do the "hardware" decode DSP_FORMAT is interesting - the Zelda
|
||||||
// DSP_FORMAT is interesting - the Zelda ucode seems to indicate that the bottom
|
// ucode seems to indicate that the bottom two bits specify the "read size"
|
||||||
// two bits specify the "read size" and the address multiplier.
|
// and the address multiplier. The bits above that may be things like sign
|
||||||
// The bits above that may be things like sign extention and do/do not use ADPCM.
|
// extention and do/do not use ADPCM. It also remains to be figured out
|
||||||
// It also remains to be figured out whether there's a difference between the usual
|
// whether there's a difference between the usual accelerator "read
|
||||||
// accelerator "read address" and 0xd3.
|
// address" and 0xd3.
|
||||||
switch (gdsp_ifx_regs[DSP_FORMAT])
|
switch (gdsp_ifx_regs[DSP_FORMAT])
|
||||||
{
|
{
|
||||||
case 0x00: // ADPCM audio
|
case 0x00: // ADPCM audio
|
||||||
|
@ -146,9 +146,9 @@ u16 dsp_read_accelerator()
|
||||||
DSPCore_SetException(EXP_4);
|
DSPCore_SetException(EXP_4);
|
||||||
DSPCore_SetException(EXP_ACCOV);
|
DSPCore_SetException(EXP_ACCOV);
|
||||||
|
|
||||||
// Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah,
|
// Somehow, YN1 and YN2 must be initialized with their "loop" values,
|
||||||
// it seems likely that we should raise an exception to let the DSP program do that,
|
// so yeah, it seems likely that we should raise an exception to let
|
||||||
// at least if DSP_FORMAT == 0x0A.
|
// the DSP program do that, at least if DSP_FORMAT == 0x0A.
|
||||||
}
|
}
|
||||||
|
|
||||||
gdsp_ifx_regs[DSP_ACCAH] = Address >> 16;
|
gdsp_ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||||
|
|
|
@ -153,51 +153,59 @@ void DSPCore_SetException(u8 level)
|
||||||
g_dsp.exceptions |= 1 << level;
|
g_dsp.exceptions |= 1 << level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Comming from the CPU
|
||||||
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 && !g_dsp.exception_in_progress_hack)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_EXP
|
#ifdef DEBUG_EXP
|
||||||
NOTICE_LOG(DSPLLE, "trying External interupt fired");
|
NOTICE_LOG(DSPLLE, "Firing external interrupt");
|
||||||
#endif
|
#endif
|
||||||
if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
|
if (dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_EXP
|
// Signal the SPU about new mail
|
||||||
NOTICE_LOG(DSPLLE, "External interupt fired");
|
|
||||||
#endif
|
|
||||||
// level 7 is the interrupt exception
|
|
||||||
DSPCore_SetException(EXP_INT);
|
DSPCore_SetException(EXP_INT);
|
||||||
|
|
||||||
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_EXP
|
||||||
|
ERROR_LOG(DSPLLE, "External interupt firing failed");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPCore_CheckExceptions()
|
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) {
|
if (g_dsp.exceptions != 0 && !g_dsp.exception_in_progress_hack) {
|
||||||
#ifdef DEBUG_EXP
|
#ifdef DEBUG_EXP
|
||||||
NOTICE_LOG(DSPLLE, "trying exception %d fired", g_dsp.exceptions);
|
NOTICE_LOG(DSPLLE, "Firing exception %d", g_dsp.exceptions);
|
||||||
#endif
|
#endif
|
||||||
// check exceptions
|
// check exceptions should it be 0..7 or 7..0?
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
// Seems 7 must pass or zelda dies
|
// Seems exp int is not masked by sr_int_enable
|
||||||
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || i == EXP_INT) {
|
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || i == EXP_INT) {
|
||||||
if (g_dsp.exceptions & (1 << i)) {
|
if (g_dsp.exceptions & (1 << i)) {
|
||||||
_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
|
_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
|
||||||
|
|
||||||
|
// 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);
|
||||||
#ifdef DEBUG_EXP
|
|
||||||
NOTICE_LOG(DSPLLE, "exception %d fired");
|
|
||||||
#endif
|
|
||||||
g_dsp.exception_in_progress_hack = true;
|
g_dsp.exception_in_progress_hack = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_EXP
|
||||||
|
ERROR_LOG(DSPLLE, "Firing exception %d failed");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,14 +90,9 @@ void gdsp_mbox_write_l(u8 mbx, u16 val)
|
||||||
#ifdef DEBUG_EXP
|
#ifdef DEBUG_EXP
|
||||||
if (mbx == GDSP_MBOX_DSP)
|
if (mbx == GDSP_MBOX_DSP)
|
||||||
{
|
{
|
||||||
NOTICE_LOG(DSPLLE, " - DSP writes mail to mbx low %i: 0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc);
|
NOTICE_LOG(DSPLLE, "DSP(WM) B:%i M:0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc);
|
||||||
//DSPHost_InterruptRequest();
|
|
||||||
//DSPCore_SetException(EXP_INT);
|
|
||||||
} else {
|
} else {
|
||||||
NOTICE_LOG(DSPLLE, " - CPU writes mail to mbx low %i: 0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_CPU), g_dsp.pc);
|
NOTICE_LOG(DSPLLE, "CPU(WM) B:%i M:0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc);
|
||||||
|
|
||||||
// DSPHost_InterruptRequest();
|
|
||||||
// DSPCore_SetException(EXP_INT);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -124,13 +119,9 @@ u16 gdsp_mbox_read_l(u8 mbx)
|
||||||
#ifdef DEBUG_EXP
|
#ifdef DEBUG_EXP
|
||||||
if (mbx == GDSP_MBOX_DSP)
|
if (mbx == GDSP_MBOX_DSP)
|
||||||
{
|
{
|
||||||
NOTICE_LOG(DSPLLE, "- DSP reads mail from mbx %i: %08x (pc=0x%04x)", mbx, gdsp_mbox_peek(mbx), g_dsp.pc);
|
NOTICE_LOG(DSPLLE, "DSP(RM) B:%i M:0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc);
|
||||||
// DSPCore_SetException(EXP_INT);
|
|
||||||
// DSPHost_InterruptRequest();
|
|
||||||
} else {
|
} else {
|
||||||
NOTICE_LOG(DSPLLE, "- CPU reads mail from mbx %i: %08x (pc=0x%04x)", mbx, gdsp_mbox_peek(mbx), g_dsp.pc);
|
NOTICE_LOG(DSPLLE, "CPU(RM) B:%i M:0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc);
|
||||||
// DSPCore_SetException(EXP_INT);
|
|
||||||
// DSPHost_InterruptRequest();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ void HandleLoop()
|
||||||
const u16 rCallAddress = g_dsp.r[DSP_REG_ST0];
|
const u16 rCallAddress = g_dsp.r[DSP_REG_ST0];
|
||||||
const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2];
|
const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2];
|
||||||
|
|
||||||
|
|
||||||
if (g_dsp.pc == (rLoopAddress + opSize[rLoopAddress]))
|
if (g_dsp.pc == (rLoopAddress + opSize[rLoopAddress]))
|
||||||
{
|
{
|
||||||
rLoopCounter--;
|
rLoopCounter--;
|
||||||
|
@ -148,7 +149,8 @@ void Run()
|
||||||
// This one has basic idle skipping, and checks breakpoints.
|
// This one has basic idle skipping, and checks breakpoints.
|
||||||
int RunCyclesDebug(int cycles)
|
int RunCyclesDebug(int cycles)
|
||||||
{
|
{
|
||||||
// First, let's run a few cycles with no idle skipping so that things can progress a bit.
|
// First, let's run a few cycles with no idle skipping so that things can
|
||||||
|
// progress a bit.
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (g_dsp.cr & CR_HALT)
|
if (g_dsp.cr & CR_HALT)
|
||||||
|
@ -231,7 +233,8 @@ int RunCycles(int cycles)
|
||||||
cycles--;
|
cycles--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, let's run a few cycles with idle skipping, so that we can skip idle loops.
|
// Next, let's run a few cycles with idle skipping, so that we can skip
|
||||||
|
// idle loops.
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (g_dsp.cr & CR_HALT)
|
if (g_dsp.cr & CR_HALT)
|
||||||
|
@ -242,8 +245,9 @@ int RunCycles(int cycles)
|
||||||
cycles--;
|
cycles--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, run the rest of the block without idle skipping. It might trip into a
|
// Now, run the rest of the block without idle skipping. It might trip into
|
||||||
// idle loop and if so we waste some time here. Might be beneficial to slice even further.
|
// a idle loop and if so we waste some time here. Might be beneficial to
|
||||||
|
// slice even further.
|
||||||
while (cycles > 0)
|
while (cycles > 0)
|
||||||
{
|
{
|
||||||
Step();
|
Step();
|
||||||
|
|
Loading…
Reference in New Issue