mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #8571 from Pokechu22/di-interrupts
Fix gamecube games not noticing disc changes
This commit is contained in:
@@ -250,8 +250,9 @@ bool CBoot::DVDReadDiscID(const DiscIO::VolumeDisc& disc, u32 output_address)
|
||||
if (!disc.Read(0, buffer.size(), buffer.data(), DiscIO::PARTITION_NONE))
|
||||
return false;
|
||||
Memory::CopyToEmu(output_address, buffer.data(), buffer.size());
|
||||
// Clear ERROR_NO_DISKID_L, probably should check if that's currently set
|
||||
DVDInterface::SetLowError(DVDInterface::ERROR_READY);
|
||||
// Transition out of the DiscIdNotRead state (which the drive should be in at this point,
|
||||
// on the assumption that this is only used for the first read)
|
||||
DVDInterface::SetDriveState(DVDInterface::DriveState::ReadyNoReadsMade);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,33 +51,41 @@ enum class DICommand : u8
|
||||
UnknownEE = 0xee,
|
||||
};
|
||||
|
||||
// "low" error codes
|
||||
constexpr u32 ERROR_READY = 0x0000000; // Ready.
|
||||
constexpr u32 ERROR_COVER = 0x01000000; // Cover is opened.
|
||||
constexpr u32 ERROR_CHANGE_DISK = 0x02000000; // Disk change.
|
||||
constexpr u32 ERROR_NO_DISK_L = 0x03000000; // No disk.
|
||||
constexpr u32 ERROR_MOTOR_STOP_L = 0x04000000; // Motor stop.
|
||||
constexpr u32 ERROR_NO_DISKID_L = 0x05000000; // Disk ID not read.
|
||||
constexpr u32 LOW_ERROR_MASK = 0xff000000;
|
||||
// Disc drive state.
|
||||
// Reported in error codes as 0 for Ready, and value-1 for the rest
|
||||
// (i.e. Ready and ReadyNoReadsMade are both reported as 0)
|
||||
enum class DriveState : u8
|
||||
{
|
||||
Ready = 0,
|
||||
ReadyNoReadsMade = 1,
|
||||
CoverOpened = 2,
|
||||
DiscChangeDetected = 3,
|
||||
NoMediumPresent = 4,
|
||||
MotorStopped = 5,
|
||||
DiscIdNotRead = 6
|
||||
};
|
||||
|
||||
// "high" error codes
|
||||
constexpr u32 ERROR_NONE = 0x000000; // No error.
|
||||
constexpr u32 ERROR_MOTOR_STOP_H = 0x020400; // Motor stopped.
|
||||
constexpr u32 ERROR_NO_DISKID_H = 0x020401; // Disk ID not read.
|
||||
constexpr u32 ERROR_NO_DISK_H = 0x023a00; // Medium not present / Cover opened.
|
||||
constexpr u32 ERROR_SEEK_NDONE = 0x030200; // No seek complete.
|
||||
constexpr u32 ERROR_READ = 0x031100; // Unrecovered read error.
|
||||
constexpr u32 ERROR_PROTOCOL = 0x040800; // Transfer protocol error.
|
||||
constexpr u32 ERROR_INV_CMD = 0x052000; // Invalid command operation code.
|
||||
constexpr u32 ERROR_AUDIO_BUF = 0x052001; // Audio Buffer not set.
|
||||
constexpr u32 ERROR_BLOCK_OOB = 0x052100; // Logical block address out of bounds.
|
||||
constexpr u32 ERROR_INV_FIELD = 0x052400; // Invalid field in command packet.
|
||||
constexpr u32 ERROR_INV_AUDIO = 0x052401; // Invalid audio command.
|
||||
constexpr u32 ERROR_INV_PERIOD = 0x052402; // Configuration out of permitted period.
|
||||
constexpr u32 ERROR_END_USR_AREA = 0x056300; // End of user area encountered on this track.
|
||||
constexpr u32 ERROR_MEDIUM = 0x062800; // Medium may have changed.
|
||||
constexpr u32 ERROR_MEDIUM_REQ = 0x0b5a01; // Operator medium removal request.
|
||||
constexpr u32 HIGH_ERROR_MASK = 0x00ffffff;
|
||||
// Actual drive error codes, which fill the remaining 3 bytes
|
||||
// Numbers more or less match a SCSI sense key (1 nybble) followed by SCSI ASC/ASCQ (2 bytes).
|
||||
enum class DriveError : u32
|
||||
{
|
||||
None = 0x00000, // No error.
|
||||
MotorStopped = 0x20400, // Motor stopped.
|
||||
NoDiscID = 0x20401, // Disk ID not read.
|
||||
MediumNotPresent = 0x23a00, // Medium not present / Cover opened.
|
||||
SeekNotDone = 0x30200, // No seek complete.
|
||||
ReadError = 0x31100, // Unrecovered read error.
|
||||
ProtocolError = 0x40800, // Transfer protocol error.
|
||||
InvalidCommand = 0x52000, // Invalid command operation code.
|
||||
NoAudioBuf = 0x52001, // Audio Buffer not set.
|
||||
BlockOOB = 0x52100, // Logical block address out of bounds.
|
||||
InvalidField = 0x52400, // Invalid field in command packet.
|
||||
InvalidAudioCommand = 0x52401, // Invalid audio command.
|
||||
InvalidPeriod = 0x52402, // Configuration out of permitted period.
|
||||
EndOfUserArea = 0x56300, // End of user area encountered on this track.
|
||||
MediumChanged = 0x62800, // Medium may have changed.
|
||||
MediumRemovalRequest = 0xb5a01, // Operator medium removal request.
|
||||
};
|
||||
|
||||
enum class DIInterruptType : int
|
||||
{
|
||||
@@ -102,7 +110,7 @@ enum class EjectCause
|
||||
};
|
||||
|
||||
void Init();
|
||||
void Reset(bool spinup = true);
|
||||
void ResetDrive(bool spinup);
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
@@ -130,8 +138,8 @@ void PerformDecryptingRead(u32 position, u32 length, u32 output_address,
|
||||
// Exposed for use by emulated BS2; does not perform any checks on drive state
|
||||
void AudioBufferConfig(bool enable_dtk, u8 dtk_buffer_length);
|
||||
|
||||
void SetLowError(u32 low_error);
|
||||
void SetHighError(u32 high_error);
|
||||
void SetDriveState(DriveState state);
|
||||
void SetDriveError(DriveError error);
|
||||
|
||||
// Used by DVDThread
|
||||
void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late,
|
||||
|
||||
@@ -348,7 +348,7 @@ static void FinishRead(u64 id, s64 cycles_late)
|
||||
PanicAlertT("The disc could not be read (at 0x%" PRIx64 " - 0x%" PRIx64 ").",
|
||||
request.dvd_offset, request.dvd_offset + request.length);
|
||||
|
||||
DVDInterface::SetHighError(DVDInterface::ERROR_BLOCK_OOB);
|
||||
DVDInterface::SetDriveError(DVDInterface::DriveError::BlockOOB);
|
||||
interrupt = DVDInterface::DIInterruptType::DEINT;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/DVD/DVDInterface.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
@@ -111,8 +112,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
MMIO::ComplexWrite<u32>(
|
||||
[](u32, u32 val) { WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", val); }));
|
||||
|
||||
mmio->Register(base | PI_RESET_CODE, MMIO::DirectRead<u32>(&m_ResetCode),
|
||||
MMIO::DirectWrite<u32>(&m_ResetCode));
|
||||
mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](u32) {
|
||||
DEBUG_LOG(PROCESSORINTERFACE, "Read PI_RESET_CODE: %08x", m_ResetCode);
|
||||
return m_ResetCode;
|
||||
}),
|
||||
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
||||
m_ResetCode = val;
|
||||
INFO_LOG(PROCESSORINTERFACE, "Wrote PI_RESET_CODE: %08x", m_ResetCode);
|
||||
if (~m_ResetCode & 0x4)
|
||||
{
|
||||
DVDInterface::ResetDrive(true);
|
||||
}
|
||||
}));
|
||||
|
||||
mmio->Register(base | PI_FLIPPER_REV, MMIO::DirectRead<u32>(&m_FlipperRev),
|
||||
MMIO::InvalidWrite<u32>());
|
||||
|
||||
@@ -266,9 +266,9 @@ std::optional<DI::DIResult> DI::StartIOCtl(const IOCtlRequest& request)
|
||||
return DIResult::Success;
|
||||
case DIIoctl::DVDLowReset:
|
||||
{
|
||||
const bool spinup = Memory::Read_U32(request.address + 4);
|
||||
const bool spinup = Memory::Read_U32(request.buffer_in + 4);
|
||||
INFO_LOG(IOS_DI, "DVDLowReset %s spinup", spinup ? "with" : "without");
|
||||
DVDInterface::Reset(spinup);
|
||||
DVDInterface::ResetDrive(spinup);
|
||||
ResetDIRegisters();
|
||||
return DIResult::Success;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ static void ReinitHardware()
|
||||
// HACK However, resetting DI will reset the DTK config, which is set by the system menu
|
||||
// (and not by MIOS), causing games that use DTK to break. Perhaps MIOS doesn't actually
|
||||
// reset DI fully, in such a way that the DTK config isn't cleared?
|
||||
// DVDInterface::Reset();
|
||||
// DVDInterface::ResetDrive(true);
|
||||
PowerPC::Reset();
|
||||
Wiimote::ResetAllWiimotes();
|
||||
// Note: this is specific to Dolphin and is required because we initialised it in Wii mode.
|
||||
|
||||
@@ -74,7 +74,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
|
||||
constexpr u32 STATE_VERSION = 121; // Last changed in PR 8988
|
||||
constexpr u32 STATE_VERSION = 122; // Last changed in PR 8571
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
||||
Reference in New Issue
Block a user