BIOS: Automatically detect images, improve selection UI

This commit is contained in:
Connor McLaughlin
2020-09-22 23:08:07 +10:00
parent 3385346b7f
commit 7d01bedf07
23 changed files with 512 additions and 179 deletions

View File

@ -4,6 +4,7 @@
#include "common/log.h"
#include "common/md5_digest.h"
#include "cpu_disasm.h"
#include <array>
#include <cerrno>
Log_SetChannel(BIOS);
@ -36,16 +37,28 @@ std::string Hash::ToString() const
return str;
}
static constexpr Hash SCPH_1000_HASH = MakeHashFromString("239665b1a3dade1b5a52c06338011044");
static constexpr Hash SCPH_1001_HASH = MakeHashFromString("924e392ed05558ffdb115408c263dccf");
static constexpr Hash SCPH_1002_HASH = MakeHashFromString("54847e693405ffeb0359c6287434cbef");
static constexpr Hash SCPH_3000_HASH = MakeHashFromString("849515939161e62f6b866f6853006780");
static constexpr Hash SCPH_5500_HASH = MakeHashFromString("8dd7d5296a650fac7319bce665a6a53c");
static constexpr Hash SCPH_5501_HASH = MakeHashFromString("490f666e1afb15b7362b406ed1cea246");
static constexpr Hash SCPH_5502_HASH = MakeHashFromString("32736f17079d0b2b7024407c39bd3050");
static constexpr Hash SCPH_7001_HASH = MakeHashFromString("1e68c231d0896b7eadcad1d7d8e76129");
static constexpr Hash SCPH_7002_HASH = MakeHashFromString("b9d9a0286c33dc6b7237bb13cd46fdee");
static constexpr Hash SCPH_POPS660_HASH = MakeHashFromString("c53ca5908936d412331790f4426c6c33");
static constexpr std::array<ImageInfo, 12> s_image_infos = {{
{"SCPH-1000, DTL-H1000 (v1.0 J)", ConsoleRegion::NTSC_J, MakeHashFromString("239665b1a3dade1b5a52c06338011044")},
{"SCPH-1001, 5003, DTL-H1201, H3001 (v2.2 12-04-95 A)", ConsoleRegion::NTSC_U,
MakeHashFromString("924e392ed05558ffdb115408c263dccf")},
{"SCPH-1002, DTL-H1002 (v2.0 05-10-95 E)", ConsoleRegion::PAL,
MakeHashFromString("54847e693405ffeb0359c6287434cbef")},
{"SCPH-3000, DTL-H1000H (v1.1 01-22-95)", ConsoleRegion::NTSC_J,
MakeHashFromString("849515939161e62f6b866f6853006780")},
{"SCPH-5000, DTL-H1200, H3000 (v2.2 12-04-95 J)", ConsoleRegion::NTSC_J,
MakeHashFromString("8dd7d5296a650fac7319bce665a6a53c")},
{"SCPH-5501, 5503, 7003 (v3.0 11-18-96 A)", ConsoleRegion::NTSC_U,
MakeHashFromString("490f666e1afb15b7362b406ed1cea246")},
{"SCPH-5502, 5552 (v3.0 01-06-97 E)", ConsoleRegion::PAL, MakeHashFromString("32736f17079d0b2b7024407c39bd3050")},
{"SCPH-7000, 7500, 9000 (v4.0 08-18-97 J)", ConsoleRegion::NTSC_J,
MakeHashFromString("8e4c14f567745eff2f0408c8129f72a6")},
{"SCPH-7000W (v4.1 11-14-97 A)", ConsoleRegion::NTSC_J, MakeHashFromString("b84be139db3ee6cbd075630aa20a6553")},
{"SCPH-7001, 7501, 7503, 9001, 9003, 9903 (v4.1 12-16-97 A)", ConsoleRegion::NTSC_U,
MakeHashFromString("1e68c231d0896b7eadcad1d7d8e76129")},
{"SCPH-7002, 7502, 9002 (v4.1 12-16-97 E)", ConsoleRegion::PAL,
MakeHashFromString("b9d9a0286c33dc6b7237bb13cd46fdee")},
{"POPS-660 (PSP)", ConsoleRegion::Auto, MakeHashFromString("c53ca5908936d412331790f4426c6c33")},
}};
Hash GetHash(const Image& image)
{
@ -56,14 +69,13 @@ Hash GetHash(const Image& image)
return hash;
}
std::optional<Image> LoadImageFromFile(std::string_view filename)
std::optional<Image> LoadImageFromFile(const char* filename)
{
Image ret(BIOS_SIZE);
std::string filename_str(filename);
auto fp = FileSystem::OpenManagedCFile(filename_str.c_str(), "rb");
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
if (!fp)
{
Log_ErrorPrintf("Failed to open BIOS image '%s', errno=%d", filename_str.c_str(), errno);
Log_ErrorPrintf("Failed to open BIOS image '%s', errno=%d", filename, errno);
return std::nullopt;
}
@ -73,21 +85,20 @@ std::optional<Image> LoadImageFromFile(std::string_view filename)
if (size != BIOS_SIZE)
{
Log_ErrorPrintf("BIOS image '%s' mismatch, expecting %u bytes, got %u bytes", filename_str.c_str(), BIOS_SIZE,
size);
Log_ErrorPrintf("BIOS image '%s' mismatch, expecting %u bytes, got %u bytes", filename, BIOS_SIZE, size);
return std::nullopt;
}
if (std::fread(ret.data(), 1, ret.size(), fp.get()) != ret.size())
{
Log_ErrorPrintf("Failed to read BIOS image '%s'", filename_str.c_str());
Log_ErrorPrintf("Failed to read BIOS image '%s'", filename);
return std::nullopt;
}
return ret;
}
std::optional<Hash> GetHashForFile(const std::string_view filename)
std::optional<Hash> GetHashForFile(const char* filename)
{
auto image = LoadImageFromFile(filename);
if (!image)
@ -96,23 +107,24 @@ std::optional<Hash> GetHashForFile(const std::string_view filename)
return GetHash(*image);
}
const ImageInfo* GetImageInfoForHash(const Hash& hash)
{
for (const ImageInfo& ii : s_image_infos)
{
if (ii.hash == hash)
return &ii;
}
return nullptr;
}
bool IsValidHashForRegion(ConsoleRegion region, const Hash& hash)
{
switch (region)
{
case ConsoleRegion::NTSC_J:
return (hash == SCPH_1000_HASH || hash == SCPH_3000_HASH || hash == SCPH_5500_HASH || hash == SCPH_POPS660_HASH);
const ImageInfo* ii = GetImageInfoForHash(hash);
if (!ii)
return false;
case ConsoleRegion::NTSC_U:
return (hash == SCPH_1001_HASH || hash == SCPH_5501_HASH || hash == SCPH_7001_HASH || hash == SCPH_POPS660_HASH);
case ConsoleRegion::PAL:
return (hash == SCPH_1002_HASH || hash == SCPH_5502_HASH || hash == SCPH_7002_HASH || hash == SCPH_POPS660_HASH);
case ConsoleRegion::Auto:
default:
return false;
}
return (ii->region == ConsoleRegion::Auto || ii->region == region);
}
void PatchBIOS(Image& bios, u32 address, u32 value, u32 mask /*= UINT32_C(0xFFFFFFFF)*/)
@ -135,9 +147,8 @@ void PatchBIOS(Image& bios, u32 address, u32 value, u32 mask /*= UINT32_C(0xFFFF
bool PatchBIOSEnableTTY(Image& image, const Hash& hash)
{
if (hash != SCPH_1000_HASH && hash != SCPH_1001_HASH && hash != SCPH_1002_HASH && hash != SCPH_3000_HASH &&
hash != SCPH_5500_HASH && hash != SCPH_5501_HASH && hash != SCPH_5502_HASH && hash != SCPH_7001_HASH &&
hash != SCPH_7002_HASH && hash != SCPH_POPS660_HASH)
const ImageInfo* ii = GetImageInfoForHash(hash);
if (!ii)
{
Log_WarningPrintf("Incompatible version for TTY patch: %s", hash.ToString().c_str());
return false;
@ -151,9 +162,8 @@ bool PatchBIOSEnableTTY(Image& image, const Hash& hash)
bool PatchBIOSFastBoot(Image& image, const Hash& hash)
{
if (hash != SCPH_1000_HASH && hash != SCPH_1001_HASH && hash != SCPH_1002_HASH && hash != SCPH_3000_HASH &&
hash != SCPH_5500_HASH && hash != SCPH_5501_HASH && hash != SCPH_5502_HASH && hash != SCPH_7001_HASH &&
hash != SCPH_7002_HASH && hash != SCPH_POPS660_HASH)
const ImageInfo* ii = GetImageInfoForHash(hash);
if (!ii)
{
Log_WarningPrintf("Incompatible version for fast-boot patch: %s", hash.ToString().c_str());
return false;