1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Fix overflow for 8-bit calculations; essentially a revert for ADC.

This commit is contained in:
Thomas Harte 2022-06-22 15:12:08 -04:00
parent 2f684ee66d
commit 76767110b7

View File

@ -910,33 +910,25 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
case SBC: case SBC:
if(registers_.flags.decimal) { if(registers_.flags.decimal) {
const uint16_t a = registers_.a.full & registers_.m_masks[1]; const uint16_t a = registers_.a.full & registers_.m_masks[1];
const uint16_t decimal_result = uint16_t(a - data_buffer_.value - (1 ^ registers_.flags.carry));
data_buffer_.value = ~data_buffer_.value & registers_.m_masks[1]; data_buffer_.value = ~data_buffer_.value & registers_.m_masks[1];
#define begin_nibble(mask) \ unsigned int result = registers_.flags.carry;
result += (a & mask) + (data_buffer_.value & mask); uint16_t partials = 0;
#define end_nibble(adjustment, carry) \ #define nibble(mask, adjustment, carry) \
if(result < carry) result -= adjustment; \ result += (a & mask) + (data_buffer_.value & mask); \
partials += result & mask; \
if(result < carry) result -= adjustment; \
result &= (carry | (carry - 1)); result &= (carry | (carry - 1));
#define nibble(mask, adjustment, carry) \
begin_nibble(mask); \
end_nibble(adjustment, carry)
unsigned int result = registers_.flags.carry;
nibble(0x000f, 0x0006, 0x00010); nibble(0x000f, 0x0006, 0x00010);
nibble(0x00f0, 0x0060, 0x00100); nibble(0x00f0, 0x0060, 0x00100);
nibble(0x0f00, 0x0600, 0x01000); nibble(0x0f00, 0x0600, 0x01000);
nibble(0xf000, 0x6000, 0x10000);
begin_nibble(0xf000);
registers_.flags.overflow = uint8_t((( (decimal_result ^ result) & (~decimal_result ^ result) ) >> (1 + registers_.m_shift))&0x40);
end_nibble(0x6000, 0x10000);
#undef nibble #undef nibble
#undef begin_nibble
#undef end_nibble
registers_.flags.overflow = (( (partials ^ registers_.a.full) & (partials ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;
registers_.flags.set_nz(uint16_t(result), registers_.m_shift); registers_.flags.set_nz(uint16_t(result), registers_.m_shift);
registers_.flags.carry = (result >> (8 + registers_.m_shift))&1; registers_.flags.carry = (result >> (8 + registers_.m_shift))&1;
LDA(result); LDA(result);
@ -945,7 +937,6 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
} }
data_buffer_.value = ~data_buffer_.value & registers_.m_masks[1]; data_buffer_.value = ~data_buffer_.value & registers_.m_masks[1];
[[fallthrough]]; [[fallthrough]];
case ADC: { case ADC: {
@ -953,29 +944,22 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
const uint16_t a = registers_.a.full & registers_.m_masks[1]; const uint16_t a = registers_.a.full & registers_.m_masks[1];
if(registers_.flags.decimal) { if(registers_.flags.decimal) {
#define begin_nibble(mask) \ uint16_t partials = 0;
result += (a & mask) + (data_buffer_.value & mask); result = registers_.flags.carry;
#define end_nibble(limit, adjustment, carry) \ #define nibble(mask, limit, adjustment, carry) \
result += (a & mask) + (data_buffer_.value & mask); \
partials += result & mask; \
if(result >= limit) result = ((result + adjustment) & (carry - 1)) + carry; if(result >= limit) result = ((result + adjustment) & (carry - 1)) + carry;
#define nibble(mask, limit, adjustment, carry) \
begin_nibble(mask); \
end_nibble(limit, adjustment, carry)
result = registers_.flags.carry;
nibble(0x000f, 0x000a, 0x0006, 0x00010); nibble(0x000f, 0x000a, 0x0006, 0x00010);
nibble(0x00f0, 0x00a0, 0x0060, 0x00100); nibble(0x00f0, 0x00a0, 0x0060, 0x00100);
nibble(0x0f00, 0x0a00, 0x0600, 0x01000); nibble(0x0f00, 0x0a00, 0x0600, 0x01000);
nibble(0xf000, 0xa000, 0x6000, 0x10000);
begin_nibble(0xf000);
registers_.flags.overflow = (( (uint16_t(result) ^ registers_.a.full) & (uint16_t(result) ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;
end_nibble(0xa000, 0x6000, 0x10000);
#undef nibble #undef nibble
#undef begin_nibble
#undef end_nibble
registers_.flags.overflow = (( (partials ^ registers_.a.full) & (partials ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;
} else { } else {
result = int(a + data_buffer_.value + registers_.flags.carry); result = int(a + data_buffer_.value + registers_.flags.carry);
registers_.flags.overflow = (( (uint16_t(result) ^ registers_.a.full) & (uint16_t(result) ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40; registers_.flags.overflow = (( (uint16_t(result) ^ registers_.a.full) & (uint16_t(result) ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;