Skip to content

Commit

Permalink
DEV9: Add support for external HDD ID.
Browse files Browse the repository at this point in the history
This commit introduces the capability to read the content of a *.hddid file located in the same directory as the HDD image (same name, different extension). The retrieved content is then used to fill the SCE_IDENTIFY_DRIVE response.
  • Loading branch information
AKuHAK authored and stenzek committed Dec 28, 2023
1 parent 0a7fc06 commit 8172b2e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 30 deletions.
42 changes: 41 additions & 1 deletion pcsx2/DEV9/ATA/ATA_State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ int ATA::Open(const std::string& hddPath)
{
readBufferLen = 256 * 512;
readBuffer = new u8[readBufferLen];
memset(sceSec, 0, sizeof(sceSec));

//Open File
if (!FileSystem::FileExists(hddPath.c_str()))
Expand All @@ -52,6 +53,45 @@ int ATA::Open(const std::string& hddPath)
return -1;
}

// Open and read the content of the hddid file
std::string hddidPath = Path::ReplaceExtension(hddPath, "hddid");
std::optional<std::vector<u8>> fileContent = FileSystem::ReadBinaryFile(hddidPath.c_str());

if (fileContent.has_value() && fileContent.value().size() <= sizeof(sceSec))
{
// Copy the content to sceSec
std::copy(fileContent.value().begin(), fileContent.value().end(), sceSec);
}
else
{
// fill sceSec with default data if hdd id file is not present
memcpy(sceSec, "Sony Computer Entertainment Inc.", 32); // Always this magic header.
memcpy(sceSec + 0x20, "SCPH-20401", 10); // sometimes this matches HDD model, the rest 6 bytes filles with zeroes, or sometimes with spaces
memcpy(sceSec + 0x30, " 40", 4); // or " 120" for PSX DESR, reference for ps2 area size. The rest bytes filled with zeroes

sceSec[0x40] = 0; // 0x40 - 0x43 - 4-byte HDD internal SCE serial, does not match real HDD serial, currently hardcoded to 0x1000000
sceSec[0x41] = 0;
sceSec[0x42] = 0;
sceSec[0x43] = 0x01;

// purpose of next 12 bytes is unknown
sceSec[0x44] = 0; // always zero
sceSec[0x45] = 0; // always zero
sceSec[0x46] = 0x1a;
sceSec[0x47] = 0x01;
sceSec[0x48] = 0x02;
sceSec[0x49] = 0x20;
sceSec[0x4a] = 0; // always zero
sceSec[0x4b] = 0; // always zero
// next 4 bytes always these values
sceSec[0x4c] = 0x01;
sceSec[0x4d] = 0x03;
sceSec[0x4e] = 0x11;
sceSec[0x4f] = 0x01;
// 0x50 - 0x80 is a random unique block of data
// 0x80 and up - zero filled
}

//Store HddImage size for later use
hddImageSize = static_cast<u64>(size);
CreateHDDinfo(hddImageSize / 512);
Expand Down Expand Up @@ -130,7 +170,7 @@ void ATA::InitSparseSupport(const std::string& hddPath)

/* https://askbob.tech/the-ntfs-blog-sparse-and-compressed-file/
* NTFS Sparse Block Size are the same size as a compression unit
* Cluster Size Compression Unit
* Cluster Size Compression Unit
* --------------------------------
* 512bytes 8kb (0x02000)
* 1kb 16kb (0x04000)
Expand Down
29 changes: 0 additions & 29 deletions pcsx2/DEV9/ATA/Commands/ATA_SCE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,6 @@ void ATA::SCE_IDENTIFY_DRIVE()
{
PreCmd();

// fill sceSec response with default data
memcpy(sceSec, "Sony Computer Entertainment Inc.", 32); // Always this magic header.
memcpy(sceSec + 0x20, "SCPH-20401", 10); // sometimes this matches HDD model, the rest 6 bytes filles with zeroes, or sometimes with spaces
memcpy(sceSec + 0x30, " 40", 4); // or " 120" for PSX DESR, reference for ps2 area size. The rest bytes filled with zeroes

sceSec[0x40] = 0; // 0x40 - 0x43 - 4-byte HDD internal SCE serial, does not match real HDD serial, currently hardcoded to 0x1000000
sceSec[0x41] = 0;
sceSec[0x42] = 0;
sceSec[0x43] = 0x01;

// purpose of next 12 bytes is unknown
sceSec[0x44] = 0; // always zero
sceSec[0x45] = 0; // always zero
sceSec[0x46] = 0x1a;
sceSec[0x47] = 0x01;
sceSec[0x48] = 0x02;
sceSec[0x49] = 0x20;
sceSec[0x4a] = 0; // always zero
sceSec[0x4b] = 0; // always zero
// next 4 bytes always these values
sceSec[0x4c] = 0x01;
sceSec[0x4d] = 0x03;
sceSec[0x4e] = 0x11;
sceSec[0x4f] = 0x01;
// 0x50 - 0x80 is a random unique block of data
// 0x80 and up - zero filled

// TODO: if exists *.hddid file (size - 128-512 bytes) along with HDD image, replace generic sceSec with its content

pioDRQEndTransferFunc = nullptr;
DRQCmdPIODataToHost(sceSec, 256 * 2, 0, 256 * 2, true);
}

0 comments on commit 8172b2e

Please sign in to comment.