From 8bd522d283de8f1e23193222c1c9885ddb7bcbdf Mon Sep 17 00:00:00 2001 From: AKuHAK <621640+AKuHAK@users.noreply.github.com> Date: Mon, 20 Feb 2023 11:28:59 +0200 Subject: [PATCH] BiosTools: Implement SysGetBiosDiscID function, for Bios Serial used EXTINFO build unique timestamp --- pcsx2/System.cpp | 27 +++++---- pcsx2/ps2/BiosTools.cpp | 124 ++++++++++++++++++++++------------------ pcsx2/ps2/BiosTools.h | 1 + 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 534c08d1ed..12ec00310f 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -27,6 +27,7 @@ #include "common/Perf.h" #include "common/StringUtil.h" #include "CDVD/CDVD.h" +#include "ps2/BiosTools.h" #include "GS/Renderers/Common/GSFunctionMap.h" #include "common/emitter/x86_intrin.h" @@ -123,8 +124,10 @@ void SysLogMachineCaps() std::string features; - if (x86caps.hasAVX) features += "AVX "; - if (x86caps.hasAVX2) features += "AVX2 "; + if (x86caps.hasAVX) + features += "AVX "; + if (x86caps.hasAVX2) + features += "AVX2 "; StringUtil::StripWhitespace(&features); @@ -340,18 +343,18 @@ void SysClearExecutionCache() } } +// This function returns part of EXTINFO data of the BIOS rom +// This module contains information about Sony build environment at offst 0x10 +// first 15 symbols is build date/time that is unique per rom and can be used as unique serial +// Example for romver 0160EC20010704 +// 20010704-160707,ROMconf,PS20160EC20010704.bin,kuma@rom-server/~/f10k/g/app/rom +// 20010704-160707 can be used as unique ID for Bios std::string SysGetBiosDiscID() { - // FIXME: we should return a serial based on - // the BIOS being run (either a checksum of the BIOS roms, and/or a string based on BIOS - // region and revision). - // Good candidate can be first part of EXTINFO data in the BIOS rom: - // Example for romver 0160EC20010704 - // 20010704-160707,ROMconf,PS20160EC20010704.bin,kuma@rom-server/~/f10k/g/app/rom - // 20010704-160707 can be used as unique ID for Bios - // rom0:EXTINFO first 15 bytes - - return {}; + if (!BiosSerial.empty()) + return BiosSerial; + else + return {}; } // This function always returns a valid DiscID -- using the Sony serial when possible, and diff --git a/pcsx2/ps2/BiosTools.cpp b/pcsx2/ps2/BiosTools.cpp index 49374d3e4e..d3766ba507 100644 --- a/pcsx2/ps2/BiosTools.cpp +++ b/pcsx2/ps2/BiosTools.cpp @@ -54,10 +54,11 @@ bool NoOSD; bool AllowParams1; bool AllowParams2; std::string BiosDescription; +std::string BiosSerial; std::string BiosPath; BiosDebugInformation CurrentBiosInformation; -static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& description, u32& region, std::string& zone) +static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& description, u32& region, std::string& zone, std::string& serial) { romdir rd; for (u32 i = 0; i < 512 * 1024; i++) @@ -72,13 +73,25 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio s64 fileOffset = 0; s64 fileSize = FileSystem::FSize64(fp); bool foundRomVer = false; + char romver[14 + 1] = {}; // ascii version loaded from disk. + char extinfo[15 + 1] = {}; // ascii version loaded from disk. // ensure it's a null-terminated and not zero-length string while (rd.fileName[0] != '\0' && strnlen(rd.fileName, sizeof(rd.fileName)) != sizeof(rd.fileName)) { + if (std::strncmp(rd.fileName, "EXTINFO", sizeof(rd.fileName)) == 0) + { + s64 pos = FileSystem::FTell64(fp); + if (FileSystem::FSeek64(fp, fileOffset + 0x10, SEEK_SET) != 0 || + std::fread(extinfo, 15, 1, fp) != 1 || FileSystem::FSeek64(fp, pos, SEEK_SET) != 0) + { + break; + } + serial = extinfo; + } + if (std::strncmp(rd.fileName, "ROMVER", sizeof(rd.fileName)) == 0) { - char romver[14 + 1] = {}; // ascii version loaded from disk. s64 pos = FileSystem::FTell64(fp); if (FileSystem::FSeek64(fp, fileOffset, SEEK_SET) != 0 || @@ -87,56 +100,7 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio break; } - // TODO: some regions can be detected only from rom1 - /* - switch (rom1:DVDID[4]) - { - // clang-format off - case 'O': zone = "Oceania";region = 3; break; - case 'R': zone = "Russia"; region = 5; break; - case 'M': zone = "Mexico"; region = 7; break; - // clang-format on - } - */ - - switch (romver[4]) - { - // clang-format off - case 'J': zone = "Japan"; region = 0; break; - case 'A': zone = "USA"; region = 1; break; - case 'E': zone = "Europe"; region = 2; break; - // case 'E': zone = "Oceania";region = 3; break; // Not implemented - case 'H': zone = "Asia"; region = 4; break; - // case 'E': zone = "Russia"; region = 3; break; // Not implemented - case 'C': zone = "China"; region = 6; break; - // case 'A': zone = "Mexico"; region = 7; break; // Not implemented - case 'T': zone = "T10K"; region = 8; break; - case 'X': zone = "Test"; region = 9; break; - case 'P': zone = "Free"; region = 10; break; - // clang-format on - default: - zone.clear(); - zone += romver[4]; - region = 0; - break; - } - - char vermaj[3] = {romver[0], romver[1], 0}; - char vermin[3] = {romver[2], romver[3], 0}; - - description = StringUtil::StdStringFromFormat("%-7s v%s.%s(%c%c/%c%c/%c%c%c%c) %s", - zone.c_str(), - vermaj, vermin, - romver[12], romver[13], // day - romver[10], romver[11], // month - romver[6], romver[7], romver[8], romver[9], // year! - (romver[5] == 'C') ? "Console" : (romver[5] == 'D') ? "Devel" : ""); - - version = strtol(vermaj, (char**)NULL, 0) << 8; - version |= strtol(vermin, (char**)NULL, 0); foundRomVer = true; - - Console.WriteLn("BIOS Found: %s", description.c_str()); } if ((rd.fileSize % 0x10) == 0) @@ -150,7 +114,57 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio fileOffset -= ((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize; - if (!foundRomVer) + if (foundRomVer) + { + switch (romver[4]) + { + // clang-format off + case 'J': zone = "Japan"; region = 0; break; + case 'A': zone = "USA"; region = 1; break; + case 'E': zone = "Europe"; region = 2; break; + // case 'E': zone = "Oceania";region = 3; break; // Not implemented + case 'H': zone = "Asia"; region = 4; break; + // case 'E': zone = "Russia"; region = 3; break; // Not implemented + case 'C': zone = "China"; region = 6; break; + // case 'A': zone = "Mexico"; region = 7; break; // Not implemented + case 'T': zone = "T10K"; region = 8; break; + case 'X': zone = "Test"; region = 9; break; + case 'P': zone = "Free"; region = 10; break; + // clang-format on + default: + zone.clear(); + zone += romver[4]; + region = 0; + break; + } + // TODO: some regions can be detected only from rom1 + /* switch (rom1:DVDID[4]) + { + // clang-format off + case 'O': zone = "Oceania";region = 3; break; + case 'R': zone = "Russia"; region = 5; break; + case 'M': zone = "Mexico"; region = 7; break; + // clang-format on + } */ + + char vermaj[3] = {romver[0], romver[1], 0}; + char vermin[3] = {romver[2], romver[3], 0}; + description = StringUtil::StdStringFromFormat("%-7s v%s.%s(%c%c/%c%c/%c%c%c%c) %s %s", + zone.c_str(), + vermaj, vermin, + romver[12], romver[13], // day + romver[10], romver[11], // month + romver[6], romver[7], romver[8], romver[9], // year! + (romver[5] == 'C') ? "Console" : (romver[5] == 'D') ? "Devel" : + "", + serial.c_str()); + + version = strtol(vermaj, (char**)NULL, 0) << 8; + version |= strtol(vermin, (char**)NULL, 0); + + Console.WriteLn("Bios Found: %s", description.c_str()); + } + else return false; if (fileSize < (int)fileOffset) @@ -284,7 +298,7 @@ bool LoadBIOS() return false; std::string zone; - LoadBiosVersion(fp.get(), BiosVersion, BiosDescription, BiosRegion, zone); + LoadBiosVersion(fp.get(), BiosVersion, BiosDescription, BiosRegion, zone, BiosSerial); if (FileSystem::FSeek64(fp.get(), 0, SEEK_SET) || std::fread(eeMem->ROM, static_cast(std::min(Ps2MemSize::Rom, filesize)), 1, fp.get()) != 1) @@ -317,14 +331,14 @@ bool LoadBIOS() bool IsBIOS(const char* filename, u32& version, std::string& description, u32& region, std::string& zone) { - const std::string bios_path(Path::Combine(EmuFolders::Bios, filename)); + std::string serial; const auto fp = FileSystem::OpenManagedCFile(filename, "rb"); if (!fp) return false; // FPS2BIOS is smaller and of variable size //if (inway.Length() < 512*1024) return false; - return LoadBiosVersion(fp.get(), version, description, region, zone); + return LoadBiosVersion(fp.get(), version, description, region, zone, serial); } bool IsBIOSAvailable(const std::string& full_path) diff --git a/pcsx2/ps2/BiosTools.h b/pcsx2/ps2/BiosTools.h index 9f83565873..82d8f81c83 100644 --- a/pcsx2/ps2/BiosTools.h +++ b/pcsx2/ps2/BiosTools.h @@ -38,6 +38,7 @@ extern bool AllowParams1; extern bool AllowParams2; extern u32 BiosChecksum; extern std::string BiosDescription; +extern std::string BiosSerial; extern std::string BiosPath; extern bool LoadBIOS(); extern bool IsBIOS(const char* filename, u32& version, std::string& description, u32& region, std::string& zone);