BIOS/HLE: Improve handling of OSD params when fast booting

This commit is contained in:
refractionpcsx2 2024-04-21 03:28:58 +01:00
parent 0acc91403d
commit b44d479921
4 changed files with 140 additions and 21 deletions

View File

@ -80,6 +80,7 @@ void cpuReset()
AllowParams1 = !VMManager::Internal::IsFastBootInProgress();
AllowParams2 = !VMManager::Internal::IsFastBootInProgress();
ParamsRead = false;
g_eeloadMain = 0;
g_eeloadExec = 0;

View File

@ -8,7 +8,6 @@
#include "R5900.h"
#include "R5900OpcodeTables.h"
#include "GS.h"
#include "CDVD/CDVD.h"
#include "ps2/BiosTools.h"
#include "DebugTools/DebugInterface.h"
#include "DebugTools/Breakpoints.h"
@ -955,43 +954,67 @@ void SYSCALL()
}
break;
case Syscall::SetOsdConfigParam:
// The whole thing gets written back to BIOS memory, so it'll be in the right place, no need to continue HLEing
AllowParams1 = true;
break;
case Syscall::GetOsdConfigParam:
if (!NoOSD && !AllowParams1)
{
ReadOSDConfigParames();
u32 memaddr = cpuRegs.GPR.n.a0.UL[0];
u8 params[16];
cdvdReadLanguageParams(params);
memWrite32(memaddr, configParams1.UL[0]);
u32 osdconf = 0;
u32 timezone = params[4] | ((u32)(params[3] & 0x7) << 8);
// Call the set function, as we need to set this back to the BIOS storage position.
if (cpuRegs.GPR.n.v1.SL[0] < 0)
cpuRegs.GPR.n.v1.SL[0] = -Syscall::SetOsdConfigParam;
else
cpuRegs.GPR.n.v1.UC[0] = Syscall::SetOsdConfigParam;
osdconf |= params[1] & 0x1F; // SPDIF, Screen mode, RGB/Comp, Jap/Eng Switch (Early bios)
osdconf |= (u32)params[0] << 5; // PS1 Mode Settings
osdconf |= (u32)((params[2] & 0xE0) >> 5) << 13; // OSD Ver (Not sure but best guess)
osdconf |= (u32)(params[2] & 0x1F) << 16; // Language
osdconf |= timezone << 21; // Timezone
memWrite32(memaddr, osdconf);
return;
AllowParams1 = true;
}
break;
case Syscall::SetOsdConfigParam2:
if (!AllowParams2)
{
ReadOSDConfigParames();
u32 memaddr = cpuRegs.GPR.n.a0.UL[0];
u32 size = cpuRegs.GPR.n.a1.UL[0];
u32 offset = cpuRegs.GPR.n.a2.UL[0];
if (offset == 0 && size >= 4)
AllowParams2 = true;
for (u32 i = 0; i < size; i++)
{
if (offset >= 4)
break;
configParams2.UC[offset++] = memRead8(memaddr++);
}
}
break;
case Syscall::GetOsdConfigParam2:
if (!NoOSD && !AllowParams2)
{
ReadOSDConfigParames();
u32 memaddr = cpuRegs.GPR.n.a0.UL[0];
u8 params[16];
u32 size = cpuRegs.GPR.n.a1.UL[0];
u32 offset = cpuRegs.GPR.n.a2.UL[0];
cdvdReadLanguageParams(params);
if (offset + size > 2)
Console.Warning("Warning: GetOsdConfigParam2 Reading extended language/version configs, may be incorrect!");
u32 osdconf2 = (((u32)params[3] & 0x78) << 9); // Daylight Savings, 24hr clock, Date format
memWrite32(memaddr, osdconf2);
for (u32 i = 0; i < size; i++)
{
if (offset >= 4)
memWrite8(memaddr++, 0);
else
memWrite8(memaddr++, configParams2.UC[offset++]);
}
return;
}
break;

View File

@ -7,6 +7,7 @@
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "CDVD/CDVD.h"
#include "Common.h"
#include "BiosTools.h"
@ -36,6 +37,9 @@ static_assert(sizeof(romdir) == DIRENTRY_SIZE, "romdir struct not packed to 16 b
u32 BiosVersion;
u32 BiosChecksum;
u32 BiosRegion;
ConfigParam configParams1;
Config2Param configParams2;
bool ParamsRead;
bool NoOSD;
bool AllowParams1;
bool AllowParams2;
@ -46,6 +50,29 @@ std::string BiosPath;
BiosDebugInformation CurrentBiosInformation;
std::vector<u8> BiosRom;
void ReadOSDConfigParames()
{
if (ParamsRead)
return;
ParamsRead = true;
u8 params[16];
cdvdReadLanguageParams(params);
configParams1.UC[0] = params[1] & 0x1F; // SPDIF, Screen mode, RGB/Comp, Jap/Eng Switch (Early bios).
configParams1.ps1drvConfig = params[0]; // PS1 Mode Settings.
configParams1.version = (params[2] & 0xE0) >> 5; // OSD Ver (Not sure but best guess).
configParams1.language = params[2] & 0x1F; // Language.
configParams1.timezoneOffset = params[4] | ((u32)(params[3] & 0x7) << 8); // Timezone offset in minutes.
// Region settings for time/date and extended language
configParams2.UC[1] = ((u32)params[3] & 0x78) << 1; // Daylight Savings, 24hr clock, Date format
// FIXME: format, version and language are set manually by the bios. Not sure if any game needs them, but it seems to set version to 2 and duplicate the language value.
configParams2.version = 2;
configParams2.language = configParams1.language;
}
static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& description, u32& region, std::string& zone, std::string& serial)
{
romdir rd;

View File

@ -20,11 +20,77 @@ struct BiosDebugInformation
u32 iopModListAddr;
};
// Obained from the Open PS2SDK here https://github.com/ps2dev/ps2sdk/blob/master/ee/kernel/include/osd_config.h
// Only used for HLEing ConfigParam Syscalls in fast boot
typedef struct
{
union
{
struct
{
/** 0=enabled, 1=disabled */
/*00*/ u32 spdifMode : 1;
/** 0=4:3, 1=fullscreen, 2=16:9 */
/*01*/ u32 screenType : 2;
/** 0=rgb(scart), 1=component */
/*03*/ u32 videoOutput : 1;
/** 0=japanese, 1=english(non-japanese) */
/*04*/ u32 japLanguage : 1;
/** Playstation driver settings. */
/*05*/ u32 ps1drvConfig : 8;
/** 0 = early Japanese OSD, 1 = OSD2, 2 = OSD2 with extended languages. Early kernels cannot retain the value set in this field (Hence always 0). */
/*13*/ u32 version : 3;
/** LANGUAGE_??? value */
/*16*/ u32 language : 5;
/** timezone minutes offset from gmt */
/*21*/ u32 timezoneOffset : 11;
};
u8 UC[4];
u16 US[2];
u32 UL[1];
};
} ConfigParam;
typedef struct
{
union
{
struct
{
// This value is unknown, seems to be set to zero by default
/*00*/ u8 format;
/*00*/ u8 reserved : 4;
/** 0=standard(winter), 1=daylight savings(summer) */
/*04*/ u8 daylightSaving : 1;
/** 0=24 hour, 1=12 hour */
/*05*/ u8 timeFormat : 1;
/** 0=YYYYMMDD, 1=MMDDYYYY, 2=DDMMYYYY */
/*06*/ u8 dateFormat : 2;
// Only used if ConfigParam.version = 2
/** Set to 2 */
/*00*/ u8 version;
/** The true language, unlike the one from ConfigParam */
/*00*/ u8 language;
};
u8 UC[4];
u16 US[2];
u32 UL[1];
};
} Config2Param;
// End of OpenSDK struct
// TODO: namespace this
extern BiosDebugInformation CurrentBiosInformation;
extern u32 BiosVersion; // Used by CDVD
extern u32 BiosRegion; // Used by CDVD
extern bool NoOSD; // Used for HLE OSD Config Params
extern ConfigParam configParams1;
extern Config2Param configParams2;
extern bool ParamsRead;
extern bool AllowParams1;
extern bool AllowParams2;
extern u32 BiosChecksum;
@ -44,6 +110,8 @@ extern std::string BiosPath;
// If we ever support read-only physical mappings, we can remove this.
extern std::vector<u8> BiosRom;
extern void ReadOSDConfigParames();
extern bool IsBIOS(const char* filename, u32& version, std::string& description, u32& region, std::string& zone);
extern bool IsBIOSAvailable(const std::string& full_path);