mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
dmnt-cheat: add clear to save/restore reg
This commit is contained in:
parent
2f1f56307d
commit
c7ffcad74e
2 changed files with 47 additions and 22 deletions
|
@ -192,13 +192,13 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode *opcode) {
|
||||||
this->LogToDebugFile("Opcode: Save or Restore Register\n");
|
this->LogToDebugFile("Opcode: Save or Restore Register\n");
|
||||||
this->LogToDebugFile("Dst Idx: %x\n", opcode->save_restore_reg.dst_index);
|
this->LogToDebugFile("Dst Idx: %x\n", opcode->save_restore_reg.dst_index);
|
||||||
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("Op Type: %d\n", opcode->save_restore_reg.op_type);
|
||||||
break;
|
break;
|
||||||
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
this->LogToDebugFile("Opcode: Save or Restore Register Mask\n");
|
this->LogToDebugFile("Opcode: Save or Restore Register Mask\n");
|
||||||
this->LogToDebugFile("Is Save: %d\n", opcode->save_restore_regmask.is_save);
|
this->LogToDebugFile("Op Type: %d\n", opcode->save_restore_regmask.op_type);
|
||||||
for (size_t i = 0; i < NumRegisters; i++) {
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
this->LogToDebugFile("Act[%02x]: %d\n", i, opcode->save_restore_regmask.should_save_or_restore[i]);
|
this->LogToDebugFile("Act[%02x]: %d\n", i, opcode->save_restore_regmask.should_operate[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -481,22 +481,22 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode *out) {
|
||||||
/* C1 = opcode 0xC1 */
|
/* C1 = opcode 0xC1 */
|
||||||
/* D = destination index. */
|
/* D = destination index. */
|
||||||
/* S = source index. */
|
/* S = source index. */
|
||||||
/* x = 1 if saving a register, 0 if restoring a register. */
|
/* x = 2 if clearing saved value, 1 if saving a register, 0 if restoring a register. */
|
||||||
/* NOTE: If we add more save slots later, current encoding is backwards compatible. */
|
/* NOTE: If we add more save slots later, current encoding is backwards compatible. */
|
||||||
opcode.save_restore_reg.dst_index = (first_dword >> 16) & 0xF;
|
opcode.save_restore_reg.dst_index = (first_dword >> 16) & 0xF;
|
||||||
opcode.save_restore_reg.src_index = (first_dword >> 8) & 0xF;
|
opcode.save_restore_reg.src_index = (first_dword >> 8) & 0xF;
|
||||||
opcode.save_restore_reg.is_save = ((first_dword >> 4) & 0xF) != 0;
|
opcode.save_restore_reg.op_type = (SaveRestoreRegisterOpType)((first_dword >> 4) & 0xF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
{
|
{
|
||||||
/* C2x0XXXX */
|
/* C2x0XXXX */
|
||||||
/* C2 = opcode 0xC2 */
|
/* C2 = opcode 0xC2 */
|
||||||
/* x = 1 if saving, 0 if restoring. */
|
/* x = 2 if clearing saved value, 1 if saving, 0 if restoring. */
|
||||||
/* X = 16-bit bitmask, bit i --> save or restore register i. */
|
/* X = 16-bit bitmask, bit i --> save or restore register i. */
|
||||||
opcode.save_restore_regmask.is_save = ((first_dword >> 20) & 0xF) != 0;
|
opcode.save_restore_regmask.op_type = (SaveRestoreRegisterOpType)((first_dword >> 20) & 0xF);
|
||||||
for (size_t i = 0; i < NumRegisters; i++) {
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
opcode.save_restore_regmask.should_save_or_restore[i] = (first_dword & (1u << i)) != 0;
|
opcode.save_restore_regmask.should_operate[i] = (first_dword & (1u << i)) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1009,25 +1009,44 @@ void DmntCheatVm::Execute(const CheatProcessMetadata *metadata) {
|
||||||
break;
|
break;
|
||||||
case CheatVmOpcodeType_SaveRestoreRegister:
|
case CheatVmOpcodeType_SaveRestoreRegister:
|
||||||
/* Save or restore a register. */
|
/* Save or restore a register. */
|
||||||
if (cur_opcode.save_restore_reg.is_save) {
|
switch (cur_opcode.save_restore_reg.op_type) {
|
||||||
this->saved_values[cur_opcode.save_restore_reg.dst_index] = this->registers[cur_opcode.save_restore_reg.src_index];
|
case SaveRestoreRegisterOpType_Clear:
|
||||||
} else {
|
this->saved_values[cur_opcode.save_restore_reg.dst_index] = 0ul;
|
||||||
this->registers[cur_opcode.save_restore_reg.dst_index] = this->saved_values[cur_opcode.save_restore_reg.src_index];
|
break;
|
||||||
|
case SaveRestoreRegisterOpType_Save:
|
||||||
|
this->saved_values[cur_opcode.save_restore_reg.dst_index] = this->registers[cur_opcode.save_restore_reg.src_index];
|
||||||
|
break;
|
||||||
|
case SaveRestoreRegisterOpType_Restore:
|
||||||
|
default:
|
||||||
|
this->registers[cur_opcode.save_restore_reg.dst_index] = this->saved_values[cur_opcode.save_restore_reg.src_index];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
case CheatVmOpcodeType_SaveRestoreRegisterMask:
|
||||||
/* Save or restore register mask. */
|
/* Save or restore register mask. */
|
||||||
|
if (cur_opcode.save_restore_reg.op_type == SaveRestoreRegisterOpType_Clear) {
|
||||||
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
|
if (cur_opcode.save_restore_regmask.should_operate[i]) {
|
||||||
|
this->saved_values[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
u64 *src;
|
u64 *src;
|
||||||
u64 *dst;
|
u64 *dst;
|
||||||
if (cur_opcode.save_restore_regmask.is_save) {
|
switch (cur_opcode.save_restore_regmask.op_type) {
|
||||||
src = this->registers;
|
case SaveRestoreRegisterOpType_Save:
|
||||||
dst = this->saved_values;
|
src = this->registers;
|
||||||
} else {
|
dst = this->saved_values;
|
||||||
src = this->registers;
|
break;
|
||||||
dst = this->saved_values;
|
case SaveRestoreRegisterOpType_Restore:
|
||||||
|
default:
|
||||||
|
src = this->registers;
|
||||||
|
dst = this->saved_values;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < NumRegisters; i++) {
|
for (size_t i = 0; i < NumRegisters; i++) {
|
||||||
if (cur_opcode.save_restore_regmask.should_save_or_restore[i]) {
|
if (cur_opcode.save_restore_regmask.should_operate[i]) {
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,12 @@ enum CompareRegisterValueType : u32 {
|
||||||
CompareRegisterValueType_OtherRegister = 5,
|
CompareRegisterValueType_OtherRegister = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SaveRestoreRegisterOpType : u32 {
|
||||||
|
SaveRestoreRegisterOpType_Restore = 0,
|
||||||
|
SaveRestoreRegisterOpType_Save = 1,
|
||||||
|
SaveRestoreRegisterOpType_Clear = 2,
|
||||||
|
};
|
||||||
|
|
||||||
union VmInt {
|
union VmInt {
|
||||||
u8 bit8;
|
u8 bit8;
|
||||||
u16 bit16;
|
u16 bit16;
|
||||||
|
@ -196,12 +202,12 @@ struct BeginRegisterConditionalOpcode {
|
||||||
struct SaveRestoreRegisterOpcode {
|
struct SaveRestoreRegisterOpcode {
|
||||||
u32 dst_index;
|
u32 dst_index;
|
||||||
u32 src_index;
|
u32 src_index;
|
||||||
bool is_save;
|
SaveRestoreRegisterOpType op_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SaveRestoreRegisterMaskOpcode {
|
struct SaveRestoreRegisterMaskOpcode {
|
||||||
bool is_save;
|
SaveRestoreRegisterOpType op_type;
|
||||||
bool should_save_or_restore[0x10];
|
bool should_operate[0x10];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CheatVmOpcode {
|
struct CheatVmOpcode {
|
||||||
|
|
Loading…
Reference in a new issue