diff --git a/src/core/cheats.cpp b/src/core/cheats.cpp index 0d656abc6..1c84dbbc3 100644 --- a/src/core/cheats.cpp +++ b/src/core/cheats.cpp @@ -14,6 +14,74 @@ Log_SetChannel(Cheats); using KeyValuePairVector = std::vector>; +static bool IsValidScanAddress(PhysicalMemoryAddress address) +{ + if ((address & CPU::DCACHE_LOCATION_MASK) == CPU::DCACHE_LOCATION && + (address & CPU::DCACHE_OFFSET_MASK) < CPU::DCACHE_SIZE) + { + return true; + } + + address &= CPU::PHYSICAL_MEMORY_ADDRESS_MASK; + + if (address < Bus::RAM_MIRROR_END) + return true; + + if (address >= Bus::BIOS_BASE && address < (Bus::BIOS_BASE + Bus::BIOS_SIZE)) + return true; + + return false; +} + +template +static T DoMemoryRead(PhysicalMemoryAddress address) +{ + T result; + + if ((address & CPU::DCACHE_LOCATION_MASK) == CPU::DCACHE_LOCATION && + (address & CPU::DCACHE_OFFSET_MASK) < CPU::DCACHE_SIZE) + { + std::memcpy(&result, &CPU::g_state.dcache[address & CPU::DCACHE_OFFSET_MASK], sizeof(result)); + return result; + } + + address &= CPU::PHYSICAL_MEMORY_ADDRESS_MASK; + + if (address < Bus::RAM_MIRROR_END) + { + std::memcpy(&result, &Bus::g_ram[address & Bus::RAM_MASK], sizeof(result)); + return result; + } + + if (address >= Bus::BIOS_BASE && address < (Bus::BIOS_BASE + Bus::BIOS_SIZE)) + { + std::memcpy(&result, &Bus::g_bios[address & Bus::BIOS_MASK], sizeof(result)); + return result; + } + + result = static_cast(0); + return result; +} + +template +static void DoMemoryWrite(PhysicalMemoryAddress address, T value) +{ + if ((address & CPU::DCACHE_LOCATION_MASK) == CPU::DCACHE_LOCATION && + (address & CPU::DCACHE_OFFSET_MASK) < CPU::DCACHE_SIZE) + { + std::memcpy(&CPU::g_state.dcache[address & CPU::DCACHE_OFFSET_MASK], &value, sizeof(value)); + return; + } + + address &= CPU::PHYSICAL_MEMORY_ADDRESS_MASK; + + if (address < Bus::RAM_MIRROR_END) + { + std::memcpy(&Bus::g_ram[address & Bus::RAM_MASK], &value, sizeof(value)); + return; + } +} + CheatList::CheatList() = default; CheatList::~CheatList() = default; @@ -533,65 +601,60 @@ void CheatCode::Apply() const case InstructionCode::ConstantWrite8: { - CPU::SafeWriteMemoryByte(inst.address, inst.value8); + DoMemoryWrite(inst.address, inst.value8); index++; } break; case InstructionCode::ConstantWrite16: { - CPU::SafeWriteMemoryHalfWord(inst.address, inst.value16); + DoMemoryWrite(inst.address, inst.value16); index++; } break; case InstructionCode::ScratchpadWrite16: { - CPU::SafeWriteMemoryHalfWord(CPU::DCACHE_LOCATION | (inst.address & CPU::DCACHE_OFFSET_MASK), inst.value16); + DoMemoryWrite(CPU::DCACHE_LOCATION | (inst.address & CPU::DCACHE_OFFSET_MASK), inst.value16); index++; } break; case InstructionCode::Increment16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); - CPU::SafeWriteMemoryHalfWord(inst.address, value + inst.value16); + u16 value = DoMemoryRead(inst.address); + DoMemoryWrite(inst.address, value + inst.value16); index++; } break; case InstructionCode::Decrement16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); - CPU::SafeWriteMemoryHalfWord(inst.address, value - inst.value16); + u16 value = DoMemoryRead(inst.address); + DoMemoryWrite(inst.address, value - inst.value16); index++; } break; case InstructionCode::Increment8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); - CPU::SafeWriteMemoryByte(inst.address, value + inst.value8); + u8 value = DoMemoryRead(inst.address); + DoMemoryWrite(inst.address, value + inst.value8); index++; } break; case InstructionCode::Decrement8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); - CPU::SafeWriteMemoryByte(inst.address, value - inst.value8); + u8 value = DoMemoryRead(inst.address); + DoMemoryWrite(inst.address, value - inst.value8); index++; } break; case InstructionCode::CompareEqual16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); + u16 value = DoMemoryRead(inst.address); if (value == inst.value16) index++; else @@ -601,8 +664,7 @@ void CheatCode::Apply() const case InstructionCode::CompareNotEqual16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); + u16 value = DoMemoryRead(inst.address); if (value != inst.value16) index++; else @@ -612,8 +674,7 @@ void CheatCode::Apply() const case InstructionCode::CompareLess16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); + u16 value = DoMemoryRead(inst.address); if (value < inst.value16) index++; else @@ -623,8 +684,7 @@ void CheatCode::Apply() const case InstructionCode::CompareGreater16: { - u16 value = 0; - CPU::SafeReadMemoryHalfWord(inst.address, &value); + u16 value = DoMemoryRead(inst.address); if (value > inst.value16) index++; else @@ -634,8 +694,7 @@ void CheatCode::Apply() const case InstructionCode::CompareEqual8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); + u8 value = DoMemoryRead(inst.address); if (value == inst.value8) index++; else @@ -645,8 +704,7 @@ void CheatCode::Apply() const case InstructionCode::CompareNotEqual8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); + u8 value = DoMemoryRead(inst.address); if (value != inst.value8) index++; else @@ -656,8 +714,7 @@ void CheatCode::Apply() const case InstructionCode::CompareLess8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); + u8 value = DoMemoryRead(inst.address); if (value < inst.value8) index++; else @@ -667,8 +724,7 @@ void CheatCode::Apply() const case InstructionCode::CompareGreater8: { - u8 value = 0; - CPU::SafeReadMemoryByte(inst.address, &value); + u8 value = DoMemoryRead(inst.address); if (value > inst.value8) index++; else @@ -696,7 +752,7 @@ void CheatCode::Apply() const { for (u32 i = 0; i < slide_count; i++) { - CPU::SafeWriteMemoryByte(address, Truncate8(value)); + DoMemoryWrite(address, Truncate8(value)); address += address_increment; value += value_increment; } @@ -705,7 +761,7 @@ void CheatCode::Apply() const { for (u32 i = 0; i < slide_count; i++) { - CPU::SafeWriteMemoryHalfWord(address, value); + DoMemoryWrite(address, value); address += address_increment; value += value_increment; } @@ -734,9 +790,8 @@ void CheatCode::Apply() const for (u32 i = 0; i < byte_count; i++) { - u8 value = 0; - CPU::SafeReadMemoryByte(src_address, &value); - CPU::SafeWriteMemoryByte(dst_address, value); + u8 value = DoMemoryRead(src_address); + DoMemoryWrite(dst_address, value); src_address++; dst_address++; } @@ -837,21 +892,6 @@ void MemoryScan::Search() } } -static bool IsValidScanAddress(PhysicalMemoryAddress address) -{ - address &= CPU::PHYSICAL_MEMORY_ADDRESS_MASK; - if (address < Bus::RAM_MIRROR_END) - return true; - - if (address >= CPU::DCACHE_LOCATION && address < (CPU::DCACHE_LOCATION + CPU::DCACHE_SIZE)) - return true; - - if (address >= Bus::BIOS_BASE && address < (Bus::BIOS_BASE + Bus::BIOS_SIZE)) - return true; - - return false; -} - void MemoryScan::SearchBytes() { for (PhysicalMemoryAddress address = m_start_address; address < m_end_address; address++) @@ -859,8 +899,7 @@ void MemoryScan::SearchBytes() if (!IsValidScanAddress(address)) continue; - u8 bvalue = 0; - CPU::SafeReadMemoryByte(address, &bvalue); + const u8 bvalue = DoMemoryRead(address); Result res; res.address = address; @@ -880,8 +919,7 @@ void MemoryScan::SearchHalfwords() if (!IsValidScanAddress(address)) continue; - u16 bvalue = 0; - CPU::SafeReadMemoryHalfWord(address, &bvalue); + const u16 bvalue = DoMemoryRead(address); Result res; res.address = address; @@ -903,7 +941,7 @@ void MemoryScan::SearchWords() Result res; res.address = address; - CPU::SafeReadMemoryWord(address, &res.value); + res.value = DoMemoryRead(address); res.last_value = res.value; res.value_changed = false; @@ -948,11 +986,11 @@ void MemoryScan::SetResultValue(u32 index, u32 value) switch (m_size) { case MemoryAccessSize::Byte: - CPU::SafeWriteMemoryByte(res.address, Truncate8(value)); + DoMemoryWrite(res.address, Truncate8(value)); break; case MemoryAccessSize::HalfWord: - CPU::SafeWriteMemoryHalfWord(res.address, Truncate16(value)); + DoMemoryWrite(res.address, Truncate16(value)); break; case MemoryAccessSize::Word: @@ -1064,16 +1102,14 @@ void MemoryScan::Result::UpdateValue(MemoryAccessSize size, bool is_signed) { case MemoryAccessSize::Byte: { - u8 bvalue = 0; - CPU::SafeReadMemoryByte(address, &bvalue); + u8 bvalue = DoMemoryRead(address); value = is_signed ? SignExtend32(bvalue) : ZeroExtend32(bvalue); } break; case MemoryAccessSize::HalfWord: { - u16 bvalue = 0; - CPU::SafeReadMemoryHalfWord(address, &bvalue); + u16 bvalue = DoMemoryRead(address); value = is_signed ? SignExtend32(bvalue) : ZeroExtend32(bvalue); } break; @@ -1205,15 +1241,15 @@ void MemoryWatchList::SetEntryValue(Entry* entry, u32 value) switch (entry->size) { case MemoryAccessSize::Byte: - CPU::SafeWriteMemoryByte(entry->address, Truncate8(value)); + DoMemoryWrite(entry->address, Truncate8(value)); break; case MemoryAccessSize::HalfWord: - CPU::SafeWriteMemoryHalfWord(entry->address, Truncate16(value)); + DoMemoryWrite(entry->address, Truncate16(value)); break; case MemoryAccessSize::Word: - CPU::SafeWriteMemoryWord(entry->address, value); + DoMemoryWrite(entry->address, value); break; } @@ -1229,23 +1265,21 @@ void MemoryWatchList::UpdateEntryValue(Entry* entry) { case MemoryAccessSize::Byte: { - u8 bvalue = 0; - CPU::SafeReadMemoryByte(entry->address, &bvalue); + u8 bvalue = DoMemoryRead(entry->address); entry->value = entry->is_signed ? SignExtend32(bvalue) : ZeroExtend32(bvalue); } break; case MemoryAccessSize::HalfWord: { - u16 bvalue = 0; - CPU::SafeReadMemoryHalfWord(entry->address, &bvalue); + u16 bvalue = DoMemoryRead(entry->address); entry->value = entry->is_signed ? SignExtend32(bvalue) : ZeroExtend32(bvalue); } break; case MemoryAccessSize::Word: { - CPU::SafeReadMemoryWord(entry->address, &entry->value); + entry->value = DoMemoryRead(entry->address); } break; }