summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/memory/dmnt_cheat_vm.cpp29
-rw-r--r--src/core/memory/dmnt_cheat_vm.h14
2 files changed, 42 insertions, 1 deletions
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp
index fb9f36bfd..2e7da23fe 100644
--- a/src/core/memory/dmnt_cheat_vm.cpp
+++ b/src/core/memory/dmnt_cheat_vm.cpp
@@ -190,6 +190,15 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode& opcode) {
190 callbacks->CommandLog( 190 callbacks->CommandLog(
191 fmt::format("Act[{:02X}]: {:d}", i, save_restore_regmask->should_operate[i])); 191 fmt::format("Act[{:02X}]: {:d}", i, save_restore_regmask->should_operate[i]));
192 } 192 }
193 } else if (auto rw_static_reg = std::get_if<ReadWriteStaticRegisterOpcode>(&opcode.opcode)) {
194 callbacks->CommandLog("Opcode: Read/Write Static Register");
195 if (rw_static_reg->static_idx < NumReadableStaticRegisters) {
196 callbacks->CommandLog("Op Type: ReadStaticRegister");
197 } else {
198 callbacks->CommandLog("Op Type: WriteStaticRegister");
199 }
200 callbacks->CommandLog(fmt::format("Reg Idx {:X}", rw_static_reg->idx));
201 callbacks->CommandLog(fmt::format("Stc Idx {:X}", rw_static_reg->static_idx));
193 } else if (auto debug_log = std::get_if<DebugLogOpcode>(&opcode.opcode)) { 202 } else if (auto debug_log = std::get_if<DebugLogOpcode>(&opcode.opcode)) {
194 callbacks->CommandLog("Opcode: Debug Log"); 203 callbacks->CommandLog("Opcode: Debug Log");
195 callbacks->CommandLog(fmt::format("Bit Width: {:X}", debug_log->bit_width)); 204 callbacks->CommandLog(fmt::format("Bit Width: {:X}", debug_log->bit_width));
@@ -544,6 +553,16 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
544 } 553 }
545 opcode.opcode = save_restore_regmask; 554 opcode.opcode = save_restore_regmask;
546 } break; 555 } break;
556 case CheatVmOpcodeType::ReadWriteStaticRegister: {
557 ReadWriteStaticRegisterOpcode rw_static_reg{};
558 // C3000XXx
559 // C3 = opcode 0xC3.
560 // XX = static register index.
561 // x = register index.
562 rw_static_reg.static_idx = ((first_dword >> 4) & 0xFF);
563 rw_static_reg.idx = (first_dword & 0xF);
564 opcode.opcode = rw_static_reg;
565 } break;
547 case CheatVmOpcodeType::DebugLog: { 566 case CheatVmOpcodeType::DebugLog: {
548 DebugLogOpcode debug_log{}; 567 DebugLogOpcode debug_log{};
549 // FFFTIX## 568 // FFFTIX##
@@ -667,6 +686,7 @@ void DmntCheatVm::ResetState() {
667 registers.fill(0); 686 registers.fill(0);
668 saved_values.fill(0); 687 saved_values.fill(0);
669 loop_tops.fill(0); 688 loop_tops.fill(0);
689 static_registers.fill(0);
670 instruction_ptr = 0; 690 instruction_ptr = 0;
671 condition_depth = 0; 691 condition_depth = 0;
672 decode_success = true; 692 decode_success = true;
@@ -1153,6 +1173,15 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
1153 } 1173 }
1154 } 1174 }
1155 } 1175 }
1176 } else if (auto rw_static_reg =
1177 std::get_if<ReadWriteStaticRegisterOpcode>(&cur_opcode.opcode)) {
1178 if (rw_static_reg->static_idx < NumReadableStaticRegisters) {
1179 // Load a register with a static register.
1180 registers[rw_static_reg->idx] = static_registers[rw_static_reg->static_idx];
1181 } else {
1182 // Store a register to a static register.
1183 static_registers[rw_static_reg->static_idx] = registers[rw_static_reg->idx];
1184 }
1156 } else if (auto debug_log = std::get_if<DebugLogOpcode>(&cur_opcode.opcode)) { 1185 } else if (auto debug_log = std::get_if<DebugLogOpcode>(&cur_opcode.opcode)) {
1157 // Read value from memory. 1186 // Read value from memory.
1158 u64 log_value = 0; 1187 u64 log_value = 0;
diff --git a/src/core/memory/dmnt_cheat_vm.h b/src/core/memory/dmnt_cheat_vm.h
index 8351fd798..21b86b72c 100644
--- a/src/core/memory/dmnt_cheat_vm.h
+++ b/src/core/memory/dmnt_cheat_vm.h
@@ -56,6 +56,7 @@ enum class CheatVmOpcodeType : u32 {
56 BeginRegisterConditionalBlock = 0xC0, 56 BeginRegisterConditionalBlock = 0xC0,
57 SaveRestoreRegister = 0xC1, 57 SaveRestoreRegister = 0xC1,
58 SaveRestoreRegisterMask = 0xC2, 58 SaveRestoreRegisterMask = 0xC2,
59 ReadWriteStaticRegister = 0xC3,
59 60
60 // This is a meta entry, and not a real opcode. 61 // This is a meta entry, and not a real opcode.
61 // This is to facilitate multi-nybble instruction decoding. 62 // This is to facilitate multi-nybble instruction decoding.
@@ -237,6 +238,11 @@ struct SaveRestoreRegisterMaskOpcode {
237 std::array<bool, 0x10> should_operate{}; 238 std::array<bool, 0x10> should_operate{};
238}; 239};
239 240
241struct ReadWriteStaticRegisterOpcode {
242 u32 static_idx{};
243 u32 idx{};
244};
245
240struct DebugLogOpcode { 246struct DebugLogOpcode {
241 u32 bit_width{}; 247 u32 bit_width{};
242 u32 log_id{}; 248 u32 log_id{};
@@ -259,7 +265,8 @@ struct CheatVmOpcode {
259 PerformArithmeticStaticOpcode, BeginKeypressConditionalOpcode, 265 PerformArithmeticStaticOpcode, BeginKeypressConditionalOpcode,
260 PerformArithmeticRegisterOpcode, StoreRegisterToAddressOpcode, 266 PerformArithmeticRegisterOpcode, StoreRegisterToAddressOpcode,
261 BeginRegisterConditionalOpcode, SaveRestoreRegisterOpcode, 267 BeginRegisterConditionalOpcode, SaveRestoreRegisterOpcode,
262 SaveRestoreRegisterMaskOpcode, DebugLogOpcode, UnrecognizedInstruction> 268 SaveRestoreRegisterMaskOpcode, ReadWriteStaticRegisterOpcode, DebugLogOpcode,
269 UnrecognizedInstruction>
263 opcode{}; 270 opcode{};
264}; 271};
265 272
@@ -281,6 +288,10 @@ public:
281 288
282 static constexpr std::size_t MaximumProgramOpcodeCount = 0x400; 289 static constexpr std::size_t MaximumProgramOpcodeCount = 0x400;
283 static constexpr std::size_t NumRegisters = 0x10; 290 static constexpr std::size_t NumRegisters = 0x10;
291 static constexpr std::size_t NumReadableStaticRegisters = 0x80;
292 static constexpr std::size_t NumWritableStaticRegisters = 0x80;
293 static constexpr std::size_t NumStaticRegisters =
294 NumReadableStaticRegisters + NumWritableStaticRegisters;
284 295
285 explicit DmntCheatVm(std::unique_ptr<Callbacks> callbacks); 296 explicit DmntCheatVm(std::unique_ptr<Callbacks> callbacks);
286 ~DmntCheatVm(); 297 ~DmntCheatVm();
@@ -302,6 +313,7 @@ private:
302 std::array<u32, MaximumProgramOpcodeCount> program{}; 313 std::array<u32, MaximumProgramOpcodeCount> program{};
303 std::array<u64, NumRegisters> registers{}; 314 std::array<u64, NumRegisters> registers{};
304 std::array<u64, NumRegisters> saved_values{}; 315 std::array<u64, NumRegisters> saved_values{};
316 std::array<u64, NumStaticRegisters> static_registers{};
305 std::array<std::size_t, NumRegisters> loop_tops{}; 317 std::array<std::size_t, NumRegisters> loop_tops{};
306 318
307 bool DecodeNextOpcode(CheatVmOpcode& out); 319 bool DecodeNextOpcode(CheatVmOpcode& out);