Cheats: Accept ".org 0x12345678" and "0x12345678:" to set pc

pull/3766/head
Stenzek 3 months ago
parent 4f51c2dcb2
commit 0c87b07263
No known key found for this signature in database

@ -231,13 +231,15 @@ TEST(Cheats, ParseAssemblyInstructionFormatsAndOrigins)
"sw t0, 16(sp)\n"
"lw v0, -4(sp)\n"
"addu v1, v0, t0\n"
".org 0x80030000\n"
".org 80030000\n"
"jal 0x80031000\n"
"jr ra\n";
"jr ra\n"
"0x80040000:\n"
"nop\n";
static constexpr std::array expected = {
std::pair{0x80020000u, 0x3C081234u}, std::pair{0x80020004u, 0x35085678u}, std::pair{0x80020008u, 0xAFA80010u},
std::pair{0x8002000Cu, 0x8FA2FFFCu}, std::pair{0x80020010u, 0x00481821u}, std::pair{0x80030000u, 0x0C00C400u},
std::pair{0x80030004u, 0x03E00008u},
std::pair{0x80030004u, 0x03E00008u}, std::pair{0x80040000u, 0x00000000u},
};
Error error;

@ -4440,6 +4440,33 @@ std::unique_ptr<Cheats::AssemblyCheatCode> Cheats::AssemblyCheatCode::Parse(Meta
if (linev.empty())
continue;
std::string_view address_text;
if (linev.starts_with(".org "))
address_text = StringUtil::StripWhitespace(linev.substr(4));
else if (linev.ends_with(':') && linev.front() >= '0' && linev.front() <= '9')
address_text = StringUtil::StripWhitespace(linev.substr(0, linev.size() - 1));
if (!address_text.empty())
{
if (address_text.starts_with("0x") || address_text.starts_with("0X"))
address_text.remove_prefix(2);
std::string_view end;
const std::optional<u32> address = StringUtil::FromChars<u32>(address_text, 16, &end);
if (!address.has_value() || !end.empty())
{
Error::SetStringFmt(error, "Malformed starting address at line {}: {}", reader.GetCurrentLineNumber(), linev);
return {};
}
if ((address.value() & (CPU::INSTRUCTION_SIZE - 1)) != 0)
{
Error::SetStringFmt(error, "Unaligned starting address at line {}: {}", reader.GetCurrentLineNumber(), linev);
return {};
}
pc = address.value();
continue;
}
const size_t colon_pos = linev.find(':');
if (colon_pos != std::string_view::npos)
{
@ -4479,29 +4506,6 @@ std::unique_ptr<Cheats::AssemblyCheatCode> Cheats::AssemblyCheatCode::Parse(Meta
continue;
}
if (linev.starts_with(".org "))
{
std::string_view address_text = StringUtil::StripWhitespace(linev.substr(4));
if (address_text.starts_with("0x") || address_text.starts_with("0X"))
address_text.remove_prefix(2);
std::string_view end;
const std::optional<u32> address = StringUtil::FromChars<u32>(address_text, 16, &end);
if (!address.has_value() || !end.empty())
{
Error::SetStringFmt(error, "Malformed starting address at line {}: {}", reader.GetCurrentLineNumber(), linev);
return {};
}
if ((address.value() & (CPU::INSTRUCTION_SIZE - 1)) != 0)
{
Error::SetStringFmt(error, "Unaligned starting address at line {}: {}", reader.GetCurrentLineNumber(), linev);
return {};
}
pc = address.value();
continue;
}
if (!pc.has_value())
{
Error::SetStringFmt(error, "Instruction before starting address at line {}: {}", reader.GetCurrentLineNumber(),

Loading…
Cancel
Save