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:
parent
2f684ee66d
commit
76767110b7
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user