macro_interpreter: Implement AddWithCarry and SubtractWithBorrow.
- Used by Undertale.
This commit is contained in:
parent
bb175ab430
commit
033b46253e
@ -35,6 +35,7 @@ void MacroInterpreter::Reset() {
|
|||||||
// The next parameter index starts at 1, because $r1 already has the value of the first
|
// The next parameter index starts at 1, because $r1 already has the value of the first
|
||||||
// parameter.
|
// parameter.
|
||||||
next_parameter_index = 1;
|
next_parameter_index = 1;
|
||||||
|
carry_flag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
|
bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
|
||||||
@ -135,14 +136,28 @@ MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const {
|
|||||||
return {macro_memory[offset + pc / sizeof(u32)]};
|
return {macro_memory[offset + pc / sizeof(u32)]};
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const {
|
u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case ALUOperation::Add:
|
case ALUOperation::Add: {
|
||||||
return src_a + src_b;
|
const u64 result{static_cast<u64>(src_a) + src_b};
|
||||||
// TODO(Subv): Implement AddWithCarry
|
carry_flag = result > 0xffffffff;
|
||||||
case ALUOperation::Subtract:
|
return static_cast<u32>(result);
|
||||||
return src_a - src_b;
|
}
|
||||||
// TODO(Subv): Implement SubtractWithBorrow
|
case ALUOperation::AddWithCarry: {
|
||||||
|
const u64 result{static_cast<u64>(src_a) + src_b + (carry_flag ? 1ULL : 0ULL)};
|
||||||
|
carry_flag = result > 0xffffffff;
|
||||||
|
return static_cast<u32>(result);
|
||||||
|
}
|
||||||
|
case ALUOperation::Subtract: {
|
||||||
|
const u64 result{static_cast<u64>(src_a) - src_b};
|
||||||
|
carry_flag = result < 0x100000000;
|
||||||
|
return static_cast<u32>(result);
|
||||||
|
}
|
||||||
|
case ALUOperation::SubtractWithBorrow: {
|
||||||
|
const u64 result{static_cast<u64>(src_a) - src_b - (carry_flag ? 0ULL : 1ULL)};
|
||||||
|
carry_flag = result < 0x100000000;
|
||||||
|
return static_cast<u32>(result);
|
||||||
|
}
|
||||||
case ALUOperation::Xor:
|
case ALUOperation::Xor:
|
||||||
return src_a ^ src_b;
|
return src_a ^ src_b;
|
||||||
case ALUOperation::Or:
|
case ALUOperation::Or:
|
||||||
|
@ -117,7 +117,7 @@ private:
|
|||||||
bool Step(u32 offset, bool is_delay_slot);
|
bool Step(u32 offset, bool is_delay_slot);
|
||||||
|
|
||||||
/// Calculates the result of an ALU operation. src_a OP src_b;
|
/// Calculates the result of an ALU operation. src_a OP src_b;
|
||||||
u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const;
|
u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b);
|
||||||
|
|
||||||
/// Performs the result operation on the input result and stores it in the specified register
|
/// Performs the result operation on the input result and stores it in the specified register
|
||||||
/// (if necessary).
|
/// (if necessary).
|
||||||
@ -165,5 +165,7 @@ private:
|
|||||||
std::vector<u32> parameters;
|
std::vector<u32> parameters;
|
||||||
/// Index of the next parameter that will be fetched by the 'parm' instruction.
|
/// Index of the next parameter that will be fetched by the 'parm' instruction.
|
||||||
u32 next_parameter_index = 0;
|
u32 next_parameter_index = 0;
|
||||||
|
|
||||||
|
bool carry_flag{};
|
||||||
};
|
};
|
||||||
} // namespace Tegra
|
} // namespace Tegra
|
||||||
|
Loading…
Reference in New Issue
Block a user