1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-23 06:28:59 +00:00

Knocks SBC into producing likely results; disables Lorenz testing.

This commit is contained in:
Thomas Harte 2020-10-10 17:13:16 -04:00
parent da4702851f
commit 0fe09cd1e4
2 changed files with 38 additions and 15 deletions

View File

@ -220,12 +220,10 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
func testFlagManipulation65816() { func testFlagManipulation65816() {
testFlagManipulation(processor: .processor65816) testFlagManipulation(processor: .processor65816)
} }
func testADC65816() { /*
runTest("adc", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816) ADC and SBC tests don't apply, as the 65816 follows the 65C02 in setting flags based on the outcome of decimal
} results, whereas Lorenzz's tests expect the original 6502 behaviour of setting flags based an intermediate value.
func testSBC65816() { */
runTest("sbc", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
}
// MARK: - Collections // MARK: - Collections

View File

@ -715,6 +715,34 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
#undef cp #undef cp
case SBC: case SBC:
if(flags_.decimal) {
// I've yet to manage to find a rational way to map this to an ADC,
// hence the yucky repetition of code here.
const uint16_t a = a_.full & m_masks_[1];
unsigned int result = 0;
unsigned int borrow = flags_.carry ^ 1;
#define nibble(mask, adjustment, carry) \
result += (a & mask) - (data_buffer_.value & mask) - borrow; \
if(result > mask) result -= adjustment;\
borrow = (result > mask) ? carry : 0; \
result &= (carry - 1);
nibble(0x000f, 0x0006, 0x00010);
nibble(0x00f0, 0x0060, 0x00100);
nibble(0x0f00, 0x0600, 0x01000);
nibble(0xf000, 0x6000, 0x10000);
#undef nibble
flags_.overflow = ~(( (result ^ a_.full) & (result ^ data_buffer_.value) ) >> (1 + m_shift_))&0x40;
flags_.set_nz(result, m_shift_);
flags_.carry = ((borrow >> 16)&1)^1;
LD(a_, result, m_masks_);
break;
}
data_buffer_.value = ~data_buffer_.value & m_masks_[1]; data_buffer_.value = ~data_buffer_.value & m_masks_[1];
[[fallthrough]]; [[fallthrough]];
@ -724,18 +752,15 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
if(flags_.decimal) { if(flags_.decimal) {
result = flags_.carry; result = flags_.carry;
const int nibble_adjustment = (active_instruction_->operation == SBC) ? 0xa : 0x6;
// TODO: this still isn't quite correct for SBC as the limit test is wrong, I think. #define nibble(mask, limit, adjustment, carry) \
#define nibble(mask, limit, addition, carry) \
result += (a & mask) + (data_buffer_.value & mask); \ result += (a & mask) + (data_buffer_.value & mask); \
if(result >= limit) result = ((result + (addition)) & (carry - 1)) + carry; if(result >= limit) result = ((result + (adjustment)) & (carry - 1)) + carry;
nibble(0x000f, 0x000a, nibble_adjustment << 0, 0x00010); nibble(0x000f, 0x000a, 0x0006, 0x00010);
nibble(0x00f0, 0x00a0, nibble_adjustment << 4, 0x00100); nibble(0x00f0, 0x00a0, 0x0060, 0x00100);
nibble(0x0f00, 0x0a00, nibble_adjustment << 8, 0x01000); nibble(0x0f00, 0x0a00, 0x0600, 0x01000);
nibble(0xf000, 0xa000, nibble_adjustment << 12, 0x10000); nibble(0xf000, 0xa000, 0x6000, 0x10000);
#undef nibble #undef nibble