1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Added test for 16-bit arithmetic, and fixed implementation.

This commit is contained in:
Thomas Harte 2017-07-26 19:04:52 -04:00
parent 728143247d
commit 9257a3f6d7
2 changed files with 34 additions and 13 deletions

View File

@ -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() {

View File

@ -1199,9 +1199,9 @@ template <class T> class Processor: public ClockReceiver<Processor<T>> {
#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 T> class Processor: public ClockReceiver<Processor<T>> {
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 T> class Processor: public ClockReceiver<Processor<T>> {
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 T> class Processor: public ClockReceiver<Processor<T>> {
parity_overflow_result_ = (uint8_t)(overflow >> 13);
*(uint16_t *)operation->destination = (uint16_t)result;
memptr_.full++;
} break;
#pragma mark - Conditionals