mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
dmnt-cheat: Add Save/Restore register mask opcode
This commit is contained in:
parent
477bee2e4c
commit
08a2f02a7c
2 changed files with 43 additions and 0 deletions
|
@ -194,6 +194,13 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode *opcode) {
|
||||||
this->LogToDebugFile("Src Idx: %x\n", opcode->save_restore_reg.src_index);
|
this->LogToDebugFile("Src Idx: %x\n", opcode->save_restore_reg.src_index);
|
||||||
this->LogToDebugFile("Is Save: %d\n", opcode->save_restore_reg.is_save);
|
this->LogToDebugFile("Is Save: %d\n", opcode->save_restore_reg.is_save);
|
||||||
break;
|
break;
|
||||||
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
|
this->LogToDebugFile("Opcode: Save or Restore Register Mask\n");
|
||||||
|
this->LogToDebugFile("Is Save: %d\n", opcode->save_restore_regmask.is_save);
|
||||||
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
|
this->LogToDebugFile("Act[%02x]: %d\n", i, opcode->save_restore_regmask.should_save_or_restore[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this->LogToDebugFile("Unknown opcode: %x\n", opcode->opcode);
|
this->LogToDebugFile("Unknown opcode: %x\n", opcode->opcode);
|
||||||
break;
|
break;
|
||||||
|
@ -481,6 +488,18 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode *out) {
|
||||||
opcode.save_restore_reg.is_save = ((first_dword >> 4) & 0xF) != 0;
|
opcode.save_restore_reg.is_save = ((first_dword >> 4) & 0xF) != 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
|
{
|
||||||
|
/* C2x0XXXX */
|
||||||
|
/* C2 = opcode 0xC2 */
|
||||||
|
/* x = 1 if saving, 0 if restoring. */
|
||||||
|
/* X = 16-bit bitmask, bit i --> save or restore register i. */
|
||||||
|
opcode.save_restore_regmask.is_save = ((first_dword >> 20) & 0xF) != 0;
|
||||||
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
|
opcode.save_restore_regmask.should_save_or_restore[i] = (first_dword & (1u << i)) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CheatVmOpcodeType_ExtendedWidth:
|
case CheatVmOpcodeType_ExtendedWidth:
|
||||||
default:
|
default:
|
||||||
/* Unrecognized instruction cannot be decoded. */
|
/* Unrecognized instruction cannot be decoded. */
|
||||||
|
@ -996,6 +1015,23 @@ void DmntCheatVm::Execute(const CheatProcessMetadata *metadata) {
|
||||||
this->registers[cur_opcode.save_restore_reg.dst_index] = this->saved_values[cur_opcode.save_restore_reg.src_index];
|
this->registers[cur_opcode.save_restore_reg.dst_index] = this->saved_values[cur_opcode.save_restore_reg.src_index];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
|
/* Save or restore register mask. */
|
||||||
|
u64 *src;
|
||||||
|
u64 *dst;
|
||||||
|
if (cur_opcode.save_restore_regmask.is_save) {
|
||||||
|
src = this->registers;
|
||||||
|
dst = this->saved_values;
|
||||||
|
} else {
|
||||||
|
src = this->registers;
|
||||||
|
dst = this->saved_values;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
|
if (cur_opcode.save_restore_regmask.should_save_or_restore[i]) {
|
||||||
|
dst[i] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* By default, we do a no-op. */
|
/* By default, we do a no-op. */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -44,6 +44,7 @@ enum CheatVmOpcodeType : u32 {
|
||||||
/* Extended width opcodes. */
|
/* Extended width opcodes. */
|
||||||
CheatVmOpcodeType_BeginRegisterConditionalBlock = 0xC0,
|
CheatVmOpcodeType_BeginRegisterConditionalBlock = 0xC0,
|
||||||
CheatVmOpcodeType_SaveRestoreRegister = 0xC1,
|
CheatVmOpcodeType_SaveRestoreRegister = 0xC1,
|
||||||
|
CheatVmOpcodeType_SaveRestoreRegisterMask = 0xC2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemoryAccessType : u32 {
|
enum MemoryAccessType : u32 {
|
||||||
|
@ -198,6 +199,11 @@ struct SaveRestoreRegisterOpcode {
|
||||||
bool is_save;
|
bool is_save;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SaveRestoreRegisterMaskOpcode {
|
||||||
|
bool is_save;
|
||||||
|
bool should_save_or_restore[0x10];
|
||||||
|
};
|
||||||
|
|
||||||
struct CheatVmOpcode {
|
struct CheatVmOpcode {
|
||||||
CheatVmOpcodeType opcode;
|
CheatVmOpcodeType opcode;
|
||||||
bool begin_conditional_block;
|
bool begin_conditional_block;
|
||||||
|
@ -215,6 +221,7 @@ struct CheatVmOpcode {
|
||||||
StoreRegisterToAddressOpcode str_register;
|
StoreRegisterToAddressOpcode str_register;
|
||||||
BeginRegisterConditionalOpcode begin_reg_cond;
|
BeginRegisterConditionalOpcode begin_reg_cond;
|
||||||
SaveRestoreRegisterOpcode save_restore_reg;
|
SaveRestoreRegisterOpcode save_restore_reg;
|
||||||
|
SaveRestoreRegisterMaskOpcode save_restore_regmask;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue