Compare commits

...

13 Commits

Author SHA1 Message Date
KamFretoZ
424951e1bb Logging: Adjust the formatting to be more consistent 2024-12-28 11:25:26 -05:00
KamFretoZ
2167d9e4f5 Settings/Log: Print advanced settings warning on the log
Warns the user through the log if they have advanced options enabled.
2024-12-28 11:25:26 -05:00
rtavarez98
82a38a7124 changed indentation from tab to space 2024-12-28 11:22:50 -05:00
Rain
eb6a52c55c replaced recursive_directory_iterator w/ FindFiles() 2024-12-28 11:22:50 -05:00
Rain
234b8f6abf Added rename input profile function 2024-12-28 11:22:50 -05:00
lightningterror
843566eb49 Qt: Properly disable all dumping options if draw dumping is disabled.
Also move around sone options.
2024-12-28 17:04:33 +01:00
nassau-tk
d63733830f GameDB: Disable MTVU for some games 2024-12-27 23:43:51 -06:00
nassau-tk
3ebd496c37 GameDB: Fix titles for Japanese games 2024-12-27 23:43:51 -06:00
Mrlinkwii
f0f2b013fc Redump: update database 2024-12-27 14:30:23 -05:00
Ty Lamontagne
9a75509614 EE Cache: Fix up TLB related register fetching 2024-12-27 14:18:32 -05:00
Ty Lamontagne
c513a29bcf EE Cache: Freeze cached entries in sstates
[SAVEVERSION+]
2024-12-27 14:18:32 -05:00
Ty Lamontagne
5d39c884b5 R5900: Improve the EE cache performance with SIMD 2024-12-27 14:18:32 -05:00
TheLastRar
6a0f811812 Build: Always set EnhancedInstructionSet for AVX2 configs
Replaces the march arguments for clang-cl
2024-12-24 22:05:50 -05:00
27 changed files with 2745 additions and 1556 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -52,10 +52,10 @@
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_M_X86;__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Platform)'=='ARM64' Or !$(Configuration.Contains(AVX2))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Platform)'=='x64' And $(Configuration.Contains(AVX2))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<!-- Allow SSE4 intrinsics on non-AVX Clang-cl builds -->
<AdditionalOptions Condition="'$(Platform)'=='x64' And $(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'=='x64' And $(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'=='ARM64' And $(Configuration.Contains(Clang))"> -march=armv8.4-a %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="!$(Configuration.Contains(Clang))">%(AdditionalOptions) /Zc:externConstexpr /Zc:__cplusplus /Zo /utf-8</AdditionalOptions>

View File

@@ -38,6 +38,7 @@ ControllerSettingsWindow::ControllerSettingsWindow()
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &ControllerSettingsWindow::close);
connect(m_ui.newProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onNewProfileClicked);
connect(m_ui.applyProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onApplyProfileClicked);
connect(m_ui.renameProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onRenameProfileClicked);
connect(m_ui.deleteProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onDeleteProfileClicked);
connect(m_ui.mappingSettings, &QPushButton::clicked, this, &ControllerSettingsWindow::onMappingSettingsClicked);
connect(m_ui.restoreDefaults, &QPushButton::clicked, this, &ControllerSettingsWindow::onRestoreDefaultsClicked);
@@ -176,6 +177,48 @@ void ControllerSettingsWindow::onApplyProfileClicked()
switchProfile({});
}
void ControllerSettingsWindow::onRenameProfileClicked()
{
const QString profile_name(QInputDialog::getText(this, tr("Rename Input Profile"),
tr("Enter the new name for the input profile:").arg(m_profile_name)));
if (profile_name.isEmpty())
return;
std::string old_profile_name(m_profile_name.toStdString());
std::string old_profile_path(VMManager::GetInputProfilePath(m_profile_name.toStdString()));
std::string profile_path(VMManager::GetInputProfilePath(profile_name.toStdString()));
if (FileSystem::FileExists(profile_path.c_str()))
{
QMessageBox::critical(this, tr("Error"), tr("A profile with the name '%1' already exists.").arg(profile_name));
return;
}
if (!FileSystem::RenamePath(old_profile_path.c_str(), profile_path.c_str()))
{
QMessageBox::critical(this, tr("Error"), tr("Failed to rename '%1'.").arg(QString::fromStdString(old_profile_path)));
return;
}
FileSystem::FindResultsArray files;
FileSystem::FindFiles(EmuFolders::GameSettings.c_str(), "*", FILESYSTEM_FIND_FILES, &files);
for (const auto& game_settings : files)
{
std::string game_settings_path(game_settings.FileName.c_str());
std::unique_ptr<INISettingsInterface> update_sif(std::make_unique<INISettingsInterface>(std::move(game_settings_path)));
update_sif->Load();
if (!old_profile_name.compare(update_sif->GetStringValue("EmuCore", "InputProfileName")))
{
update_sif->SetStringValue("EmuCore", "InputProfileName", profile_name.toUtf8());
}
}
refreshProfileList();
switchProfile({profile_name});
}
void ControllerSettingsWindow::onDeleteProfileClicked()
{
if (QMessageBox::question(this, tr("Delete Input Profile"),
@@ -451,6 +494,7 @@ void ControllerSettingsWindow::createWidgets()
}
m_ui.applyProfile->setEnabled(isEditingProfile());
m_ui.renameProfile->setEnabled(isEditingProfile());
m_ui.deleteProfile->setEnabled(isEditingProfile());
m_ui.restoreDefaults->setEnabled(isEditingGlobalSettings());
}

View File

@@ -76,6 +76,7 @@ private Q_SLOTS:
void onCurrentProfileChanged(int index);
void onNewProfileClicked();
void onApplyProfileClicked();
void onRenameProfileClicked();
void onDeleteProfileClicked();
void onMappingSettingsClicked();
void onRestoreDefaultsClicked();

View File

@@ -113,6 +113,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="renameProfile">
<property name="text">
<string>Rename Profile</string>
</property>
<property name="icon">
<iconset theme="pencil-line"/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteProfile">
<property name="text">

View File

@@ -151,6 +151,14 @@ void DebugSettingsWidget::onDrawDumpingChanged()
m_ui.saveFrame->setEnabled(enabled);
m_ui.saveTexture->setEnabled(enabled);
m_ui.saveDepth->setEnabled(enabled);
m_ui.startDraw->setEnabled(enabled);
m_ui.dumpCount->setEnabled(enabled);
m_ui.hwDumpDirectory->setEnabled(enabled);
m_ui.hwDumpBrowse->setEnabled(enabled);
m_ui.hwDumpOpen->setEnabled(enabled);
m_ui.swDumpDirectory->setEnabled(enabled);
m_ui.swDumpBrowse->setEnabled(enabled);
m_ui.swDumpOpen->setEnabled(enabled);
}
#ifdef PCSX2_DEVBUILD

View File

@@ -167,7 +167,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QCheckBox" name="saveRT">
<property name="text">
<string>Save RT</string>
@@ -181,7 +181,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QCheckBox" name="saveTexture">
<property name="text">
<string>Save Texture</string>

View File

@@ -300,7 +300,7 @@ std::string Achievements::GetGameHash(const std::string& elf_path)
Error error;
if (!cdvdLoadElf(&elfo, elf_path, false, &error))
{
Console.Error(fmt::format("(Achievements) Failed to read ELF '{}' on disc: {}", elf_path, error.GetDescription()));
Console.Error(fmt::format("Achievements: Failed to read ELF '{}' on disc: {}", elf_path, error.GetDescription()));
return {};
}
@@ -441,7 +441,7 @@ bool Achievements::Initialize()
const std::string api_token = Host::GetBaseStringSettingValue("Achievements", "Token");
if (!username.empty() && !api_token.empty())
{
Console.WriteLn("(Achievements) Attempting login with user '%s'...", username.c_str());
Console.WriteLn("Achievements: Attempting login with user '%s'...", username.c_str());
s_login_request =
rc_client_begin_login_with_token(s_client, username.c_str(), api_token.c_str(), ClientLoginWithTokenCallback, nullptr);
}
@@ -608,7 +608,7 @@ void Achievements::EnsureCacheDirectoriesExist()
void Achievements::ClientMessageCallback(const char* message, const rc_client_t* client)
{
Console.WriteLn("(Achievements) %s", message);
Console.WriteLn("Achievements: %s", message);
}
uint32_t Achievements::ClientReadMemory(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client)
@@ -865,7 +865,7 @@ void Achievements::IdentifyGame(u32 disc_crc, u32 crc)
// bail out if we're not logged in, just save the hash
if (!IsLoggedInOrLoggingIn())
{
Console.WriteLn(Color_StrongYellow, "(Achievements) Skipping load game because we're not logged in.");
Console.WriteLn(Color_StrongYellow, "Achievements: Skipping load game because we're not logged in.");
DisableHardcoreMode();
return;
}
@@ -908,7 +908,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
if (result == RC_NO_GAME_LOADED)
{
// Unknown game.
Console.WriteLn(Color_StrongYellow, "(Achievements) Unknown game '%s', disabling achievements.", s_game_hash.c_str());
Console.WriteLn(Color_StrongYellow, "Achievements: Unknown game '%s', disabling achievements.", s_game_hash.c_str());
DisableHardcoreMode();
return;
}
@@ -1083,7 +1083,7 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
const rc_client_achievement_t* cheevo = event->achievement;
pxAssert(cheevo);
Console.WriteLn("(Achievements) Achievement %s (%u) for game %u unlocked", cheevo->title, cheevo->id, s_game_id);
Console.WriteLn("Achievements: Achievement %s (%u) for game %u unlocked", cheevo->title, cheevo->id, s_game_id);
UpdateGameSummary();
if (EmuConfig.Achievements.Notifications)
@@ -1109,7 +1109,7 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
{
Console.WriteLn("(Achievements) Game %u complete", s_game_id);
Console.WriteLn("Achievements: Game %u complete", s_game_id);
UpdateGameSummary();
if (EmuConfig.Achievements.Notifications)
@@ -1133,7 +1133,7 @@ void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
void Achievements::HandleLeaderboardStartedEvent(const rc_client_event_t* event)
{
DevCon.WriteLn("(Achievements) Leaderboard %u (%s) started", event->leaderboard->id, event->leaderboard->title);
DevCon.WriteLn("Achievements: Leaderboard %u (%s) started", event->leaderboard->id, event->leaderboard->title);
if (EmuConfig.Achievements.LeaderboardNotifications)
{
@@ -1152,7 +1152,7 @@ void Achievements::HandleLeaderboardStartedEvent(const rc_client_event_t* event)
void Achievements::HandleLeaderboardFailedEvent(const rc_client_event_t* event)
{
DevCon.WriteLn("(Achievements) Leaderboard %u (%s) failed", event->leaderboard->id, event->leaderboard->title);
DevCon.WriteLn("Achievements: Leaderboard %u (%s) failed", event->leaderboard->id, event->leaderboard->title);
if (EmuConfig.Achievements.LeaderboardNotifications)
{
@@ -1171,7 +1171,7 @@ void Achievements::HandleLeaderboardFailedEvent(const rc_client_event_t* event)
void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* event)
{
Console.WriteLn("(Achievements) Leaderboard %u (%s) submitted", event->leaderboard->id, event->leaderboard->title);
Console.WriteLn("Achievements: Leaderboard %u (%s) submitted", event->leaderboard->id, event->leaderboard->title);
if (EmuConfig.Achievements.LeaderboardNotifications)
{
@@ -1203,7 +1203,7 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event)
{
Console.WriteLn("(Achievements) Leaderboard %u scoreboard rank %u of %u", event->leaderboard_scoreboard->leaderboard_id,
Console.WriteLn("Achievements: Leaderboard %u scoreboard rank %u of %u", event->leaderboard_scoreboard->leaderboard_id,
event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries);
if (EmuConfig.Achievements.LeaderboardNotifications)
@@ -1234,7 +1234,7 @@ void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* eve
void Achievements::HandleLeaderboardTrackerShowEvent(const rc_client_event_t* event)
{
DevCon.WriteLn(
"(Achievements) Showing leaderboard tracker: %u: %s", event->leaderboard_tracker->id, event->leaderboard_tracker->display);
"Achievements: Showing leaderboard tracker: %u: %s", event->leaderboard_tracker->id, event->leaderboard_tracker->display);
LeaderboardTrackerIndicator indicator;
indicator.tracker_id = event->leaderboard_tracker->id;
@@ -1251,7 +1251,7 @@ void Achievements::HandleLeaderboardTrackerHideEvent(const rc_client_event_t* ev
if (it == s_active_leaderboard_trackers.end())
return;
DevCon.WriteLn("(Achievements) Hiding leaderboard tracker: %u", id);
DevCon.WriteLn("Achievements: Hiding leaderboard tracker: %u", id);
it->active = false;
it->show_hide_time.Reset();
}
@@ -1265,7 +1265,7 @@ void Achievements::HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t*
return;
DevCon.WriteLn(
"(Achievements) Updating leaderboard tracker: %u: %s", event->leaderboard_tracker->id, event->leaderboard_tracker->display);
"Achievements: Updating leaderboard tracker: %u: %s", event->leaderboard_tracker->id, event->leaderboard_tracker->display);
it->text = event->leaderboard_tracker->display;
it->active = true;
@@ -1288,7 +1288,7 @@ void Achievements::HandleAchievementChallengeIndicatorShowEvent(const rc_client_
indicator.active = true;
s_active_challenge_indicators.push_back(std::move(indicator));
DevCon.WriteLn("(Achievements) Show challenge indicator for %u (%s)", event->achievement->id, event->achievement->title);
DevCon.WriteLn("Achievements: Show challenge indicator for %u (%s)", event->achievement->id, event->achievement->title);
}
void Achievements::HandleAchievementChallengeIndicatorHideEvent(const rc_client_event_t* event)
@@ -1298,14 +1298,14 @@ void Achievements::HandleAchievementChallengeIndicatorHideEvent(const rc_client_
if (it == s_active_challenge_indicators.end())
return;
DevCon.WriteLn("(Achievements) Hide challenge indicator for %u (%s)", event->achievement->id, event->achievement->title);
DevCon.WriteLn("Achievements: Hide challenge indicator for %u (%s)", event->achievement->id, event->achievement->title);
it->show_hide_time.Reset();
it->active = false;
}
void Achievements::HandleAchievementProgressIndicatorShowEvent(const rc_client_event_t* event)
{
DevCon.WriteLn("(Achievements) Showing progress indicator: %u (%s): %s", event->achievement->id, event->achievement->title,
DevCon.WriteLn("Achievements: Showing progress indicator: %u (%s): %s", event->achievement->id, event->achievement->title,
event->achievement->measured_progress);
if (!s_active_progress_indicator.has_value())
@@ -1323,14 +1323,14 @@ void Achievements::HandleAchievementProgressIndicatorHideEvent(const rc_client_e
if (!s_active_progress_indicator.has_value())
return;
DevCon.WriteLn("(Achievements) Hiding progress indicator");
DevCon.WriteLn("Achievements: Hiding progress indicator");
s_active_progress_indicator->show_hide_time.Reset();
s_active_progress_indicator->active = false;
}
void Achievements::HandleAchievementProgressIndicatorUpdateEvent(const rc_client_event_t* event)
{
DevCon.WriteLn("(Achievements) Updating progress indicator: %u (%s): %s", event->achievement->id, event->achievement->title,
DevCon.WriteLn("Achievements: Updating progress indicator: %u (%s): %s", event->achievement->id, event->achievement->title,
event->achievement->measured_progress);
s_active_progress_indicator->achievement = event->achievement;
s_active_progress_indicator->active = true;
@@ -1341,13 +1341,13 @@ void Achievements::HandleServerErrorEvent(const rc_client_event_t* event)
std::string message = fmt::format(TRANSLATE_FS("Achievements", "Server error in {0}:\n{1}"),
event->server_error->api ? event->server_error->api : "UNKNOWN",
event->server_error->error_message ? event->server_error->error_message : "UNKNOWN");
Console.Error("(Achievements) %s", message.c_str());
Console.Error("Achievements: %s", message.c_str());
Host::AddOSDMessage(std::move(message), Host::OSD_ERROR_DURATION);
}
void Achievements::HandleServerDisconnectedEvent(const rc_client_event_t* event)
{
Console.Warning("(Achievements) Server disconnected.");
Console.Warning("Achievements: Server disconnected.");
MTGS::RunOnGSThread([]() {
if (ImGuiManager::InitializeFullscreenUI())
@@ -1360,7 +1360,7 @@ void Achievements::HandleServerDisconnectedEvent(const rc_client_event_t* event)
void Achievements::HandleServerReconnectedEvent(const rc_client_event_t* event)
{
Console.Warning("(Achievements) Server reconnected.");
Console.Warning("Achievements: Server reconnected.");
MTGS::RunOnGSThread([]() {
if (ImGuiManager::InitializeFullscreenUI())
@@ -1385,7 +1385,7 @@ void Achievements::ResetClient()
if (!IsActive())
return;
Console.WriteLn("(Achievements) Reset client");
Console.WriteLn("Achievements: Reset client");
rc_client_reset(s_client);
}
@@ -1811,11 +1811,11 @@ void Achievements::Logout()
if (HasActiveGame())
ClearGameInfo();
Console.WriteLn("(Achievements) Logging out...");
Console.WriteLn("Achievements: Logging out...");
rc_client_logout(s_client);
}
Console.WriteLn("(Achievements) Clearing credentials...");
Console.WriteLn("Achievements: Clearing credentials...");
Host::RemoveBaseSettingValue("Achievements", "Username");
Host::RemoveBaseSettingValue("Achievements", "Token");
Host::RemoveBaseSettingValue("Achievements", "LoginTimestamp");
@@ -1961,7 +1961,7 @@ void Achievements::DrawGameOverlays()
if (!indicator.active && opacity <= 0.01f)
{
DevCon.WriteLn("(Achievements) Remove challenge indicator");
DevCon.WriteLn("Achievements: Remove challenge indicator");
it = s_active_challenge_indicators.erase(it);
}
else
@@ -2004,7 +2004,7 @@ void Achievements::DrawGameOverlays()
if (!indicator.active && opacity <= 0.01f)
{
DevCon.WriteLn("(Achievements) Remove progress indicator");
DevCon.WriteLn("Achievements: Remove progress indicator");
s_active_progress_indicator.reset();
}
@@ -2046,7 +2046,7 @@ void Achievements::DrawGameOverlays()
if (!indicator.active && opacity <= 0.01f)
{
DevCon.WriteLn("(Achievements) Remove tracker indicator");
DevCon.WriteLn("Achievements: Remove tracker indicator");
it = s_active_leaderboard_trackers.erase(it);
}
else
@@ -2151,7 +2151,7 @@ bool Achievements::PrepareAchievementsWindow()
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS /*RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE*/);
if (!s_achievement_list)
{
Console.Error("(Achievements) rc_client_create_achievement_list() returned null");
Console.Error("Achievements: rc_client_create_achievement_list() returned null");
return false;
}
@@ -2489,7 +2489,7 @@ bool Achievements::PrepareLeaderboardsWindow()
s_leaderboard_list = rc_client_create_leaderboard_list(client, RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE);
if (!s_leaderboard_list)
{
Console.Error("(Achievements) rc_client_create_leaderboard_list() returned null");
Console.Error("Achievements: rc_client_create_leaderboard_list() returned null");
return false;
}
@@ -2920,7 +2920,7 @@ void Achievements::DrawLeaderboardListEntry(const rc_client_leaderboard_t* lboar
void Achievements::OpenLeaderboard(const rc_client_leaderboard_t* lboard)
{
Console.WriteLn("(Achievements) Opening leaderboard '%s' (%u)", lboard->title, lboard->id);
Console.WriteLn("Achievements: Opening leaderboard '%s' (%u)", lboard->title, lboard->id);
CloseLeaderboard();
@@ -2974,7 +2974,7 @@ void Achievements::FetchNextLeaderboardEntries()
for (rc_client_leaderboard_entry_list_t* list : s_leaderboard_entry_lists)
start += list->num_entries;
Console.WriteLn("(Achievements) Fetching entries %u to %u", start, start + LEADERBOARD_ALL_FETCH_SIZE);
Console.WriteLn("Achievements: Fetching entries %u to %u", start, start + LEADERBOARD_ALL_FETCH_SIZE);
if (s_leaderboard_fetch_handle)
rc_client_abort_async(s_client, s_leaderboard_fetch_handle);

View File

@@ -230,49 +230,49 @@ void MapTLB(const tlbs& t, int i)
u32 saddr, eaddr;
COP0_LOG("MAP TLB %d: 0x%08X-> [0x%08X 0x%08X] S=%d G=%d ASID=%d Mask=0x%03X EntryLo0 PFN=%x EntryLo0 Cache=%x EntryLo1 PFN=%x EntryLo1 Cache=%x VPN2=%x",
i, t.VPN2, t.PFN0, t.PFN1, t.S >> 31, t.G, t.ASID,
t.Mask, t.EntryLo0 >> 6, (t.EntryLo0 & 0x38) >> 3, t.EntryLo1 >> 6, (t.EntryLo1 & 0x38) >> 3, t.VPN2);
i, t.VPN2(), t.PFN0(), t.PFN1(), t.isSPR() >> 31, t.isGlobal(), t.EntryHi.ASID,
t.Mask(), t.EntryLo0.PFN, t.EntryLo0.C, t.EntryLo1.PFN, t.EntryLo1.C, t.VPN2());
// According to the manual
// 'It [SPR] must be mapped into a contiguous 16 KB of virtual address space that is
// aligned on a 16KB boundary.Results are not guaranteed if this restriction is not followed.'
// Assume that the game isn't doing anything less-than-ideal with the scratchpad mapping and map it directly to eeMem->Scratch.
if (t.S)
if (t.isSPR())
{
if (t.VPN2 != 0x70000000)
Console.Warning("COP0: Mapping Scratchpad to non-default address 0x%08X", t.VPN2);
if (t.VPN2() != 0x70000000)
Console.Warning("COP0: Mapping Scratchpad to non-default address 0x%08X", t.VPN2());
vtlb_VMapBuffer(t.VPN2, eeMem->Scratch, Ps2MemSize::Scratch);
vtlb_VMapBuffer(t.VPN2(), eeMem->Scratch, Ps2MemSize::Scratch);
}
else
{
if (t.EntryLo0 & 0x2)
if (t.EntryLo0.V)
{
mask = ((~t.Mask) << 1) & 0xfffff;
saddr = t.VPN2 >> 12;
eaddr = saddr + t.Mask + 1;
mask = ((~t.Mask()) << 1) & 0xfffff;
saddr = t.VPN2() >> 12;
eaddr = saddr + t.Mask() + 1;
for (addr = saddr; addr < eaddr; addr++)
{
if ((addr & mask) == ((t.VPN2 >> 12) & mask))
if ((addr & mask) == ((t.VPN2() >> 12) & mask))
{ //match
memSetPageAddr(addr << 12, t.PFN0 + ((addr - saddr) << 12));
memSetPageAddr(addr << 12, t.PFN0() + ((addr - saddr) << 12));
Cpu->Clear(addr << 12, 0x400);
}
}
}
if (t.EntryLo1 & 0x2)
if (t.EntryLo1.V)
{
mask = ((~t.Mask) << 1) & 0xfffff;
saddr = (t.VPN2 >> 12) + t.Mask + 1;
eaddr = saddr + t.Mask + 1;
mask = ((~t.Mask()) << 1) & 0xfffff;
saddr = (t.VPN2() >> 12) + t.Mask() + 1;
eaddr = saddr + t.Mask() + 1;
for (addr = saddr; addr < eaddr; addr++)
{
if ((addr & mask) == ((t.VPN2 >> 12) & mask))
if ((addr & mask) == ((t.VPN2() >> 12) & mask))
{ //match
memSetPageAddr(addr << 12, t.PFN1 + ((addr - saddr) << 12));
memSetPageAddr(addr << 12, t.PFN1() + ((addr - saddr) << 12));
Cpu->Clear(addr << 12, 0x400);
}
}
@@ -280,27 +280,36 @@ void MapTLB(const tlbs& t, int i)
}
}
__inline u32 ConvertPageMask(const u32 PageMask)
{
const u32 mask = std::popcount(PageMask >> 13);
pxAssertMsg(!((mask & 1) || mask > 12), "Invalid page mask for this TLB entry. EE cache doesn't know what to do here.");
return (1 << (12 + mask)) - 1;
}
void UnmapTLB(const tlbs& t, int i)
{
//Console.WriteLn("Clear TLB %d: %08x-> [%08x %08x] S=%d G=%d ASID=%d Mask= %03X", i,t.VPN2,t.PFN0,t.PFN1,t.S,t.G,t.ASID,t.Mask);
u32 mask, addr;
u32 saddr, eaddr;
if (t.S)
if (t.isSPR())
{
vtlb_VMapUnmap(t.VPN2, 0x4000);
vtlb_VMapUnmap(t.VPN2(), 0x4000);
return;
}
if (t.EntryLo0 & 0x2)
if (t.EntryLo0.V)
{
mask = ((~t.Mask) << 1) & 0xfffff;
saddr = t.VPN2 >> 12;
eaddr = saddr + t.Mask + 1;
mask = ((~t.Mask()) << 1) & 0xfffff;
saddr = t.VPN2() >> 12;
eaddr = saddr + t.Mask() + 1;
// Console.WriteLn("Clear TLB: %08x ~ %08x",saddr,eaddr-1);
for (addr = saddr; addr < eaddr; addr++)
{
if ((addr & mask) == ((t.VPN2 >> 12) & mask))
if ((addr & mask) == ((t.VPN2() >> 12) & mask))
{ //match
memClearPageAddr(addr << 12);
Cpu->Clear(addr << 12, 0x400);
@@ -308,38 +317,74 @@ void UnmapTLB(const tlbs& t, int i)
}
}
if (t.EntryLo1 & 0x2)
if (t.EntryLo1.V)
{
mask = ((~t.Mask) << 1) & 0xfffff;
saddr = (t.VPN2 >> 12) + t.Mask + 1;
eaddr = saddr + t.Mask + 1;
mask = ((~t.Mask()) << 1) & 0xfffff;
saddr = (t.VPN2() >> 12) + t.Mask() + 1;
eaddr = saddr + t.Mask() + 1;
// Console.WriteLn("Clear TLB: %08x ~ %08x",saddr,eaddr-1);
for (addr = saddr; addr < eaddr; addr++)
{
if ((addr & mask) == ((t.VPN2 >> 12) & mask))
if ((addr & mask) == ((t.VPN2() >> 12) & mask))
{ //match
memClearPageAddr(addr << 12);
Cpu->Clear(addr << 12, 0x400);
}
}
}
for (size_t i = 0; i < cachedTlbs.count; i++)
{
if (cachedTlbs.PFN0s[i] == t.PFN0() && cachedTlbs.PFN1s[i] == t.PFN1() && cachedTlbs.PageMasks[i] == ConvertPageMask(t.PageMask.UL))
{
for (size_t j = i; j < cachedTlbs.count - 1; j++)
{
cachedTlbs.CacheEnabled0[j] = cachedTlbs.CacheEnabled0[j + 1];
cachedTlbs.CacheEnabled1[j] = cachedTlbs.CacheEnabled1[j + 1];
cachedTlbs.PFN0s[j] = cachedTlbs.PFN0s[j + 1];
cachedTlbs.PFN1s[j] = cachedTlbs.PFN1s[j + 1];
cachedTlbs.PageMasks[j] = cachedTlbs.PageMasks[j + 1];
}
cachedTlbs.count--;
break;
}
}
}
void WriteTLB(int i)
{
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
tlb[i].EntryLo1 = cpuRegs.CP0.n.EntryLo1;
tlb[i].PageMask.UL = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi.UL = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0.UL = cpuRegs.CP0.n.EntryLo0;
tlb[i].EntryLo1.UL = cpuRegs.CP0.n.EntryLo1;
tlb[i].Mask = (cpuRegs.CP0.n.PageMask >> 13) & 0xfff;
tlb[i].nMask = (~tlb[i].Mask) & 0xfff;
tlb[i].VPN2 = ((cpuRegs.CP0.n.EntryHi >> 13) & (~tlb[i].Mask)) << 13;
tlb[i].ASID = cpuRegs.CP0.n.EntryHi & 0xfff;
tlb[i].G = cpuRegs.CP0.n.EntryLo0 & cpuRegs.CP0.n.EntryLo1 & 0x1;
tlb[i].PFN0 = (((cpuRegs.CP0.n.EntryLo0 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN1 = (((cpuRegs.CP0.n.EntryLo1 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].S = cpuRegs.CP0.n.EntryLo0 & 0x80000000;
// Setting the cache mode to reserved values is vaguely defined in the manual.
// I found that SPR is set to cached regardless.
// Non-SPR entries default to uncached on reserved cache modes.
if (tlb[i].isSPR())
{
tlb[i].EntryLo0.C = 3;
tlb[i].EntryLo1.C = 3;
}
else
{
if (!tlb[i].EntryLo0.isValidCacheMode())
tlb[i].EntryLo0.C = 2;
if (!tlb[i].EntryLo1.isValidCacheMode())
tlb[i].EntryLo1.C = 2;
}
if (!tlb[i].isSPR() && ((tlb[i].EntryLo0.V && tlb[i].EntryLo0.isCached()) || (tlb[i].EntryLo1.V && tlb[i].EntryLo1.isCached())))
{
const size_t idx = cachedTlbs.count;
cachedTlbs.CacheEnabled0[idx] = tlb[i].EntryLo0.isCached() ? ~0 : 0;
cachedTlbs.CacheEnabled1[idx] = tlb[i].EntryLo1.isCached() ? ~0 : 0;
cachedTlbs.PFN1s[idx] = tlb[i].PFN1();
cachedTlbs.PFN0s[idx] = tlb[i].PFN0();
cachedTlbs.PageMasks[idx] = ConvertPageMask(tlb[i].PageMask.UL);
cachedTlbs.count++;
}
MapTLB(tlb[i], i);
}
@@ -355,49 +400,57 @@ namespace COP0 {
cpuRegs.CP0.n.Index, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);
int i = cpuRegs.CP0.n.Index & 0x3f;
const u8 i = cpuRegs.CP0.n.Index & 0x3f;
cpuRegs.CP0.n.PageMask = tlb[i].PageMask;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi & ~(tlb[i].PageMask | 0x1f00);
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0 & ~1) | ((tlb[i].EntryHi >> 12) & 1);
cpuRegs.CP0.n.EntryLo1 = (tlb[i].EntryLo1 & ~1) | ((tlb[i].EntryHi >> 12) & 1);
if (i > 47)
{
Console.Warning("TLBR with index > 47! (%d)", i);
return;
}
cpuRegs.CP0.n.PageMask = tlb[i].PageMask.Mask << 13;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi.UL & ~((tlb[i].PageMask.Mask << 13) | 0x1f00);
cpuRegs.CP0.n.EntryLo0 = tlb[i].EntryLo0.UL & ~(0xFC000000) & ~1;
cpuRegs.CP0.n.EntryLo1 = tlb[i].EntryLo1.UL & ~(0x7C000000) & ~1;
// "If both the Global bit of EntryLo0 and EntryLo1 are set to 1, the processor ignores the ASID during TLB lookup."
// This is reflected during TLBR, where G is only set if both EntryLo0 and EntryLo1 are global.
cpuRegs.CP0.n.EntryLo0 |= (tlb[i].EntryLo0.UL & 1) & (tlb[i].EntryLo1.UL & 1);
cpuRegs.CP0.n.EntryLo1 |= (tlb[i].EntryLo0.UL & 1) & (tlb[i].EntryLo1.UL & 1);
}
void TLBWI()
{
int j = cpuRegs.CP0.n.Index & 0x3f;
const u8 j = cpuRegs.CP0.n.Index & 0x3f;
//if (j > 48) return;
if (j > 47)
{
Console.Warning("TLBWI with index > 47! (%d)", j);
return;
}
COP0_LOG("COP0_TLBWI %d:%x,%x,%x,%x",
cpuRegs.CP0.n.Index, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);
UnmapTLB(tlb[j], j);
tlb[j].PageMask = cpuRegs.CP0.n.PageMask;
tlb[j].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[j].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
tlb[j].EntryLo1 = cpuRegs.CP0.n.EntryLo1;
WriteTLB(j);
}
void TLBWR()
{
int j = cpuRegs.CP0.n.Random & 0x3f;
const u8 j = cpuRegs.CP0.n.Random & 0x3f;
//if (j > 48) return;
if (j > 47)
{
Console.Warning("TLBWR with random > 47! (%d)", j);
return;
}
DevCon.Warning("COP0_TLBWR %d:%x,%x,%x,%x\n",
cpuRegs.CP0.n.Random, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);
//if (j > 48) return;
UnmapTLB(tlb[j], j);
tlb[j].PageMask = cpuRegs.CP0.n.PageMask;
tlb[j].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[j].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
tlb[j].EntryLo1 = cpuRegs.CP0.n.EntryLo1;
WriteTLB(j);
}
@@ -422,7 +475,7 @@ namespace COP0 {
cpuRegs.CP0.n.Index = 0xFFFFFFFF;
for (i = 0; i < 48; i++)
{
if (tlb[i].VPN2 == ((~tlb[i].Mask) & (EntryHi32.s.VPN2)) && ((tlb[i].G & 1) || ((tlb[i].ASID & 0xff) == EntryHi32.s.ASID)))
if (tlb[i].VPN2() == ((~tlb[i].Mask()) & (EntryHi32.s.VPN2)) && ((tlb[i].isGlobal()) || ((tlb[i].EntryHi.ASID & 0xff) == EntryHi32.s.ASID)))
{
cpuRegs.CP0.n.Index = i;
break;

View File

@@ -403,7 +403,7 @@ void UpdateVSyncRate(bool force)
vSyncInfoCalc(&vSyncInfo, frames_per_second, total_scanlines);
if (video_mode_initialized)
Console.WriteLn(Color_Green, "(UpdateVSyncRate) Mode Changed to %s.", ReportVideoMode());
Console.WriteLn(Color_Green, "UpdateVSyncRate: Mode Changed to %s.", ReportVideoMode());
if (custom && video_mode_initialized)
Console.WriteLn(Color_StrongGreen, " ... with user configured refresh rate: %.02f Hz", vertical_frequency);

View File

@@ -118,7 +118,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (eeVal >= 0 && eeVal < static_cast<int>(FPRoundMode::MaxCount))
gameEntry.eeRoundMode = static_cast<FPRoundMode>(eeVal);
else
Console.Error(fmt::format("[GameDB] Invalid EE round mode '{}', specified for serial: '{}'.", eeVal, serial));
Console.Error(fmt::format("GameDB: Invalid EE round mode '{}', specified for serial: '{}'.", eeVal, serial));
}
if (node["roundModes"].has_child("eeDivRoundMode"))
{
@@ -127,7 +127,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (eeVal >= 0 && eeVal < static_cast<int>(FPRoundMode::MaxCount))
gameEntry.eeDivRoundMode = static_cast<FPRoundMode>(eeVal);
else
Console.Error(fmt::format("[GameDB] Invalid EE division round mode '{}', specified for serial: '{}'.", eeVal, serial));
Console.Error(fmt::format("GameDB: Invalid EE division round mode '{}', specified for serial: '{}'.", eeVal, serial));
}
if (node["roundModes"].has_child("vuRoundMode"))
{
@@ -140,7 +140,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
}
else
{
Console.Error(fmt::format("[GameDB] Invalid VU round mode '{}', specified for serial: '{}'.", vuVal, serial));
Console.Error(fmt::format("GameDB: Invalid VU round mode '{}', specified for serial: '{}'.", vuVal, serial));
}
}
if (node["roundModes"].has_child("vu0RoundMode"))
@@ -150,7 +150,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (vuVal >= 0 && vuVal < static_cast<int>(FPRoundMode::MaxCount))
gameEntry.vu0RoundMode = static_cast<FPRoundMode>(vuVal);
else
Console.Error(fmt::format("[GameDB] Invalid VU0 round mode '{}', specified for serial: '{}'.", vuVal, serial));
Console.Error(fmt::format("GameDB: Invalid VU0 round mode '{}', specified for serial: '{}'.", vuVal, serial));
}
if (node["roundModes"].has_child("vu1RoundMode"))
{
@@ -159,7 +159,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (vuVal >= 0 && vuVal < static_cast<int>(FPRoundMode::MaxCount))
gameEntry.vu1RoundMode = static_cast<FPRoundMode>(vuVal);
else
Console.Error(fmt::format("[GameDB] Invalid VU1 round mode '{}', specified for serial: '{}'.", vuVal, serial));
Console.Error(fmt::format("GameDB: Invalid VU1 round mode '{}', specified for serial: '{}'.", vuVal, serial));
}
}
if (node.has_child("clampModes"))
@@ -217,7 +217,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (!fixValidated)
{
Console.Error(fmt::format("[GameDB] Invalid gamefix: '{}', specified for serial: '{}'. Dropping!", fix, serial));
Console.Error(fmt::format("GameDB: Invalid gamefix: '{}', specified for serial: '{}'. Dropping!", fix, serial));
}
}
}
@@ -239,7 +239,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
}
else
{
Console.Error(fmt::format("[GameDB] Invalid speedhack: '{}={}', specified for serial: '{}'. Dropping!",
Console.Error(fmt::format("GameDB: Invalid speedhack: '{}={}', specified for serial: '{}'. Dropping!",
id_view, value_view, serial));
}
}
@@ -266,7 +266,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
if (value.value_or(-1) < 0)
{
Console.Error(fmt::format("[GameDB] Invalid GS HW Fix Value for '{}' in '{}': '{}'", id_name, serial, str_value));
Console.Error(fmt::format("GameDB: Invalid GS HW Fix Value for '{}' in '{}': '{}'", id_name, serial, str_value));
continue;
}
}
@@ -276,7 +276,7 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
}
if (!id.has_value() || !value.has_value())
{
Console.Error(fmt::format("[GameDB] Invalid GS HW Fix: '{}' specified for serial '{}'. Dropping!", id_name, serial));
Console.Error(fmt::format("GameDB: Invalid GS HW Fix: '{}' specified for serial '{}'. Dropping!", id_name, serial));
continue;
}
@@ -305,12 +305,12 @@ void GameDatabase::parseAndInsert(const std::string_view serial, const c4::yml::
const std::optional<u32> crc = (StringUtil::compareNoCase(crc_str, "default")) ? std::optional<u32>(0) : StringUtil::FromChars<u32>(crc_str, 16);
if (!crc.has_value())
{
Console.Error(fmt::format("[GameDB] Invalid CRC '{}' found for serial: '{}'. Skipping!", crc_str, serial));
Console.Error(fmt::format("GameDB: Invalid CRC '{}' found for serial: '{}'. Skipping!", crc_str, serial));
continue;
}
if (gameEntry.patches.find(crc.value()) != gameEntry.patches.end())
{
Console.Error(fmt::format("[GameDB] Duplicate CRC '{}' found for serial: '{}'. Skipping, CRCs are case-insensitive!", crc_str, serial));
Console.Error(fmt::format("GameDB: Duplicate CRC '{}' found for serial: '{}'. Skipping, CRCs are case-insensitive!", crc_str, serial));
continue;
}
@@ -442,18 +442,18 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
// Only apply core game fixes if the user has enabled them.
if (!applyAuto)
Console.Warning("[GameDB] Game Fixes are disabled");
Console.Warning("GameDB: Game Fixes are disabled");
if (eeRoundMode < FPRoundMode::MaxCount)
{
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
Console.WriteLn("GameDB: Changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
config.Cpu.FPUFPCR.SetRoundMode(eeRoundMode);
}
else
{
Console.Warning("[GameDB] Skipping changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
Console.Warning("GameDB: Skipping changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
}
}
@@ -461,12 +461,12 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing EE/FPU divison roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeDivRoundMode)]);
Console.WriteLn("GameDB: Changing EE/FPU divison roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeDivRoundMode)]);
config.Cpu.FPUDivFPCR.SetRoundMode(eeDivRoundMode);
}
else
{
Console.Warning("[GameDB] Skipping changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
Console.Warning("GameDB: Skipping changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast<u8>(eeRoundMode)]);
}
}
@@ -474,12 +474,12 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing VU0 roundmode to %d [%s]", vu0RoundMode, s_round_modes[static_cast<u8>(vu0RoundMode)]);
Console.WriteLn("GameDB: Changing VU0 roundmode to %d [%s]", vu0RoundMode, s_round_modes[static_cast<u8>(vu0RoundMode)]);
config.Cpu.VU0FPCR.SetRoundMode(vu0RoundMode);
}
else
{
Console.Warning("[GameDB] Skipping changing VU0 roundmode to %d [%s]", vu0RoundMode, s_round_modes[static_cast<u8>(vu0RoundMode)]);
Console.Warning("GameDB: Skipping changing VU0 roundmode to %d [%s]", vu0RoundMode, s_round_modes[static_cast<u8>(vu0RoundMode)]);
}
}
@@ -487,12 +487,12 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing VU1 roundmode to %d [%s]", vu1RoundMode, s_round_modes[static_cast<u8>(vu1RoundMode)]);
Console.WriteLn("GameDB: Changing VU1 roundmode to %d [%s]", vu1RoundMode, s_round_modes[static_cast<u8>(vu1RoundMode)]);
config.Cpu.VU1FPCR.SetRoundMode(vu1RoundMode);
}
else
{
Console.Warning("[GameDB] Skipping changing VU1 roundmode to %d [%s]", vu1RoundMode, s_round_modes[static_cast<u8>(vu1RoundMode)]);
Console.Warning("GameDB: Skipping changing VU1 roundmode to %d [%s]", vu1RoundMode, s_round_modes[static_cast<u8>(vu1RoundMode)]);
}
}
@@ -501,13 +501,13 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
const int clampMode = enum_cast(eeClampMode);
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode);
Console.WriteLn("GameDB: Changing EE/FPU clamp mode [mode=%d]", clampMode);
config.Cpu.Recompiler.fpuOverflow = (clampMode >= 1);
config.Cpu.Recompiler.fpuExtraOverflow = (clampMode >= 2);
config.Cpu.Recompiler.fpuFullMode = (clampMode >= 3);
}
else
Console.Warning("[GameDB] Skipping changing EE/FPU clamp mode [mode=%d]", clampMode);
Console.Warning("GameDB: Skipping changing EE/FPU clamp mode [mode=%d]", clampMode);
}
if (vu0ClampMode != GameDatabaseSchema::ClampMode::Undefined)
@@ -515,13 +515,13 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
const int clampMode = enum_cast(vu0ClampMode);
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing VU0 clamp mode [mode=%d]", clampMode);
Console.WriteLn("GameDB: Changing VU0 clamp mode [mode=%d]", clampMode);
config.Cpu.Recompiler.vu0Overflow = (clampMode >= 1);
config.Cpu.Recompiler.vu0ExtraOverflow = (clampMode >= 2);
config.Cpu.Recompiler.vu0SignOverflow = (clampMode >= 3);
}
else
Console.Warning("[GameDB] Skipping changing VU0 clamp mode [mode=%d]", clampMode);
Console.Warning("GameDB: Skipping changing VU0 clamp mode [mode=%d]", clampMode);
}
if (vu1ClampMode != GameDatabaseSchema::ClampMode::Undefined)
@@ -529,13 +529,13 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
const int clampMode = enum_cast(vu1ClampMode);
if (applyAuto)
{
Console.WriteLn("(GameDB) Changing VU1 clamp mode [mode=%d]", clampMode);
Console.WriteLn("GameDB: Changing VU1 clamp mode [mode=%d]", clampMode);
config.Cpu.Recompiler.vu1Overflow = (clampMode >= 1);
config.Cpu.Recompiler.vu1ExtraOverflow = (clampMode >= 2);
config.Cpu.Recompiler.vu1SignOverflow = (clampMode >= 3);
}
else
Console.Warning("[GameDB] Skipping changing VU1 clamp mode [mode=%d]", clampMode);
Console.Warning("GameDB: Skipping changing VU1 clamp mode [mode=%d]", clampMode);
}
// TODO - config - this could be simplified with maps instead of bitfields and enums
@@ -543,14 +543,14 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
if (!applyAuto)
{
Console.Warning("[GameDB] Skipping setting Speedhack '%s' to [mode=%d]",
Console.Warning("GameDB: Skipping setting Speedhack '%s' to [mode=%d]",
Pcsx2Config::SpeedhackOptions::GetSpeedHackName(it.first), it.second);
continue;
}
// Legacy note - speedhacks are setup in the GameDB as integer values, but
// are effectively booleans like the gamefixes
config.Speedhacks.Set(it.first, it.second);
Console.WriteLn("(GameDB) Setting Speedhack '%s' to [mode=%d]",
Console.WriteLn("GameDB: Setting Speedhack '%s' to [mode=%d]",
Pcsx2Config::SpeedhackOptions::GetSpeedHackName(it.first), it.second);
}
@@ -559,12 +559,12 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
{
if (!applyAuto)
{
Console.Warning("[GameDB] Skipping Gamefix: %s", Pcsx2Config::GamefixOptions::GetGameFixName(id));
Console.Warning("GameDB: Skipping Gamefix: %s", Pcsx2Config::GamefixOptions::GetGameFixName(id));
continue;
}
// if the fix is present, it is said to be enabled
config.Gamefixes.Set(id, true);
Console.WriteLn("(GameDB) Enabled Gamefix: %s", Pcsx2Config::GamefixOptions::GetGameFixName(id));
Console.WriteLn("GameDB: Enabled Gamefix: %s", Pcsx2Config::GamefixOptions::GetGameFixName(id));
// The LUT is only used for 1 game so we allocate it only when the gamefix is enabled (save 4MB)
if (id == Fix_GoemonTlbMiss && true)
@@ -694,7 +694,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
const bool apply_auto_fixes = !config.ManualUserHacks;
const bool is_sw_renderer = EmuConfig.GS.Renderer == GSRendererType::SW;
if (!apply_auto_fixes)
Console.Warning("[GameDB] Manual GS hardware renderer fixes are enabled, not using automatic hardware renderer fixes from GameDB.");
Console.Warning("GameDB: Manual GS hardware renderer fixes are enabled, not using automatic hardware renderer fixes from GameDB.");
for (const auto& [id, value] : gsHWFixes)
{
@@ -703,7 +703,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
if (configMatchesHWFix(config, id, value))
continue;
Console.Warning("[GameDB] Skipping GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
Console.Warning("GameDB: Skipping GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
fmt::format_to(std::back_inserter(disabled_fixes), "{} {} = {}", disabled_fixes.empty() ? " " : "\n ", getHWFixName(id), value);
continue;
}
@@ -790,7 +790,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
if (config.TriFilter == TriFiltering::Automatic)
config.TriFilter = static_cast<TriFiltering>(value);
else if (config.TriFilter > TriFiltering::Off)
Console.Warning("[GameDB] Game requires trilinear filtering to be disabled.");
Console.Warning("GameDB: Game requires trilinear filtering to be disabled.");
}
}
break;
@@ -832,7 +832,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
if (config.InterlaceMode == GSInterlaceMode::Automatic)
config.InterlaceMode = static_cast<GSInterlaceMode>(value);
else
Console.Warning("[GameDB] Game requires different deinterlace mode but it has been overridden by user setting.");
Console.Warning("GameDB: Game requires different deinterlace mode but it has been overridden by user setting.");
}
}
break;
@@ -919,7 +919,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
break;
}
Console.WriteLn("[GameDB] Enabled GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
Console.WriteLn("GameDB: Enabled GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
}
// fixup skipdraw range just in case the db has a bad range (but the linter should catch this)
@@ -954,7 +954,7 @@ void GameDatabase::initDatabase()
auto buf = FileSystem::ReadFileToString(Path::Combine(EmuFolders::Resources, GAMEDB_YAML_FILE_NAME).c_str());
if (!buf.has_value())
{
Console.Error("[GameDB] Unable to open GameDB file, file does not exist.");
Console.Error("GameDB: Unable to open GameDB file, file does not exist.");
return;
}
@@ -971,7 +971,7 @@ void GameDatabase::initDatabase()
// However, YAML's keys are as expected case-sensitive, so we have to explicitly do our own duplicate checking
if (s_game_db.count(serial) == 1)
{
Console.Error(fmt::format("[GameDB] Duplicate serial '{}' found in GameDB. Skipping, Serials are case-insensitive!", serial));
Console.Error(fmt::format("GameDB: Duplicate serial '{}' found in GameDB. Skipping, Serials are case-insensitive!", serial));
continue;
}
@@ -988,9 +988,9 @@ void GameDatabase::ensureLoaded()
{
std::call_once(s_load_once_flag, []() {
Common::Timer timer;
Console.WriteLn(fmt::format("[GameDB] Has not been initialized yet, initializing..."));
Console.WriteLn(fmt::format("GameDB: Has not been initialized yet, initializing..."));
initDatabase();
Console.WriteLn("[GameDB] %zu games on record (loaded in %.2fms)", s_game_db.size(), timer.GetTimeMilliseconds());
Console.WriteLn("GameDB: %zu games on record (loaded in %.2fms)", s_game_db.size(), timer.GetTimeMilliseconds());
});
}
@@ -1115,7 +1115,7 @@ bool GameDatabase::loadHashDatabase()
auto buf = FileSystem::ReadFileToString(Path::Combine(EmuFolders::Resources, HASHDB_YAML_FILE_NAME).c_str());
if (!buf.has_value())
{
Console.Error("[GameDB] Unable to open hash database file, file does not exist.");
Console.Error("GameDB: Unable to open hash database file, file does not exist.");
return false;
}

View File

@@ -540,14 +540,14 @@ bool SDLInputSource::ProcessSDLEvent(const SDL_Event* event)
{
case SDL_CONTROLLERDEVICEADDED:
{
Console.WriteLn("(SDLInputSource) Controller %d inserted", event->cdevice.which);
Console.WriteLn("SDLInputSource: Controller %d inserted", event->cdevice.which);
OpenDevice(event->cdevice.which, true);
return true;
}
case SDL_CONTROLLERDEVICEREMOVED:
{
Console.WriteLn("(SDLInputSource) Controller %d removed", event->cdevice.which);
Console.WriteLn("SDLInputSource: Controller %d removed", event->cdevice.which);
CloseDevice(event->cdevice.which);
return true;
}
@@ -558,7 +558,7 @@ bool SDLInputSource::ProcessSDLEvent(const SDL_Event* event)
if (SDL_IsGameController(event->jdevice.which))
return false;
Console.WriteLn("(SDLInputSource) Joystick %d inserted", event->jdevice.which);
Console.WriteLn("SDLInputSource: Joystick %d inserted", event->jdevice.which);
OpenDevice(event->cdevice.which, false);
return true;
}
@@ -569,7 +569,7 @@ bool SDLInputSource::ProcessSDLEvent(const SDL_Event* event)
if (auto it = GetControllerDataForJoystickId(event->cdevice.which); it != m_controllers.end() && it->game_controller)
return false;
Console.WriteLn("(SDLInputSource) Joystick %d removed", event->jdevice.which);
Console.WriteLn("SDLInputSource: Joystick %d removed", event->jdevice.which);
CloseDevice(event->cdevice.which);
return true;
}
@@ -657,7 +657,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
if (!gcontroller && !joystick)
{
ERROR_LOG("(SDLInputSource) Failed to open controller {}", index);
ERROR_LOG("SDLInputSource: Failed to open controller {}", index);
return false;
}
@@ -667,7 +667,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
{
if (it->joystick_id == joystick_id)
{
ERROR_LOG("(SDLInputSource) Controller {}, instance {}, player {} already connected, ignoring.", index, joystick_id, player_id);
ERROR_LOG("SDLInputSource: Controller {}, instance {}, player {} already connected, ignoring.", index, joystick_id, player_id);
if (gcontroller)
SDL_GameControllerClose(gcontroller);
else
@@ -680,7 +680,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
if (player_id < 0 || GetControllerDataForPlayerId(player_id) != m_controllers.end())
{
const int free_player_id = GetFreePlayerId();
WARNING_LOG("(SDLInputSource) Controller {} (joystick {}) returned player ID {}, which is invalid or in "
WARNING_LOG("SDLInputSource: Controller {} (joystick {}) returned player ID {}, which is invalid or in "
"use. Using ID {} instead.",
index, joystick_id, player_id, free_player_id);
player_id = free_player_id;
@@ -690,7 +690,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
if (!name)
name = "Unknown Device";
INFO_LOG("(SDLInputSource) Opened {} {} (instance id {}, player id {}): {}", is_gamecontroller ? "game controller" : "joystick",
INFO_LOG("SDLInputSource: Opened {} {} (instance id {}, player id {}): {}", is_gamecontroller ? "game controller" : "joystick",
index, joystick_id, player_id, name);
ControllerData cd = {};
@@ -717,7 +717,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
for (size_t i = 0; i < std::size(s_sdl_button_names); i++)
mark_bind(SDL_GameControllerGetBindForButton(gcontroller, static_cast<SDL_GameControllerButton>(i)));
INFO_LOG("(SDLInputSource) Controller {} has {} axes and {} buttons", player_id, num_axes, num_buttons);
INFO_LOG("SDLInputSource: Controller {} has {} axes and {} buttons", player_id, num_axes, num_buttons);
}
else
{
@@ -726,14 +726,14 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
if (num_hats > 0)
cd.last_hat_state.resize(static_cast<size_t>(num_hats), u8(0));
INFO_LOG("(SDLInputSource) Joystick {} has {} axes, {} buttons and {} hats", player_id,
INFO_LOG("SDLInputSource: Joystick {} has {} axes, {} buttons and {} hats", player_id,
SDL_JoystickNumAxes(joystick), SDL_JoystickNumButtons(joystick), num_hats);
}
cd.use_game_controller_rumble = (gcontroller && SDL_GameControllerRumble(gcontroller, 0, 0, 0) == 0);
if (cd.use_game_controller_rumble)
{
INFO_LOG("(SDLInputSource) Rumble is supported on '{}' via gamecontroller", name);
INFO_LOG("SDLInputSource: Rumble is supported on '{}' via gamecontroller", name);
}
else
{
@@ -752,25 +752,25 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
}
else
{
ERROR_LOG("(SDLInputSource) Failed to create haptic left/right effect: {}", SDL_GetError());
ERROR_LOG("SDLInputSource: Failed to create haptic left/right effect: {}", SDL_GetError());
if (SDL_HapticRumbleSupported(haptic) && SDL_HapticRumbleInit(haptic) != 0)
{
cd.haptic = haptic;
}
else
{
ERROR_LOG("(SDLInputSource) No haptic rumble supported: {}", SDL_GetError());
ERROR_LOG("SDLInputSource: No haptic rumble supported: {}", SDL_GetError());
SDL_HapticClose(haptic);
}
}
}
if (cd.haptic)
INFO_LOG("(SDLInputSource) Rumble is supported on '{}' via haptic", name);
INFO_LOG("SDLInputSource: Rumble is supported on '{}' via haptic", name);
}
if (!cd.haptic && !cd.use_game_controller_rumble)
WARNING_LOG("(SDLInputSource) Rumble is not supported on '{}'", name);
WARNING_LOG("SDLInputSource: Rumble is not supported on '{}'", name);
if (player_id >= 0 && static_cast<u32>(player_id) < MAX_LED_COLORS && gcontroller && SDL_GameControllerHasLED(gcontroller))
{

View File

@@ -237,7 +237,7 @@ static void doBranch(s32 tar) {
// This detects when SYSMEM is called and clears the modules then
if(tar == 0x890)
{
DevCon.WriteLn(Color_Gray, "[R3000 Debugger] Branch to 0x890 (SYSMEM). Clearing modules.");
DevCon.WriteLn(Color_Gray, "R3000 Debugger: Branch to 0x890 (SYSMEM). Clearing modules.");
R3000SymbolGuardian.ClearIrxModules();
}

View File

@@ -36,6 +36,8 @@ u32 EEoCycle;
alignas(16) cpuRegistersPack _cpuRegistersPack;
alignas(16) tlbs tlb[48];
cachedTlbs_t cachedTlbs;
R5900cpu *Cpu = NULL;
static constexpr uint eeWaitCycles = 3072;
@@ -59,6 +61,7 @@ void cpuReset()
std::memset(&cpuRegs, 0, sizeof(cpuRegs));
std::memset(&fpuRegs, 0, sizeof(fpuRegs));
std::memset(&tlb, 0, sizeof(tlb));
cachedTlbs.count = 0;
cpuRegs.pc = 0xbfc00000; //set pc reg to stack
cpuRegs.CP0.n.Config = 0x440;

View File

@@ -5,6 +5,8 @@
#include "common/Pcsx2Defs.h"
#include <array>
// --------------------------------------------------------------------------------------
// EE Bios function name tables.
// --------------------------------------------------------------------------------------
@@ -160,17 +162,68 @@ struct fpuRegisters {
u32 ACCflag; // an internal accumulator overflow flag
};
union PageMask_t
{
struct
{
u32 : 13;
u32 Mask : 12;
u32 : 7;
};
u32 UL;
};
union EntryHi_t
{
struct
{
u32 ASID:8;
u32 : 5;
u32 VPN2:19;
};
u32 UL;
};
union EntryLo_t
{
struct
{
u32 G:1;
u32 V:1;
u32 D:1;
u32 C:3;
u32 PFN:20;
u32 : 5;
u32 S : 1; // Only used in EntryLo0
};
u32 UL;
constexpr bool isCached() const { return C == 0x3; }
constexpr bool isValidCacheMode() const { return C == 0x2 || C == 0x3 || C == 0x7; }
};
struct tlbs
{
u32 PageMask,EntryHi;
u32 EntryLo0,EntryLo1;
u32 Mask, nMask;
u32 G;
u32 ASID;
u32 VPN2;
u32 PFN0;
u32 PFN1;
u32 S;
PageMask_t PageMask;
EntryHi_t EntryHi;
EntryLo_t EntryLo0;
EntryLo_t EntryLo1;
// (((cpuRegs.CP0.n.EntryLo0 >> 6) & 0xFFFFF) & (~tlb[i].Mask())) << 12;
constexpr u32 PFN0() const { return (EntryLo0.PFN & ~Mask()) << 12; }
constexpr u32 PFN1() const { return (EntryLo1.PFN & ~Mask()) << 12; }
constexpr u32 VPN2() const {return ((EntryHi.VPN2) & (~Mask())) << 13; }
constexpr u32 Mask() const { return PageMask.Mask; }
constexpr bool isGlobal() const { return EntryLo0.G && EntryLo1.G; }
constexpr bool isSPR() const { return EntryLo0.S; }
constexpr bool operator==(const tlbs& other) const
{
return PageMask.UL == other.PageMask.UL &&
EntryHi.UL == other.EntryHi.UL &&
EntryLo0.UL == other.EntryLo0.UL &&
EntryLo1.UL == other.EntryLo1.UL;
}
};
#ifndef _PC_
@@ -211,6 +264,19 @@ struct cpuRegistersPack
alignas(16) extern cpuRegistersPack _cpuRegistersPack;
alignas(16) extern tlbs tlb[48];
struct cachedTlbs_t
{
u32 count;
alignas(16) std::array<u32, 48> PageMasks;
alignas(16) std::array<u32, 48> PFN1s;
alignas(16) std::array<u32, 48> CacheEnabled1;
alignas(16) std::array<u32, 48> PFN0s;
alignas(16) std::array<u32, 48> CacheEnabled0;
};
extern cachedTlbs_t cachedTlbs;
static cpuRegisters& cpuRegs = _cpuRegistersPack.cpuRegs;
static fpuRegisters& fpuRegs = _cpuRegistersPack.fpuRegs;

View File

@@ -260,11 +260,11 @@ void FolderMemoryCard::LoadMemoryCardData(const u32 sizeInClusters, const bool e
{
if (enableFiltering)
{
Console.WriteLn(Color_Green, "(FolderMcd) Indexing slot %u with filter \"%s\".", m_slot, filter.c_str());
Console.WriteLn(Color_Green, "FolderMcd: Indexing slot %u with filter \"%s\".", m_slot, filter.c_str());
}
else
{
Console.WriteLn(Color_Green, "(FolderMcd) Indexing slot %u without filter.", m_slot);
Console.WriteLn(Color_Green, "FolderMcd: Indexing slot %u without filter.", m_slot);
}
CreateFat();
@@ -636,7 +636,7 @@ bool FolderMemoryCard::AddFile(MemoryCardFileEntry* const dirEntry, const std::s
}
else
{
Console.WriteLn("(FolderMcd) Could not open file: %s", relativeFilePath.c_str());
Console.WriteLn("FolderMcd: Could not open file: %s", relativeFilePath.c_str());
return false;
}
}
@@ -1082,7 +1082,7 @@ void FolderMemoryCard::Flush()
WriteToFile(m_folderName.GetFullPath().RemoveLast() + L"-debug_" + wxDateTime::Now().Format(L"%Y-%m-%d-%H-%M-%S") + L"_pre-flush.ps2");
#endif
Console.WriteLn("(FolderMcd) Writing data for slot %u to file system...", m_slot);
Console.WriteLn("FolderMcd: Writing data for slot %u to file system...", m_slot);
Common::Timer timeFlushStart;
// Keep a copy of the old file entries so we can figure out which files and directories, if any, have been deleted from the memory card.
@@ -1104,7 +1104,7 @@ void FolderMemoryCard::Flush()
FlushBlock(m_superBlock.data.backup_block2);
if (m_backupBlock2.programmedBlock != 0xFFFFFFFFu)
{
Console.Warning("(FolderMcd) Aborting flush of slot %u, emulation was interrupted during save process!", m_slot);
Console.Warning("FolderMcd: Aborting flush of slot %u, emulation was interrupted during save process!", m_slot);
return;
}
@@ -1150,7 +1150,7 @@ void FolderMemoryCard::Flush()
m_lastAccessedFile.ClearMetadataWriteState();
m_oldDataCache.clear();
Console.WriteLn("(FolderMcd) Done! Took %.2f ms.", timeFlushStart.GetTimeMilliseconds());
Console.WriteLn("FolderMcd: Done! Took %.2f ms.", timeFlushStart.GetTimeMilliseconds());
#ifdef DEBUG_WRITE_FOLDER_CARD_IN_MEMORY_TO_FILE_ON_CHANGE
WriteToFile(m_folderName.GetFullPath().RemoveLast() + L"-debug_" + wxDateTime::Now().Format(L"%Y-%m-%d-%H-%M-%S") + L"_post-flush.ps2");
@@ -1763,7 +1763,7 @@ std::string FolderMemoryCard::GetDisabledMessage(uint slot) const
std::string FolderMemoryCard::GetCardFullMessage(const std::string& filePath) const
{
return fmt::format("(FolderMcd) Memory Card is full, could not add: {}", filePath);
return fmt::format("FolderMcd: Memory Card is full, could not add: {}", filePath);
}
std::vector<FolderMemoryCard::EnumeratedFileEntry> FolderMemoryCard::GetOrderedFiles(const std::string& dirPath) const

View File

@@ -145,7 +145,7 @@ void PadDualshock2::ConfigLog()
// VS: Vibration Small (how is the small vibration motor mapped)
// VL: Vibration Large (how is the large vibration motor mapped)
// RB: Response Bytes (what data is included in the controller's responses - D = Digital, A = Analog, P = Pressure)
Console.WriteLn(fmt::format("[Pad] DS2 Config Finished - P{0}/S{1} - AL: {2} - AB: {3} - VS: {4} - VL: {5} - RB: {6} (0x{7:08X})",
Console.WriteLn(fmt::format("Pad: DS2 Config Finished - P{0}/S{1} - AL: {2} - AB: {3} - VS: {4} - VL: {5} - RB: {6} (0x{7:08X})",
port + 1,
slot + 1,
(this->analogLight ? "On" : "Off"),

View File

@@ -47,7 +47,7 @@ void PadGuitar::ConfigLog()
// AL: Analog Light (is it turned on right now)
// AB: Analog Button (is it useable or is it locked in its current state)
Console.WriteLn(fmt::format("[Pad] Guitar Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
Console.WriteLn(fmt::format("Pad: Guitar Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
port + 1,
slot + 1,
(this->analogLight ? "On" : "Off"),

View File

@@ -53,7 +53,7 @@ void PadJogcon::ConfigLog()
// AL: Analog Light (is it turned on right now)
// AB: Analog Button (is it useable or is it locked in its current state)
Console.WriteLn(fmt::format("[Pad] Jogcon Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
Console.WriteLn(fmt::format("Pad: Jogcon Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
port + 1,
slot + 1,
(this->analogLight ? "On" : "Off"),

View File

@@ -50,7 +50,7 @@ void PadNegcon::ConfigLog()
// AL: Analog Light (is it turned on right now)
// AB: Analog Button (is it useable or is it locked in its current state)
Console.WriteLn(fmt::format("[Pad] Negcon Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
Console.WriteLn(fmt::format("Pad: Negcon Config Finished - P{0}/S{1} - AL: {2} - AB: {3}",
port + 1,
slot + 1,
(this->analogLight ? "On" : "Off"),

View File

@@ -56,7 +56,7 @@ void PadPopn::ConfigLog()
// AL: Analog Light (is it turned on right now)
// AB: Analog Button (is it useable or is it locked in its current state)
// RB: Response Bytes (what data is included in the controller's responses - D = Digital, A = Analog, P = Pressure)
Console.WriteLn(fmt::format("[Pad] Pop'n Config Finished - P{0}/S{1} - AL: {2} - AB: {3} - RB: {4} (0x{5:08X})",
Console.WriteLn(fmt::format("Pad: Pop'n Config Finished - P{0}/S{1} - AL: {2} - AB: {3} - RB: {4} (0x{5:08X})",
port + 1,
slot + 1,
(this->analogLight ? "On" : "Off"),

View File

@@ -183,6 +183,7 @@ bool SaveStateBase::FreezeInternals(Error* error)
Freeze(psxRegs); // iop regs
Freeze(fpuRegs);
Freeze(tlb); // tlbs
Freeze(cachedTlbs); // cached tlbs
Freeze(AllowParams1); //OSDConfig written (Fast Boot)
Freeze(AllowParams2);

View File

@@ -25,7 +25,7 @@ enum class FreezeAction
// [SAVEVERSION+]
// This informs the auto updater that the users savestates will be invalidated.
static const u32 g_SaveVersion = (0x9A52 << 16) | 0x0000;
static const u32 g_SaveVersion = (0x9A53 << 16) | 0x0000;
// the freezing data between submodules and core

View File

@@ -415,6 +415,10 @@ bool VMManager::Internal::CPUThreadInitialize()
if (EmuConfig.EnableDiscordPresence)
InitializeDiscordPresence();
// Check for advanced settings status and warn the user if its enabled
if (Host::GetBaseBoolSettingValue("UI", "ShowAdvancedSettings", false))
Console.Warning("Settings: Advanced Settings are enabled; only proceed if you know what you're doing! No support will be provided if you have the option enabled.");
return true;
}

View File

@@ -30,6 +30,7 @@
#include "fmt/core.h"
#include <bit>
#include <immintrin.h>
#include <map>
#include <unordered_set>
#include <unordered_map>
@@ -109,46 +110,77 @@ vtlb_private::VTLBVirtual::VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr)
}
}
__inline int ConvertPageMask(u32 PageMask)
{
const u32 mask = std::popcount(PageMask >> 13);
pxAssertMsg(!((mask & 1) || mask > 12), "Invalid page mask for this TLB entry. EE cache doesn't know what to do here.");
return (1 << (12 + mask)) - 1;
}
__inline int CheckCache(u32 addr)
{
u32 mask;
// Check if the cache is enabled
if (((cpuRegs.CP0.n.Config >> 16) & 0x1) == 0)
{
//DevCon.Warning("Data Cache Disabled! %x", cpuRegs.CP0.n.Config);
return false; //
return false;
}
for (int i = 1; i < 48; i++)
const size_t size = cachedTlbs.count;
const int stride = 4;
__m128i addr_vec = _mm_set1_epi32(addr);
size_t i = 0;
for (; i + stride <= size; i += stride)
{
if (((tlb[i].EntryLo1 & 0x38) >> 3) == 0x3)
const __m128i pfn1_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PFN1s[i]));
const __m128i pfn0_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PFN0s[i]));
const __m128i mask_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PageMasks[i]));
const __m128i cached1_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.CacheEnabled1[i]));
const __m128i cached0_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.CacheEnabled0[i]));
const __m128i pfn1_end_vec = _mm_add_epi32(pfn1_vec, mask_vec);
const __m128i pfn0_end_vec = _mm_add_epi32(pfn0_vec, mask_vec);
// pfn0 <= addr
const __m128i gteLowerBound0 = _mm_or_si128(
_mm_cmpgt_epi32(addr_vec, pfn0_vec),
_mm_cmpeq_epi32(addr_vec, pfn0_vec));
// pfn0 + mask >= addr
const __m128i gteUpperBound0 = _mm_or_si128(
_mm_cmpgt_epi32(pfn0_end_vec, addr_vec),
_mm_cmpeq_epi32(pfn0_end_vec, addr_vec));
// pfn1 <= addr
const __m128i gteUpperBound1 = _mm_or_si128(
_mm_cmpgt_epi32(pfn1_end_vec, addr_vec),
_mm_cmpeq_epi32(pfn1_end_vec, addr_vec));
// pfn1 + mask >= addr
const __m128i gteLowerBound1 = _mm_or_si128(
_mm_cmpgt_epi32(addr_vec, pfn1_vec),
_mm_cmpeq_epi32(addr_vec, pfn1_vec));
// pfn0 <= addr <= pfn0 + mask
__m128i cmp0 = _mm_and_si128(gteLowerBound0, gteUpperBound0);
// pfn1 <= addr <= pfn1 + mask
__m128i cmp1 = _mm_and_si128(gteLowerBound1, gteUpperBound1);
cmp1 = _mm_and_si128(cmp1, cached1_vec);
cmp0 = _mm_and_si128(cmp0, cached0_vec);
const __m128i cmp = _mm_or_si128(cmp1, cmp0);
if (!_mm_testz_si128(cmp, cmp))
{
mask = ConvertPageMask(tlb[i].PageMask);
if ((addr >= tlb[i].PFN1) && (addr <= tlb[i].PFN1 + mask))
{
//DevCon.Warning("Yay! Cache check cache addr=%x, mask=%x, addr+mask=%x, VPN2=%x PFN0=%x", addr, mask, (addr & mask), tlb[i].VPN2, tlb[i].PFN0);
return true;
}
}
if (((tlb[i].EntryLo0 & 0x38) >> 3) == 0x3)
{
mask = ConvertPageMask(tlb[i].PageMask);
if ((addr >= tlb[i].PFN0) && (addr <= tlb[i].PFN0 + mask))
{
//DevCon.Warning("Yay! Cache check cache addr=%x, mask=%x, addr+mask=%x, VPN2=%x PFN0=%x", addr, mask, (addr & mask), tlb[i].VPN2, tlb[i].PFN0);
return true;
}
return true;
}
}
for (; i < size; i++)
{
const u32 mask = cachedTlbs.PageMasks[i];
if ((cachedTlbs.CacheEnabled1[i] && addr >= cachedTlbs.PFN1s[i] && addr <= cachedTlbs.PFN1s[i] + mask) ||
(cachedTlbs.CacheEnabled0[i] && addr >= cachedTlbs.PFN0s[i] && addr <= cachedTlbs.PFN0s[i] + mask))
{
return true;
}
}
return false;
}
// --------------------------------------------------------------------------------------

View File

@@ -1543,7 +1543,7 @@ static void iopRecRecompile(const u32 startpc)
// This detects when SYSMEM is called and clears the modules then
if(startpc == 0x890)
{
DevCon.WriteLn(Color_Gray, "[R3000 Debugger] Branch to 0x890 (SYSMEM). Clearing modules.");
DevCon.WriteLn(Color_Gray, "R3000 Debugger: Branch to 0x890 (SYSMEM). Clearing modules.");
R3000SymbolGuardian.ClearIrxModules();
}