From b2ddffeeb104d1323daa4539846cee07eb714e9c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 12 Jun 2022 22:27:42 -0700 Subject: [PATCH 1/2] BS2Emu: Set HID0/1/2/4 and MSR with correct default values These values were obtained by setting a breakpoint at a game's entry point, and then observing the register values with Dolphin's register widget. There are other registers that aren't handled by this PR, including CR, XER, SRR0, SRR1, and "Int Mask" (as well as most of the GPRs). They could be added in a later PR if it turns out that their values matter, but probably most of them don't. This fixes Datel titles booting with the IPL skipped (see https://bugs.dolphin-emu.org/issues/8223), though when booted this way they are currently missing textures. Due to somewhat janky code, Datel overwrites the syscall interrupt handler and then immediately triggers it (with the `sc` instruction) before they restore the correct one. This works on real hardware due to icache, and also works in Dolphin when the IPL runs due to icache, but prior to this change `HID0.ICE` defaulted to 0 so icache was not enabled when the IPL was skipped. --- Source/Core/Core/Boot/Boot.cpp | 4 +-- Source/Core/Core/Boot/Boot.h | 1 + Source/Core/Core/Boot/Boot_BS2Emu.cpp | 40 +++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 4e2844c95b..86ea8e2179 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -538,14 +538,12 @@ bool CBoot::BootUp(std::unique_ptr boot) SetDefaultDisc(); SetupMSR(); + SetupHID(config.bWii); SetupBAT(config.bWii); CopyDefaultExceptionHandlers(); if (config.bWii) { - PowerPC::ppcState.spr[SPR_HID0] = 0x0011c464; - PowerPC::ppcState.spr[SPR_HID4] = 0x82000000; - // Set a value for the SP. It doesn't matter where this points to, // as long as it is a valid location. This value is taken from a homebrew binary. PowerPC::ppcState.gpr[1] = 0x8004d4bc; diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 236dddaeca..78748717d0 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -160,6 +160,7 @@ private: static bool BootNANDTitle(u64 title_id); static void SetupMSR(); + static void SetupHID(bool is_wii); static void SetupBAT(bool is_wii); static bool RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume, const std::vector& riivolution_patches); diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 1265317a90..2c51a8ddbf 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -61,10 +61,44 @@ void CBoot::RunFunction(u32 address) void CBoot::SetupMSR() { - MSR.FP = 1; + // 0x0002032 + MSR.RI = 1; MSR.DR = 1; MSR.IR = 1; - MSR.EE = 1; + MSR.FP = 1; +} + +void CBoot::SetupHID(bool is_wii) +{ + // HID0 is 0x0011c464 on GC, 0x0011c664 on Wii + HID0.BHT = 1; + HID0.BTIC = 1; + HID0.DCFA = 1; + if (is_wii) + HID0.SPD = 1; + HID0.DCFI = 1; + HID0.DCE = 1; + // Note that Datel titles will fail to boot if the instruction cache is not enabled; see + // https://bugs.dolphin-emu.org/issues/8223 + HID0.ICE = 1; + HID0.NHR = 1; + HID0.DPM = 1; + + // HID1 is initialized in PowerPC.cpp to 0x80000000 + // HID2 is 0xe0000000 + HID2.PSE = 1; + HID2.WPE = 1; + HID2.LSQE = 1; + + // HID4 is 0 on GC and 0x83900000 on Wii + if (is_wii) + { + HID4.L2CFI = 1; + HID4.LPE = 1; + HID4.ST0 = 1; + HID4.SBE = 1; + HID4.reserved_3 = 1; + } } void CBoot::SetupBAT(bool is_wii) @@ -214,6 +248,7 @@ bool CBoot::EmulatedBS2_GC(const DiscIO::VolumeDisc& volume, INFO_LOG_FMT(BOOT, "Faking GC BS2..."); SetupMSR(); + SetupHID(/*is_wii*/ false); SetupBAT(/*is_wii*/ false); SetupGCMemory(); @@ -500,6 +535,7 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume, DVDRead(volume, 0, 0x3180, 4, partition); SetupMSR(); + SetupHID(/*is_wii*/ true); SetupBAT(/*is_wii*/ true); Memory::Write_U32(0x4c000064, 0x00000300); // Write default DSI Handler: rfi From 76401e8ffb3795e127ab8c377c1ac29aa2745d02 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 12 Jun 2022 23:38:33 -0700 Subject: [PATCH 2/2] BS2Emu: Initialize the last rows of postMatrices to the identity matrix This fixes Datel titles having missing textures (which was an issue with the previous commit). --- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 2c51a8ddbf..9068c63983 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -37,6 +37,10 @@ #include "DiscIO/RiivolutionPatcher.h" #include "DiscIO/VolumeDisc.h" +#include "VideoCommon/VertexManagerBase.h" +#include "VideoCommon/VertexShaderManager.h" +#include "VideoCommon/XFMemory.h" + namespace { void PresetTimeBaseTicks() @@ -253,6 +257,17 @@ bool CBoot::EmulatedBS2_GC(const DiscIO::VolumeDisc& volume, SetupGCMemory(); + // Datel titles don't initialize the postMatrices, but they have dual-texture coordinate + // transformation enabled. We initialize all of xfmem to 0, which results in everything using + // a texture coordinate of (0, 0), breaking textures. Normally the IPL will initialize the last + // entry to the identity matrix, but the whole point of BS2 EMU is that it skips the IPL, so we + // need to do this initialization ourselves. + xfmem.postMatrices[0x3d * 4 + 0] = 1.0f; + xfmem.postMatrices[0x3e * 4 + 1] = 1.0f; + xfmem.postMatrices[0x3f * 4 + 2] = 1.0f; + g_vertex_manager->Flush(); + VertexShaderManager::InvalidateXFRange(XFMEM_POSTMATRICES + 0x3d * 4, XFMEM_POSTMATRICES_END); + DVDReadDiscID(volume, 0x00000000); bool streaming = Memory::Read_U8(0x80000008);