summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDolphin Bot <dolphin-emu-bot@users.noreply.github.com>2014-07-26 21:26:33 +0200
committerDolphin Bot <dolphin-emu-bot@users.noreply.github.com>2014-07-26 21:26:33 +0200
commit30962ec36173eabfe3dc7ac21beeeaa31d459b77 (patch)
tree82355017f958d1f42cfb62d503198b8e63ba029a
parent6bd5fb3a67a7a649533b072e926619a027f2da5f (diff)
parenta6a4229865e498dd62b74d3d7b508546a69025cf (diff)
Merge pull request #664 from booto/dtk-surgery
DTK: Adjustments attempting to increase accuracy
-rw-r--r--Source/Core/Core/HW/AudioInterface.cpp29
-rw-r--r--Source/Core/Core/HW/AudioInterface.h1
-rw-r--r--Source/Core/Core/HW/DVDInterface.cpp113
-rw-r--r--Source/Core/Core/State.cpp2
4 files changed, 89 insertions, 56 deletions
diff --git a/Source/Core/Core/HW/AudioInterface.cpp b/Source/Core/Core/HW/AudioInterface.cpp
index 37dbded47e..227831389c 100644
--- a/Source/Core/Core/HW/AudioInterface.cpp
+++ b/Source/Core/Core/HW/AudioInterface.cpp
@@ -58,7 +58,6 @@ This file mainly deals with the [Drive I/F], however [AIDFR] controls
#include "Core/CoreTiming.h"
#include "Core/HW/AudioInterface.h"
#include "Core/HW/CPU.h"
-#include "Core/HW/DVDInterface.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SystemTimers.h"
@@ -177,8 +176,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
MMIO::ComplexWrite<u32>([](u32, u32 val) {
AICR tmpAICtrl(val);
- m_Control.AIINTMSK = tmpAICtrl.AIINTMSK;
- m_Control.AIINTVLD = tmpAICtrl.AIINTVLD;
+
+ if (m_Control.AIINTMSK != tmpAICtrl.AIINTMSK)
+ {
+ DEBUG_LOG(AUDIO_INTERFACE, "Change AIINTMSK to %d", tmpAICtrl.AIINTMSK);
+ m_Control.AIINTMSK = tmpAICtrl.AIINTMSK;
+ }
+
+ if (m_Control.AIINTVLD != tmpAICtrl.AIINTVLD)
+ {
+ DEBUG_LOG(AUDIO_INTERFACE, "Change AIINTVLD to %d", tmpAICtrl.AIINTVLD);
+ m_Control.AIINTVLD = tmpAICtrl.AIINTVLD;
+ }
// Set frequency of streaming audio
if (tmpAICtrl.AISFR != m_Control.AISFR)
@@ -207,9 +216,6 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
m_Control.PSTAT = tmpAICtrl.PSTAT;
g_LastCPUTime = CoreTiming::GetTicks();
- // Tell Drive Interface to start/stop streaming
- DVDInterface::g_bStream = tmpAICtrl.PSTAT;
-
CoreTiming::RemoveEvent(et_AI);
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
}
@@ -253,6 +259,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
mmio->Register(base | AI_INTERRUPT_TIMING,
MMIO::DirectRead<u32>(&m_InterruptTiming),
MMIO::ComplexWrite<u32>([](u32, u32 val) {
+ DEBUG_LOG(AUDIO_INTERFACE, "AI_INTERRUPT_TIMING=%08x@%08x", val, PowerPC::ppcState.pc);
m_InterruptTiming = val;
CoreTiming::RemoveEvent(et_AI);
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
@@ -281,14 +288,22 @@ static void IncreaseSampleCount(const u32 _iAmount)
{
if (m_Control.PSTAT)
{
+ u32 old_SampleCounter = m_SampleCounter + 1;
m_SampleCounter += _iAmount;
- if (m_Control.AIINTVLD && (m_SampleCounter >= m_InterruptTiming))
+
+ if ((m_InterruptTiming - old_SampleCounter) <= (m_SampleCounter - old_SampleCounter))
{
+ DEBUG_LOG(AUDIO_INTERFACE, "GenerateAudioInterrupt %08x:%08x @ %08x m_Control.AIINTVLD=%d", m_SampleCounter, m_InterruptTiming, PowerPC::ppcState.pc, m_Control.AIINTVLD);
GenerateAudioInterrupt();
}
}
}
+bool IsPlaying()
+{
+ return (m_Control.PSTAT == 1);
+}
+
unsigned int GetAIDSampleRate()
{
return g_AIDSampleRate;
diff --git a/Source/Core/Core/HW/AudioInterface.h b/Source/Core/Core/HW/AudioInterface.h
index 0b36692083..cf79701068 100644
--- a/Source/Core/Core/HW/AudioInterface.h
+++ b/Source/Core/Core/HW/AudioInterface.h
@@ -17,6 +17,7 @@ namespace AudioInterface
void Init();
void Shutdown();
void DoState(PointerWrap &p);
+bool IsPlaying();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp
index 7e4ebf5919..8c01ba64df 100644
--- a/Source/Core/Core/HW/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVDInterface.cpp
@@ -200,15 +200,17 @@ static UDICR m_DICR;
static UDIIMMBUF m_DIIMMBUF;
static UDICFG m_DICFG;
-static u32 LoopStart;
static u32 AudioPos;
static u32 CurrentStart;
-static u32 LoopLength;
static u32 CurrentLength;
+static u32 NextStart;
+static u32 NextLength;
+
static u32 g_ErrorCode = 0;
static bool g_bDiscInside = false;
bool g_bStream = false;
+static bool g_bStopAtTrackEnd = false;
static int tc = 0;
static int dtk = 0;
@@ -240,9 +242,9 @@ void DoState(PointerWrap &p)
p.Do(m_DIIMMBUF);
p.DoPOD(m_DICFG);
- p.Do(LoopStart);
+ p.Do(NextStart);
p.Do(AudioPos);
- p.Do(LoopLength);
+ p.Do(NextLength);
p.Do(g_ErrorCode);
p.Do(g_bDiscInside);
@@ -253,6 +255,8 @@ void DoState(PointerWrap &p)
p.Do(g_last_read_offset);
p.Do(g_last_read_time);
+
+ p.Do(g_bStopAtTrackEnd);
}
static void TransferComplete(u64 userdata, int cyclesLate)
@@ -268,18 +272,22 @@ static u32 ProcessDTKSamples(short *tempPCM, u32 num_samples)
{
if (AudioPos >= CurrentStart + CurrentLength)
{
- AudioPos = LoopStart;
- CurrentStart = LoopStart;
- CurrentLength = LoopLength;
- NGCADPCM::InitFilter();
- AudioInterface::GenerateAISInterrupt();
+ DEBUG_LOG(DVDINTERFACE,
+ "ProcessDTKSamples: NextStart=%08x,NextLength=%08x,CurrentStart=%08x,CurrentLength=%08x,AudioPos=%08x",
+ NextStart, NextLength, CurrentStart, CurrentLength, AudioPos);
+
+ AudioPos = NextStart;
+ CurrentStart = NextStart;
+ CurrentLength = NextLength;
- // If there isn't any audio to stream, stop streaming.
- if (AudioPos >= CurrentStart + CurrentLength)
+ if (g_bStopAtTrackEnd)
{
+ g_bStopAtTrackEnd = false;
g_bStream = false;
+ break;
}
- break;
+
+ NGCADPCM::InitFilter();
}
u8 tempADPCM[NGCADPCM::ONE_BLOCK_SIZE];
@@ -303,7 +311,7 @@ static void DTKStreamingCallback(u64 userdata, int cyclesLate)
static const int NUM_SAMPLES = 48000 / 2000 * 7; // 3.5ms of 48kHz samples
short tempPCM[NUM_SAMPLES * 2];
unsigned samples_processed;
- if (g_bStream)
+ if (g_bStream && AudioInterface::IsPlaying())
{
samples_processed = ProcessDTKSamples(tempPCM, NUM_SAMPLES);
}
@@ -333,12 +341,13 @@ void Init()
m_DICFG.CONFIG = 1; // Disable bootrom descrambler
AudioPos = 0;
- LoopStart = 0;
- LoopLength = 0;
+ NextStart = 0;
+ NextLength = 0;
CurrentStart = 0;
CurrentLength = 0;
g_bStream = false;
+ g_bStopAtTrackEnd = false;
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
@@ -928,31 +937,41 @@ void ExecuteCommand()
// m_DICMDBUF[2].Hex = Length of the stream
case 0xE1:
{
- u32 pos = m_DICMDBUF[1].Hex << 2;
- u32 length = m_DICMDBUF[2].Hex;
-
- // Start playing
- if (!g_bStream && m_DICMDBUF[0].CMDBYTE1 == 0 && pos != 0 && length != 0)
- {
- AudioPos = pos;
- CurrentStart = pos;
- CurrentLength = length;
- NGCADPCM::InitFilter();
- }
-
- LoopStart = pos;
- LoopLength = length;
- g_bStream = (m_DICMDBUF[0].CMDBYTE1 == 0); // This command can start/stop the stream
-
- // Stop stream
- if (m_DICMDBUF[0].CMDBYTE1 == 1)
+ u8 cancel_stream = m_DICMDBUF[0].CMDBYTE1;
+ if (cancel_stream)
{
+ g_bStopAtTrackEnd = false;
+ g_bStream = false;
AudioPos = 0;
- LoopStart = 0;
- LoopLength = 0;
+ NextStart = 0;
+ NextLength = 0;
CurrentStart = 0;
CurrentLength = 0;
}
+ else
+ {
+ u32 pos = m_DICMDBUF[1].Hex << 2;
+ u32 length = m_DICMDBUF[2].Hex;
+
+ if ((pos == 0) && (length == 0))
+ {
+ g_bStopAtTrackEnd = true;
+ }
+ else if (!g_bStopAtTrackEnd)
+ {
+ NextStart = pos;
+ NextLength = length;
+ if (!g_bStream)
+ {
+ CurrentStart = NextStart;
+ CurrentLength = NextLength;
+ AudioPos = CurrentStart;
+ NGCADPCM::InitFilter();
+ g_bStream = true;
+ }
+ }
+ }
+
WARN_LOG(DVDINTERFACE, "(Audio) Stream subcmd = %08x offset = %08x length=%08x",
m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex << 2, m_DICMDBUF[2].Hex);
@@ -965,25 +984,23 @@ void ExecuteCommand()
switch (m_DICMDBUF[0].CMDBYTE1)
{
case 0x00: // Returns streaming status
- m_DIIMMBUF.Hex = (AudioPos == 0) ? 0 : 1;
+ DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status AudioPos:%08x/%08x CurrentStart:%08x CurrentLength:%08x", AudioPos, CurrentStart + CurrentLength, CurrentStart, CurrentLength);
+ m_DIIMMBUF.REGVAL0 = 0;
+ m_DIIMMBUF.REGVAL1 = 0;
+ m_DIIMMBUF.REGVAL2 = 0;
+ m_DIIMMBUF.REGVAL3 = (g_bStream) ? 1 : 0;
break;
case 0x01: // Returns the current offset
- if (g_bStream)
- m_DIIMMBUF.Hex = (AudioPos - CurrentStart) >> 2;
- else
- m_DIIMMBUF.Hex = 0;
+ DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status AudioPos:%08x", AudioPos);
+ m_DIIMMBUF.Hex = AudioPos >> 2;
break;
case 0x02: // Returns the start offset
- if (g_bStream)
- m_DIIMMBUF.Hex = CurrentStart >> 2;
- else
- m_DIIMMBUF.Hex = 0;
+ DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentStart:%08x", CurrentStart);
+ m_DIIMMBUF.Hex = CurrentStart >> 2;
break;
case 0x03: // Returns the total length
- if (g_bStream)
- m_DIIMMBUF.Hex = CurrentLength;
- else
- m_DIIMMBUF.Hex = 0;
+ DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentLength:%08x", CurrentLength);
+ m_DIIMMBUF.Hex = CurrentLength;
break;
default:
WARN_LOG(DVDINTERFACE, "(Audio): Subcommand: %02x Request Audio status %s", m_DICMDBUF[0].CMDBYTE1, g_bStream? "on":"off");
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 08fad24001..a26b4e576a 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -63,7 +63,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system
-static const u32 STATE_VERSION = 28;
+static const u32 STATE_VERSION = 29;
enum
{