diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpdouble.cpp | 6 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpsingle.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/function_wrappers.h | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/process.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg.cpp | 139 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg.h | 164 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg_i.cpp | 57 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg_s.cpp | 62 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg_u.cpp | 219 | ||||
-rw-r--r-- | src/core/hle/svc.cpp | 14 | ||||
-rw-r--r-- | src/video_core/command_processor.cpp | 44 | ||||
-rw-r--r-- | src/video_core/pica.h | 2 |
12 files changed, 354 insertions, 369 deletions
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index ab9fec39d..f91049585 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp @@ -531,7 +531,7 @@ static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vdm.sign = (m & 0x80000000) >> 16; vdm.exponent = 1023 + 63 - 1; - vdm.significand = vdm.sign ? -m : m; + vdm.significand = vdm.sign ? (~m + 1) : m; return vfp_double_normaliseround(state, dd, &vdm, fpscr, 0, "fsito"); } @@ -669,7 +669,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 exceptions |= FPSCR_IXC; if (vdm.sign) - d = -d; + d = (~d + 1); } else { d = 0; if (vdm.exponent | vdm.significand) { @@ -817,7 +817,7 @@ u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_dou m_sig = vdn->significand - m_sig; if ((s64)m_sig < 0) { vdd->sign = vfp_sign_negate(vdd->sign); - m_sig = -m_sig; + m_sig = (~m_sig + 1); } else if (m_sig == 0) { vdd->sign = (fpscr & FPSCR_RMODE_MASK) == FPSCR_ROUND_MINUSINF ? 0x8000 : 0; diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index 4dfe0254d..a692c1909 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp @@ -388,7 +388,7 @@ sqrt_invalid: } else { u64 term; s64 rem; - vsm.significand <<= !(vsm.exponent & 1); + vsm.significand <<= static_cast<u32>((vsm.exponent & 1) == 0); term = (u64)vsd.significand * vsd.significand; rem = ((u64)vsm.significand << 32) - term; @@ -691,7 +691,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f exceptions |= FPSCR_IXC; if (vsm.sign) - d = 0-d; + d = (~d + 1); } else { d = 0; if (vsm.exponent | vsm.significand) { @@ -843,7 +843,7 @@ vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, m_sig = vsn->significand - m_sig; if ((s32)m_sig < 0) { vsd->sign = vfp_sign_negate(vsd->sign); - m_sig = 0-m_sig; + m_sig = (~m_sig + 1); } else if (m_sig == 0) { vsd->sign = (fpscr & FPSCR_RMODE_MASK) == FPSCR_ROUND_MINUSINF ? 0x8000 : 0; diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index 0e5ae29ae..23c86a72d 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -166,6 +166,10 @@ template<void func(const char*)> void Wrap() { func((char*)Memory::GetPointer(PARAM(0))); } +template<void func(u8)> void Wrap() { + func((u8)PARAM(0)); +} + #undef PARAM #undef FuncReturn diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b5c87e883..b0e75ba59 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -28,7 +28,7 @@ SharedPtr<Process> Process::Create(std::string name, u64 program_id) { } void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { - for (int i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) { u32 descriptor = kernel_caps[i]; u32 type = descriptor >> 20; @@ -65,8 +65,8 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { AddressMapping mapping; mapping.address = descriptor << 12; mapping.size = (end_desc << 12) - mapping.address; - mapping.writable = descriptor & (1 << 20); - mapping.unk_flag = end_desc & (1 << 20); + mapping.writable = (descriptor & (1 << 20)) != 0; + mapping.unk_flag = (end_desc & (1 << 20)) != 0; address_mappings.push_back(mapping); } else if ((type & 0xFFF) == 0xFFE) { // 0x000F diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 2d26c9330..d42682883 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -6,8 +6,11 @@ #include "common/logging/log.h" #include "common/string_util.h" +#include "common/file_util.h" +#include "core/file_sys/archive_systemsavedata.h" #include "core/file_sys/file_backend.h" +#include "core/settings.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" #include "core/hle/service/cfg/cfg_s.h" @@ -23,7 +26,7 @@ const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; const char CONSOLE_USERNAME[0x14] = "CITRA"; -/// This will be initialized in CFGInit, and will be used when creating the block +/// This will be initialized in Init, and will be used when creating the block UsernameBlock CONSOLE_USERNAME_BLOCK; /// TODO(Subv): Find out what this actually is const u8 SOUND_OUTPUT_MODE = 2; @@ -47,6 +50,140 @@ static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; static Service::FS::ArchiveHandle cfg_system_save_data_archive; static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 }; +void GetCountryCodeString(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 country_code_id = cmd_buff[1]; + + if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { + LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); + cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + return; + } + + cmd_buff[1] = 0; + cmd_buff[2] = country_codes[country_code_id]; +} + +void GetCountryCodeID(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u16 country_code = cmd_buff[1]; + u16 country_code_id = 0; + + // The following algorithm will fail if the first country code isn't 0. + DEBUG_ASSERT(country_codes[0] == 0); + + for (u16 id = 0; id < country_codes.size(); ++id) { + if (country_codes[id] == country_code) { + country_code_id = id; + break; + } + } + + if (0 == country_code_id) { + LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, country_code >> 8); + cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + cmd_buff[2] = 0xFFFF; + return; + } + + cmd_buff[1] = 0; + cmd_buff[2] = country_code_id; +} + +void SecureInfoGetRegion(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = Settings::values.region_value; +} + +void GenHashConsoleUnique(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 app_id_salt = cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0x33646D6F ^ (app_id_salt & 0xFFFFF); // 3dmoo hash + cmd_buff[3] = 0x6F534841 ^ (app_id_salt & 0xFFFFF); + + LOG_WARNING(Service_CFG, "(STUBBED) called app_id_salt=0x%X", app_id_salt); +} + +void GetRegionCanadaUSA(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + + u8 canada_or_usa = 1; + if (canada_or_usa == Settings::values.region_value) { + cmd_buff[2] = 1; + } else { + cmd_buff[2] = 0; + } +} + +void GetSystemModel(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 data; + + // TODO(Subv): Find out the correct error codes + cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, + reinterpret_cast<u8*>(&data)).raw; + cmd_buff[2] = data & 0xFF; +} + +void GetModelNintendo2DS(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 data; + + // TODO(Subv): Find out the correct error codes + cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, + reinterpret_cast<u8*>(&data)).raw; + + u8 model = data & 0xFF; + if (model == Service::CFG::NINTENDO_2DS) + cmd_buff[2] = 0; + else + cmd_buff[2] = 1; +} + +void GetConfigInfoBlk2(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 size = cmd_buff[1]; + u32 block_id = cmd_buff[2]; + u8* data_pointer = Memory::GetPointer(cmd_buff[4]); + + if (data_pointer == nullptr) { + cmd_buff[1] = -1; // TODO(Subv): Find the right error code + return; + } + + cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data_pointer).raw; +} + +void GetConfigInfoBlk8(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 size = cmd_buff[1]; + u32 block_id = cmd_buff[2]; + u8* data_pointer = Memory::GetPointer(cmd_buff[4]); + + if (data_pointer == nullptr) { + cmd_buff[1] = -1; // TODO(Subv): Find the right error code + return; + } + + cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data_pointer).raw; +} + +void UpdateConfigNANDSavegame(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + cmd_buff[1] = Service::CFG::UpdateConfigNANDSavegame().raw; +} + +void FormatConfig(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + cmd_buff[1] = Service::CFG::FormatConfig().raw; +} + ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { // Read the header SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 3488c40d0..ff76dc9dc 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -6,6 +6,7 @@ #include <array> #include "core/hle/result.h" +#include "core/hle/service/service.h" namespace Service { namespace CFG { @@ -40,6 +41,169 @@ struct SaveConfigBlockEntry { u16 flags; ///< The flags of the block, possibly used for access control }; +// TODO(Link Mauve): use a constexpr once MSVC starts supporting it. +#define C(code) ((code)[0] | ((code)[1] << 8)) + +static const std::array<u16, 187> country_codes = { + 0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7 + C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15 + C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23 + C("DO"), C("EC"), C("SV"), C("GF"), C("GD"), C("GP"), C("GT"), C("GY"), // 24-31 + C("HT"), C("HN"), C("JM"), C("MQ"), C("MX"), C("MS"), C("AN"), C("NI"), // 32-39 + C("PA"), C("PY"), C("PE"), C("KN"), C("LC"), C("VC"), C("SR"), C("TT"), // 40-47 + C("TC"), C("US"), C("UY"), C("VI"), C("VE"), 0, 0, 0, // 48-55 + 0, 0, 0, 0, 0, 0, 0, 0, // 56-63 + C("AL"), C("AU"), C("AT"), C("BE"), C("BA"), C("BW"), C("BG"), C("HR"), // 64-71 + C("CY"), C("CZ"), C("DK"), C("EE"), C("FI"), C("FR"), C("DE"), C("GR"), // 72-79 + C("HU"), C("IS"), C("IE"), C("IT"), C("LV"), C("LS"), C("LI"), C("LT"), // 80-87 + C("LU"), C("MK"), C("MT"), C("ME"), C("MZ"), C("NA"), C("NL"), C("NZ"), // 88-95 + C("NO"), C("PL"), C("PT"), C("RO"), C("RU"), C("RS"), C("SK"), C("SI"), // 96-103 + C("ZA"), C("ES"), C("SZ"), C("SE"), C("CH"), C("TR"), C("GB"), C("ZM"), // 104-111 + C("ZW"), C("AZ"), C("MR"), C("ML"), C("NE"), C("TD"), C("SD"), C("ER"), // 112-119 + C("DJ"), C("SO"), C("AD"), C("GI"), C("GG"), C("IM"), C("JE"), C("MC"), // 120-127 + C("TW"), 0, 0, 0, 0, 0, 0, 0, // 128-135 + C("KR"), 0, 0, 0, 0, 0, 0, 0, // 136-143 + C("HK"), C("MO"), 0, 0, 0, 0, 0, 0, // 144-151 + C("ID"), C("SG"), C("TH"), C("PH"), C("MY"), 0, 0, 0, // 152-159 + C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167 + C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 + C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 + C("SM"), C("VA"), C("BM") // 184-186 +}; + +#undef C + +/** + * CFG::GetCountryCodeString service function + * Inputs: + * 1 : Country Code ID + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Country's 2-char string + */ +void GetCountryCodeString(Service::Interface* self); + +/** + * CFG::GetCountryCodeID service function + * Inputs: + * 1 : Country Code 2-char string + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Country Code ID + */ +void GetCountryCodeID(Service::Interface* self); + +/** + * CFG::GetConfigInfoBlk2 service function + * Inputs: + * 0 : 0x00010082 + * 1 : Size + * 2 : Block ID + * 3 : Descriptor for the output buffer + * 4 : Output buffer pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetConfigInfoBlk2(Service::Interface* self); + +/** + * CFG::SecureInfoGetRegion service function + * Inputs: + * 1 : None + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Region value loaded from SecureInfo offset 0x100 + */ +void SecureInfoGetRegion(Service::Interface* self); + +/** + * CFG::GenHashConsoleUnique service function + * Inputs: + * 1 : 20 bit application ID salt + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Hash/"ID" lower word + * 3 : Hash/"ID" upper word + */ +void GenHashConsoleUnique(Service::Interface* self); + +/** + * CFG::GetRegionCanadaUSA service function + * Inputs: + * 1 : None + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : 1 if the system is a Canada or USA model, 0 otherwise + */ +void GetRegionCanadaUSA(Service::Interface* self); + +/** + * CFG::GetSystemModel service function + * Inputs: + * 0 : 0x00050000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Model of the console + */ +void GetSystemModel(Service::Interface* self); + +/** + * CFG::GetModelNintendo2DS service function + * Inputs: + * 0 : 0x00060000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : 0 if the system is a Nintendo 2DS, 1 otherwise + */ +void GetModelNintendo2DS(Service::Interface* self); + +/** + * CFG::GetConfigInfoBlk2 service function + * Inputs: + * 0 : 0x00010082 + * 1 : Size + * 2 : Block ID + * 3 : Descriptor for the output buffer + * 4 : Output buffer pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetConfigInfoBlk2(Service::Interface* self); + +/** + * CFG::GetConfigInfoBlk8 service function + * Inputs: + * 0 : 0x04010082 / 0x08010082 + * 1 : Size + * 2 : Block ID + * 3 : Descriptor for the output buffer + * 4 : Output buffer pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetConfigInfoBlk8(Service::Interface* self); + +/** + * CFG::UpdateConfigNANDSavegame service function + * Inputs: + * 0 : 0x04030000 / 0x08030000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void UpdateConfigNANDSavegame(Service::Interface* self); + +/** + * CFG::FormatConfig service function + * Inputs: + * 0 : 0x08060000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void FormatConfig(Service::Interface* self); + /// The maximum number of block entries that can exist in the config file static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 6d1eee4e0..5aeadc084 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -8,59 +8,6 @@ namespace Service { namespace CFG { - -/** - * CFG_I::GetConfigInfoBlk8 service function - * This function is called by two command headers, - * there appears to be no difference between them according to 3dbrew - * Inputs: - * 0 : 0x04010082 / 0x08010082 - * 1 : Size - * 2 : Block ID - * 3 : Descriptor for the output buffer - * 4 : Output buffer pointer - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetConfigInfoBlk8(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 size = cmd_buffer[1]; - u32 block_id = cmd_buffer[2]; - u8* data_pointer = Memory::GetPointer(cmd_buffer[4]); - - if (data_pointer == nullptr) { - cmd_buffer[1] = -1; // TODO(Subv): Find the right error code - return; - } - - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data_pointer).raw; -} - -/** - * CFG_I::UpdateConfigNANDSavegame service function - * This function is called by two command headers, - * there appears to be no difference between them according to 3dbrew - * Inputs: - * 0 : 0x04030000 / 0x08030000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void UpdateConfigNANDSavegame(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - cmd_buffer[1] = Service::CFG::UpdateConfigNANDSavegame().raw; -} - -/** - * CFG_I::FormatConfig service function - * Inputs: - * 0 : 0x08060000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void FormatConfig(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - cmd_buffer[1] = Service::CFG::FormatConfig().raw; -} const Interface::FunctionInfo FunctionTable[] = { {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, @@ -68,7 +15,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, - {0x04060000, nullptr, "SecureInfoGetRegion"}, + {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"}, {0x04070000, nullptr, "SecureInfoGetByte101"}, {0x04080042, nullptr, "SecureInfoGetSerialNo"}, {0x04090000, nullptr, "UpdateConfigBlk00040003"}, @@ -92,7 +39,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08130000, nullptr, "VerifySigSecureInfo"}, {0x08140042, nullptr, "SecureInfoGetData"}, {0x08150042, nullptr, "SecureInfoGetSignature"}, - {0x08160000, nullptr, "SecureInfoGetRegion"}, + {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"}, {0x08170000, nullptr, "SecureInfoGetByte101"}, {0x08180042, nullptr, "SecureInfoGetSerialNo"}, }; diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index d9a3e5d51..af4adba84 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -8,68 +8,6 @@ namespace Service { namespace CFG { - -/** - * CFG_S::GetConfigInfoBlk2 service function - * Inputs: - * 0 : 0x00010082 - * 1 : Size - * 2 : Block ID - * 3 : Descriptor for the output buffer - * 4 : Output buffer pointer - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetConfigInfoBlk2(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 size = cmd_buffer[1]; - u32 block_id = cmd_buffer[2]; - u8* data_pointer = Memory::GetPointer(cmd_buffer[4]); - - if (data_pointer == nullptr) { - cmd_buffer[1] = -1; // TODO(Subv): Find the right error code - return; - } - - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data_pointer).raw; -} - -/** - * CFG_S::GetConfigInfoBlk8 service function - * Inputs: - * 0 : 0x04010082 - * 1 : Size - * 2 : Block ID - * 3 : Descriptor for the output buffer - * 4 : Output buffer pointer - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetConfigInfoBlk8(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 size = cmd_buffer[1]; - u32 block_id = cmd_buffer[2]; - u8* data_pointer = Memory::GetPointer(cmd_buffer[4]); - - if (data_pointer == nullptr) { - cmd_buffer[1] = -1; // TODO(Subv): Find the right error code - return; - } - - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data_pointer).raw; -} - -/** - * CFG_S::UpdateConfigNANDSavegame service function - * Inputs: - * 0 : 0x04030000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void UpdateConfigNANDSavegame(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - cmd_buffer[1] = Service::CFG::UpdateConfigNANDSavegame().raw; -} const Interface::FunctionInfo FunctionTable[] = { {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 221de9918..18939750b 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -2,12 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/file_util.h" -#include "common/logging/log.h" -#include "common/string_util.h" - -#include "core/settings.h" -#include "core/file_sys/archive_systemsavedata.h" #include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_u.h" @@ -15,219 +9,6 @@ namespace Service { namespace CFG { -// TODO(Link Mauve): use a constexpr once MSVC starts supporting it. -#define C(code) ((code)[0] | ((code)[1] << 8)) - -static const std::array<u16, 187> country_codes = { - 0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7 - C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15 - C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23 - C("DO"), C("EC"), C("SV"), C("GF"), C("GD"), C("GP"), C("GT"), C("GY"), // 24-31 - C("HT"), C("HN"), C("JM"), C("MQ"), C("MX"), C("MS"), C("AN"), C("NI"), // 32-39 - C("PA"), C("PY"), C("PE"), C("KN"), C("LC"), C("VC"), C("SR"), C("TT"), // 40-47 - C("TC"), C("US"), C("UY"), C("VI"), C("VE"), 0, 0, 0, // 48-55 - 0, 0, 0, 0, 0, 0, 0, 0, // 56-63 - C("AL"), C("AU"), C("AT"), C("BE"), C("BA"), C("BW"), C("BG"), C("HR"), // 64-71 - C("CY"), C("CZ"), C("DK"), C("EE"), C("FI"), C("FR"), C("DE"), C("GR"), // 72-79 - C("HU"), C("IS"), C("IE"), C("IT"), C("LV"), C("LS"), C("LI"), C("LT"), // 80-87 - C("LU"), C("MK"), C("MT"), C("ME"), C("MZ"), C("NA"), C("NL"), C("NZ"), // 88-95 - C("NO"), C("PL"), C("PT"), C("RO"), C("RU"), C("RS"), C("SK"), C("SI"), // 96-103 - C("ZA"), C("ES"), C("SZ"), C("SE"), C("CH"), C("TR"), C("GB"), C("ZM"), // 104-111 - C("ZW"), C("AZ"), C("MR"), C("ML"), C("NE"), C("TD"), C("SD"), C("ER"), // 112-119 - C("DJ"), C("SO"), C("AD"), C("GI"), C("GG"), C("IM"), C("JE"), C("MC"), // 120-127 - C("TW"), 0, 0, 0, 0, 0, 0, 0, // 128-135 - C("KR"), 0, 0, 0, 0, 0, 0, 0, // 136-143 - C("HK"), C("MO"), 0, 0, 0, 0, 0, 0, // 144-151 - C("ID"), C("SG"), C("TH"), C("PH"), C("MY"), 0, 0, 0, // 152-159 - C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167 - C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 - C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 - C("SM"), C("VA"), C("BM") // 184-186 -}; - -#undef C - -/** - * CFG_User::GetCountryCodeString service function - * Inputs: - * 1 : Country Code ID - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Country's 2-char string - */ -static void GetCountryCodeString(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 country_code_id = cmd_buffer[1]; - - if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { - LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); - cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; - return; - } - - cmd_buffer[1] = 0; - cmd_buffer[2] = country_codes[country_code_id]; -} - -/** - * CFG_User::GetCountryCodeID service function - * Inputs: - * 1 : Country Code 2-char string - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Country Code ID - */ -static void GetCountryCodeID(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u16 country_code = cmd_buffer[1]; - u16 country_code_id = 0; - - // The following algorithm will fail if the first country code isn't 0. - DEBUG_ASSERT(country_codes[0] == 0); - - for (u16 id = 0; id < country_codes.size(); ++id) { - if (country_codes[id] == country_code) { - country_code_id = id; - break; - } - } - - if (0 == country_code_id) { - LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, country_code >> 8); - cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; - cmd_buffer[2] = 0xFFFF; - return; - } - - cmd_buffer[1] = 0; - cmd_buffer[2] = country_code_id; -} - -/** - * CFG_User::GetConfigInfoBlk2 service function - * Inputs: - * 0 : 0x00010082 - * 1 : Size - * 2 : Block ID - * 3 : Descriptor for the output buffer - * 4 : Output buffer pointer - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetConfigInfoBlk2(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 size = cmd_buffer[1]; - u32 block_id = cmd_buffer[2]; - u8* data_pointer = Memory::GetPointer(cmd_buffer[4]); - - if (data_pointer == nullptr) { - cmd_buffer[1] = -1; // TODO(Subv): Find the right error code - return; - } - - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data_pointer).raw; -} - -/** - * CFG_User::SecureInfoGetRegion service function - * Inputs: - * 1 : None - * Outputs: - * 0 : Result Header code - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Region value loaded from SecureInfo offset 0x100 - */ -static void SecureInfoGetRegion(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - - cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error - cmd_buffer[2] = Settings::values.region_value; -} - -/** - * CFG_User::GenHashConsoleUnique service function - * Inputs: - * 1 : 20 bit application ID salt - * Outputs: - * 0 : Result Header code - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Hash/"ID" lower word - * 3 : Hash/"ID" upper word - */ -static void GenHashConsoleUnique(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 app_id_salt = cmd_buffer[1]; - - cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error - cmd_buffer[2] = 0x33646D6F ^ (app_id_salt & 0xFFFFF); // 3dmoo hash - cmd_buffer[3] = 0x6F534841 ^ (app_id_salt & 0xFFFFF); - - LOG_WARNING(Service_CFG, "(STUBBED) called app_id_salt=0x%08X", app_id_salt); -} - -/** - * CFG_User::GetRegionCanadaUSA service function - * Inputs: - * 1 : None - * Outputs: - * 0 : Result Header code - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Output value - */ -static void GetRegionCanadaUSA(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - - cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error - - u8 canada_or_usa = 1; - if (canada_or_usa == Settings::values.region_value) { - cmd_buffer[2] = 1; - } else { - cmd_buffer[2] = 0; - } -} - -/** - * CFG_User::GetSystemModel service function - * Inputs: - * 0 : 0x00050000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Model of the console - */ -static void GetSystemModel(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 data; - - // TODO(Subv): Find out the correct error codes - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, - reinterpret_cast<u8*>(&data)).raw; - cmd_buffer[2] = data & 0xFF; -} - -/** - * CFG_User::GetModelNintendo2DS service function - * Inputs: - * 0 : 0x00060000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : 0 if the system is a Nintendo 2DS, 1 otherwise - */ -static void GetModelNintendo2DS(Service::Interface* self) { - u32* cmd_buffer = Kernel::GetCommandBuffer(); - u32 data; - - // TODO(Subv): Find out the correct error codes - cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, - reinterpret_cast<u8*>(&data)).raw; - - u8 model = data & 0xFF; - if (model == Service::CFG::NINTENDO_2DS) - cmd_buffer[2] = 0; - else - cmd_buffer[2] = 1; -} - const Interface::FunctionInfo FunctionTable[] = { {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 654ee2bf6..22adf9595 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -296,6 +296,18 @@ static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 val return res; } +static void Break(u8 break_reason) { + LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); + std::string reason_str; + switch (break_reason) { + case 0: reason_str = "PANIC"; break; + case 1: reason_str = "ASSERT"; break; + case 2: reason_str = "USER"; break; + default: reason_str = "UNKNOWN"; break; + } + LOG_CRITICAL(Debug_Emulated, "Break reason: %s", reason_str.c_str()); +} + /// Used to output a message on a debug hardware unit - does nothing on a retail unit static void OutputDebugString(const char* string) { LOG_DEBUG(Debug_Emulated, "%s", string); @@ -737,7 +749,7 @@ static const FunctionDef SVC_Table[] = { {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, {0x3B, nullptr, "GetThreadContext"}, - {0x3C, nullptr, "Break"}, + {0x3C, HLE::Wrap<Break>, "Break"}, {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"}, {0x3E, nullptr, "ControlPerformanceCounter"}, {0x3F, nullptr, "Unknown"}, diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 1ea7cad07..6121df8e3 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -74,11 +74,11 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { // Information about internal vertex attributes u32 vertex_attribute_sources[16]; boost::fill(vertex_attribute_sources, 0xdeadbeef); - u32 vertex_attribute_strides[16]; - Regs::VertexAttributeFormat vertex_attribute_formats[16]; + u32 vertex_attribute_strides[16] = {}; + Regs::VertexAttributeFormat vertex_attribute_formats[16] = {}; - u32 vertex_attribute_elements[16]; - u32 vertex_attribute_element_size[16]; + u32 vertex_attribute_elements[16] = {}; + u32 vertex_attribute_element_size[16] = {}; // Setup attribute data from loaders for (int loader = 0; loader < 12; ++loader) { @@ -127,29 +127,31 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { input.attr[0].w = debug_token; for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { + // Load the default attribute if we're configured to do so, this data will be overwritten by the loader data if it's set if (attribute_config.IsDefaultAttribute(i)) { input.attr[i] = VertexShader::GetDefaultAttribute(i); LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", i, vertex, index, input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); - } else { - for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { - const u8* srcdata = Memory::GetPhysicalPointer(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]); - - const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : - (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : - (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : - *(float*)srcdata; - - input.attr[i][comp] = float24::FromFloat32(srcval); - LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", - comp, i, vertex, index, - attribute_config.GetPhysicalBaseAddress(), - vertex_attribute_sources[i] - base_address, - vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], - input.attr[i][comp].ToFloat32()); - } + } + + // Load per-vertex data from the loader arrays + for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { + const u8* srcdata = Memory::GetPhysicalPointer(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]); + + const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : + (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : + (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : + *(float*)srcdata; + + input.attr[i][comp] = float24::FromFloat32(srcval); + LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", + comp, i, vertex, index, + attribute_config.GetPhysicalBaseAddress(), + vertex_attribute_sources[i] - base_address, + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], + input.attr[i][comp].ToFloat32()); } } diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 3fbf95721..e9bc7fb3b 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -614,7 +614,7 @@ struct Regs { } inline bool IsDefaultAttribute(int id) const { - return (id >= 12) || (attribute_mask & (1 << id)) != 0; + return (id >= 12) || (attribute_mask & (1ULL << id)) != 0; } inline int GetNumTotalAttributes() const { |