summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2020-08-03 18:07:17 -0700
committerGravatar GitHub2020-08-03 18:07:17 -0700
commitc6e5a3645232eaddb19aa776969ac4942a7caa8b (patch)
tree7af49e4b94d58cee8eb8616724b1d3127938a893
parentMerge pull request #4456 from Morph1984/stub-really-long-fs-func (diff)
parentdmnt_cheat_vm: Make use of designated initializers (diff)
downloadyuzu-c6e5a3645232eaddb19aa776969ac4942a7caa8b.tar.gz
yuzu-c6e5a3645232eaddb19aa776969ac4942a7caa8b.tar.xz
yuzu-c6e5a3645232eaddb19aa776969ac4942a7caa8b.zip
Merge pull request #4473 from lioncash/cheat-desig
dmnt_cheat_vm: Make use of designated initializers
-rw-r--r--src/core/memory/dmnt_cheat_vm.cpp226
1 files changed, 121 insertions, 105 deletions
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp
index 2e7da23fe..48be80c12 100644
--- a/src/core/memory/dmnt_cheat_vm.cpp
+++ b/src/core/memory/dmnt_cheat_vm.cpp
@@ -313,30 +313,32 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
313 313
314 switch (opcode_type) { 314 switch (opcode_type) {
315 case CheatVmOpcodeType::StoreStatic: { 315 case CheatVmOpcodeType::StoreStatic: {
316 StoreStaticOpcode store_static{};
317 // 0TMR00AA AAAAAAAA YYYYYYYY (YYYYYYYY) 316 // 0TMR00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
318 // Read additional words. 317 // Read additional words.
319 const u32 second_dword = GetNextDword(); 318 const u32 second_dword = GetNextDword();
320 store_static.bit_width = (first_dword >> 24) & 0xF; 319 const u32 bit_width = (first_dword >> 24) & 0xF;
321 store_static.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); 320
322 store_static.offset_register = ((first_dword >> 16) & 0xF); 321 opcode.opcode = StoreStaticOpcode{
323 store_static.rel_address = 322 .bit_width = bit_width,
324 (static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); 323 .mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
325 store_static.value = GetNextVmInt(store_static.bit_width); 324 .offset_register = (first_dword >> 16) & 0xF,
326 opcode.opcode = store_static; 325 .rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
326 .value = GetNextVmInt(bit_width),
327 };
327 } break; 328 } break;
328 case CheatVmOpcodeType::BeginConditionalBlock: { 329 case CheatVmOpcodeType::BeginConditionalBlock: {
329 BeginConditionalOpcode begin_cond{};
330 // 1TMC00AA AAAAAAAA YYYYYYYY (YYYYYYYY) 330 // 1TMC00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
331 // Read additional words. 331 // Read additional words.
332 const u32 second_dword = GetNextDword(); 332 const u32 second_dword = GetNextDword();
333 begin_cond.bit_width = (first_dword >> 24) & 0xF; 333 const u32 bit_width = (first_dword >> 24) & 0xF;
334 begin_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); 334
335 begin_cond.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF); 335 opcode.opcode = BeginConditionalOpcode{
336 begin_cond.rel_address = 336 .bit_width = bit_width,
337 (static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); 337 .mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
338 begin_cond.value = GetNextVmInt(begin_cond.bit_width); 338 .cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF),
339 opcode.opcode = begin_cond; 339 .rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
340 .value = GetNextVmInt(bit_width),
341 };
340 } break; 342 } break;
341 case CheatVmOpcodeType::EndConditionalBlock: { 343 case CheatVmOpcodeType::EndConditionalBlock: {
342 // 20000000 344 // 20000000
@@ -344,12 +346,14 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
344 opcode.opcode = EndConditionalOpcode{}; 346 opcode.opcode = EndConditionalOpcode{};
345 } break; 347 } break;
346 case CheatVmOpcodeType::ControlLoop: { 348 case CheatVmOpcodeType::ControlLoop: {
347 ControlLoopOpcode ctrl_loop{};
348 // 300R0000 VVVVVVVV 349 // 300R0000 VVVVVVVV
349 // 310R0000 350 // 310R0000
350 // Parse register, whether loop start or loop end. 351 // Parse register, whether loop start or loop end.
351 ctrl_loop.start_loop = ((first_dword >> 24) & 0xF) == 0; 352 ControlLoopOpcode ctrl_loop{
352 ctrl_loop.reg_index = ((first_dword >> 20) & 0xF); 353 .start_loop = ((first_dword >> 24) & 0xF) == 0,
354 .reg_index = (first_dword >> 20) & 0xF,
355 .num_iters = 0,
356 };
353 357
354 // Read number of iters if loop start. 358 // Read number of iters if loop start.
355 if (ctrl_loop.start_loop) { 359 if (ctrl_loop.start_loop) {
@@ -358,66 +362,65 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
358 opcode.opcode = ctrl_loop; 362 opcode.opcode = ctrl_loop;
359 } break; 363 } break;
360 case CheatVmOpcodeType::LoadRegisterStatic: { 364 case CheatVmOpcodeType::LoadRegisterStatic: {
361 LoadRegisterStaticOpcode ldr_static{};
362 // 400R0000 VVVVVVVV VVVVVVVV 365 // 400R0000 VVVVVVVV VVVVVVVV
363 // Read additional words. 366 // Read additional words.
364 ldr_static.reg_index = ((first_dword >> 16) & 0xF); 367 opcode.opcode = LoadRegisterStaticOpcode{
365 ldr_static.value = 368 .reg_index = (first_dword >> 16) & 0xF,
366 (static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword()); 369 .value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(),
367 opcode.opcode = ldr_static; 370 };
368 } break; 371 } break;
369 case CheatVmOpcodeType::LoadRegisterMemory: { 372 case CheatVmOpcodeType::LoadRegisterMemory: {
370 LoadRegisterMemoryOpcode ldr_memory{};
371 // 5TMRI0AA AAAAAAAA 373 // 5TMRI0AA AAAAAAAA
372 // Read additional words. 374 // Read additional words.
373 const u32 second_dword = GetNextDword(); 375 const u32 second_dword = GetNextDword();
374 ldr_memory.bit_width = (first_dword >> 24) & 0xF; 376 opcode.opcode = LoadRegisterMemoryOpcode{
375 ldr_memory.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF); 377 .bit_width = (first_dword >> 24) & 0xF,
376 ldr_memory.reg_index = ((first_dword >> 16) & 0xF); 378 .mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
377 ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0; 379 .reg_index = ((first_dword >> 16) & 0xF),
378 ldr_memory.rel_address = 380 .load_from_reg = ((first_dword >> 12) & 0xF) != 0,
379 (static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword); 381 .rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
380 opcode.opcode = ldr_memory; 382 };
381 } break; 383 } break;
382 case CheatVmOpcodeType::StoreStaticToAddress: { 384 case CheatVmOpcodeType::StoreStaticToAddress: {
383 StoreStaticToAddressOpcode str_static{};
384 // 6T0RIor0 VVVVVVVV VVVVVVVV 385 // 6T0RIor0 VVVVVVVV VVVVVVVV
385 // Read additional words. 386 // Read additional words.
386 str_static.bit_width = (first_dword >> 24) & 0xF; 387 opcode.opcode = StoreStaticToAddressOpcode{
387 str_static.reg_index = ((first_dword >> 16) & 0xF); 388 .bit_width = (first_dword >> 24) & 0xF,
388 str_static.increment_reg = ((first_dword >> 12) & 0xF) != 0; 389 .reg_index = (first_dword >> 16) & 0xF,
389 str_static.add_offset_reg = ((first_dword >> 8) & 0xF) != 0; 390 .increment_reg = ((first_dword >> 12) & 0xF) != 0,
390 str_static.offset_reg_index = ((first_dword >> 4) & 0xF); 391 .add_offset_reg = ((first_dword >> 8) & 0xF) != 0,
391 str_static.value = 392 .offset_reg_index = (first_dword >> 4) & 0xF,
392 (static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword()); 393 .value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(),
393 opcode.opcode = str_static; 394 };
394 } break; 395 } break;
395 case CheatVmOpcodeType::PerformArithmeticStatic: { 396 case CheatVmOpcodeType::PerformArithmeticStatic: {
396 PerformArithmeticStaticOpcode perform_math_static{};
397 // 7T0RC000 VVVVVVVV 397 // 7T0RC000 VVVVVVVV
398 // Read additional words. 398 // Read additional words.
399 perform_math_static.bit_width = (first_dword >> 24) & 0xF; 399 opcode.opcode = PerformArithmeticStaticOpcode{
400 perform_math_static.reg_index = ((first_dword >> 16) & 0xF); 400 .bit_width = (first_dword >> 24) & 0xF,
401 perform_math_static.math_type = 401 .reg_index = ((first_dword >> 16) & 0xF),
402 static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF); 402 .math_type = static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF),
403 perform_math_static.value = GetNextDword(); 403 .value = GetNextDword(),
404 opcode.opcode = perform_math_static; 404 };
405 } break; 405 } break;
406 case CheatVmOpcodeType::BeginKeypressConditionalBlock: { 406 case CheatVmOpcodeType::BeginKeypressConditionalBlock: {
407 BeginKeypressConditionalOpcode begin_keypress_cond{};
408 // 8kkkkkkk 407 // 8kkkkkkk
409 // Just parse the mask. 408 // Just parse the mask.
410 begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; 409 opcode.opcode = BeginKeypressConditionalOpcode{
411 opcode.opcode = begin_keypress_cond; 410 .key_mask = first_dword & 0x0FFFFFFF,
411 };
412 } break; 412 } break;
413 case CheatVmOpcodeType::PerformArithmeticRegister: { 413 case CheatVmOpcodeType::PerformArithmeticRegister: {
414 PerformArithmeticRegisterOpcode perform_math_reg{};
415 // 9TCRSIs0 (VVVVVVVV (VVVVVVVV)) 414 // 9TCRSIs0 (VVVVVVVV (VVVVVVVV))
416 perform_math_reg.bit_width = (first_dword >> 24) & 0xF; 415 PerformArithmeticRegisterOpcode perform_math_reg{
417 perform_math_reg.math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF); 416 .bit_width = (first_dword >> 24) & 0xF,
418 perform_math_reg.dst_reg_index = ((first_dword >> 16) & 0xF); 417 .math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF),
419 perform_math_reg.src_reg_1_index = ((first_dword >> 12) & 0xF); 418 .dst_reg_index = (first_dword >> 16) & 0xF,
420 perform_math_reg.has_immediate = ((first_dword >> 8) & 0xF) != 0; 419 .src_reg_1_index = (first_dword >> 12) & 0xF,
420 .src_reg_2_index = 0,
421 .has_immediate = ((first_dword >> 8) & 0xF) != 0,
422 .value = {},
423 };
421 if (perform_math_reg.has_immediate) { 424 if (perform_math_reg.has_immediate) {
422 perform_math_reg.src_reg_2_index = 0; 425 perform_math_reg.src_reg_2_index = 0;
423 perform_math_reg.value = GetNextVmInt(perform_math_reg.bit_width); 426 perform_math_reg.value = GetNextVmInt(perform_math_reg.bit_width);
@@ -427,7 +430,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
427 opcode.opcode = perform_math_reg; 430 opcode.opcode = perform_math_reg;
428 } break; 431 } break;
429 case CheatVmOpcodeType::StoreRegisterToAddress: { 432 case CheatVmOpcodeType::StoreRegisterToAddress: {
430 StoreRegisterToAddressOpcode str_register{};
431 // ATSRIOxa (aaaaaaaa) 433 // ATSRIOxa (aaaaaaaa)
432 // A = opcode 10 434 // A = opcode 10
433 // T = bit width 435 // T = bit width
@@ -439,20 +441,23 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
439 // Relative Address 441 // Relative Address
440 // x = offset register (for offset type 1), memory type (for offset type 3) 442 // x = offset register (for offset type 1), memory type (for offset type 3)
441 // a = relative address (for offset type 2+3) 443 // a = relative address (for offset type 2+3)
442 str_register.bit_width = (first_dword >> 24) & 0xF; 444 StoreRegisterToAddressOpcode str_register{
443 str_register.str_reg_index = ((first_dword >> 20) & 0xF); 445 .bit_width = (first_dword >> 24) & 0xF,
444 str_register.addr_reg_index = ((first_dword >> 16) & 0xF); 446 .str_reg_index = (first_dword >> 20) & 0xF,
445 str_register.increment_reg = ((first_dword >> 12) & 0xF) != 0; 447 .addr_reg_index = (first_dword >> 16) & 0xF,
446 str_register.ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF)); 448 .increment_reg = ((first_dword >> 12) & 0xF) != 0,
447 str_register.ofs_reg_index = ((first_dword >> 4) & 0xF); 449 .ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF)),
450 .mem_type = MemoryAccessType::MainNso,
451 .ofs_reg_index = (first_dword >> 4) & 0xF,
452 .rel_address = 0,
453 };
448 switch (str_register.ofs_type) { 454 switch (str_register.ofs_type) {
449 case StoreRegisterOffsetType::None: 455 case StoreRegisterOffsetType::None:
450 case StoreRegisterOffsetType::Reg: 456 case StoreRegisterOffsetType::Reg:
451 // Nothing more to do 457 // Nothing more to do
452 break; 458 break;
453 case StoreRegisterOffsetType::Imm: 459 case StoreRegisterOffsetType::Imm:
454 str_register.rel_address = 460 str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
455 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
456 break; 461 break;
457 case StoreRegisterOffsetType::MemReg: 462 case StoreRegisterOffsetType::MemReg:
458 str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 463 str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
@@ -460,8 +465,7 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
460 case StoreRegisterOffsetType::MemImm: 465 case StoreRegisterOffsetType::MemImm:
461 case StoreRegisterOffsetType::MemImmReg: 466 case StoreRegisterOffsetType::MemImmReg:
462 str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 467 str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
463 str_register.rel_address = 468 str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
464 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
465 break; 469 break;
466 default: 470 default:
467 str_register.ofs_type = StoreRegisterOffsetType::None; 471 str_register.ofs_type = StoreRegisterOffsetType::None;
@@ -470,7 +474,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
470 opcode.opcode = str_register; 474 opcode.opcode = str_register;
471 } break; 475 } break;
472 case CheatVmOpcodeType::BeginRegisterConditionalBlock: { 476 case CheatVmOpcodeType::BeginRegisterConditionalBlock: {
473 BeginRegisterConditionalOpcode begin_reg_cond{};
474 // C0TcSX## 477 // C0TcSX##
475 // C0TcS0Ma aaaaaaaa 478 // C0TcS0Ma aaaaaaaa
476 // C0TcS1Mr 479 // C0TcS1Mr
@@ -492,11 +495,19 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
492 // r = offset register. 495 // r = offset register.
493 // X = other register. 496 // X = other register.
494 // V = value. 497 // V = value.
495 begin_reg_cond.bit_width = (first_dword >> 20) & 0xF; 498
496 begin_reg_cond.cond_type = 499 BeginRegisterConditionalOpcode begin_reg_cond{
497 static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF); 500 .bit_width = (first_dword >> 20) & 0xF,
498 begin_reg_cond.val_reg_index = ((first_dword >> 12) & 0xF); 501 .cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF),
499 begin_reg_cond.comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF); 502 .val_reg_index = (first_dword >> 12) & 0xF,
503 .comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF),
504 .mem_type = MemoryAccessType::MainNso,
505 .addr_reg_index = 0,
506 .other_reg_index = 0,
507 .ofs_reg_index = 0,
508 .rel_address = 0,
509 .value = {},
510 };
500 511
501 switch (begin_reg_cond.comp_type) { 512 switch (begin_reg_cond.comp_type) {
502 case CompareRegisterValueType::StaticValue: 513 case CompareRegisterValueType::StaticValue:
@@ -508,26 +519,25 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
508 case CompareRegisterValueType::MemoryRelAddr: 519 case CompareRegisterValueType::MemoryRelAddr:
509 begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 520 begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
510 begin_reg_cond.rel_address = 521 begin_reg_cond.rel_address =
511 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); 522 (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
512 break; 523 break;
513 case CompareRegisterValueType::MemoryOfsReg: 524 case CompareRegisterValueType::MemoryOfsReg:
514 begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 525 begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
515 begin_reg_cond.ofs_reg_index = (first_dword & 0xF); 526 begin_reg_cond.ofs_reg_index = (first_dword & 0xF);
516 break; 527 break;
517 case CompareRegisterValueType::RegisterRelAddr: 528 case CompareRegisterValueType::RegisterRelAddr:
518 begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF); 529 begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF;
519 begin_reg_cond.rel_address = 530 begin_reg_cond.rel_address =
520 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword())); 531 (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
521 break; 532 break;
522 case CompareRegisterValueType::RegisterOfsReg: 533 case CompareRegisterValueType::RegisterOfsReg:
523 begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF); 534 begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF;
524 begin_reg_cond.ofs_reg_index = (first_dword & 0xF); 535 begin_reg_cond.ofs_reg_index = first_dword & 0xF;
525 break; 536 break;
526 } 537 }
527 opcode.opcode = begin_reg_cond; 538 opcode.opcode = begin_reg_cond;
528 } break; 539 } break;
529 case CheatVmOpcodeType::SaveRestoreRegister: { 540 case CheatVmOpcodeType::SaveRestoreRegister: {
530 SaveRestoreRegisterOpcode save_restore_reg{};
531 // C10D0Sx0 541 // C10D0Sx0
532 // C1 = opcode 0xC1 542 // C1 = opcode 0xC1
533 // D = destination index. 543 // D = destination index.
@@ -535,36 +545,37 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
535 // x = 3 if clearing reg, 2 if clearing saved value, 1 if saving a register, 0 if restoring 545 // x = 3 if clearing reg, 2 if clearing saved value, 1 if saving a register, 0 if restoring
536 // a register. 546 // a register.
537 // NOTE: If we add more save slots later, current encoding is backwards compatible. 547 // NOTE: If we add more save slots later, current encoding is backwards compatible.
538 save_restore_reg.dst_index = (first_dword >> 16) & 0xF; 548 opcode.opcode = SaveRestoreRegisterOpcode{
539 save_restore_reg.src_index = (first_dword >> 8) & 0xF; 549 .dst_index = (first_dword >> 16) & 0xF,
540 save_restore_reg.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF); 550 .src_index = (first_dword >> 8) & 0xF,
541 opcode.opcode = save_restore_reg; 551 .op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF),
552 };
542 } break; 553 } break;
543 case CheatVmOpcodeType::SaveRestoreRegisterMask: { 554 case CheatVmOpcodeType::SaveRestoreRegisterMask: {
544 SaveRestoreRegisterMaskOpcode save_restore_regmask{};
545 // C2x0XXXX 555 // C2x0XXXX
546 // C2 = opcode 0xC2 556 // C2 = opcode 0xC2
547 // x = 3 if clearing reg, 2 if clearing saved value, 1 if saving, 0 if restoring. 557 // x = 3 if clearing reg, 2 if clearing saved value, 1 if saving, 0 if restoring.
548 // X = 16-bit bitmask, bit i --> save or restore register i. 558 // X = 16-bit bitmask, bit i --> save or restore register i.
549 save_restore_regmask.op_type = 559 SaveRestoreRegisterMaskOpcode save_restore_regmask{
550 static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF); 560 .op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF),
561 .should_operate = {},
562 };
551 for (std::size_t i = 0; i < NumRegisters; i++) { 563 for (std::size_t i = 0; i < NumRegisters; i++) {
552 save_restore_regmask.should_operate[i] = (first_dword & (1u << i)) != 0; 564 save_restore_regmask.should_operate[i] = (first_dword & (1U << i)) != 0;
553 } 565 }
554 opcode.opcode = save_restore_regmask; 566 opcode.opcode = save_restore_regmask;
555 } break; 567 } break;
556 case CheatVmOpcodeType::ReadWriteStaticRegister: { 568 case CheatVmOpcodeType::ReadWriteStaticRegister: {
557 ReadWriteStaticRegisterOpcode rw_static_reg{};
558 // C3000XXx 569 // C3000XXx
559 // C3 = opcode 0xC3. 570 // C3 = opcode 0xC3.
560 // XX = static register index. 571 // XX = static register index.
561 // x = register index. 572 // x = register index.
562 rw_static_reg.static_idx = ((first_dword >> 4) & 0xFF); 573 opcode.opcode = ReadWriteStaticRegisterOpcode{
563 rw_static_reg.idx = (first_dword & 0xF); 574 .static_idx = (first_dword >> 4) & 0xFF,
564 opcode.opcode = rw_static_reg; 575 .idx = first_dword & 0xF,
576 };
565 } break; 577 } break;
566 case CheatVmOpcodeType::DebugLog: { 578 case CheatVmOpcodeType::DebugLog: {
567 DebugLogOpcode debug_log{};
568 // FFFTIX## 579 // FFFTIX##
569 // FFFTI0Ma aaaaaaaa 580 // FFFTI0Ma aaaaaaaa
570 // FFFTI1Mr 581 // FFFTI1Mr
@@ -583,31 +594,36 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
583 // a = relative address. 594 // a = relative address.
584 // r = offset register. 595 // r = offset register.
585 // X = value register. 596 // X = value register.
586 debug_log.bit_width = (first_dword >> 16) & 0xF; 597 DebugLogOpcode debug_log{
587 debug_log.log_id = ((first_dword >> 12) & 0xF); 598 .bit_width = (first_dword >> 16) & 0xF,
588 debug_log.val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF); 599 .log_id = (first_dword >> 12) & 0xF,
600 .val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF),
601 .mem_type = MemoryAccessType::MainNso,
602 .addr_reg_index = 0,
603 .val_reg_index = 0,
604 .ofs_reg_index = 0,
605 .rel_address = 0,
606 };
589 607
590 switch (debug_log.val_type) { 608 switch (debug_log.val_type) {
591 case DebugLogValueType::RegisterValue: 609 case DebugLogValueType::RegisterValue:
592 debug_log.val_reg_index = ((first_dword >> 4) & 0xF); 610 debug_log.val_reg_index = (first_dword >> 4) & 0xF;
593 break; 611 break;
594 case DebugLogValueType::MemoryRelAddr: 612 case DebugLogValueType::MemoryRelAddr:
595 debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 613 debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
596 debug_log.rel_address = 614 debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
597 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
598 break; 615 break;
599 case DebugLogValueType::MemoryOfsReg: 616 case DebugLogValueType::MemoryOfsReg:
600 debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF); 617 debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
601 debug_log.ofs_reg_index = (first_dword & 0xF); 618 debug_log.ofs_reg_index = first_dword & 0xF;
602 break; 619 break;
603 case DebugLogValueType::RegisterRelAddr: 620 case DebugLogValueType::RegisterRelAddr:
604 debug_log.addr_reg_index = ((first_dword >> 4) & 0xF); 621 debug_log.addr_reg_index = (first_dword >> 4) & 0xF;
605 debug_log.rel_address = 622 debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
606 ((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
607 break; 623 break;
608 case DebugLogValueType::RegisterOfsReg: 624 case DebugLogValueType::RegisterOfsReg:
609 debug_log.addr_reg_index = ((first_dword >> 4) & 0xF); 625 debug_log.addr_reg_index = (first_dword >> 4) & 0xF;
610 debug_log.ofs_reg_index = (first_dword & 0xF); 626 debug_log.ofs_reg_index = first_dword & 0xF;
611 break; 627 break;
612 } 628 }
613 opcode.opcode = debug_log; 629 opcode.opcode = debug_log;