diff options
| author | 2018-11-21 14:32:21 -0500 | |
|---|---|---|
| committer | 2018-11-22 00:58:00 -0500 | |
| commit | 033b46253e6c7de33c5f8b51adb9d96ca606669d (patch) | |
| tree | af5ad3a30c91e3e769e55eb542f8455bed694ccf /src/video_core/macro_interpreter.cpp | |
| parent | Merge pull request #1754 from ReinUsesLisp/zero-register (diff) | |
| download | yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.gz yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.xz yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.zip | |
macro_interpreter: Implement AddWithCarry and SubtractWithBorrow.
- Used by Undertale.
Diffstat (limited to 'src/video_core/macro_interpreter.cpp')
| -rw-r--r-- | src/video_core/macro_interpreter.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 335a8d407..2b0dea5cd 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp | |||
| @@ -35,6 +35,7 @@ void MacroInterpreter::Reset() { | |||
| 35 | // The next parameter index starts at 1, because $r1 already has the value of the first | 35 | // The next parameter index starts at 1, because $r1 already has the value of the first |
| 36 | // parameter. | 36 | // parameter. |
| 37 | next_parameter_index = 1; | 37 | next_parameter_index = 1; |
| 38 | carry_flag = false; | ||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) { | 41 | bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) { |
| @@ -135,14 +136,28 @@ MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const { | |||
| 135 | return {macro_memory[offset + pc / sizeof(u32)]}; | 136 | return {macro_memory[offset + pc / sizeof(u32)]}; |
| 136 | } | 137 | } |
| 137 | 138 | ||
| 138 | u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const { | 139 | u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) { |
| 139 | switch (operation) { | 140 | switch (operation) { |
| 140 | case ALUOperation::Add: | 141 | case ALUOperation::Add: { |
| 141 | return src_a + src_b; | 142 | const u64 result{static_cast<u64>(src_a) + src_b}; |
| 142 | // TODO(Subv): Implement AddWithCarry | 143 | carry_flag = result > 0xffffffff; |
| 143 | case ALUOperation::Subtract: | 144 | return static_cast<u32>(result); |
| 144 | return src_a - src_b; | 145 | } |
| 145 | // TODO(Subv): Implement SubtractWithBorrow | 146 | case ALUOperation::AddWithCarry: { |
| 147 | const u64 result{static_cast<u64>(src_a) + src_b + (carry_flag ? 1ULL : 0ULL)}; | ||
| 148 | carry_flag = result > 0xffffffff; | ||
| 149 | return static_cast<u32>(result); | ||
| 150 | } | ||
| 151 | case ALUOperation::Subtract: { | ||
| 152 | const u64 result{static_cast<u64>(src_a) - src_b}; | ||
| 153 | carry_flag = result < 0x100000000; | ||
| 154 | return static_cast<u32>(result); | ||
| 155 | } | ||
| 156 | case ALUOperation::SubtractWithBorrow: { | ||
| 157 | const u64 result{static_cast<u64>(src_a) - src_b - (carry_flag ? 0ULL : 1ULL)}; | ||
| 158 | carry_flag = result < 0x100000000; | ||
| 159 | return static_cast<u32>(result); | ||
| 160 | } | ||
| 146 | case ALUOperation::Xor: | 161 | case ALUOperation::Xor: |
| 147 | return src_a ^ src_b; | 162 | return src_a ^ src_b; |
| 148 | case ALUOperation::Or: | 163 | case ALUOperation::Or: |