diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 575b9c307f..0e65566688 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -23,7 +23,7 @@
#include "Core/Debugger/Debugger_SymbolMap.h"
#include "Core/GeckoCode.h"
#include "Core/HLE/HLE.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/VideoInterface.h"
diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
index caba5422f1..a5c6c94189 100644
--- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp
+++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
@@ -18,7 +18,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HLE/HLE.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/ES.h"
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index f5d6699324..7d17cde612 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -8,7 +8,6 @@ set(SRCS
CoreTiming.cpp
DSPEmulator.cpp
ec_wii.cpp
- FileMonitor.cpp
GeckoCodeConfig.cpp
GeckoCode.cpp
HotkeyManager.cpp
@@ -90,8 +89,10 @@ set(SRCS
HW/DSPLLE/DSPLLEGlobals.cpp
HW/DSPLLE/DSPLLE.cpp
HW/DSPLLE/DSPLLETools.cpp
- HW/DVDInterface.cpp
- HW/DVDThread.cpp
+ HW/DVD/DVDInterface.cpp
+ HW/DVD/DVDMath.cpp
+ HW/DVD/DVDThread.cpp
+ HW/DVD/FileMonitor.cpp
HW/EXI/EXI_Channel.cpp
HW/EXI/EXI.cpp
HW/EXI/EXI_Device.cpp
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index 6d87bab40e..bfc2745969 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -24,8 +24,8 @@
#include "Core/Core.h"
#include "Core/FifoPlayer/FifoDataFile.h"
#include "Core/HLE/HLE.h"
-#include "Core/HW/DVDInterface.h"
-#include "Core/HW/DVDThread.h"
+#include "Core/HW/DVD/DVDInterface.h"
+#include "Core/HW/DVD/DVDThread.h"
#include "Core/HW/SI/SI.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/USB/Bluetooth/BTBase.h"
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 69a7f542bf..23e6c0df6e 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -89,7 +89,6 @@
-
@@ -115,8 +114,10 @@
-
-
+
+
+
+
@@ -341,7 +342,6 @@
-
@@ -369,8 +369,10 @@
-
-
+
+
+
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index ca147279eb..a3773aad87 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -281,9 +281,6 @@
FifoPlayer
-
- FileMonitor
-
GeckoCode
@@ -347,10 +344,16 @@
HW %28Flipper/Hollywood%29\AI - Audio Interface
-
+
HW %28Flipper/Hollywood%29\DI - Drive Interface
-
+
+ HW %28Flipper/Hollywood%29\DI - Drive Interface
+
+
+ HW %28Flipper/Hollywood%29\DI - Drive Interface
+
+
HW %28Flipper/Hollywood%29\DI - Drive Interface
@@ -964,9 +967,6 @@
FifoPlayer
-
- FileMonitor
-
GeckoCode
@@ -1003,12 +1003,18 @@
HW %28Flipper/Hollywood%29\AI - Audio Interface
-
+
HW %28Flipper/Hollywood%29\DI - Drive Interface
-
+
HW %28Flipper/Hollywood%29\DI - Drive Interface
+
+ HW %28Flipper/Hollywood%29\DI - Drive Interface
+
+
+ HW %28Flipper/Hollywood%29\DI - Drive Interface
+
HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE\uCodes
diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp
similarity index 85%
rename from Source/Core/Core/HW/DVDInterface.cpp
rename to Source/Core/Core/HW/DVD/DVDInterface.cpp
index d49865267c..49c7926c07 100644
--- a/Source/Core/Core/HW/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp
@@ -4,7 +4,6 @@
#include
#include
-#include
#include
#include
@@ -13,14 +12,16 @@
#include "Common/Align.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
+#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
-#include "Core/FileMonitor.h"
#include "Core/HW/AudioInterface.h"
-#include "Core/HW/DVDInterface.h"
-#include "Core/HW/DVDThread.h"
+#include "Core/HW/DVD/DVDInterface.h"
+#include "Core/HW/DVD/DVDMath.h"
+#include "Core/HW/DVD/DVDThread.h"
+#include "Core/HW/DVD/FileMonitor.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
@@ -52,31 +53,6 @@ constexpr u64 DVD_ECC_BLOCK_SIZE = 16 * DVD_SECTOR_SIZE;
// is already buffered. Measured in bytes per second.
constexpr u64 BUFFER_TRANSFER_RATE = 32 * 1024 * 1024;
-// The size of the first Wii disc layer in bytes (2294912 sectors per layer)
-constexpr u64 WII_DISC_LAYER_SIZE = 2294912 * DVD_SECTOR_SIZE;
-
-// 24 mm
-constexpr double DVD_INNER_RADIUS = 0.024;
-// 58 mm
-constexpr double WII_DVD_OUTER_RADIUS = 0.058;
-// 38 mm
-constexpr double GC_DVD_OUTER_RADIUS = 0.038;
-
-// Approximate read speeds at the inner and outer locations of Wii and GC
-// discs. These speeds are approximations of speeds measured on real Wiis.
-constexpr double GC_DISC_INNER_READ_SPEED = 1024 * 1024 * 2.1; // bytes/s
-constexpr double GC_DISC_OUTER_READ_SPEED = 1024 * 1024 * 3.325; // bytes/s
-constexpr double WII_DISC_INNER_READ_SPEED = 1024 * 1024 * 3.48; // bytes/s
-constexpr double WII_DISC_OUTER_READ_SPEED = 1024 * 1024 * 8.41; // bytes/s
-
-// Experimentally measured seek constants. The time to seek appears to be
-// linear, but short seeks appear to be lower velocity.
-constexpr double SHORT_SEEK_MAX_DISTANCE = 0.001; // 1 mm
-constexpr double SHORT_SEEK_CONSTANT = 0.045; // seconds
-constexpr double SHORT_SEEK_VELOCITY_INVERSE = 50; // inverse: s/m
-constexpr double LONG_SEEK_CONSTANT = 0.085; // seconds
-constexpr double LONG_SEEK_VELOCITY_INVERSE = 4.5; // inverse: s/m
-
namespace DVDInterface
{
// internal hardware addresses
@@ -276,9 +252,6 @@ bool ExecuteReadCommand(u64 DVD_offset, u32 output_address, u32 DVD_length, u32
u64 PackFinishExecutingCommandUserdata(ReplyType reply_type, DIInterruptType interrupt_type);
void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, ReplyType reply_type);
-double CalculatePhysicalDiscPosition(u64 offset);
-u64 CalculateSeekTime(u64 offset_from, u64 offset_to);
-u64 CalculateRawDiscReadTime(u64 offset, u64 length);
void DoState(PointerWrap& p)
{
@@ -1191,6 +1164,8 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
// places, the video before the save-file select screen lags.
const u64 current_time = CoreTiming::GetTicks();
+ const u32 ticks_per_second = SystemTimers::GetTicksPerSecond();
+ const bool wii_disc = s_inserted_volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
// Where the DVD read head is (usually parked at the end of the buffer,
// unless we've interrupted it mid-buffer-read).
@@ -1300,14 +1275,18 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
if (dvd_offset != head_position)
{
// Unbuffered seek+read
- ticks_until_completion += CalculateSeekTime(head_position, dvd_offset);
+ ticks_until_completion += static_cast(
+ ticks_per_second * DVDMath::CalculateSeekTime(head_position, dvd_offset));
+
DEBUG_LOG(DVDINTERFACE, "Seek+read 0x%" PRIx32 " bytes @ 0x%" PRIx64 " ticks=%" PRId64,
chunk_length, offset, ticks_until_completion);
}
else
{
// Unbuffered read
- ticks_until_completion += CalculateRawDiscReadTime(dvd_offset, DVD_ECC_BLOCK_SIZE);
+ ticks_until_completion +=
+ static_cast(ticks_per_second * DVDMath::CalculateRawDiscReadTime(
+ dvd_offset, DVD_ECC_BLOCK_SIZE, wii_disc));
}
unbuffered_blocks++;
@@ -1350,8 +1329,10 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
s_read_buffer_start_time = current_time + ticks_until_completion;
s_read_buffer_end_time =
s_read_buffer_start_time +
- CalculateRawDiscReadTime(s_read_buffer_start_offset,
- s_read_buffer_end_offset - s_read_buffer_start_offset);
+ static_cast(ticks_per_second *
+ DVDMath::CalculateRawDiscReadTime(
+ s_read_buffer_start_offset,
+ s_read_buffer_end_offset - s_read_buffer_start_offset, wii_disc));
}
DEBUG_LOG(DVDINTERFACE, "Schedule reads: ECC blocks unbuffered=%d, buffered=%d, "
@@ -1360,124 +1341,4 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
ticks_until_completion * 1000000 / SystemTimers::GetTicksPerSecond());
}
-// We can approximate the relationship between a byte offset on disc and its
-// radial distance from the center by using an approximation for the length of
-// a rolled material, which is the area of the material divided by the pitch
-// (ie: assume that you can squish and deform the area of the disc into a
-// rectangle as thick as the track pitch).
-//
-// In practice this yields good-enough numbers as a more exact formula
-// involving the integral over a polar equation (too complex to describe here)
-// or the approximation of a DVD as a set of concentric circles (which is a
-// better approximation, but makes futher derivations more complicated than
-// they need to be).
-//
-// From the area approximation, we end up with this formula:
-//
-// L = pi*(r.outer^2-r.inner^2)/pitch
-//
-// Where:
-// L = the data track's physical length
-// r.{inner,outer} = the inner/outer radii (24 mm and 58 mm)
-// pitch = the track pitch (.74 um)
-//
-// We can then use this equation to compute the radius for a given sector in
-// the disc by mapping it along the length to a linear position and inverting
-// the equation and solving for r.outer (using the DVD's r.inner and pitch)
-// given that linear position:
-//
-// r.outer = sqrt(L * pitch / pi + r.inner^2)
-//
-// Where:
-// L = the offset's linear position, as offset/density
-// r.outer = the radius for the offset
-// r.inner and pitch are the same as before.
-//
-// The data density of the disc is just the number of bytes addressable on a
-// DVD, divided by the spiral length holding that data. offset/density yields
-// the linear position for a given offset.
-//
-// When we put it all together and simplify, we can compute the radius for a
-// given byte offset as a drastically simplified:
-//
-// r = sqrt(offset/total_bytes*(r.outer^2-r.inner^2) + r.inner^2)
-double CalculatePhysicalDiscPosition(u64 offset)
-{
- // Just in case someone has an overly large disc image
- // that can't exist in reality...
- offset %= WII_DISC_LAYER_SIZE * 2;
-
- // Assumption: the layout on the second disc layer is opposite of the first,
- // ie layer 2 starts where layer 1 ends and goes backwards.
- if (offset > WII_DISC_LAYER_SIZE)
- offset = WII_DISC_LAYER_SIZE * 2 - offset;
-
- // The track pitch here is 0.74 um, but it cancels out and we don't need it
-
- // Note that because Wii and GC discs have identical data densities
- // we can simply use the Wii numbers in both cases
- return std::sqrt(
- static_cast(offset) / WII_DISC_LAYER_SIZE *
- (WII_DVD_OUTER_RADIUS * WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS * DVD_INNER_RADIUS) +
- DVD_INNER_RADIUS * DVD_INNER_RADIUS);
-}
-
-// Returns the number of ticks to move the read head from one offset to
-// another, plus the number of ticks to read one ECC block immediately
-// afterwards. Based on hardware testing, this appears to be a function of the
-// linear distance between the radius of the first and second positions on the
-// disc, though the head speed varies depending on the length of the seek.
-u64 CalculateSeekTime(u64 offset_from, u64 offset_to)
-{
- const double position_from = CalculatePhysicalDiscPosition(offset_from);
- const double position_to = CalculatePhysicalDiscPosition(offset_to);
-
- // Seek time is roughly linear based on head distance travelled
- const double distance = fabs(position_from - position_to);
-
- double time_in_seconds;
- if (distance < SHORT_SEEK_MAX_DISTANCE)
- time_in_seconds = distance * SHORT_SEEK_VELOCITY_INVERSE + SHORT_SEEK_CONSTANT;
- else
- time_in_seconds = distance * LONG_SEEK_VELOCITY_INVERSE + LONG_SEEK_CONSTANT;
-
- return static_cast(time_in_seconds * SystemTimers::GetTicksPerSecond());
-}
-
-// Returns the number of ticks it takes to read an amount of data from a disc,
-// ignoring factors such as seek times. This is the streaming rate of the
-// drive and varies between ~3-8MiB/s for Wii discs. Note that there is technically
-// a DMA delay on top of this, but we model that as part of this read time.
-u64 CalculateRawDiscReadTime(u64 offset, u64 length)
-{
- // The Wii/GC have a CAV drive and the data has a constant pit length
- // regardless of location on disc. This means we can linearly interpolate
- // speed from the inner to outer radius. This matches a hardware test.
- // We're just picking a point halfway into the read as our benchmark for
- // read speed as speeds don't change materially in this small window.
- const double physical_offset = CalculatePhysicalDiscPosition(offset + length / 2);
-
- double speed;
- if (s_inserted_volume->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- speed = (physical_offset - DVD_INNER_RADIUS) / (WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
- (WII_DISC_OUTER_READ_SPEED - WII_DISC_INNER_READ_SPEED) +
- WII_DISC_INNER_READ_SPEED;
- }
- else
- {
- speed = (physical_offset - DVD_INNER_RADIUS) / (GC_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
- (GC_DISC_OUTER_READ_SPEED - GC_DISC_INNER_READ_SPEED) +
- GC_DISC_INNER_READ_SPEED;
- }
-
- DEBUG_LOG(DVDINTERFACE, "Read 0x%" PRIx64 " @ 0x%" PRIx64 " @%lf mm: %lf us, %lf MiB/s", length,
- offset, physical_offset * 1000, length / speed * 1000 * 1000, speed / 1024 / 1024);
-
- // (ticks/second) / (bytes/second) * bytes = ticks
- const double ticks = static_cast(SystemTimers::GetTicksPerSecond()) * length / speed;
-
- return static_cast(ticks);
-}
-
} // namespace
diff --git a/Source/Core/Core/HW/DVDInterface.h b/Source/Core/Core/HW/DVD/DVDInterface.h
similarity index 100%
rename from Source/Core/Core/HW/DVDInterface.h
rename to Source/Core/Core/HW/DVD/DVDInterface.h
diff --git a/Source/Core/Core/HW/DVD/DVDMath.cpp b/Source/Core/Core/HW/DVD/DVDMath.cpp
new file mode 100644
index 0000000000..cb37aae412
--- /dev/null
+++ b/Source/Core/Core/HW/DVD/DVDMath.cpp
@@ -0,0 +1,154 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Core/HW/DVD/DVDMath.h"
+
+#include
+#include
+
+#include "Common/CommonTypes.h"
+#include "Common/Logging/Log.h"
+
+namespace DVDMath
+{
+// The size of the first Wii disc layer in bytes (2294912 sectors, 2048 bytes per sector)
+constexpr u64 WII_DISC_LAYER_SIZE = 0x118240000;
+
+// 24 mm
+constexpr double DVD_INNER_RADIUS = 0.024;
+// 58 mm
+constexpr double WII_DVD_OUTER_RADIUS = 0.058;
+// 38 mm
+constexpr double GC_DVD_OUTER_RADIUS = 0.038;
+
+// Approximate read speeds at the inner and outer locations of Wii and GC
+// discs. These speeds are approximations of speeds measured on real Wiis.
+constexpr double GC_DISC_INNER_READ_SPEED = 1024 * 1024 * 2.1; // bytes/s
+constexpr double GC_DISC_OUTER_READ_SPEED = 1024 * 1024 * 3.325; // bytes/s
+constexpr double WII_DISC_INNER_READ_SPEED = 1024 * 1024 * 3.48; // bytes/s
+constexpr double WII_DISC_OUTER_READ_SPEED = 1024 * 1024 * 8.41; // bytes/s
+
+// Experimentally measured seek constants. The time to seek appears to be
+// linear, but short seeks appear to be lower velocity.
+constexpr double SHORT_SEEK_MAX_DISTANCE = 0.001; // 1 mm
+constexpr double SHORT_SEEK_CONSTANT = 0.045; // seconds
+constexpr double SHORT_SEEK_VELOCITY_INVERSE = 50; // inverse: s/m
+constexpr double LONG_SEEK_CONSTANT = 0.085; // seconds
+constexpr double LONG_SEEK_VELOCITY_INVERSE = 4.5; // inverse: s/m
+
+// We can approximate the relationship between a byte offset on disc and its
+// radial distance from the center by using an approximation for the length of
+// a rolled material, which is the area of the material divided by the pitch
+// (ie: assume that you can squish and deform the area of the disc into a
+// rectangle as thick as the track pitch).
+//
+// In practice this yields good-enough numbers as a more exact formula
+// involving the integral over a polar equation (too complex to describe here)
+// or the approximation of a DVD as a set of concentric circles (which is a
+// better approximation, but makes futher derivations more complicated than
+// they need to be).
+//
+// From the area approximation, we end up with this formula:
+//
+// L = pi*(r.outer^2-r.inner^2)/pitch
+//
+// Where:
+// L = the data track's physical length
+// r.{inner,outer} = the inner/outer radii (24 mm and 58 mm)
+// pitch = the track pitch (.74 um)
+//
+// We can then use this equation to compute the radius for a given sector in
+// the disc by mapping it along the length to a linear position and inverting
+// the equation and solving for r.outer (using the DVD's r.inner and pitch)
+// given that linear position:
+//
+// r.outer = sqrt(L * pitch / pi + r.inner^2)
+//
+// Where:
+// L = the offset's linear position, as offset/density
+// r.outer = the radius for the offset
+// r.inner and pitch are the same as before.
+//
+// The data density of the disc is just the number of bytes addressable on a
+// DVD, divided by the spiral length holding that data. offset/density yields
+// the linear position for a given offset.
+//
+// When we put it all together and simplify, we can compute the radius for a
+// given byte offset as a drastically simplified:
+//
+// r = sqrt(offset/total_bytes*(r.outer^2-r.inner^2) + r.inner^2)
+double CalculatePhysicalDiscPosition(u64 offset)
+{
+ // Just in case someone has an overly large disc image
+ // that can't exist in reality...
+ offset %= WII_DISC_LAYER_SIZE * 2;
+
+ // Assumption: the layout on the second disc layer is opposite of the first,
+ // ie layer 2 starts where layer 1 ends and goes backwards.
+ if (offset > WII_DISC_LAYER_SIZE)
+ offset = WII_DISC_LAYER_SIZE * 2 - offset;
+
+ // The track pitch here is 0.74 um, but it cancels out and we don't need it
+
+ // Note that because Wii and GC discs have identical data densities
+ // we can simply use the Wii numbers in both cases
+ return std::sqrt(
+ static_cast(offset) / WII_DISC_LAYER_SIZE *
+ (WII_DVD_OUTER_RADIUS * WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS * DVD_INNER_RADIUS) +
+ DVD_INNER_RADIUS * DVD_INNER_RADIUS);
+}
+
+// Returns the time in seconds to move the read head from one offset to
+// another, plus the number of ticks to read one ECC block immediately
+// afterwards. Based on hardware testing, this appears to be a function of the
+// linear distance between the radius of the first and second positions on the
+// disc, though the head speed varies depending on the length of the seek.
+double CalculateSeekTime(u64 offset_from, u64 offset_to)
+{
+ const double position_from = CalculatePhysicalDiscPosition(offset_from);
+ const double position_to = CalculatePhysicalDiscPosition(offset_to);
+
+ // Seek time is roughly linear based on head distance travelled
+ const double distance = fabs(position_from - position_to);
+
+ if (distance < SHORT_SEEK_MAX_DISTANCE)
+ return distance * SHORT_SEEK_VELOCITY_INVERSE + SHORT_SEEK_CONSTANT;
+ else
+ return distance * LONG_SEEK_VELOCITY_INVERSE + LONG_SEEK_CONSTANT;
+}
+
+// Returns the time in seconds it takes to read an amount of data from a disc,
+// ignoring factors such as seek times. This is the streaming rate of the
+// drive and varies between ~3-8MiB/s for Wii discs. Note that there is technically
+// a DMA delay on top of this, but we model that as part of this read time.
+double CalculateRawDiscReadTime(u64 offset, u64 length, bool wii_disc)
+{
+ // The Wii/GC have a CAV drive and the data has a constant pit length
+ // regardless of location on disc. This means we can linearly interpolate
+ // speed from the inner to outer radius. This matches a hardware test.
+ // We're just picking a point halfway into the read as our benchmark for
+ // read speed as speeds don't change materially in this small window.
+ const double physical_offset = CalculatePhysicalDiscPosition(offset + length / 2);
+
+ double speed;
+ if (wii_disc)
+ {
+ speed = (physical_offset - DVD_INNER_RADIUS) / (WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
+ (WII_DISC_OUTER_READ_SPEED - WII_DISC_INNER_READ_SPEED) +
+ WII_DISC_INNER_READ_SPEED;
+ }
+ else
+ {
+ speed = (physical_offset - DVD_INNER_RADIUS) / (GC_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
+ (GC_DISC_OUTER_READ_SPEED - GC_DISC_INNER_READ_SPEED) +
+ GC_DISC_INNER_READ_SPEED;
+ }
+
+ DEBUG_LOG(DVDINTERFACE, "Read 0x%" PRIx64 " @ 0x%" PRIx64 " @%lf mm: %lf us, %lf MiB/s", length,
+ offset, physical_offset * 1000, length / speed * 1000 * 1000, speed / 1024 / 1024);
+
+ return length / speed;
+}
+
+} // namespace DVDMath
diff --git a/Source/Core/Core/HW/DVD/DVDMath.h b/Source/Core/Core/HW/DVD/DVDMath.h
new file mode 100644
index 0000000000..8c76a6db15
--- /dev/null
+++ b/Source/Core/Core/HW/DVD/DVDMath.h
@@ -0,0 +1,15 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Common/CommonTypes.h"
+
+namespace DVDMath
+{
+double CalculatePhysicalDiscPosition(u64 offset);
+double CalculateSeekTime(u64 offset_from, u64 offset_to);
+double CalculateRawDiscReadTime(u64 offset, u64 length, bool wii_disc);
+
+} // namespace DVDMath
diff --git a/Source/Core/Core/HW/DVDThread.cpp b/Source/Core/Core/HW/DVD/DVDThread.cpp
similarity index 98%
rename from Source/Core/Core/HW/DVDThread.cpp
rename to Source/Core/Core/HW/DVD/DVDThread.cpp
index bbb930f043..8bd0ccf5cd 100644
--- a/Source/Core/Core/HW/DVDThread.cpp
+++ b/Source/Core/Core/HW/DVD/DVDThread.cpp
@@ -21,9 +21,9 @@
#include "Core/Core.h"
#include "Core/CoreTiming.h"
-#include "Core/FileMonitor.h"
-#include "Core/HW/DVDInterface.h"
-#include "Core/HW/DVDThread.h"
+#include "Core/HW/DVD/DVDInterface.h"
+#include "Core/HW/DVD/DVDThread.h"
+#include "Core/HW/DVD/FileMonitor.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
diff --git a/Source/Core/Core/HW/DVDThread.h b/Source/Core/Core/HW/DVD/DVDThread.h
similarity index 100%
rename from Source/Core/Core/HW/DVDThread.h
rename to Source/Core/Core/HW/DVD/DVDThread.h
diff --git a/Source/Core/Core/FileMonitor.cpp b/Source/Core/Core/HW/DVD/FileMonitor.cpp
similarity index 98%
rename from Source/Core/Core/FileMonitor.cpp
rename to Source/Core/Core/HW/DVD/FileMonitor.cpp
index bb223cc578..93449abce3 100644
--- a/Source/Core/Core/FileMonitor.cpp
+++ b/Source/Core/Core/HW/DVD/FileMonitor.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
-#include "Core/FileMonitor.h"
+#include "Core/HW/DVD/FileMonitor.h"
#include
#include
diff --git a/Source/Core/Core/FileMonitor.h b/Source/Core/Core/HW/DVD/FileMonitor.h
similarity index 100%
rename from Source/Core/Core/FileMonitor.h
rename to Source/Core/Core/HW/DVD/FileMonitor.h
diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp
index cbb297cf39..b388d72889 100644
--- a/Source/Core/Core/HW/HW.cpp
+++ b/Source/Core/Core/HW/HW.cpp
@@ -11,7 +11,7 @@
#include "Core/HW/AudioInterface.h"
#include "Core/HW/CPU.h"
#include "Core/HW/DSP.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/GPFifo.h"
#include "Core/HW/HW.h"
diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp
index cff92dea1b..452f198884 100644
--- a/Source/Core/Core/HW/Memmap.cpp
+++ b/Source/Core/Core/HW/Memmap.cpp
@@ -18,7 +18,7 @@
#include "Core/ConfigManager.h"
#include "Core/HW/AudioInterface.h"
#include "Core/HW/DSP.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/Memmap.h"
diff --git a/Source/Core/Core/IOS/DI/DI.cpp b/Source/Core/Core/IOS/DI/DI.cpp
index 4dc743b81c..639038b565 100644
--- a/Source/Core/Core/IOS/DI/DI.cpp
+++ b/Source/Core/Core/IOS/DI/DI.cpp
@@ -11,7 +11,7 @@
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/DI/DI.h"
#include "Core/IOS/ES/ES.h"
diff --git a/Source/Core/Core/IOS/MIOS.cpp b/Source/Core/Core/IOS/MIOS.cpp
index a7e51f51fe..aad859a0ef 100644
--- a/Source/Core/Core/IOS/MIOS.cpp
+++ b/Source/Core/Core/IOS/MIOS.cpp
@@ -18,8 +18,8 @@
#include "Core/DSPEmulator.h"
#include "Core/HLE/HLE.h"
#include "Core/HW/DSP.h"
-#include "Core/HW/DVDInterface.h"
-#include "Core/HW/DVDThread.h"
+#include "Core/HW/DVD/DVDInterface.h"
+#include "Core/HW/DVD/DVDThread.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
#include "Core/IOS/ES/Formats.h"
diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.cpp b/Source/Core/Core/IOS/WFS/WFSSRV.cpp
index 1c22e23b93..74a67bff2f 100644
--- a/Source/Core/Core/IOS/WFS/WFSSRV.cpp
+++ b/Source/Core/Core/IOS/WFS/WFSSRV.cpp
@@ -11,7 +11,6 @@
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/NandPaths.h"
-#include "Core/HW/DVDInterface.h"
#include "Core/HW/Memmap.h"
namespace IOS
diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp
index 1c22b8340a..b0de9e3faa 100644
--- a/Source/Core/Core/Movie.cpp
+++ b/Source/Core/Core/Movie.cpp
@@ -25,7 +25,7 @@
#include "Core/CoreTiming.h"
#include "Core/DSP/DSPCore.h"
#include "Core/HW/CPU.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SI/SI.h"
diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp
index 845839e046..a62134b8ab 100644
--- a/Source/Core/DolphinWX/Frame.cpp
+++ b/Source/Core/DolphinWX/Frame.cpp
@@ -43,7 +43,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/GCKeyboard.h"
#include "Core/HW/GCPad.h"
#include "Core/HW/Wiimote.h"
diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp
index 151c8fc02b..58986f4fe0 100644
--- a/Source/Core/DolphinWX/FrameTools.cpp
+++ b/Source/Core/DolphinWX/FrameTools.cpp
@@ -33,7 +33,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HW/CPU.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/GCKeyboard.h"
#include "Core/HW/GCPad.h"
#include "Core/HW/ProcessorInterface.h"
diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp
index 625ee8e09b..01861cd7f7 100644
--- a/Source/Core/DolphinWX/GameListCtrl.cpp
+++ b/Source/Core/DolphinWX/GameListCtrl.cpp
@@ -47,7 +47,7 @@
#include "Core/Boot/Boot.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
-#include "Core/HW/DVDInterface.h"
+#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/WiiSaveCrypted.h"
#include "Core/Movie.h"
#include "DiscIO/Blob.h"