diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/OSBindings/Mac/Clock Signal.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 6fa3be333..87fffc12d 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -1,9 +1,6 @@ - - diff --git a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm index e59cbaf9c..6b77b8441 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm @@ -18,6 +18,10 @@ std::unique_ptr _machine; } +- (RAM68000 *)machine { + return _machine.get(); +} + - (void)setUp { _machine.reset(new RAM68000()); } @@ -26,108 +30,114 @@ _machine.reset(); } -// MARK: ADD +@end + +// MARK: - ADD + +@interface M68000ADDTests : M68000ArithmeticTests +@end +@implementation M68000ADDTests - (void)testADDb { - _machine->set_program({ + self.machine->set_program({ 0x0602, 0xff // ADD.B #$ff, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x9ae; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Negative | Flag::Extend); XCTAssertEqual(state.data[2], 0x9ad); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testADDb_Overflow { - _machine->set_program({ + self.machine->set_program({ 0xd43c, 0x82 // ADD.B #$82, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x82; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Overflow | Flag::Carry | Flag::Extend); XCTAssertEqual(state.data[2], 0x04); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testADDb_XXXw { - _machine->set_program({ + self.machine->set_program({ 0xd538, 0x3000 // ADD.B D2, ($3000).W }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x82; - *_machine->ram_at(0x3000) = 0x8200; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + *self.machine->ram_at(0x3000) = 0x8200; + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Overflow | Flag::Carry | Flag::Extend); XCTAssertEqual(state.data[2], 0x82); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x0400); - XCTAssertEqual(16, _machine->get_cycle_count()); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x0400); + XCTAssertEqual(16, self.machine->get_cycle_count()); } - (void)testADDw_DnDn { - _machine->set_program({ + self.machine->set_program({ 0xd442 // ADD.W D2, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x3e8; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0x7D0); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testADDl_DnPostInc { - _machine->set_program({ + self.machine->set_program({ 0xd59a // ADD.L D2, (A2)+ }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0xb2d05e00; state.address[2] = 0x2000; - *_machine->ram_at(0x2000) = 0x7735; - *_machine->ram_at(0x2002) = 0x9400; + *self.machine->ram_at(0x2000) = 0x7735; + *self.machine->ram_at(0x2002) = 0x9400; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0xb2d05e00); - XCTAssertEqual(*_machine->ram_at(0x2000), 0x2a05); - XCTAssertEqual(*_machine->ram_at(0x2002), 0xf200); + XCTAssertEqual(*self.machine->ram_at(0x2000), 0x2a05); + XCTAssertEqual(*self.machine->ram_at(0x2002), 0xf200); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend); - XCTAssertEqual(20, _machine->get_cycle_count()); + XCTAssertEqual(20, self.machine->get_cycle_count()); } - (void)testADDw_PreDec { - _machine->set_program({ + self.machine->set_program({ 0xd462 // ADD.W -(A2), D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0xFFFF0000; state.address[2] = 0x2002; - *_machine->ram_at(0x2000) = 0; - *_machine->ram_at(0x2002) = 0xffff; + *self.machine->ram_at(0x2000) = 0; + *self.machine->ram_at(0x2002) = 0xffff; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0xFFFF0000); XCTAssertEqual(state.address[2], 0x2000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero); - XCTAssertEqual(10, _machine->get_cycle_count()); + XCTAssertEqual(10, self.machine->get_cycle_count()); } /* @@ -136,305 +146,335 @@ */ - (void)testADDl_DnDn { - _machine->set_program({ + self.machine->set_program({ 0xd481 // ADD.l D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0xfe35aab0; state.data[2] = 0x012557ac; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xfe35aab0); XCTAssertEqual(state.data[2], 0xff5b025c); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } -// MARK: ADDA +@end + +// MARK: - ADDA + +@interface M68000ADDATests : M68000ArithmeticTests +@end +@implementation M68000ADDATests - (void)testADDAL { - _machine->set_program({ + self.machine->set_program({ 0xd5fc, 0x1234, 0x5678 // ADDA.L #$12345678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; state.status = Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[2], 0xc0780195); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } - (void)testADDAWPositive { - _machine->set_program({ + self.machine->set_program({ 0xd4fc, 0x5678 // ADDA.W #$5678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; state.status = Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[2], 0xae440195); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } - (void)testADDAWNegative { - _machine->set_program({ + self.machine->set_program({ 0xd4fc, 0xf678 // ADDA.W #$f678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; state.status = Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[2], 0xae43a195); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } - (void)testADDAWNegative_2 { - _machine->set_program({ + self.machine->set_program({ 0xd4fc, 0xf000 // ADDA.W #$f000, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.status = Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[2], 0xfffff000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } - (void)testADDALPreDec { - _machine->set_program({ + self.machine->set_program({ 0xd5e2 // ADDA.L -(A2), A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.status = Flag::ConditionCodes; state.address[2] = 0x2004; - *_machine->ram_at(0x2000) = 0x7002; - *_machine->ram_at(0x2002) = 0; + *self.machine->ram_at(0x2000) = 0x7002; + *self.machine->ram_at(0x2002) = 0; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[2], 0x70022000); - XCTAssertEqual(*_machine->ram_at(0x2000), 0x7002); - XCTAssertEqual(*_machine->ram_at(0x2002), 0x0000); + XCTAssertEqual(*self.machine->ram_at(0x2000), 0x7002); + XCTAssertEqual(*self.machine->ram_at(0x2002), 0x0000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } -// MARL: ADDX +@end + +// MARK: - ADDX + +@interface M68000ADDXTests : M68000ArithmeticTests +@end +@implementation M68000ADDXTests - (void)testADDXl_Dn { - _machine->set_program({ + self.machine->set_program({ 0xd581 // ADDX.l D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x12345678; state.data[2] = 0x12345678; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x12345678); XCTAssertEqual(state.data[2], 0x2468acf1); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testADDXb { - _machine->set_program({ + self.machine->set_program({ 0xd501 // ADDX.b D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x80; state.data[2] = 0x8080; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x80); XCTAssertEqual(state.data[2], 0x8000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Overflow | Flag::Extend); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testADDXw { - _machine->set_program({ + self.machine->set_program({ 0xd541 // ADDX.w D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x1ffff; state.data[2] = 0x18080; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x1ffff); XCTAssertEqual(state.data[2], 0x18080); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Negative | Flag::Extend); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testADDXl_PreDec { - _machine->set_program({ + self.machine->set_program({ 0xd389 // ADDX.l -(A1), -(A1) }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0x3000; state.status |= Flag::ConditionCodes; - *_machine->ram_at(0x2ff8) = 0x1000; - *_machine->ram_at(0x2ffa) = 0x0000; - *_machine->ram_at(0x2ffc) = 0x7000; - *_machine->ram_at(0x2ffe) = 0x1ff1; + *self.machine->ram_at(0x2ff8) = 0x1000; + *self.machine->ram_at(0x2ffa) = 0x0000; + *self.machine->ram_at(0x2ffc) = 0x7000; + *self.machine->ram_at(0x2ffe) = 0x1ff1; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[1], 0x2ff8); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Overflow); - XCTAssertEqual(*_machine->ram_at(0x2ff8), 0x8000); - XCTAssertEqual(*_machine->ram_at(0x2ffa), 0x1ff2); - XCTAssertEqual(*_machine->ram_at(0x2ffc), 0x7000); - XCTAssertEqual(*_machine->ram_at(0x2ffe), 0x1ff1); - XCTAssertEqual(30, _machine->get_cycle_count()); + XCTAssertEqual(*self.machine->ram_at(0x2ff8), 0x8000); + XCTAssertEqual(*self.machine->ram_at(0x2ffa), 0x1ff2); + XCTAssertEqual(*self.machine->ram_at(0x2ffc), 0x7000); + XCTAssertEqual(*self.machine->ram_at(0x2ffe), 0x1ff1); + XCTAssertEqual(30, self.machine->get_cycle_count()); } -// MARK: ADDI +@end + +// MARK: - ADDI + +@interface M68000ADDITests : M68000ArithmeticTests +@end +@implementation M68000ADDITests - (void)testADDIl { - _machine->set_program({ + self.machine->set_program({ 0x0681, 0x1111, 0x1111 // ADDI.l #$11111111, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x300021b3; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x411132C4); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(16, _machine->get_cycle_count()); + XCTAssertEqual(16, self.machine->get_cycle_count()); } - (void)testADDIw { - _machine->set_program({ + self.machine->set_program({ 0x0678, 0x7aaa, 0x3000 // ADDI.W #$7aaa, ($3000).W }); - *_machine->ram_at(0x3000) = 0xaaaa; + *self.machine->ram_at(0x3000) = 0xaaaa; - _machine->run_for_instructions(1); + self.machine->run_for_instructions(1); - const auto state = _machine->get_processor_state(); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x2554); + const auto state = self.machine->get_processor_state(); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x2554); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); - XCTAssertEqual(20, _machine->get_cycle_count()); + XCTAssertEqual(20, self.machine->get_cycle_count()); } -// MARK: ADDQ +@end + +// MARK: - ADDQ + +@interface M68000ADDQTests : M68000ArithmeticTests +@end +@implementation M68000ADDQTests - (void)testADDQl { - _machine->set_program({ + self.machine->set_program({ 0x5e81 // ADDQ.l #$7, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0xffffffff; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x6); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testADDQw_Dn { - _machine->set_program({ + self.machine->set_program({ 0x5641 // ADDQ.W #$3, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0xfffffffe; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xffff0001); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testADDQw_An { - _machine->set_program({ + self.machine->set_program({ 0x5649 // ADDQ.W #$3, A1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0xfffffffe; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[1], 1); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testADDQw_XXXw { - _machine->set_program({ + self.machine->set_program({ 0x5078, 0x3000 // ADDQ.W #$8, ($3000).W }); - *_machine->ram_at(0x3000) = 0x7ffd; + *self.machine->ram_at(0x3000) = 0x7ffd; - _machine->run_for_instructions(1); + self.machine->run_for_instructions(1); - const auto state = _machine->get_processor_state(); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x8005); + const auto state = self.machine->get_processor_state(); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x8005); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Overflow); - XCTAssertEqual(16, _machine->get_cycle_count()); + XCTAssertEqual(16, self.machine->get_cycle_count()); } -// MARK: CMP +@end + +// MARK: - CMP + +@interface M68000CMPTests : M68000ArithmeticTests +@end +@implementation M68000CMPTests - (void)performCMPb:(uint16_t)opcode expectedFlags:(uint16_t)flags { - _machine->set_program({ + self.machine->set_program({ opcode }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x1234567f; state.data[2] = 0x12345680; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x1234567f); XCTAssertEqual(state.data[2], 0x12345680); XCTAssertEqual(state.status & Flag::ConditionCodes, flags); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testCMPb_D1D2 { @@ -446,21 +486,21 @@ } - (void)performCMPwd1:(uint32_t)d1 d2:(uint32_t)d2 expectedFlags:(uint16_t)flags { - _machine->set_program({ + self.machine->set_program({ 0xb242 // CMP.W D2, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.data[2] = d2; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], d1); XCTAssertEqual(state.data[2], d2); XCTAssertEqual(state.status & Flag::ConditionCodes, flags); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testCMPw_8004v7002 { @@ -472,228 +512,253 @@ } - (void)testCMPl { - _machine->set_program({ + self.machine->set_program({ 0xb282 // CMP.l D2, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x12347002; state.data[2] = 0x12348004; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x12347002); XCTAssertEqual(state.data[2], 0x12348004); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Carry); - XCTAssertEqual(6, _machine->get_cycle_count()); + XCTAssertEqual(6, self.machine->get_cycle_count()); } -// MARK: CMPA +@end + +// MARK: - CMPA + +@interface M68000CMPATests : M68000ArithmeticTests +@end +@implementation M68000CMPATests - (void)performCMPAld1:(uint32_t)d1 a2:(uint32_t)a2 { - _machine->set_program({ + self.machine->set_program({ 0xb5c1 // CMPA.l D1, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.address[2] = a2; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], d1); XCTAssertEqual(state.address[2], a2); - XCTAssertEqual(6, _machine->get_cycle_count()); + XCTAssertEqual(6, self.machine->get_cycle_count()); } - (void)testCMPAl_noFlags { [self performCMPAld1:0x1234567f a2:0x12345680]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); } - (void)testCMPAl_carry { [self performCMPAld1:0xfd234577 a2:0x12345680]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry); } - (void)testCMPAl_carryOverflowNegative { [self performCMPAld1:0x85678943 a2:0x22563245]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Overflow | Flag::Negative); } - (void)performCMPAwd1:(uint32_t)d1 a2:(uint32_t)a2 { - _machine->set_program({ + self.machine->set_program({ 0xb4c1 // CMPA.w D1, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.address[2] = a2; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], d1); XCTAssertEqual(state.address[2], a2); - XCTAssertEqual(6, _machine->get_cycle_count()); + XCTAssertEqual(6, self.machine->get_cycle_count()); } - (void)testCMPAw_carry { [self performCMPAwd1:0x85678943 a2:0x22563245]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry); } - (void)testCMPAw_zero { [self performCMPAwd1:0x0000ffff a2:0xffffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero); } +@end + // MARK: CMPI +@interface M68000CMPITests : M68000ArithmeticTests +@end +@implementation M68000CMPITests + - (void)testCMPIw { - _machine->set_program({ + self.machine->set_program({ 0x0c41, 0xffff // CMPI.W #$ffff, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0xfff2ffff; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xfff2ffff); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testCMPIl { - _machine->set_program({ + self.machine->set_program({ 0x0c81, 0x8000, 0x0000 // CMPI.L #$80000000, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x7fffffff; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x7fffffff); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Overflow | Flag::Carry); - XCTAssertEqual(14, _machine->get_cycle_count()); + XCTAssertEqual(14, self.machine->get_cycle_count()); } - (void)testCMPIb { - _machine->set_program({ + self.machine->set_program({ 0x0c01, 0x0090 // CMPI.B #$90, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x8f; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x8f); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Carry); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } -// MARK: CMPM + +@end + +// MARK: - CMPM + +@interface M68000CMPMTests : M68000ArithmeticTests +@end +@implementation M68000CMPMTests - (void)testCMPMl { - _machine->set_program({ + self.machine->set_program({ 0xb389 // CMPM.L (A1)+, (A1)+ }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0x3000; state.status |= Flag::ConditionCodes; - *_machine->ram_at(0x3000) = 0x7000; - *_machine->ram_at(0x3002) = 0x1ff1; - *_machine->ram_at(0x3004) = 0x1000; - *_machine->ram_at(0x3006) = 0x0000; + *self.machine->ram_at(0x3000) = 0x7000; + *self.machine->ram_at(0x3002) = 0x1ff1; + *self.machine->ram_at(0x3004) = 0x1000; + *self.machine->ram_at(0x3006) = 0x0000; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[1], 0x3008); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Extend | Flag::Carry); - XCTAssertEqual(20, _machine->get_cycle_count()); + XCTAssertEqual(20, self.machine->get_cycle_count()); } - (void)testCMPMw { - _machine->set_program({ + self.machine->set_program({ 0xb549 // CMPM.w (A1)+, (A2)+ }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0x3000; state.address[2] = 0x3002; state.status |= Flag::ConditionCodes; - *_machine->ram_at(0x3000) = 0; - *_machine->ram_at(0x3002) = 0; + *self.machine->ram_at(0x3000) = 0; + *self.machine->ram_at(0x3002) = 0; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[1], 0x3002); XCTAssertEqual(state.address[2], 0x3004); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero | Flag::Extend); - XCTAssertEqual(12, _machine->get_cycle_count()); + XCTAssertEqual(12, self.machine->get_cycle_count()); } - (void)testCMPMb { - _machine->set_program({ + self.machine->set_program({ 0xb509 // CMPM.b (A1)+, (A2)+ }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0x3000; state.address[2] = 0x3001; state.status |= Flag::ConditionCodes; - *_machine->ram_at(0x3000) = 0x807f; + *self.machine->ram_at(0x3000) = 0x807f; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.address[1], 0x3001); XCTAssertEqual(state.address[2], 0x3002); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Extend | Flag::Carry | Flag::Overflow); - XCTAssertEqual(12, _machine->get_cycle_count()); + XCTAssertEqual(12, self.machine->get_cycle_count()); } -// MARK: DIVS +@end + +// MARK: - DIVS + +@interface M68000DIVSTests : M68000ArithmeticTests +@end +@implementation M68000DIVSTests - (void)performDIVS:(uint16_t)divisor d1:(uint32_t)d1 { - _machine->set_program({ + self.machine->set_program({ 0x83fc, divisor // DIVS #$eef0, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); } - (void)performDIVSOverflowTestDivisor:(uint16_t)divisor { [self performDIVS:divisor d1:0x4768f231]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x4768f231); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Overflow); - XCTAssertEqual(20, _machine->get_cycle_count()); + XCTAssertEqual(20, self.machine->get_cycle_count()); } - (void)testDIVSOverflow { @@ -711,193 +776,205 @@ - (void)testDIVS_2 { [self performDIVS:0xeef0 d1:0x0768f231]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x026190D3); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(138, _machine->get_cycle_count()); + XCTAssertEqual(138, self.machine->get_cycle_count()); } - (void)testDIVS_3 { [self performDIVS:0xffff d1:0xffffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 1); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(158, _machine->get_cycle_count()); + XCTAssertEqual(158, self.machine->get_cycle_count()); } - (void)testDIVS_4 { [self performDIVS:0x3333 d1:0xffff0000]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xfffffffb); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(158, _machine->get_cycle_count()); + XCTAssertEqual(158, self.machine->get_cycle_count()); } - (void)testDIVS_5 { [self performDIVS:0x23 d1:0x8765]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xb03de); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(138, _machine->get_cycle_count()); + XCTAssertEqual(138, self.machine->get_cycle_count()); } - (void)testDIVS_6 { [self performDIVS:0x8765 d1:0x65]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x650000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero); - XCTAssertEqual(156, _machine->get_cycle_count()); + XCTAssertEqual(156, self.machine->get_cycle_count()); } - (void)testDIVSExpensiveOverflow { // DIVS.W #$ffff, D1 alt [self performDIVS:0xffff d1:0x80000000]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x80000000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Overflow); - XCTAssertEqual(158, _machine->get_cycle_count()); + XCTAssertEqual(158, self.machine->get_cycle_count()); } - (void)testDIVS_8 { // DIVS.W #$fffd, D1 [self performDIVS:0xfffd d1:0xfffffffd]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x1); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(158, _machine->get_cycle_count()); + XCTAssertEqual(158, self.machine->get_cycle_count()); } - (void)testDIVS_9 { // DIVS.W #$7aee, D1 [self performDIVS:0x7aee d1:0xdaaa00fe]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0xc97eb240); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(148, _machine->get_cycle_count()); + XCTAssertEqual(148, self.machine->get_cycle_count()); } - (void)testDIVS_10 { // DIVS.W #$7fff, D1 [self performDIVS:0x7fff d1:0x82f9fff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x305e105f); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(142, _machine->get_cycle_count()); + XCTAssertEqual(142, self.machine->get_cycle_count()); } - (void)testDIVS_11 { // DIVS.W #$f32, D1 [self performDIVS:0xf32 d1:0x00e1d44]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x0bfa00ed); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(144, _machine->get_cycle_count()); + XCTAssertEqual(144, self.machine->get_cycle_count()); } - (void)testDIVS_12 { // DIVS.W #$af32, D1 [self performDIVS:0xaf32 d1:0xe1d44]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x39dcffd4); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(150, _machine->get_cycle_count()); + XCTAssertEqual(150, self.machine->get_cycle_count()); } - (void)testDIVSException { // DIVS.W #0, D1 - _machine->set_initial_stack_pointer(0); + self.machine->set_initial_stack_pointer(0); [self performDIVS:0x0 d1:0x1fffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x1fffffff); XCTAssertEqual(state.supervisor_stack_pointer, 0xfffffffa); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(42, _machine->get_cycle_count()); + XCTAssertEqual(42, self.machine->get_cycle_count()); } -// MARK: DIVU +@end + +// MARK: - DIVU + +@interface M68000DIVUTests : M68000ArithmeticTests +@end +@implementation M68000DIVUTests - (void)performDIVU:(uint16_t)divisor d1:(uint32_t)d1 { - _machine->set_program({ + self.machine->set_program({ 0x82fc, divisor // DIVU #$eef0, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); } - (void)testDIVU_0001 { [self performDIVU:1 d1:0x4768f231]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x4768f231); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Overflow); - XCTAssertEqual(14, _machine->get_cycle_count()); + XCTAssertEqual(14, self.machine->get_cycle_count()); } - (void)testDIVU_1234 { [self performDIVU:0x1234 d1:0x4768f231]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x4768f231); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Overflow); - XCTAssertEqual(14, _machine->get_cycle_count()); + XCTAssertEqual(14, self.machine->get_cycle_count()); } - (void)testDIVU_eeff { [self performDIVU:0xeeff d1:0x4768f231]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x8bae4c7d); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(108, _machine->get_cycle_count()); + XCTAssertEqual(108, self.machine->get_cycle_count()); } - (void)testDIVU_3333 { [self performDIVU:0x3333 d1:0x1fffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x1fffa000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(136, _machine->get_cycle_count()); + XCTAssertEqual(136, self.machine->get_cycle_count()); } // Omitted: divide by zero test. -// MARK: EXT +@end + +// MARK: - EXT + +@interface M68000EXTTests : M68000ArithmeticTests +@end +@implementation M68000EXTTests - (void)performEXTwd3:(uint32_t)d3 { - _machine->set_program({ + self.machine->set_program({ 0x4883 // EXT.W D3 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[3] = d3; state.status = 0x13; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testEXTw_78 { [self performEXTwd3:0x12345678]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[3], 0x12340078); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); } @@ -905,7 +982,7 @@ - (void)testEXTw_00 { [self performEXTwd3:0x12345600]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[3], 0x12340000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero); } @@ -913,175 +990,193 @@ - (void)testEXTw_f0 { [self performEXTwd3:0x123456f0]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[3], 0x1234fff0); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); } - (void)testEXTl { - _machine->set_program({ + self.machine->set_program({ 0x48c3 // EXT.L D3 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[3] = 0x1234f6f0; state.status = 0x13; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[3], 0xfffff6f0); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); } -// MARK: MULS +@end + +// MARK: - MULS + +@interface M68000MULSTests : M68000ArithmeticTests +@end +@implementation M68000MULSTests - (void)performMULSd1:(uint32_t)d1 d2:(uint32_t)d2 ccr:(uint8_t)ccr { - _machine->set_program({ + self.machine->set_program({ 0xc5c1 // MULS D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.data[2] = d2; state.status = ccr; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); } - (void)performMULSConstant:(uint16_t)constant d2:(uint32_t)d2 { - _machine->set_program({ + self.machine->set_program({ 0xc5fc, constant // MULS #constant, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = d2; state.status = Flag::Carry | Flag::Extend | Flag::Overflow; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); } - (void)testMULS { [self performMULSd1:0x12345678 d2:0x12345678 ccr:0]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x12345678); XCTAssertEqual(state.data[2], 0x1d34d840); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(54, _machine->get_cycle_count()); + XCTAssertEqual(54, self.machine->get_cycle_count()); } - (void)testMULS_2 { [self performMULSd1:0x82348678 d2:0x823486ff ccr:0]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 0x82348678); XCTAssertEqual(state.data[2], 0x3971c188); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(48, _machine->get_cycle_count()); + XCTAssertEqual(48, self.machine->get_cycle_count()); } - (void)testMULSZero { [self performMULSd1:1 d2:0 ccr:Flag::Carry | Flag::Overflow | Flag::Extend]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 1); XCTAssertEqual(state.data[2], 0); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero); - XCTAssertEqual(42, _machine->get_cycle_count()); + XCTAssertEqual(42, self.machine->get_cycle_count()); } - (void)testMULSFFFF { [self performMULSConstant:0xffff d2:0xffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 1); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend); - XCTAssertEqual(44, _machine->get_cycle_count()); + XCTAssertEqual(44, self.machine->get_cycle_count()); } - (void)testMULSNegative { [self performMULSConstant:0x1fff d2:0x8fff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0xf2005001); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(46, _machine->get_cycle_count()); + XCTAssertEqual(46, self.machine->get_cycle_count()); } -// MARK: MULU +@end + +// MARK: - MULU + +@interface M68000MULUTests : M68000ArithmeticTests +@end +@implementation M68000MULUTests - (void)performMULUd1:(uint32_t)d1 d2:(uint32_t)d2 ccr:(uint8_t)ccr { - _machine->set_program({ + self.machine->set_program({ 0xc4c1 // MULU D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = d1; state.data[2] = d2; state.status |= ccr; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); } - (void)testMULU_Dn { [self performMULUd1:0x12345678 d2:0x12345678 ccr:0]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0x1d34d840); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(54, _machine->get_cycle_count()); + XCTAssertEqual(54, self.machine->get_cycle_count()); } - (void)testMULU_Dn_Zero { [self performMULUd1:1 d2:0 ccr:Flag::Extend | Flag::Overflow | Flag::Carry]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[1], 1); XCTAssertEqual(state.data[2], 0); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero); - XCTAssertEqual(40, _machine->get_cycle_count()); + XCTAssertEqual(40, self.machine->get_cycle_count()); } - (void)testMULU_Imm { - _machine->set_program({ + self.machine->set_program({ 0xc4fc, 0xffff // MULU.W #$ffff, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0xffff; state.status |= Flag::Extend | Flag::Overflow | Flag::Carry; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); + state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0xfffe0001); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative); - XCTAssertEqual(74, _machine->get_cycle_count()); + XCTAssertEqual(74, self.machine->get_cycle_count()); } -// MARK: NEG +@end + +// MARK: - NEG + +@interface M68000NEGTests : M68000ArithmeticTests +@end +@implementation M68000NEGTests - (void)performNEGb:(uint32_t)value { - _machine->set_program({ + self.machine->set_program({ 0x4400 // NEG.b D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = value; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testNEGb_78 { [self performNEGb:0x12345678]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x12345688); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); } @@ -1089,7 +1184,7 @@ - (void)testNEGb_00 { [self performNEGb:0x12345600]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x12345600); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero); } @@ -1097,44 +1192,44 @@ - (void)testNEGb_80 { [self performNEGb:0x12345680]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x12345680); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Overflow | Flag::Extend | Flag::Carry); } - (void)testNEGw { - _machine->set_program({ + self.machine->set_program({ 0x4440 // NEG.w D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = 0x12348000; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(4, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.data[0], 0x12348000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative | Flag::Overflow | Flag::Extend | Flag::Carry); } - (void)performNEGl:(uint32_t)value { - _machine->set_program({ + self.machine->set_program({ 0x4480 // NEG.l D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = value; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(6, _machine->get_cycle_count()); + XCTAssertEqual(6, self.machine->get_cycle_count()); } - (void)testNEGl_large { [self performNEGl:0x12345678]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0xedcba988); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); } @@ -1142,47 +1237,53 @@ - (void)testNEGl_small { [self performNEGl:0xffffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x1); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend); } - (void)testNEGl_XXXl { - _machine->set_program({ + self.machine->set_program({ 0x44b9, 0x0000, 0x3000 // NEG.L ($3000).L }); - *_machine->ram_at(0x3000) = 0xf001; - *_machine->ram_at(0x3002) = 0x2311; + *self.machine->ram_at(0x3000) = 0xf001; + *self.machine->ram_at(0x3002) = 0x2311; - _machine->run_for_instructions(1); + self.machine->run_for_instructions(1); - const auto state = _machine->get_processor_state(); - XCTAssertEqual(28, _machine->get_cycle_count()); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x0ffe); - XCTAssertEqual(*_machine->ram_at(0x3002), 0xdcef); + const auto state = self.machine->get_processor_state(); + XCTAssertEqual(28, self.machine->get_cycle_count()); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x0ffe); + XCTAssertEqual(*self.machine->ram_at(0x3002), 0xdcef); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); } -// MARK: NEGX +@end + +// MARK: - NEGX + +@interface M68000NEGXTests : M68000ArithmeticTests +@end +@implementation M68000NEGXTests - (void)performNEGXb:(uint32_t)value { - _machine->set_program({ + self.machine->set_program({ 0x4000 // NEGX.b D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = value; state.status |= Flag::Extend; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(4, _machine->get_cycle_count()); + XCTAssertEqual(4, self.machine->get_cycle_count()); } - (void)testNEGXb_78 { [self performNEGXb:0x12345678]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x12345687); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); } @@ -1190,7 +1291,7 @@ - (void)testNEGXb_00 { [self performNEGXb:0x12345600]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x123456ff); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); } @@ -1198,46 +1299,46 @@ - (void)testNEGXb_80 { [self performNEGXb:0x12345680]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x1234567f); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); } - (void)testNEGXw { - _machine->set_program({ + self.machine->set_program({ 0x4040 // NEGX.w D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = 0x12348000; state.status |= Flag::Extend; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(4, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.data[0], 0x12347fff); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); } - (void)performNEGXl:(uint32_t)value { - _machine->set_program({ + self.machine->set_program({ 0x4080 // NEGX.l D0 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[0] = value; state.status |= Flag::Extend; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(6, _machine->get_cycle_count()); + XCTAssertEqual(6, self.machine->get_cycle_count()); } - (void)testNEGXl_large { [self performNEGXl:0x12345678]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0xedcba987); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); } @@ -1245,49 +1346,55 @@ - (void)testNEGXl_small { [self performNEGXl:0xffffffff]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[0], 0x0); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend); } - (void)testNEGXl_XXXl { - _machine->set_program({ + self.machine->set_program({ 0x40b9, 0x0000, 0x3000 // NEGX.L ($3000).L }); - *_machine->ram_at(0x3000) = 0xf001; - *_machine->ram_at(0x3002) = 0x2311; - auto state = _machine->get_processor_state(); + *self.machine->ram_at(0x3000) = 0xf001; + *self.machine->ram_at(0x3002) = 0x2311; + auto state = self.machine->get_processor_state(); state.status |= Flag::Extend; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(28, _machine->get_cycle_count()); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x0ffe); - XCTAssertEqual(*_machine->ram_at(0x3002), 0xdcee); + state = self.machine->get_processor_state(); + XCTAssertEqual(28, self.machine->get_cycle_count()); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x0ffe); + XCTAssertEqual(*self.machine->ram_at(0x3002), 0xdcee); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry); } -// MARK: SUB +@end + +// MARK: - SUB + +@interface M68000SUBTests : M68000ArithmeticTests +@end +@implementation M68000SUBTests - (void)performSUBbIMM:(uint16_t)value d2:(uint32_t)d2 { - _machine->set_program({ + self.machine->set_program({ 0x0402, value // SUB.b #value, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = d2; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - XCTAssertEqual(8, _machine->get_cycle_count()); + XCTAssertEqual(8, self.machine->get_cycle_count()); } - (void)testSUBb_IMM_ff { [self performSUBbIMM:0xff d2:0x9ae]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0x9af); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Negative | Flag::Extend); } @@ -1295,7 +1402,7 @@ - (void)testSUBb_IMM_82 { [self performSUBbIMM:0x82 d2:0x0a]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0x88); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Negative | Flag::Overflow | Flag::Extend); } @@ -1303,7 +1410,7 @@ - (void)testSUBb_IMM_f0 { [self performSUBbIMM:0xf0 d2:0x64]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0x74); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend); } @@ -1311,25 +1418,25 @@ - (void)testSUBb_IMM_28 { [self performSUBbIMM:0x28 d2:0xff96]; - const auto state = _machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.data[2], 0xff6e); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Overflow); } - (void)testSUBb_PreDec { - _machine->set_program({ + self.machine->set_program({ 0x9427 // SUB.b -(A7), D2 }); - _machine->set_initial_stack_pointer(0x2002); - auto state = _machine->get_processor_state(); + self.machine->set_initial_stack_pointer(0x2002); + auto state = self.machine->get_processor_state(); state.data[2] = 0x9c40; - *_machine->ram_at(0x2000) = 0x2710; + *self.machine->ram_at(0x2000) = 0x2710; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(10, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(10, self.machine->get_cycle_count()); XCTAssertEqual(state.data[2], 0x9c19); XCTAssertEqual(state.stack_pointer(), 0x2000); } @@ -1337,244 +1444,268 @@ // Omitted: SUB.w -(A6), D2, which is designed to trigger an address error. - (void)testSUBw_XXXw { - _machine->set_program({ + self.machine->set_program({ 0x9578, 0x3000 // SUB.w D2, ($3000).w }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x2711; - *_machine->ram_at(0x3000) = 0x759f; + *self.machine->ram_at(0x3000) = 0x759f; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(16, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.data[2], 0x2711); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); - XCTAssertEqual(*_machine->ram_at(0x3000), 0x4e8e); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0x4e8e); } - (void)testSUBl_dAn { - _machine->set_program({ + self.machine->set_program({ 0x95ab, 0x0004 // SUB.l D2, 4(A3) }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[2] = 0x45fd5ab4; state.address[3] = 0x3000; - *_machine->ram_at(0x3004) = 0x327a; - *_machine->ram_at(0x3006) = 0x4ef3; + *self.machine->ram_at(0x3004) = 0x327a; + *self.machine->ram_at(0x3006) = 0x4ef3; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(24, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(24, self.machine->get_cycle_count()); XCTAssertEqual(state.data[2], 0x45fd5ab4); XCTAssertEqual(state.address[3], 0x3000); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend | Flag::Negative); - XCTAssertEqual(*_machine->ram_at(0x3004), 0xec7c); - XCTAssertEqual(*_machine->ram_at(0x3006), 0xf43f); + XCTAssertEqual(*self.machine->ram_at(0x3004), 0xec7c); + XCTAssertEqual(*self.machine->ram_at(0x3006), 0xf43f); } -// MARK: SUBA +@end + +// MARK: - SUBA + +@interface M68000SUBATests : M68000ArithmeticTests +@end +@implementation M68000SUBATests - (void)testSUBAl_Imm { - _machine->set_program({ + self.machine->set_program({ 0x95fc, 0x1234, 0x5678 // SUBA.l #$12345678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(16, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.address[2], 0x9c0f54a5); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes); } - (void)testSUBAw_ImmPositive { - _machine->set_program({ + self.machine->set_program({ 0x94fc, 0x5678 // SUBA.w #$5678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(12, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(12, self.machine->get_cycle_count()); XCTAssertEqual(state.address[2], 0xae4354a5); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); } - (void)testSUBAw_ImmNegative { - _machine->set_program({ + self.machine->set_program({ 0x94fc, 0xf678 // SUBA.w #$5678, A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0xae43ab1d; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(12, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(12, self.machine->get_cycle_count()); XCTAssertEqual(state.address[2], 0xae43b4a5); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); } - (void)testSUBAw_PreDec { - _machine->set_program({ + self.machine->set_program({ 0x95e2 // SUBA.l -(A2), A2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[2] = 0x2004; - *_machine->ram_at(0x2000) = 0x7002; - *_machine->ram_at(0x2002) = 0x0000; + *self.machine->ram_at(0x2000) = 0x7002; + *self.machine->ram_at(0x2002) = 0x0000; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(16, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.address[2], 0x8ffe2000); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); } -// MARK: SUBI +@end + +// MARK: - SUBI + +@interface M68000SUBITests : M68000ArithmeticTests +@end +@implementation M68000SUBITests - (void)testSUBIl { - _machine->set_program({ + self.machine->set_program({ 0x0481, 0xf111, 0x1111 // SUBI.L #$f1111111, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x300021b3; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(16, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.data[1], 0x3eef10a2); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Carry | Flag::Extend); } // Test of SUBI.W #$7aaa, ($3000).W omitted; that doesn't appear to be a valid instruction? -// MARK: SUBQ +@end + +// MARK: - SUBQ + +@interface M68000SUBQTests : M68000ArithmeticTests +@end +@implementation M68000SUBQTests - (void)testSUBQl { - _machine->set_program({ + self.machine->set_program({ 0x5f81 // SUBQ.L #$7, D1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0xffffffff; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(8, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.data[1], 0xfffffff8); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative); } - (void)testSUBQw { - _machine->set_program({ + self.machine->set_program({ 0x5f49 // SUBQ.W #$7, A1 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0xffff0001; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(8, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.address[1], 0xfffefffa); XCTAssertEqual(state.status & Flag::ConditionCodes, 0); } - (void)testSUBQb { - _machine->set_program({ + self.machine->set_program({ 0x5f38, 0x3000 // SUBQ.b #$7, ($3000).w }); - *_machine->ram_at(0x3000) = 0x0600; + *self.machine->ram_at(0x3000) = 0x0600; - _machine->run_for_instructions(1); + self.machine->run_for_instructions(1); - const auto state = _machine->get_processor_state(); - XCTAssertEqual(16, _machine->get_cycle_count()); - XCTAssertEqual(*_machine->ram_at(0x3000), 0xff00); + const auto state = self.machine->get_processor_state(); + XCTAssertEqual(16, self.machine->get_cycle_count()); + XCTAssertEqual(*self.machine->ram_at(0x3000), 0xff00); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Carry); } -// MARK: SUBX +@end + +// MARK: - SUBX + +@interface M68000SUBXTests : M68000ArithmeticTests +@end +@implementation M68000SUBXTests - (void)testSUBXl_Dn { - _machine->set_program({ + self.machine->set_program({ 0x9581 // SUBX.l D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x12345678; state.data[2] = 0x12345678; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(8, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.data[1], 0x12345678); XCTAssertEqual(state.data[2], 0xffffffff); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative); } - (void)testSUBXb_Dn { - _machine->set_program({ + self.machine->set_program({ 0x9501 // SUBX.b D1, D2 }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.data[1] = 0x80; state.data[2] = 0x01; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(4, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.data[1], 0x80); XCTAssertEqual(state.data[2], 0x81); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative | Flag::Overflow); } - (void)testSUBXl_PreDec { - _machine->set_program({ + self.machine->set_program({ 0x9389 // SUBX.l -(A1), -(A1) }); - auto state = _machine->get_processor_state(); + auto state = self.machine->get_processor_state(); state.address[1] = 0x3000; - *_machine->ram_at(0x2ff8) = 0x1000; - *_machine->ram_at(0x2ffa) = 0x0000; - *_machine->ram_at(0x2ffc) = 0x7000; - *_machine->ram_at(0x2ffe) = 0x1ff1; + *self.machine->ram_at(0x2ff8) = 0x1000; + *self.machine->ram_at(0x2ffa) = 0x0000; + *self.machine->ram_at(0x2ffc) = 0x7000; + *self.machine->ram_at(0x2ffe) = 0x1ff1; state.status |= Flag::ConditionCodes; - _machine->set_processor_state(state); - _machine->run_for_instructions(1); + self.machine->set_processor_state(state); + self.machine->run_for_instructions(1); - state = _machine->get_processor_state(); - XCTAssertEqual(30, _machine->get_cycle_count()); + state = self.machine->get_processor_state(); + XCTAssertEqual(30, self.machine->get_cycle_count()); XCTAssertEqual(state.address[1], 0x2ff8); XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative ); - XCTAssertEqual(*_machine->ram_at(0x2ff8), 0x9fff); - XCTAssertEqual(*_machine->ram_at(0x2ffa), 0xe00e); - XCTAssertEqual(*_machine->ram_at(0x2ffc), 0x7000); - XCTAssertEqual(*_machine->ram_at(0x2ffe), 0x1ff1); + XCTAssertEqual(*self.machine->ram_at(0x2ff8), 0x9fff); + XCTAssertEqual(*self.machine->ram_at(0x2ffa), 0xe00e); + XCTAssertEqual(*self.machine->ram_at(0x2ffc), 0x7000); + XCTAssertEqual(*self.machine->ram_at(0x2ffe), 0x1ff1); } @end