|
|
|
@ -313,30 +313,32 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
|
|
|
|
switch (opcode_type) { |
|
|
|
case CheatVmOpcodeType::StoreStatic: { |
|
|
|
StoreStaticOpcode store_static{}; |
|
|
|
// 0TMR00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
|
|
|
|
// Read additional words.
|
|
|
|
const u32 second_dword = GetNextDword(); |
|
|
|
store_static.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
store_static.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); |
|
|
|
store_static.offset_register = ((first_dword >> 16) & 0xF); |
|
|
|
store_static.rel_address = |
|
|
|
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); |
|
|
|
store_static.value = GetNextVmInt(store_static.bit_width); |
|
|
|
opcode.opcode = store_static; |
|
|
|
const u32 bit_width = (first_dword >> 24) & 0xF; |
|
|
|
|
|
|
|
opcode.opcode = StoreStaticOpcode{ |
|
|
|
.bit_width = bit_width, |
|
|
|
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF), |
|
|
|
.offset_register = (first_dword >> 16) & 0xF, |
|
|
|
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword, |
|
|
|
.value = GetNextVmInt(bit_width), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::BeginConditionalBlock: { |
|
|
|
BeginConditionalOpcode begin_cond{}; |
|
|
|
// 1TMC00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
|
|
|
|
// Read additional words.
|
|
|
|
const u32 second_dword = GetNextDword(); |
|
|
|
begin_cond.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
begin_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); |
|
|
|
begin_cond.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF); |
|
|
|
begin_cond.rel_address = |
|
|
|
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); |
|
|
|
begin_cond.value = GetNextVmInt(begin_cond.bit_width); |
|
|
|
opcode.opcode = begin_cond; |
|
|
|
const u32 bit_width = (first_dword >> 24) & 0xF; |
|
|
|
|
|
|
|
opcode.opcode = BeginConditionalOpcode{ |
|
|
|
.bit_width = bit_width, |
|
|
|
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF), |
|
|
|
.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF), |
|
|
|
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword, |
|
|
|
.value = GetNextVmInt(bit_width), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::EndConditionalBlock: { |
|
|
|
// 20000000
|
|
|
|
@ -344,12 +346,14 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
opcode.opcode = EndConditionalOpcode{}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::ControlLoop: { |
|
|
|
ControlLoopOpcode ctrl_loop{}; |
|
|
|
// 300R0000 VVVVVVVV
|
|
|
|
// 310R0000
|
|
|
|
// Parse register, whether loop start or loop end.
|
|
|
|
ctrl_loop.start_loop = ((first_dword >> 24) & 0xF) == 0; |
|
|
|
ctrl_loop.reg_index = ((first_dword >> 20) & 0xF); |
|
|
|
ControlLoopOpcode ctrl_loop{ |
|
|
|
.start_loop = ((first_dword >> 24) & 0xF) == 0, |
|
|
|
.reg_index = (first_dword >> 20) & 0xF, |
|
|
|
.num_iters = 0, |
|
|
|
}; |
|
|
|
|
|
|
|
// Read number of iters if loop start.
|
|
|
|
if (ctrl_loop.start_loop) { |
|
|
|
@ -358,66 +362,65 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
opcode.opcode = ctrl_loop; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::LoadRegisterStatic: { |
|
|
|
LoadRegisterStaticOpcode ldr_static{}; |
|
|
|
// 400R0000 VVVVVVVV VVVVVVVV
|
|
|
|
// Read additional words.
|
|
|
|
ldr_static.reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
ldr_static.value = |
|
|
|
(static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword()); |
|
|
|
opcode.opcode = ldr_static; |
|
|
|
opcode.opcode = LoadRegisterStaticOpcode{ |
|
|
|
.reg_index = (first_dword >> 16) & 0xF, |
|
|
|
.value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::LoadRegisterMemory: { |
|
|
|
LoadRegisterMemoryOpcode ldr_memory{}; |
|
|
|
// 5TMRI0AA AAAAAAAA
|
|
|
|
// Read additional words.
|
|
|
|
const u32 second_dword = GetNextDword(); |
|
|
|
ldr_memory.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
ldr_memory.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); |
|
|
|
ldr_memory.reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0; |
|
|
|
ldr_memory.rel_address = |
|
|
|
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); |
|
|
|
opcode.opcode = ldr_memory; |
|
|
|
opcode.opcode = LoadRegisterMemoryOpcode{ |
|
|
|
.bit_width = (first_dword >> 24) & 0xF, |
|
|
|
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF), |
|
|
|
.reg_index = ((first_dword >> 16) & 0xF), |
|
|
|
.load_from_reg = ((first_dword >> 12) & 0xF) != 0, |
|
|
|
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword, |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::StoreStaticToAddress: { |
|
|
|
StoreStaticToAddressOpcode str_static{}; |
|
|
|
// 6T0RIor0 VVVVVVVV VVVVVVVV
|
|
|
|
// Read additional words.
|
|
|
|
str_static.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
str_static.reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
str_static.increment_reg = ((first_dword >> 12) & 0xF) != 0; |
|
|
|
str_static.add_offset_reg = ((first_dword >> 8) & 0xF) != 0; |
|
|
|
str_static.offset_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
str_static.value = |
|
|
|
(static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword()); |
|
|
|
opcode.opcode = str_static; |
|
|
|
opcode.opcode = StoreStaticToAddressOpcode{ |
|
|
|
.bit_width = (first_dword >> 24) & 0xF, |
|
|
|
.reg_index = (first_dword >> 16) & 0xF, |
|
|
|
.increment_reg = ((first_dword >> 12) & 0xF) != 0, |
|
|
|
.add_offset_reg = ((first_dword >> 8) & 0xF) != 0, |
|
|
|
.offset_reg_index = (first_dword >> 4) & 0xF, |
|
|
|
.value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::PerformArithmeticStatic: { |
|
|
|
PerformArithmeticStaticOpcode perform_math_static{}; |
|
|
|
// 7T0RC000 VVVVVVVV
|
|
|
|
// Read additional words.
|
|
|
|
perform_math_static.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
perform_math_static.reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
perform_math_static.math_type = |
|
|
|
static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF); |
|
|
|
perform_math_static.value = GetNextDword(); |
|
|
|
opcode.opcode = perform_math_static; |
|
|
|
opcode.opcode = PerformArithmeticStaticOpcode{ |
|
|
|
.bit_width = (first_dword >> 24) & 0xF, |
|
|
|
.reg_index = ((first_dword >> 16) & 0xF), |
|
|
|
.math_type = static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF), |
|
|
|
.value = GetNextDword(), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::BeginKeypressConditionalBlock: { |
|
|
|
BeginKeypressConditionalOpcode begin_keypress_cond{}; |
|
|
|
// 8kkkkkkk
|
|
|
|
// Just parse the mask.
|
|
|
|
begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; |
|
|
|
opcode.opcode = begin_keypress_cond; |
|
|
|
opcode.opcode = BeginKeypressConditionalOpcode{ |
|
|
|
.key_mask = first_dword & 0x0FFFFFFF, |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::PerformArithmeticRegister: { |
|
|
|
PerformArithmeticRegisterOpcode perform_math_reg{}; |
|
|
|
// 9TCRSIs0 (VVVVVVVV (VVVVVVVV))
|
|
|
|
perform_math_reg.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
perform_math_reg.math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF); |
|
|
|
perform_math_reg.dst_reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
perform_math_reg.src_reg_1_index = ((first_dword >> 12) & 0xF); |
|
|
|
perform_math_reg.has_immediate = ((first_dword >> 8) & 0xF) != 0; |
|
|
|
PerformArithmeticRegisterOpcode perform_math_reg{ |
|
|
|
.bit_width = (first_dword >> 24) & 0xF, |
|
|
|
.math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF), |
|
|
|
.dst_reg_index = (first_dword >> 16) & 0xF, |
|
|
|
.src_reg_1_index = (first_dword >> 12) & 0xF, |
|
|
|
.src_reg_2_index = 0, |
|
|
|
.has_immediate = ((first_dword >> 8) & 0xF) != 0, |
|
|
|
.value = {}, |
|
|
|
}; |
|
|
|
if (perform_math_reg.has_immediate) { |
|
|
|
perform_math_reg.src_reg_2_index = 0; |
|
|
|
perform_math_reg.value = GetNextVmInt(perform_math_reg.bit_width); |
|
|
|
@ -427,7 +430,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
opcode.opcode = perform_math_reg; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::StoreRegisterToAddress: { |
|
|
|
StoreRegisterToAddressOpcode str_register{}; |
|
|
|
// ATSRIOxa (aaaaaaaa)
|
|
|
|
// A = opcode 10
|
|
|
|
// T = bit width
|
|
|
|
@ -439,20 +441,23 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
// Relative Address
|
|
|
|
// x = offset register (for offset type 1), memory type (for offset type 3)
|
|
|
|
// a = relative address (for offset type 2+3)
|
|
|
|
str_register.bit_width = (first_dword >> 24) & 0xF; |
|
|
|
str_register.str_reg_index = ((first_dword >> 20) & 0xF); |
|
|
|
str_register.addr_reg_index = ((first_dword >> 16) & 0xF); |
|
|
|
str_register.increment_reg = ((first_dword >> 12) & 0xF) != 0; |
|
|
|
str_register.ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF)); |
|
|
|
str_register.ofs_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
StoreRegisterToAddressOpcode str_register{ |
|
|
|
.bit_width = (first_dword >> 24) & 0xF, |
|
|
|
.str_reg_index = (first_dword >> 20) & 0xF, |
|
|
|
.addr_reg_index = (first_dword >> 16) & 0xF, |
|
|
|
.increment_reg = ((first_dword >> 12) & 0xF) != 0, |
|
|
|
.ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF)), |
|
|
|
.mem_type = MemoryAccessType::MainNso, |
|
|
|
.ofs_reg_index = (first_dword >> 4) & 0xF, |
|
|
|
.rel_address = 0, |
|
|
|
}; |
|
|
|
switch (str_register.ofs_type) { |
|
|
|
case StoreRegisterOffsetType::None: |
|
|
|
case StoreRegisterOffsetType::Reg: |
|
|
|
// Nothing more to do
|
|
|
|
break; |
|
|
|
case StoreRegisterOffsetType::Imm: |
|
|
|
str_register.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
case StoreRegisterOffsetType::MemReg: |
|
|
|
str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
@ -460,8 +465,7 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
case StoreRegisterOffsetType::MemImm: |
|
|
|
case StoreRegisterOffsetType::MemImmReg: |
|
|
|
str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
str_register.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
default: |
|
|
|
str_register.ofs_type = StoreRegisterOffsetType::None; |
|
|
|
@ -470,7 +474,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
opcode.opcode = str_register; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::BeginRegisterConditionalBlock: { |
|
|
|
BeginRegisterConditionalOpcode begin_reg_cond{}; |
|
|
|
// C0TcSX##
|
|
|
|
// C0TcS0Ma aaaaaaaa
|
|
|
|
// C0TcS1Mr
|
|
|
|
@ -492,11 +495,19 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
// r = offset register.
|
|
|
|
// X = other register.
|
|
|
|
// V = value.
|
|
|
|
begin_reg_cond.bit_width = (first_dword >> 20) & 0xF; |
|
|
|
begin_reg_cond.cond_type = |
|
|
|
static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF); |
|
|
|
begin_reg_cond.val_reg_index = ((first_dword >> 12) & 0xF); |
|
|
|
begin_reg_cond.comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF); |
|
|
|
|
|
|
|
BeginRegisterConditionalOpcode begin_reg_cond{ |
|
|
|
.bit_width = (first_dword >> 20) & 0xF, |
|
|
|
.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF), |
|
|
|
.val_reg_index = (first_dword >> 12) & 0xF, |
|
|
|
.comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF), |
|
|
|
.mem_type = MemoryAccessType::MainNso, |
|
|
|
.addr_reg_index = 0, |
|
|
|
.other_reg_index = 0, |
|
|
|
.ofs_reg_index = 0, |
|
|
|
.rel_address = 0, |
|
|
|
.value = {}, |
|
|
|
}; |
|
|
|
|
|
|
|
switch (begin_reg_cond.comp_type) { |
|
|
|
case CompareRegisterValueType::StaticValue: |
|
|
|
@ -508,26 +519,25 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
case CompareRegisterValueType::MemoryRelAddr: |
|
|
|
begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
begin_reg_cond.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
(static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
case CompareRegisterValueType::MemoryOfsReg: |
|
|
|
begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
begin_reg_cond.ofs_reg_index = (first_dword & 0xF); |
|
|
|
break; |
|
|
|
case CompareRegisterValueType::RegisterRelAddr: |
|
|
|
begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF; |
|
|
|
begin_reg_cond.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
(static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
case CompareRegisterValueType::RegisterOfsReg: |
|
|
|
begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
begin_reg_cond.ofs_reg_index = (first_dword & 0xF); |
|
|
|
begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF; |
|
|
|
begin_reg_cond.ofs_reg_index = first_dword & 0xF; |
|
|
|
break; |
|
|
|
} |
|
|
|
opcode.opcode = begin_reg_cond; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::SaveRestoreRegister: { |
|
|
|
SaveRestoreRegisterOpcode save_restore_reg{}; |
|
|
|
// C10D0Sx0
|
|
|
|
// C1 = opcode 0xC1
|
|
|
|
// D = destination index.
|
|
|
|
@ -535,36 +545,37 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
// x = 3 if clearing reg, 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.
|
|
|
|
save_restore_reg.dst_index = (first_dword >> 16) & 0xF; |
|
|
|
save_restore_reg.src_index = (first_dword >> 8) & 0xF; |
|
|
|
save_restore_reg.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF); |
|
|
|
opcode.opcode = save_restore_reg; |
|
|
|
opcode.opcode = SaveRestoreRegisterOpcode{ |
|
|
|
.dst_index = (first_dword >> 16) & 0xF, |
|
|
|
.src_index = (first_dword >> 8) & 0xF, |
|
|
|
.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF), |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::SaveRestoreRegisterMask: { |
|
|
|
SaveRestoreRegisterMaskOpcode save_restore_regmask{}; |
|
|
|
// C2x0XXXX
|
|
|
|
// C2 = opcode 0xC2
|
|
|
|
// x = 3 if clearing reg, 2 if clearing saved value, 1 if saving, 0 if restoring.
|
|
|
|
// X = 16-bit bitmask, bit i --> save or restore register i.
|
|
|
|
save_restore_regmask.op_type = |
|
|
|
static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF); |
|
|
|
SaveRestoreRegisterMaskOpcode save_restore_regmask{ |
|
|
|
.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF), |
|
|
|
.should_operate = {}, |
|
|
|
}; |
|
|
|
for (std::size_t i = 0; i < NumRegisters; i++) { |
|
|
|
save_restore_regmask.should_operate[i] = (first_dword & (1u << i)) != 0; |
|
|
|
save_restore_regmask.should_operate[i] = (first_dword & (1U << i)) != 0; |
|
|
|
} |
|
|
|
opcode.opcode = save_restore_regmask; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::ReadWriteStaticRegister: { |
|
|
|
ReadWriteStaticRegisterOpcode rw_static_reg{}; |
|
|
|
// C3000XXx
|
|
|
|
// C3 = opcode 0xC3.
|
|
|
|
// XX = static register index.
|
|
|
|
// x = register index.
|
|
|
|
rw_static_reg.static_idx = ((first_dword >> 4) & 0xFF); |
|
|
|
rw_static_reg.idx = (first_dword & 0xF); |
|
|
|
opcode.opcode = rw_static_reg; |
|
|
|
opcode.opcode = ReadWriteStaticRegisterOpcode{ |
|
|
|
.static_idx = (first_dword >> 4) & 0xFF, |
|
|
|
.idx = first_dword & 0xF, |
|
|
|
}; |
|
|
|
} break; |
|
|
|
case CheatVmOpcodeType::DebugLog: { |
|
|
|
DebugLogOpcode debug_log{}; |
|
|
|
// FFFTIX##
|
|
|
|
// FFFTI0Ma aaaaaaaa
|
|
|
|
// FFFTI1Mr
|
|
|
|
@ -583,31 +594,36 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { |
|
|
|
// a = relative address.
|
|
|
|
// r = offset register.
|
|
|
|
// X = value register.
|
|
|
|
debug_log.bit_width = (first_dword >> 16) & 0xF; |
|
|
|
debug_log.log_id = ((first_dword >> 12) & 0xF); |
|
|
|
debug_log.val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF); |
|
|
|
DebugLogOpcode debug_log{ |
|
|
|
.bit_width = (first_dword >> 16) & 0xF, |
|
|
|
.log_id = (first_dword >> 12) & 0xF, |
|
|
|
.val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF), |
|
|
|
.mem_type = MemoryAccessType::MainNso, |
|
|
|
.addr_reg_index = 0, |
|
|
|
.val_reg_index = 0, |
|
|
|
.ofs_reg_index = 0, |
|
|
|
.rel_address = 0, |
|
|
|
}; |
|
|
|
|
|
|
|
switch (debug_log.val_type) { |
|
|
|
case DebugLogValueType::RegisterValue: |
|
|
|
debug_log.val_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
debug_log.val_reg_index = (first_dword >> 4) & 0xF; |
|
|
|
break; |
|
|
|
case DebugLogValueType::MemoryRelAddr: |
|
|
|
debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
debug_log.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
case DebugLogValueType::MemoryOfsReg: |
|
|
|
debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); |
|
|
|
debug_log.ofs_reg_index = (first_dword & 0xF); |
|
|
|
debug_log.ofs_reg_index = first_dword & 0xF; |
|
|
|
break; |
|
|
|
case DebugLogValueType::RegisterRelAddr: |
|
|
|
debug_log.addr_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
debug_log.rel_address = |
|
|
|
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); |
|
|
|
debug_log.addr_reg_index = (first_dword >> 4) & 0xF; |
|
|
|
debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword(); |
|
|
|
break; |
|
|
|
case DebugLogValueType::RegisterOfsReg: |
|
|
|
debug_log.addr_reg_index = ((first_dword >> 4) & 0xF); |
|
|
|
debug_log.ofs_reg_index = (first_dword & 0xF); |
|
|
|
debug_log.addr_reg_index = (first_dword >> 4) & 0xF; |
|
|
|
debug_log.ofs_reg_index = first_dword & 0xF; |
|
|
|
break; |
|
|
|
} |
|
|
|
opcode.opcode = debug_log; |
|
|
|
|