Add new Cheat Type F4, Find & Replace Bytes (#1345)

* Add new Cheat Type F4, Find & Replace Bytes

Also knows as 'AOB' apparently. Information about how it works will be in the next chtdb.txt header or you can read/ask about it on the discord channel.

* Add new Cheat Type F4, Find & Replace Bytes 

Also knows as 'AOB' apparently. Information about how it works will be in the next chtdb.txt header or you can read/ask about it on the discord channel.

* Added error trapping for cheat type F4

As suggested
This commit is contained in:
PugsyMAME 2020-12-29 14:55:49 +00:00 committed by GitHub
parent 1b99233466
commit 3284a18ad3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 1 deletions

View File

@ -1214,6 +1214,98 @@ void CheatCode::Apply() const
}
break;
case InstructionCode::ExtFindAndReplace:
{
if ((index + 4) >= instructions.size())
{
Log_ErrorPrintf("Incomplete find/replace instruction");
return;
}
const Instruction& inst2 = instructions[index + 1];
const Instruction& inst3 = instructions[index + 2];
const Instruction& inst4 = instructions[index + 3];
const Instruction& inst5 = instructions[index + 4];
const u32 offset = Truncate16(inst.value32 & 0x0000FFFFu) << 1;
const u8 wildcard = Truncate8((inst.value32 & 0x00FF0000u) >> 16);
const u32 minaddress = inst.address - offset;
const u32 maxaddress = inst.address + offset;
const u8 f1 = Truncate8((inst2.first & 0xFF000000u) >> 24);
const u8 f2 = Truncate8((inst2.first & 0x00FF0000u) >> 16);
const u8 f3 = Truncate8((inst2.first & 0x0000FF00u) >> 8);
const u8 f4 = Truncate8 (inst2.first & 0x000000FFu);
const u8 f5 = Truncate8((inst2.value32 & 0xFF000000u) >> 24);
const u8 f6 = Truncate8((inst2.value32 & 0x00FF0000u) >> 16);
const u8 f7 = Truncate8((inst2.value32 & 0x0000FF00u) >> 8);
const u8 f8 = Truncate8 (inst2.value32 & 0x000000FFu);
const u8 f9 = Truncate8((inst3.first & 0xFF000000u) >> 24);
const u8 f10 = Truncate8((inst3.first & 0x00FF0000u) >> 16);
const u8 f11 = Truncate8((inst3.first & 0x0000FF00u) >> 8);
const u8 f12 = Truncate8 (inst3.first & 0x000000FFu);
const u8 f13 = Truncate8((inst3.value32 & 0xFF000000u) >> 24);
const u8 f14 = Truncate8((inst3.value32 & 0x00FF0000u) >> 16);
const u8 f15 = Truncate8((inst3.value32 & 0x0000FF00u) >> 8);
const u8 f16 = Truncate8 (inst3.value32 & 0x000000FFu);
const u8 r1 = Truncate8((inst4.first & 0xFF000000u) >> 24);
const u8 r2 = Truncate8((inst4.first & 0x00FF0000u) >> 16);
const u8 r3 = Truncate8((inst4.first & 0x0000FF00u) >> 8);
const u8 r4 = Truncate8 (inst4.first & 0x000000FFu);
const u8 r5 = Truncate8((inst4.value32 & 0xFF000000u) >> 24);
const u8 r6 = Truncate8((inst4.value32 & 0x00FF0000u) >> 16);
const u8 r7 = Truncate8((inst4.value32 & 0x0000FF00u) >> 8);
const u8 r8 = Truncate8 (inst4.value32 & 0x000000FFu);
const u8 r9 = Truncate8((inst5.first & 0xFF000000u) >> 24);
const u8 r10 = Truncate8((inst5.first & 0x00FF0000u) >> 16);
const u8 r11 = Truncate8((inst5.first & 0x0000FF00u) >> 8);
const u8 r12 = Truncate8 (inst5.first & 0x000000FFu);
const u8 r13 = Truncate8((inst5.value32 & 0xFF000000u) >> 24);
const u8 r14 = Truncate8((inst5.value32 & 0x00FF0000u) >> 16);
const u8 r15 = Truncate8((inst5.value32 & 0x0000FF00u) >> 8);
const u8 r16 = Truncate8 (inst5.value32 & 0x000000FFu);
for (u32 address = minaddress;address<=maxaddress;address+=2)
{
if ((DoMemoryRead<u8>(address )==f1 || f1 == wildcard) &&
(DoMemoryRead<u8>(address+1 )==f2 || f2 == wildcard) &&
(DoMemoryRead<u8>(address+2 )==f3 || f3 == wildcard) &&
(DoMemoryRead<u8>(address+3 )==f4 || f4 == wildcard) &&
(DoMemoryRead<u8>(address+4 )==f5 || f5 == wildcard) &&
(DoMemoryRead<u8>(address+5 )==f6 || f6 == wildcard) &&
(DoMemoryRead<u8>(address+6 )==f7 || f7 == wildcard) &&
(DoMemoryRead<u8>(address+7 )==f8 || f8 == wildcard) &&
(DoMemoryRead<u8>(address+8 )==f9 || f9 == wildcard) &&
(DoMemoryRead<u8>(address+9 )==f10|| f10 == wildcard) &&
(DoMemoryRead<u8>(address+10)==f11|| f11 == wildcard) &&
(DoMemoryRead<u8>(address+11)==f12|| f12 == wildcard) &&
(DoMemoryRead<u8>(address+12)==f13|| f13 == wildcard) &&
(DoMemoryRead<u8>(address+13)==f14|| f14 == wildcard) &&
(DoMemoryRead<u8>(address+14)==f15|| f15 == wildcard) &&
(DoMemoryRead<u8>(address+15)==f16|| f16 == wildcard))
{
if (r1 != wildcard) DoMemoryWrite<u8>(address , r1 );
if (r2 != wildcard) DoMemoryWrite<u8>(address+1 , r2 );
if (r3 != wildcard) DoMemoryWrite<u8>(address+2 , r3 );
if (r4 != wildcard) DoMemoryWrite<u8>(address+3 , r4 );
if (r5 != wildcard) DoMemoryWrite<u8>(address+4 , r5 );
if (r6 != wildcard) DoMemoryWrite<u8>(address+5 , r6 );
if (r7 != wildcard) DoMemoryWrite<u8>(address+6 , r7 );
if (r8 != wildcard) DoMemoryWrite<u8>(address+7 , r8 );
if (r9 != wildcard) DoMemoryWrite<u8>(address+8 , r9 );
if (r10 != wildcard) DoMemoryWrite<u8>(address+9 , r10);
if (r11 != wildcard) DoMemoryWrite<u8>(address+10, r11);
if (r12 != wildcard) DoMemoryWrite<u8>(address+11, r12);
if (r13 != wildcard) DoMemoryWrite<u8>(address+12, r13);
if (r14 != wildcard) DoMemoryWrite<u8>(address+13, r14);
if (r15 != wildcard) DoMemoryWrite<u8>(address+14, r15);
if (r16 != wildcard) DoMemoryWrite<u8>(address+15, r16);
address=address+15;
}
}
index += 5;
}
break;
case InstructionCode::CompareEqual16:
{
const u16 value = DoMemoryRead<u16>(inst.address);
@ -1479,7 +1571,9 @@ void CheatCode::ApplyOnDisable() const
case InstructionCode::MemoryCopy:
index += 2;
break;
case InstructionCode::ExtFindAndReplace:
index += 5;
break;
// for conditionals, we don't want to skip over in case it changed at some point
case InstructionCode::ExtCompareEqual32:
case InstructionCode::ExtCompareNotEqual32:

View File

@ -62,6 +62,7 @@ struct CheatCode
ExtConstantForceRangeLimits16 = 0xF1,
ExtConstantForceRangeRollRound16 = 0xF2,
ExtConstantForceRange16 = 0xF3,
ExtFindAndReplace = 0xF4,
ExtConstantBitSet8 = 0x31,
ExtConstantBitClear8 = 0x32,
ExtConstantBitSet16 = 0x81,