dmnt_cheat_vm: Make use of designated initializers
Allows for more compact code.
This commit is contained in:
		
							parent
							
								
									05781ce8c4
								
							
						
					
					
						commit
						c883666045
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user