1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-30 04:50:08 +00:00

Eliminate branches from SBCD.

This commit is contained in:
Thomas Harte 2022-05-12 15:18:03 -04:00
parent c6d84e7e60
commit 79c5af755f

View File

@ -37,10 +37,11 @@ template <
// Pull out the two halves, for simplicity.
const uint8_t source = src.b;
const uint8_t destination = dest.b;
const int extend = (status.extend_flag ? 1 : 0);
// Perform the BCD add 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);
const int unadjusted_result = destination + source + extend;
int result = (destination & 0xf) + (source & 0xf) + extend;
if(result > 0x09) result += 0x06;
result += (destination & 0xf0) + (source & 0xf0);
if(result > 0x9f) result += 0x60;
@ -788,29 +789,25 @@ template <
break;
#define sbcd(d) \
/* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \
const int unadjusted_result = destination - source - (status.extend_flag ? 1 : 0); \
const int extend = (status.extend_flag ? 1 : 0); \
const int unadjusted_result = destination - source - extend; \
\
int top = (destination & 0xf0) - (source & 0xf0); \
if(unadjusted_result & 0x100) top -= 0x60; \
const int top = (destination & 0xf0) - (source & 0xf0) - (0x60 & (unadjusted_result >> 4)); \
\
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; \
int result = (destination & 0xf) - (source & 0xf) - extend; \
const int low_adjustment = 0x06 & (result >> 4); \
status.extend_flag = status.carry_flag = Status::FlagT( \
(unadjusted_result - low_adjustment) & 0x300 \
); \
result = result + top - low_adjustment; \
\
/* Store the result. */ \
d = uint8_t(result);
d = uint8_t(result); \
\
/* Set all remaining flags essentially as if this were normal subtraction. */ \
status.zero_result |= d; \
status.negative_flag = result & 0x80; \
status.overflow_flag = unadjusted_result & ~result & 0x80; \
/*
SBCD subtracts the lowest byte of the source from that of the destination using