mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-19 12:31:17 +01:00
43c09c63d8
Fixes https://bugs.dolphin-emu.org/issues/10265 (Star Wars: The Clone Wars hangs on loading screen with DSP-HLE and JIT Recompiler). The Clone Wars hangs upon initial boot if this interrupt happens too quickly after submitting a command list. When played in DSP-LLE, the interrupt lags by about 160,000 cycles, though any value greater than or equal to 814 will work. In other games, the lag can be as small as 50,000 cycles (in Metroid Prime) and as large as 718,092 cycles (in Tales of Symphonia!). All credit to @hthh, who put in a heroic(!) amount of detective work and discovered that The Clone Wars tracks a "AXCommandListCycles" variable which matches the aforementioned 160,000 cycles. It's initialized to ~2500 cycles for a minimal, empty command list, so that should be a safe number for pretty much anything a game does (*crosses fingers*).
86 lines
1.7 KiB
C++
86 lines
1.7 KiB
C++
// Copyright 2008 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
class PointerWrap;
|
|
class DSPEmulator;
|
|
namespace MMIO
|
|
{
|
|
class Mapping;
|
|
}
|
|
|
|
namespace DSP
|
|
{
|
|
enum DSPInterruptType
|
|
{
|
|
INT_DSP = 0x80,
|
|
INT_ARAM = 0x20,
|
|
INT_AID = 0x08,
|
|
};
|
|
|
|
// aram size and mask
|
|
enum
|
|
{
|
|
ARAM_SIZE = 0x01000000, // 16 MB
|
|
ARAM_MASK = 0x00FFFFFF,
|
|
};
|
|
|
|
// UDSPControl
|
|
constexpr u16 DSP_CONTROL_MASK = 0x0C07;
|
|
union UDSPControl
|
|
{
|
|
u16 Hex;
|
|
struct
|
|
{
|
|
// DSP Control
|
|
u16 DSPReset : 1; // Write 1 to reset and waits for 0
|
|
u16 DSPAssertInt : 1;
|
|
u16 DSPHalt : 1;
|
|
// Interrupt for DMA to the AI/speakers
|
|
u16 AID : 1;
|
|
u16 AID_mask : 1;
|
|
// ARAM DMA interrupt
|
|
u16 ARAM : 1;
|
|
u16 ARAM_mask : 1;
|
|
// DSP DMA interrupt
|
|
u16 DSP : 1;
|
|
u16 DSP_mask : 1;
|
|
// Other ???
|
|
u16 DMAState : 1; // DSPGetDMAStatus() uses this flag. __ARWaitForDMA() uses it too...maybe
|
|
// it's just general DMA flag
|
|
u16 DSPInitCode : 1; // Indicator that the DSP was initialized?
|
|
u16 DSPInit : 1; // DSPInit() writes to this flag
|
|
u16 pad : 4;
|
|
};
|
|
UDSPControl(u16 hex = 0) : Hex(hex) {}
|
|
};
|
|
|
|
void Init(bool hle);
|
|
void Reinit(bool hle);
|
|
void Shutdown();
|
|
|
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
|
|
|
DSPEmulator* GetDSPEmulator();
|
|
|
|
void DoState(PointerWrap& p);
|
|
|
|
// TODO: Maybe rethink this? The timing is unpredictable.
|
|
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, int cycles_into_future = 0);
|
|
|
|
// Audio/DSP Helper
|
|
u8 ReadARAM(u32 address);
|
|
void WriteARAM(u8 value, u32 address);
|
|
|
|
// Debugger Helper
|
|
u8* GetARAMPtr();
|
|
|
|
void UpdateAudioDMA();
|
|
void UpdateDSPSlice(int cycles);
|
|
|
|
} // end of namespace DSP
|