diff --git a/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift b/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift index 75bfde211..6b6c108e2 100644 --- a/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift +++ b/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift @@ -167,10 +167,28 @@ class Z80MemptrTests: XCTestCase { } } - /* TODO: - ADD/ADC/SBC rp1,rp2 - MEMPTR = rp1_before_operation + 1 - */ + // ADD/ADC/SBC dest, src + func testADDADCSBCrr() { + // MEMPTR = dest prior to modification + 1 + let addProgram: [UInt8] = [ + 0x09 + ] + let adcProgram: [UInt8] = [ + 0xed, 0x4a + ] + let sbcProgram: [UInt8] = [ + 0xed, 0x42 + ] + + for addr in 0 ..< 65536 { + let expectedResult = UInt16((addr + 1) & 0xffff) + machine.setValue(UInt16(addr), for: .HL) + + XCTAssertEqual(test(program: addProgram, length: 11, initialValue: 0xffff), expectedResult) + XCTAssertEqual(test(program: adcProgram, length: 15, initialValue: 0xffff), expectedResult) + XCTAssertEqual(test(program: sbcProgram, length: 15, initialValue: 0xffff), expectedResult) + } + } // RLD/RRD func testRLDRRD() { diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index b99b3446c..ab842695e 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -1199,9 +1199,9 @@ template class Processor: public ClockReceiver> { #pragma mark - 16-bit arithmetic case MicroOp::ADD16: { - memptr_.full = *(uint16_t *)operation->source; - uint16_t sourceValue = memptr_.full; - uint16_t destinationValue = *(uint16_t *)operation->destination; + memptr_.full = *(uint16_t *)operation->destination; + uint16_t sourceValue = *(uint16_t *)operation->source; + uint16_t destinationValue = memptr_.full; int result = sourceValue + destinationValue; int halfResult = (sourceValue&0xfff) + (destinationValue&0xfff); @@ -1211,12 +1211,13 @@ template class Processor: public ClockReceiver> { subtract_flag_ = 0; *(uint16_t *)operation->destination = (uint16_t)result; + memptr_.full++; } break; case MicroOp::ADC16: { - memptr_.full = *(uint16_t *)operation->source; - uint16_t sourceValue = memptr_.full; - uint16_t destinationValue = *(uint16_t *)operation->destination; + memptr_.full = *(uint16_t *)operation->destination; + uint16_t sourceValue = *(uint16_t *)operation->source; + uint16_t destinationValue = memptr_.full; int result = sourceValue + destinationValue + (carry_result_ & Flag::Carry); int halfResult = (sourceValue&0xfff) + (destinationValue&0xfff) + (carry_result_ & Flag::Carry); @@ -1231,12 +1232,13 @@ template class Processor: public ClockReceiver> { parity_overflow_result_ = (uint8_t)(overflow >> 13); *(uint16_t *)operation->destination = (uint16_t)result; + memptr_.full++; } break; case MicroOp::SBC16: { - memptr_.full = *(uint16_t *)operation->source; - uint16_t sourceValue = memptr_.full; - uint16_t destinationValue = *(uint16_t *)operation->destination; + memptr_.full = *(uint16_t *)operation->destination; + uint16_t sourceValue = *(uint16_t *)operation->source; + uint16_t destinationValue = memptr_.full; int result = destinationValue - sourceValue - (carry_result_ & Flag::Carry); int halfResult = (destinationValue&0xfff) - (sourceValue&0xfff) - (carry_result_ & Flag::Carry); @@ -1254,6 +1256,7 @@ template class Processor: public ClockReceiver> { parity_overflow_result_ = (uint8_t)(overflow >> 13); *(uint16_t *)operation->destination = (uint16_t)result; + memptr_.full++; } break; #pragma mark - Conditionals