System: Support changing BIOS path

This commit is contained in:
Connor McLaughlin 2019-11-11 18:19:57 +10:00
parent 7b6a2f1aaf
commit 6f4cf7d5e3
21 changed files with 93 additions and 77 deletions

View File

@ -1,6 +1,7 @@
#include "bus.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/MD5Digest.h"
#include "YBaseLib/String.h"
#include "cdrom.h"
#include "common/state_wrapper.h"
@ -31,12 +32,9 @@ Bus::Bus() = default;
Bus::~Bus() = default;
bool Bus::Initialize(CPU::Core* cpu, DMA* dma, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom,
void Bus::Initialize(CPU::Core* cpu, DMA* dma, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom,
Pad* pad, Timers* timers, SPU* spu, MDEC* mdec)
{
if (!LoadBIOS())
return false;
m_cpu = cpu;
m_dma = dma;
m_interrupt_controller = interrupt_controller;
@ -46,7 +44,6 @@ bool Bus::Initialize(CPU::Core* cpu, DMA* dma, InterruptController* interrupt_co
m_timers = timers;
m_spu = spu;
m_mdec = mdec;
return true;
}
void Bus::Reset()
@ -187,16 +184,26 @@ void Bus::PatchBIOS(u32 address, u32 value, u32 mask /*= UINT32_C(0xFFFFFFFF)*/)
old_disasm.GetCharArray(), new_value, new_disasm.GetCharArray());
}
void Bus::GetBIOSHash(u8 hash[16])
{
MD5Digest digest;
digest.Update(m_bios.data(), static_cast<u32>(m_bios.size()));
digest.Final(hash);
}
void Bus::SetExpansionROM(std::vector<u8> data)
{
m_exp1_rom = std::move(data);
}
bool Bus::LoadBIOS()
bool Bus::LoadBIOS(const char* filename)
{
std::FILE* fp = std::fopen("SCPH1001.BIN", "rb");
std::FILE* fp = std::fopen(filename, "rb");
if (!fp)
{
Log_ErrorPrintf("Failed to open BIOS image '%s'", filename);
return false;
}
std::fseek(fp, 0, SEEK_END);
const u32 size = static_cast<u32>(std::ftell(fp));
@ -217,13 +224,6 @@ bool Bus::LoadBIOS()
}
std::fclose(fp);
#if 1
// Patch to enable TTY.
PatchBIOS(BIOS_BASE + 0x6F0C, 0x24010001);
PatchBIOS(BIOS_BASE + 0x6F14, 0xAF81A9C0);
#endif
return true;
}

View File

@ -27,11 +27,15 @@ public:
Bus();
~Bus();
bool Initialize(CPU::Core* cpu, DMA* dma, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom, Pad* pad,
void Initialize(CPU::Core* cpu, DMA* dma, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom, Pad* pad,
Timers* timers, SPU* spu, MDEC* mdec);
void Reset();
bool DoState(StateWrapper& sw);
bool LoadBIOS(const char* filename);
void PatchBIOS(u32 address, u32 value, u32 mask = UINT32_C(0xFFFFFFFF));
void GetBIOSHash(u8 hash[16]);
bool ReadByte(PhysicalMemoryAddress address, u8* value);
bool ReadHalfWord(PhysicalMemoryAddress address, u16* value);
bool ReadWord(PhysicalMemoryAddress address, u32* value);
@ -46,7 +50,6 @@ public:
TickCount ReadWords(PhysicalMemoryAddress address, u32* words, u32 word_count);
TickCount WriteWords(PhysicalMemoryAddress address, const u32* words, u32 word_count);
void PatchBIOS(u32 address, u32 value, u32 mask = UINT32_C(0xFFFFFFFF));
void SetExpansionROM(std::vector<u8> data);
// changing interfaces
@ -154,8 +157,6 @@ private:
};
};
bool LoadBIOS();
static std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay);
void RecalculateMemoryTimings();

View File

@ -16,13 +16,12 @@ CDROM::CDROM()
CDROM::~CDROM() = default;
bool CDROM::Initialize(System* system, DMA* dma, InterruptController* interrupt_controller, SPU* spu)
void CDROM::Initialize(System* system, DMA* dma, InterruptController* interrupt_controller, SPU* spu)
{
m_system = system;
m_dma = dma;
m_interrupt_controller = interrupt_controller;
m_spu = spu;
return true;
}
void CDROM::Reset()

View File

@ -22,7 +22,7 @@ public:
CDROM();
~CDROM();
bool Initialize(System* system, DMA* dma, InterruptController* interrupt_controller, SPU* spu);
void Initialize(System* system, DMA* dma, InterruptController* interrupt_controller, SPU* spu);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -38,7 +38,7 @@ Core::Core() = default;
Core::~Core() = default;
bool Core::Initialize(Bus* bus)
void Core::Initialize(Bus* bus)
{
m_bus = bus;
@ -46,8 +46,6 @@ bool Core::Initialize(Bus* bus)
m_cop0_regs.PRID = UINT32_C(0x00000002);
m_cop2.Initialize();
return true;
}
void Core::Reset()

View File

@ -24,7 +24,7 @@ public:
Core();
~Core();
bool Initialize(Bus* bus);
void Initialize(Bus* bus);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -14,7 +14,7 @@ DMA::DMA() = default;
DMA::~DMA() = default;
bool DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom,
void DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom,
SPU* spu, MDEC* mdec)
{
m_system = system;
@ -25,7 +25,6 @@ bool DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_co
m_spu = spu;
m_mdec = mdec;
m_transfer_buffer.resize(32);
return true;
}
void DMA::Reset()

View File

@ -35,7 +35,7 @@ public:
DMA();
~DMA();
bool Initialize(System* system, Bus* bus, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom, SPU* spu,
void Initialize(System* system, Bus* bus, InterruptController* interrupt_controller, GPU* gpu, CDROM* cdrom, SPU* spu,
MDEC* mdec);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -8,10 +8,9 @@ InterruptController::InterruptController() = default;
InterruptController::~InterruptController() = default;
bool InterruptController::Initialize(CPU::Core* cpu)
void InterruptController::Initialize(CPU::Core* cpu)
{
m_cpu = cpu;
return true;
}
void InterruptController::Reset()

View File

@ -32,7 +32,7 @@ public:
InterruptController();
~InterruptController();
bool Initialize(CPU::Core* cpu);
void Initialize(CPU::Core* cpu);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -11,11 +11,10 @@ MDEC::MDEC() = default;
MDEC::~MDEC() = default;
bool MDEC::Initialize(System* system, DMA* dma)
void MDEC::Initialize(System* system, DMA* dma)
{
m_system = system;
m_dma = dma;
return true;
}
void MDEC::Reset()

View File

@ -15,7 +15,7 @@ public:
MDEC();
~MDEC();
bool Initialize(System* system, DMA* dma);
void Initialize(System* system, DMA* dma);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -12,11 +12,10 @@ Pad::Pad() = default;
Pad::~Pad() = default;
bool Pad::Initialize(System* system, InterruptController* interrupt_controller)
void Pad::Initialize(System* system, InterruptController* interrupt_controller)
{
m_system = system;
m_interrupt_controller = interrupt_controller;
return true;
}
void Pad::Reset()

View File

@ -18,7 +18,7 @@ public:
Pad();
~Pad();
bool Initialize(System* system, InterruptController* interrupt_controller);
void Initialize(System* system, InterruptController* interrupt_controller);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -19,13 +19,12 @@ SPU::SPU() = default;
SPU::~SPU() = default;
bool SPU::Initialize(System* system, DMA* dma, InterruptController* interrupt_controller)
void SPU::Initialize(System* system, DMA* dma, InterruptController* interrupt_controller)
{
m_audio_stream = system->GetHostInterface()->GetAudioStream();
m_system = system;
m_dma = dma;
m_interrupt_controller = interrupt_controller;
return true;
}
void SPU::Reset()

View File

@ -17,7 +17,7 @@ public:
SPU();
~SPU();
bool Initialize(System* system, DMA* dma, InterruptController* interrupt_controller);
void Initialize(System* system, DMA* dma, InterruptController* interrupt_controller);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -19,8 +19,16 @@
#include <imgui.h>
Log_SetChannel(System);
System::System(HostInterface* host_interface)
: m_host_interface(host_interface)
namespace BIOSHashes {
static constexpr char SCPH_1000[] = "239665b1a3dade1b5a52c06338011044";
static constexpr char SCPH_1001[] = "924e392ed05558ffdb115408c263dccf";
static constexpr char SCPH_1002[] = "54847e693405ffeb0359c6287434cbef";
static constexpr char SCPH_5500[] = "8dd7d5296a650fac7319bce665a6a53c";
static constexpr char SCPH_5501[] = "490f666e1afb15b7362b406ed1cea246";
static constexpr char SCPH_5502[] = "32736f17079d0b2b7024407c39bd3050";
} // namespace BIOSHashes
System::System(HostInterface* host_interface) : m_host_interface(host_interface)
{
m_cpu = std::make_unique<CPU::Core>();
m_bus = std::make_unique<Bus>();
@ -64,44 +72,28 @@ bool System::RecreateGPU()
bool System::Initialize()
{
if (!m_cpu->Initialize(m_bus.get()))
return false;
m_cpu->Initialize(m_bus.get());
m_bus->Initialize(m_cpu.get(), m_dma.get(), m_interrupt_controller.get(), m_gpu.get(), m_cdrom.get(), m_pad.get(),
m_timers.get(), m_spu.get(), m_mdec.get());
if (!m_bus->Initialize(m_cpu.get(), m_dma.get(), m_interrupt_controller.get(), m_gpu.get(), m_cdrom.get(),
m_pad.get(), m_timers.get(), m_spu.get(), m_mdec.get()))
{
return false;
}
m_dma->Initialize(this, m_bus.get(), m_interrupt_controller.get(), m_gpu.get(), m_cdrom.get(), m_spu.get(),
m_mdec.get());
if (!m_dma->Initialize(this, m_bus.get(), m_interrupt_controller.get(), m_gpu.get(), m_cdrom.get(), m_spu.get(),
m_mdec.get()))
{
return false;
}
m_interrupt_controller->Initialize(m_cpu.get());
if (!m_interrupt_controller->Initialize(m_cpu.get()))
return false;
m_cdrom->Initialize(this, m_dma.get(), m_interrupt_controller.get(), m_spu.get());
m_pad->Initialize(this, m_interrupt_controller.get());
m_timers->Initialize(this, m_interrupt_controller.get());
m_spu->Initialize(this, m_dma.get(), m_interrupt_controller.get());
m_mdec->Initialize(this, m_dma.get());
if (!CreateGPU())
return false;
if (!m_cdrom->Initialize(this, m_dma.get(), m_interrupt_controller.get(), m_spu.get()))
return false;
if (!m_pad->Initialize(this, m_interrupt_controller.get()))
return false;
if (!m_timers->Initialize(this, m_interrupt_controller.get()))
return false;
if (!m_spu->Initialize(this, m_dma.get(), m_interrupt_controller.get()))
return false;
if (!m_mdec->Initialize(this, m_dma.get()))
if (!LoadBIOS())
return false;
UpdateMemoryCards();
return true;
}
@ -144,6 +136,38 @@ bool System::CreateGPU()
return true;
}
bool System::LoadBIOS()
{
if (!m_bus->LoadBIOS(GetSettings().bios_path.c_str()))
return false;
// apply patches
u8 bios_hash[16];
m_bus->GetBIOSHash(bios_hash);
SmallString bios_hash_string;
bios_hash_string.Format("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", bios_hash[0],
bios_hash[1], bios_hash[2], bios_hash[3], bios_hash[4], bios_hash[5], bios_hash[6],
bios_hash[7], bios_hash[8], bios_hash[9], bios_hash[10], bios_hash[11], bios_hash[12],
bios_hash[13], bios_hash[14], bios_hash[15]);
Log_InfoPrintf("BIOS hash: %s", bios_hash_string.GetCharArray());
if (bios_hash_string == BIOSHashes::SCPH_1000 || bios_hash_string == BIOSHashes::SCPH_1001 ||
bios_hash_string == BIOSHashes::SCPH_1002 || bios_hash_string == BIOSHashes::SCPH_5500 ||
bios_hash_string == BIOSHashes::SCPH_5501 || bios_hash_string == BIOSHashes::SCPH_5502)
{
// Patch to enable TTY.
Log_InfoPrintf("Patching BIOS to enable TTY/printf");
m_bus->PatchBIOS(0x1FC06F0C, 0x24010001);
m_bus->PatchBIOS(0x1FC06F14, 0xAF81A9C0);
}
else
{
Log_WarningPrintf("Unknown BIOS version, not patching TTY/printf");
}
return true;
}
bool System::DoState(StateWrapper& sw)
{
if (!sw.DoMarker("System"))

View File

@ -78,6 +78,7 @@ public:
private:
bool DoState(StateWrapper& sw);
bool CreateGPU();
bool LoadBIOS();
HostInterface* m_host_interface;
std::unique_ptr<CPU::Core> m_cpu;

View File

@ -10,11 +10,10 @@ Timers::Timers() = default;
Timers::~Timers() = default;
bool Timers::Initialize(System* system, InterruptController* interrupt_controller)
void Timers::Initialize(System* system, InterruptController* interrupt_controller)
{
m_system = system;
m_interrupt_controller = interrupt_controller;
return true;
}
void Timers::Reset()

View File

@ -14,7 +14,7 @@ public:
Timers();
~Timers();
bool Initialize(System* system, InterruptController* interrupt_controller);
void Initialize(System* system, InterruptController* interrupt_controller);
void Reset();
bool DoState(StateWrapper& sw);

View File

@ -903,7 +903,7 @@ void SDLHostInterface::DrawSettingsWindow()
ImGui::Text("BIOS Path:");
ImGui::SameLine(indent);
DrawFileChooser("##bios_path", &m_settings.bios_path);
settings_changed |= DrawFileChooser("##bios_path", &m_settings.bios_path);
ImGui::Checkbox("Enable Speed Limiter", &m_settings.speed_limiter_enabled);
@ -1029,9 +1029,8 @@ void SDLHostInterface::DrawSettingsWindow()
ImGui::End();
if (settings_changed)
{
// TODO: Save to file
}
SaveSettings();
if (gpu_settings_changed && m_system)
m_system->GetGPU()->UpdateSettings();
}