1 // Copyright 2008 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <memory> 8 #include <optional> 9 #include <string> 10 #include <vector> 11 12 #include "Common/CommonTypes.h" 13 14 class PointerWrap; 15 namespace DiscIO 16 { 17 class VolumeDisc; 18 struct Partition; 19 } // namespace DiscIO 20 namespace MMIO 21 { 22 class Mapping; 23 } 24 25 namespace DVDInterface 26 { 27 enum class DICommand : u8 28 { 29 Inquiry = 0x12, 30 ReportKey = 0xa4, 31 Read = 0xa8, 32 Seek = 0xab, 33 ReadDVDMetadata = 0xad, 34 ReadDVD = 0xd0, 35 ReadDVDConfig = 0xd1, 36 StopLaser = 0xd2, 37 Offset = 0xd9, 38 ReadBCA = 0xda, 39 RequestDiscStatus = 0xdb, 40 RequestRetryNumber = 0xdc, 41 SetMaximumRotation = 0xdd, 42 SerMeasControl = 0xdf, 43 RequestError = 0xe0, 44 AudioStream = 0xe1, 45 RequestAudioStatus = 0xe2, 46 StopMotor = 0xe3, 47 AudioBufferConfig = 0xe4, 48 Debug = 0xfe, 49 DebugUnlock = 0xff, 50 Unknown55 = 0x55, 51 UnknownEE = 0xee, 52 }; 53 54 // Disc drive state. 55 // Reported in error codes as 0 for Ready, and value-1 for the rest 56 // (i.e. Ready and ReadyNoReadsMade are both reported as 0) 57 enum class DriveState : u8 58 { 59 Ready = 0, 60 ReadyNoReadsMade = 1, 61 CoverOpened = 2, 62 DiscChangeDetected = 3, 63 NoMediumPresent = 4, 64 MotorStopped = 5, 65 DiscIdNotRead = 6 66 }; 67 68 // Actual drive error codes, which fill the remaining 3 bytes 69 // Numbers more or less match a SCSI sense key (1 nybble) followed by SCSI ASC/ASCQ (2 bytes). 70 enum class DriveError : u32 71 { 72 None = 0x00000, // No error. 73 MotorStopped = 0x20400, // Motor stopped. 74 NoDiscID = 0x20401, // Disk ID not read. 75 MediumNotPresent = 0x23a00, // Medium not present / Cover opened. 76 SeekNotDone = 0x30200, // No seek complete. 77 ReadError = 0x31100, // Unrecovered read error. 78 ProtocolError = 0x40800, // Transfer protocol error. 79 InvalidCommand = 0x52000, // Invalid command operation code. 80 NoAudioBuf = 0x52001, // Audio Buffer not set. 81 BlockOOB = 0x52100, // Logical block address out of bounds. 82 InvalidField = 0x52400, // Invalid field in command packet. 83 InvalidAudioCommand = 0x52401, // Invalid audio command. 84 InvalidPeriod = 0x52402, // Configuration out of permitted period. 85 EndOfUserArea = 0x56300, // End of user area encountered on this track. 86 MediumChanged = 0x62800, // Medium may have changed. 87 MediumRemovalRequest = 0xb5a01, // Operator medium removal request. 88 }; 89 90 enum class DIInterruptType : int 91 { 92 DEINT = 0, 93 TCINT = 1, 94 BRKINT = 2, 95 CVRINT = 3, 96 }; 97 98 enum class ReplyType : u32 99 { 100 NoReply, 101 Interrupt, 102 IOS, 103 DTK, 104 }; 105 106 enum class EjectCause 107 { 108 User, 109 Software, 110 }; 111 112 void Init(); 113 void ResetDrive(bool spinup); 114 void Shutdown(); 115 void DoState(PointerWrap& p); 116 117 void RegisterMMIO(MMIO::Mapping* mmio, u32 base); 118 119 void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc, 120 std::optional<std::vector<std::string>> auto_disc_change_paths); 121 bool IsDiscInside(); 122 void EjectDisc(EjectCause cause); // Must only be called on the CPU thread 123 void ChangeDisc(const std::vector<std::string>& paths); // Must only be called on the CPU thread 124 void ChangeDisc(const std::string& new_path); // Must only be called on the CPU thread 125 bool AutoChangeDisc(); // Must only be called on the CPU thread 126 127 // This function returns true and calls SConfig::SetRunningGameMetadata(Volume&, Partition&) 128 // if both of the following conditions are true: 129 // - A disc is inserted 130 // - The title_id argument doesn't contain a value, or its value matches the disc's title ID 131 bool UpdateRunningGameMetadata(std::optional<u64> title_id = {}); 132 133 // Direct access to DI for IOS HLE (simpler to implement than how real IOS accesses DI, 134 // and lets us skip encrypting/decrypting in some cases) 135 void ExecuteCommand(ReplyType reply_type); 136 void PerformDecryptingRead(u32 position, u32 length, u32 output_address, 137 const DiscIO::Partition& partition, ReplyType reply_type); 138 // Exposed for use by emulated BS2; does not perform any checks on drive state 139 void AudioBufferConfig(bool enable_dtk, u8 dtk_buffer_length); 140 141 void SetDriveState(DriveState state); 142 void SetDriveError(DriveError error); 143 144 // Used by DVDThread 145 void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late, 146 const std::vector<u8>& data = std::vector<u8>()); 147 148 // Used by IOS HLE 149 void SetInterruptEnabled(DIInterruptType interrupt, bool enabled); 150 void ClearInterrupt(DIInterruptType interrupt); 151 152 } // end of namespace DVDInterface 153