diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index 0a069a4dd..5e8bb4e66 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -790,13 +790,21 @@ template < #define sbcd(d) \ /* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \ const int unadjusted_result = destination - source - (status.extend_flag ? 1 : 0); \ - int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0); \ - if(result & 0xf0) result -= 0x06; \ - result += (destination & 0xf0) - (source & 0xf0); \ - status.extend_flag = status.carry_flag = decltype(status.carry_flag)(unadjusted_result & 0x300); \ - if(unadjusted_result & 0x100) result -= 0x60; \ \ - /* Set all flags essentially as if this were normal subtraction. */ \ + int top = (destination & 0xf0) - (source & 0xf0); \ + if(unadjusted_result & 0x100) top -= 0x60; \ + \ + int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0); \ + if(result & 0xf0) { \ + result -= 0x06; \ + status.extend_flag = status.carry_flag = Status::FlagT((unadjusted_result - 0x6) & 0x300); \ + } else { \ + status.extend_flag = status.carry_flag = Status::FlagT(unadjusted_result & 0x300); \ + } \ + \ + result += top; \ + \ + /* Set all remaining flags essentially as if this were normal subtraction. */ \ status.zero_result |= result & 0xff; \ status.negative_flag = result & 0x80; \ status.overflow_flag = unadjusted_result & ~result & 0x80; \ diff --git a/InstructionSets/M68k/Status.hpp b/InstructionSets/M68k/Status.hpp index 5bfb5e94f..8d03ab8ab 100644 --- a/InstructionSets/M68k/Status.hpp +++ b/InstructionSets/M68k/Status.hpp @@ -15,6 +15,8 @@ namespace InstructionSet { namespace M68k { struct Status { + using FlagT = uint_fast32_t; + enum ConditionCode: uint16_t { Carry = (1 << 0), Overflow = (1 << 1), @@ -29,20 +31,20 @@ struct Status { }; /* b15 */ - uint_fast32_t trace_flag = 0; // The trace flag is set if this value is non-zero. + FlagT trace_flag = 0; // The trace flag is set if this value is non-zero. /* b13 */ - int is_supervisor = 0; // 1 => processor is in supervisor mode; 0 => it isn't. + int is_supervisor = 0; // 1 => processor is in supervisor mode; 0 => it isn't. /* b7–b9 */ - int interrupt_level = 0; // The direct integer value of the current interrupt level. + int interrupt_level = 0; // The direct integer value of the current interrupt level. /* b0–b4 */ - uint_fast32_t zero_result = 0; // The zero flag is set if this value is zero. - uint_fast32_t carry_flag = 0; // The carry flag is set if this value is non-zero. - uint_fast32_t extend_flag = 0; // The extend flag is set if this value is non-zero. - uint_fast32_t overflow_flag = 0; // The overflow flag is set if this value is non-zero. - uint_fast32_t negative_flag = 0; // The negative flag is set if this value is non-zero. + FlagT zero_result = 0; // The zero flag is set if this value is zero. + FlagT carry_flag = 0; // The carry flag is set if this value is non-zero. + FlagT extend_flag = 0; // The extend flag is set if this value is non-zero. + FlagT overflow_flag = 0; // The overflow flag is set if this value is non-zero. + FlagT negative_flag = 0; // The negative flag is set if this value is non-zero. /// Gets the current condition codes. constexpr uint16_t ccr() const { diff --git a/OSBindings/Mac/Clock SignalTests/68000flamewingTests.mm b/OSBindings/Mac/Clock SignalTests/68000flamewingTests.mm index 044fff358..5fef6eb97 100644 --- a/OSBindings/Mac/Clock SignalTests/68000flamewingTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000flamewingTests.mm @@ -86,8 +86,6 @@ using namespace InstructionSet::M68k; } } - return; - // Test NBCD. for(int source = 0; source < 256; source++) { for(int flags = 0; flags < 4; flags++) { @@ -96,7 +94,7 @@ using namespace InstructionSet::M68k; CPU::SlicedInt32 s, d; s.l = source; - perform( + perform( Preinstruction(), s, d, status, flow_controller); [self validate:bytes source:source dest:0 flags:flags result:s.l status:status operation:@"NBCD"];