1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-13 07:30:21 +00:00

Adapt remaining 68000 tests to use Mk2.

This commit is contained in:
Thomas Harte 2022-05-25 10:55:03 -04:00
parent 24f7b5806c
commit b6e473a515
10 changed files with 1234 additions and 1224 deletions

View File

@ -18,6 +18,11 @@ struct RegisterSet {
uint32_t supervisor_stack_pointer;
uint16_t status;
uint32_t program_counter;
/// @returns The active stack pointer, whichever it may be.
uint32_t stack_pointer() const {
return (status & 0x2000) ? supervisor_stack_pointer : user_stack_pointer;
}
};
}

View File

@ -22,6 +22,8 @@ static constexpr uint16_t Zero = 1 << 2;
static constexpr uint16_t Negative = 1 << 3;
static constexpr uint16_t Extend = 1 << 4;
static constexpr uint16_t AllConditions = Carry | Overflow | Zero | Negative | Extend;
static constexpr uint16_t Supervisor = 1 << 13;
static constexpr uint16_t Trace = 1 << 15;

File diff suppressed because it is too large Load Diff

View File

@ -33,15 +33,15 @@
0xc302, // ABCD D2, D1
});
auto state = _machine->get_processor_state();
state.data[1] = 0x1234567a;
state.data[2] = 0xf745ff78;
state.registers.data[1] = 0x1234567a;
state.registers.data[2] = 0xf745ff78;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Carry);
XCTAssertEqual(state.data[1], 0x12345658);
XCTAssertEqual(state.data[2], 0xf745ff78);
XCTAssert(state.registers.status & ConditionCode::Carry);
XCTAssertEqual(state.registers.data[1], 0x12345658);
XCTAssertEqual(state.registers.data[2], 0xf745ff78);
}
- (void)testABCDZero {
@ -49,16 +49,16 @@
0xc302, // ABCD D2, D1
});
auto state = _machine->get_processor_state();
state.data[1] = 0x12345600;
state.data[2] = 0x12345600;
state.status = Flag::Zero;
state.registers.data[1] = 0x12345600;
state.registers.data[2] = 0x12345600;
state.registers.status = ConditionCode::Zero;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Zero);
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.data[2], 0x12345600);
XCTAssert(state.registers.status & ConditionCode::Zero);
XCTAssertEqual(state.registers.data[1], 0x12345600);
XCTAssertEqual(state.registers.data[2], 0x12345600);
}
- (void)testABCDNegative {
@ -66,16 +66,16 @@
0xc302, // ABCD D2, D1
});
auto state = _machine->get_processor_state();
state.data[1] = 0x12345645;
state.data[2] = 0x12345654;
state.status = Flag::Zero;
state.registers.data[1] = 0x12345645;
state.registers.data[2] = 0x12345654;
state.registers.status = ConditionCode::Zero;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Negative);
XCTAssertEqual(state.data[1], 0x12345699);
XCTAssertEqual(state.data[2], 0x12345654);
XCTAssert(state.registers.status & ConditionCode::Negative);
XCTAssertEqual(state.registers.data[1], 0x12345699);
XCTAssertEqual(state.registers.data[2], 0x12345654);
}
- (void)testABCDWithX {
@ -83,16 +83,16 @@
0xc302, // ABCD D2, D1
});
auto state = _machine->get_processor_state();
state.data[1] = 0x12345645;
state.data[2] = 0x12345654;
state.status = Flag::Extend;
state.registers.data[1] = 0x12345645;
state.registers.data[2] = 0x12345654;
state.registers.status = ConditionCode::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Carry);
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.data[2], 0x12345654);
XCTAssert(state.registers.status & ConditionCode::Carry);
XCTAssertEqual(state.registers.data[1], 0x12345600);
XCTAssertEqual(state.registers.data[2], 0x12345654);
}
- (void)testABCDOverflow {
@ -100,16 +100,16 @@
0xc302, // ABCD D2, D1
});
auto state = _machine->get_processor_state();
state.data[1] = 0x1234563e;
state.data[2] = 0x1234563e;
state.status = Flag::Extend;
state.registers.data[1] = 0x1234563e;
state.registers.data[2] = 0x1234563e;
state.registers.status = ConditionCode::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Overflow);
XCTAssertEqual(state.data[1], 0x12345683);
XCTAssertEqual(state.data[2], 0x1234563e);
XCTAssert(state.registers.status & ConditionCode::Overflow);
XCTAssertEqual(state.registers.data[1], 0x12345683);
XCTAssertEqual(state.registers.data[2], 0x1234563e);
}
- (void)testABCDPredecDifferent {
@ -120,17 +120,17 @@
*_machine->ram_at(0x4000) = 0x1900;
auto state = _machine->get_processor_state();
state.address[1] = 0x3001;
state.address[2] = 0x4001;
state.status = Flag::Extend;
state.registers.address[1] = 0x3001;
state.registers.address[2] = 0x4001;
state.registers.status = ConditionCode::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Carry);
XCTAssert(state.status & Flag::Extend);
XCTAssertEqual(state.address[1], 0x3000);
XCTAssertEqual(state.address[2], 0x4000);
XCTAssert(state.registers.status & ConditionCode::Carry);
XCTAssert(state.registers.status & ConditionCode::Extend);
XCTAssertEqual(state.registers.address[1], 0x3000);
XCTAssertEqual(state.registers.address[2], 0x4000);
XCTAssertEqual(*_machine->ram_at(0x3000), 0x2200);
XCTAssertEqual(*_machine->ram_at(0x4000), 0x1900);
}
@ -142,15 +142,15 @@
*_machine->ram_at(0x3000) = 0x19a2;
auto state = _machine->get_processor_state();
state.address[1] = 0x3002;
state.status = Flag::Extend;
state.registers.address[1] = 0x3002;
state.registers.status = ConditionCode::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.status & Flag::Carry);
XCTAssert(state.status & Flag::Extend);
XCTAssertEqual(state.address[1], 0x3000);
XCTAssert(state.registers.status & ConditionCode::Carry);
XCTAssert(state.registers.status & ConditionCode::Extend);
XCTAssertEqual(state.registers.address[1], 0x3000);
XCTAssertEqual(*_machine->ram_at(0x3000), 0x22a2);
}
@ -161,8 +161,8 @@
0x4801 // NBCD D1
});
auto state = _machine->get_processor_state();
state.status |= ccr;
state.data[1] = d1;
state.registers.status |= ccr;
state.registers.data[1] = d1;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
@ -174,32 +174,32 @@
[self performNBCDd1:0x7a ccr:0];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x20);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
XCTAssertEqual(state.registers.data[1], 0x20);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow);
}
- (void)testNBCD_Dn_extend {
[self performNBCDd1:0x1234567a ccr:Flag::Extend | Flag::Zero];
[self performNBCDd1:0x1234567a ccr:ConditionCode::Extend | ConditionCode::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x1234561f);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
XCTAssertEqual(state.registers.data[1], 0x1234561f);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow);
}
- (void)testNBCD_Dn_zero {
[self performNBCDd1:0x12345600 ccr:Flag::Zero];
[self performNBCDd1:0x12345600 ccr:ConditionCode::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero);
XCTAssertEqual(state.registers.data[1], 0x12345600);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero);
}
- (void)testNBCD_Dn_negative {
[self performNBCDd1:0x123456ff ccr:Flag::Extend | Flag::Zero];
[self performNBCDd1:0x123456ff ccr:ConditionCode::Extend | ConditionCode::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x1234569a);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
XCTAssertEqual(state.registers.data[1], 0x1234569a);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Negative);
}
- (void)testNBCD_Dn_XXXw {
@ -213,7 +213,7 @@
const auto state = _machine->get_processor_state();
XCTAssertEqual(16, _machine->get_cycle_count());
XCTAssertEqual(*_machine->ram_at(0x3000), 0x9900);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Negative);
}
// MARK: SBCD
@ -223,48 +223,48 @@
0x8302 // SBCD D2, D1
});
auto state = _machine->get_processor_state();
state.status |= ccr;
state.data[1] = d1;
state.data[2] = d2;
state.registers.status |= ccr;
state.registers.data[1] = d1;
state.registers.data[2] = d2;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(6, _machine->get_cycle_count());
XCTAssertEqual(state.data[2], d2);
XCTAssertEqual(state.registers.data[2], d2);
}
- (void)testSBCD_Dn {
[self performSBCDd1:0x12345689 d2:0xf745ff78 ccr:Flag::Zero];
[self performSBCDd1:0x12345689 d2:0xf745ff78 ccr:ConditionCode::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345611);
XCTAssertEqual(state.status & Flag::ConditionCodes, 0);
XCTAssertEqual(state.registers.data[1], 0x12345611);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0);
}
- (void)testSBCD_Dn_zero {
[self performSBCDd1:0x123456ff d2:0xf745ffff ccr:Flag::Zero];
[self performSBCDd1:0x123456ff d2:0xf745ffff ccr:ConditionCode::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero);
XCTAssertEqual(state.registers.data[1], 0x12345600);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero);
}
- (void)testSBCD_Dn_negative {
[self performSBCDd1:0x12345634 d2:0xf745ff45 ccr:Flag::Extend];
[self performSBCDd1:0x12345634 d2:0xf745ff45 ccr:ConditionCode::Extend];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345688);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
XCTAssertEqual(state.registers.data[1], 0x12345688);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Negative);
}
- (void)testSBCD_Dn_overflow {
[self performSBCDd1:0x123456a9 d2:0xf745ffff ccr:Flag::Extend];
[self performSBCDd1:0x123456a9 d2:0xf745ffff ccr:ConditionCode::Extend];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345643);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
XCTAssertEqual(state.registers.data[1], 0x12345643);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow);
}
- (void)testSBCD_Dn_PreDec {
@ -274,9 +274,9 @@
*_machine->ram_at(0x3000) = 0xa200;
*_machine->ram_at(0x4000) = 0x1900;
auto state = _machine->get_processor_state();
state.address[1] = 0x3001;
state.address[2] = 0x4001;
state.status |= Flag::Extend;
state.registers.address[1] = 0x3001;
state.registers.address[2] = 0x4001;
state.registers.status |= ConditionCode::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
@ -285,7 +285,7 @@
XCTAssertEqual(18, _machine->get_cycle_count());
XCTAssertEqual(*_machine->ram_at(0x3000), 0x8200);
XCTAssertEqual(*_machine->ram_at(0x4000), 0x1900);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative);
}
@end

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@
[self performBccb:0x6200];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1008 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1008 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 10);
}
@ -57,7 +57,7 @@
[self performBccb:0x6500];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 8);
}
@ -65,7 +65,7 @@
[self performBccw:0x6200];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1008 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1008 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 10);
}
@ -73,7 +73,7 @@
[self performBccw:0x6500];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1004 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1004 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 12);
}
@ -87,7 +87,7 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1006 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1006 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 10);
}
@ -99,7 +99,7 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1006 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1006 + 4);
XCTAssertEqual(_machine->get_cycle_count(), 10);
}
@ -114,9 +114,9 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1008 + 4);
XCTAssertEqual(state.stack_pointer(), 0x2ffc);
XCTAssertEqual(state.status & Flag::ConditionCodes, 0);
XCTAssertEqual(state.registers.program_counter, 0x1008 + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0x2ffc);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0);
XCTAssertEqual(*_machine->ram_at(0x2ffc), 0);
XCTAssertEqual(*_machine->ram_at(0x2ffe), 0x1004);
@ -132,9 +132,9 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1008 + 4);
XCTAssertEqual(state.stack_pointer(), 0x2ffc);
XCTAssertEqual(state.status & Flag::ConditionCodes, 0);
XCTAssertEqual(state.registers.program_counter, 0x1008 + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0x2ffc);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0);
XCTAssertEqual(*_machine->ram_at(0x2ffc), 0);
XCTAssertEqual(*_machine->ram_at(0x2ffe), 0x1002);
@ -148,25 +148,25 @@
0x4581 // CHK D1, D2
});
auto state = _machine->get_processor_state();
state.data[1] = d1;
state.data[2] = d2;
state.status |= Flag::ConditionCodes;
state.registers.data[1] = d1;
state.registers.data[2] = d2;
state.registers.status |= ConditionCode::AllConditions;
_machine->set_initial_stack_pointer(0);
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], d1);
XCTAssertEqual(state.data[2], d2);
XCTAssertEqual(state.registers.data[1], d1);
XCTAssertEqual(state.registers.data[2], d2);
}
- (void)testCHK_1111v1111 {
[self performCHKd1:0x1111 d2:0x1111];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
XCTAssertEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend);
XCTAssertEqual(10, _machine->get_cycle_count());
}
@ -174,8 +174,8 @@
[self performCHKd1:0x1111 d2:0x0000];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero);
XCTAssertEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero);
XCTAssertEqual(10, _machine->get_cycle_count());
}
@ -183,9 +183,9 @@
[self performCHKd1:0x8000 d2:0x8001];
const auto state = _machine->get_processor_state();
XCTAssertNotEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.stack_pointer(), 0xfffffffa);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
XCTAssertNotEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0xfffffffa);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend);
XCTAssertEqual(42, _machine->get_cycle_count());
}
@ -193,8 +193,8 @@
[self performCHKd1:0x8000 d2:0x8000];
const auto state = _machine->get_processor_state();
XCTAssertNotEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative);
XCTAssertNotEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative);
XCTAssertEqual(44, _machine->get_cycle_count());
}
@ -205,15 +205,15 @@
opcode, 0x0008 // DBcc D2, +8
});
auto state = _machine->get_processor_state();
state.status = status;
state.data[2] = 1;
state.registers.status = status;
state.registers.data[2] = 1;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(state.data[2], d2Output);
XCTAssertEqual(state.status, status);
XCTAssertEqual(state.registers.data[2], d2Output);
XCTAssertEqual(state.registers.status, status);
}
- (void)testDBT {
@ -229,27 +229,27 @@
}
- (void)testDBHI_Carry {
[self performDBccTestOpcode:0x52ca status:Flag::Carry d2Outcome:0];
[self performDBccTestOpcode:0x52ca status:ConditionCode::Carry d2Outcome:0];
}
- (void)testDBHI_Zero {
[self performDBccTestOpcode:0x52ca status:Flag::Zero d2Outcome:0];
[self performDBccTestOpcode:0x52ca status:ConditionCode::Zero d2Outcome:0];
}
- (void)testDBLS_CarryOverflow {
[self performDBccTestOpcode:0x53ca status:Flag::Carry | Flag::Overflow d2Outcome:1];
[self performDBccTestOpcode:0x53ca status:ConditionCode::Carry | ConditionCode::Overflow d2Outcome:1];
}
- (void)testDBLS_Carry {
[self performDBccTestOpcode:0x53ca status:Flag::Carry d2Outcome:1];
[self performDBccTestOpcode:0x53ca status:ConditionCode::Carry d2Outcome:1];
}
- (void)testDBLS_Overflow {
[self performDBccTestOpcode:0x53ca status:Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x53ca status:ConditionCode::Overflow d2Outcome:0];
}
- (void)testDBCC_Carry {
[self performDBccTestOpcode:0x54ca status:Flag::Carry d2Outcome:0];
[self performDBccTestOpcode:0x54ca status:ConditionCode::Carry d2Outcome:0];
}
- (void)testDBCC {
@ -261,7 +261,7 @@
}
- (void)testDBCS_Carry {
[self performDBccTestOpcode:0x55ca status:Flag::Carry d2Outcome:1];
[self performDBccTestOpcode:0x55ca status:ConditionCode::Carry d2Outcome:1];
}
- (void)testDBNE {
@ -269,7 +269,7 @@
}
- (void)testDBNE_Zero {
[self performDBccTestOpcode:0x56ca status:Flag::Zero d2Outcome:0];
[self performDBccTestOpcode:0x56ca status:ConditionCode::Zero d2Outcome:0];
}
- (void)testDBEQ {
@ -277,7 +277,7 @@
}
- (void)testDBEQ_Zero {
[self performDBccTestOpcode:0x57ca status:Flag::Zero d2Outcome:1];
[self performDBccTestOpcode:0x57ca status:ConditionCode::Zero d2Outcome:1];
}
- (void)testDBVC {
@ -285,7 +285,7 @@
}
- (void)testDBVC_Overflow {
[self performDBccTestOpcode:0x58ca status:Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x58ca status:ConditionCode::Overflow d2Outcome:0];
}
- (void)testDBVS {
@ -293,7 +293,7 @@
}
- (void)testDBVS_Overflow {
[self performDBccTestOpcode:0x59ca status:Flag::Overflow d2Outcome:1];
[self performDBccTestOpcode:0x59ca status:ConditionCode::Overflow d2Outcome:1];
}
- (void)testDBPL {
@ -301,7 +301,7 @@
}
- (void)testDBPL_Negative {
[self performDBccTestOpcode:0x5aca status:Flag::Negative d2Outcome:0];
[self performDBccTestOpcode:0x5aca status:ConditionCode::Negative d2Outcome:0];
}
- (void)testDBMI {
@ -309,11 +309,11 @@
}
- (void)testDBMI_Negative {
[self performDBccTestOpcode:0x5bca status:Flag::Negative d2Outcome:1];
[self performDBccTestOpcode:0x5bca status:ConditionCode::Negative d2Outcome:1];
}
- (void)testDBGE_NegativeOverflow {
[self performDBccTestOpcode:0x5cca status:Flag::Negative | Flag::Overflow d2Outcome:1];
[self performDBccTestOpcode:0x5cca status:ConditionCode::Negative | ConditionCode::Overflow d2Outcome:1];
}
- (void)testDBGE {
@ -321,15 +321,15 @@
}
- (void)testDBGE_Negative {
[self performDBccTestOpcode:0x5cca status:Flag::Negative d2Outcome:0];
[self performDBccTestOpcode:0x5cca status:ConditionCode::Negative d2Outcome:0];
}
- (void)testDBGE_Overflow {
[self performDBccTestOpcode:0x5cca status:Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x5cca status:ConditionCode::Overflow d2Outcome:0];
}
- (void)testDBLT_NegativeOverflow {
[self performDBccTestOpcode:0x5dca status:Flag::Negative | Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x5dca status:ConditionCode::Negative | ConditionCode::Overflow d2Outcome:0];
}
- (void)testDBLT {
@ -337,11 +337,11 @@
}
- (void)testDBLT_Negative {
[self performDBccTestOpcode:0x5dca status:Flag::Negative d2Outcome:1];
[self performDBccTestOpcode:0x5dca status:ConditionCode::Negative d2Outcome:1];
}
- (void)testDBLT_Overflow {
[self performDBccTestOpcode:0x5dca status:Flag::Overflow d2Outcome:1];
[self performDBccTestOpcode:0x5dca status:ConditionCode::Overflow d2Outcome:1];
}
- (void)testDBGT {
@ -349,15 +349,15 @@
}
- (void)testDBGT_ZeroNegativeOverflow {
[self performDBccTestOpcode:0x5eca status:Flag::Zero | Flag::Negative | Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x5eca status:ConditionCode::Zero | ConditionCode::Negative | ConditionCode::Overflow d2Outcome:0];
}
- (void)testDBGT_NegativeOverflow {
[self performDBccTestOpcode:0x5eca status:Flag::Negative | Flag::Overflow d2Outcome:1];
[self performDBccTestOpcode:0x5eca status:ConditionCode::Negative | ConditionCode::Overflow d2Outcome:1];
}
- (void)testDBGT_Zero {
[self performDBccTestOpcode:0x5eca status:Flag::Zero d2Outcome:0];
[self performDBccTestOpcode:0x5eca status:ConditionCode::Zero d2Outcome:0];
}
- (void)testDBLE {
@ -365,15 +365,15 @@
}
- (void)testDBLE_Zero {
[self performDBccTestOpcode:0x5fca status:Flag::Zero d2Outcome:1];
[self performDBccTestOpcode:0x5fca status:ConditionCode::Zero d2Outcome:1];
}
- (void)testDBLE_Negative {
[self performDBccTestOpcode:0x5fca status:Flag::Negative d2Outcome:1];
[self performDBccTestOpcode:0x5fca status:ConditionCode::Negative d2Outcome:1];
}
- (void)testDBLE_NegativeOverflow {
[self performDBccTestOpcode:0x5fca status:Flag::Negative | Flag::Overflow d2Outcome:0];
[self performDBccTestOpcode:0x5fca status:ConditionCode::Negative | ConditionCode::Overflow d2Outcome:0];
}
/* Further DBF tests omitted; they seemed to be duplicative, assuming I'm not suffering a failure of comprehension. */
@ -386,14 +386,14 @@
});
auto state = _machine->get_processor_state();
state.address[1] = 0x3000;
state.registers.address[1] = 0x3000;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(state.address[1], 0x3000);
XCTAssertEqual(state.program_counter, 0x3000 + 4);
XCTAssertEqual(state.registers.address[1], 0x3000);
XCTAssertEqual(state.registers.program_counter, 0x3000 + 4);
XCTAssertEqual(8, _machine->get_cycle_count());
}
@ -405,7 +405,7 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x100c + 4);
XCTAssertEqual(state.registers.program_counter, 0x100c + 4);
XCTAssertEqual(10, _machine->get_cycle_count());
}
@ -420,8 +420,8 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.stack_pointer(), 0x1ffc);
XCTAssertEqual(state.program_counter, 0x100c + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0x1ffc);
XCTAssertEqual(state.registers.program_counter, 0x100c + 4);
XCTAssertEqual(*_machine->ram_at(0x1ffc), 0x0000);
XCTAssertEqual(*_machine->ram_at(0x1ffe), 0x1004);
XCTAssertEqual(18, _machine->get_cycle_count());
@ -436,8 +436,8 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.stack_pointer(), 0x1ffc);
XCTAssertEqual(state.program_counter, 0x1008 + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0x1ffc);
XCTAssertEqual(state.registers.program_counter, 0x1008 + 4);
XCTAssertEqual(*_machine->ram_at(0x1ffc), 0x0000);
XCTAssertEqual(*_machine->ram_at(0x1ffe), 0x1006);
XCTAssertEqual(20, _machine->get_cycle_count());
@ -467,9 +467,9 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.stack_pointer(), 0x2006);
XCTAssertEqual(state.program_counter, 0x10);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes);
XCTAssertEqual(state.registers.stack_pointer(), 0x2006);
XCTAssertEqual(state.registers.program_counter, 0x10);
XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions);
XCTAssertEqual(20, _machine->get_cycle_count());
}
@ -486,8 +486,8 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.stack_pointer(), 0x2004);
XCTAssertEqual(state.program_counter, 0x000c + 4);
XCTAssertEqual(state.registers.stack_pointer(), 0x2004);
XCTAssertEqual(state.registers.program_counter, 0x000c + 4);
XCTAssertEqual(16, _machine->get_cycle_count());
}
@ -498,9 +498,9 @@
0x4e41 // TRAP #1
});
auto state = _machine->get_processor_state();
state.status = 0x700;
state.user_stack_pointer = 0x200;
state.supervisor_stack_pointer = 0x206;
state.registers.status = 0x700;
state.registers.user_stack_pointer = 0x200;
state.registers.supervisor_stack_pointer = 0x206;
*_machine->ram_at(0x84) = 0xfffe;
*_machine->ram_at(0xfffe) = 0x4e71;
@ -508,11 +508,11 @@
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(state.status, 0x2700);
XCTAssertEqual(state.registers.status, 0x2700);
XCTAssertEqual(*_machine->ram_at(0x200), 0x700);
XCTAssertEqual(*_machine->ram_at(0x202), 0x0000);
XCTAssertEqual(*_machine->ram_at(0x204), 0x1002);
XCTAssertEqual(state.supervisor_stack_pointer, 0x200);
XCTAssertEqual(state.registers.supervisor_stack_pointer, 0x200);
XCTAssertEqual(34, _machine->get_cycle_count());
}
@ -525,8 +525,8 @@
_machine->set_initial_stack_pointer(0x206);
auto state = _machine->get_processor_state();
state.status = 0x702;
state.supervisor_stack_pointer = 0x206;
state.registers.status = 0x702;
state.registers.supervisor_stack_pointer = 0x206;
*_machine->ram_at(0x1e) = 0xfffe;
*_machine->ram_at(0xfffe) = 0x4e71;
@ -534,8 +534,8 @@
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(state.status, 0x2702);
XCTAssertEqual(state.stack_pointer(), 0x200);
XCTAssertEqual(state.registers.status, 0x2702);
XCTAssertEqual(state.registers.stack_pointer(), 0x200);
XCTAssertEqual(*_machine->ram_at(0x202), 0x0000);
XCTAssertEqual(*_machine->ram_at(0x204), 0x1002);
XCTAssertEqual(*_machine->ram_at(0x200), 0x702);
@ -550,7 +550,7 @@
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.program_counter, 0x1002 + 4);
XCTAssertEqual(state.registers.program_counter, 0x1002 + 4);
XCTAssertEqual(4, _machine->get_cycle_count());
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
#include "TestRunner68000.hpp"
/*
class CPU::MC68000::ProcessorStorageTests {
public:
ProcessorStorageTests(const CPU::MC68000::ProcessorStorage &storage, const char *coverage_file_name) {
@ -80,6 +81,7 @@ class CPU::MC68000::ProcessorStorageTests {
NSMutableSet<NSNumber *> *false_invalids_;
NSMutableSet<NSNumber *> *false_valids_;
};
*/
@interface NSSet (CSHexDump)
@ -126,7 +128,7 @@ class CPU::MC68000::ProcessorStorageTests {
auto state = _machine->get_processor_state();
const uint8_t bcd_d = ((d / 10) * 16) + (d % 10);
state.data[0] = bcd_d;
state.registers.data[0] = bcd_d;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
@ -134,7 +136,7 @@ class CPU::MC68000::ProcessorStorageTests {
state = _machine->get_processor_state();
const uint8_t double_d = (d * 2) % 100;
const uint8_t bcd_double_d = ((double_d / 10) * 16) + (double_d % 10);
XCTAssert(state.data[0] == bcd_double_d, "%02x + %02x = %02x; should equal %02x", bcd_d, bcd_d, state.data[0], bcd_double_d);
XCTAssert(state.registers.data[0] == bcd_double_d, "%02x + %02x = %02x; should equal %02x", bcd_d, bcd_d, state.registers.data[0], bcd_double_d);
}
}
@ -152,9 +154,9 @@ class CPU::MC68000::ProcessorStorageTests {
_machine->run_for_instructions(4);
const auto state = _machine->get_processor_state();
XCTAssert(state.supervisor_stack_pointer == 0x1000 - 6, @"Exception information should have been pushed to stack.");
XCTAssert(state.registers.supervisor_stack_pointer == 0x1000 - 6, @"Exception information should have been pushed to stack.");
const uint16_t *const stack_top = _machine->ram_at(state.supervisor_stack_pointer);
const uint16_t *const stack_top = _machine->ram_at(state.registers.supervisor_stack_pointer);
XCTAssert(stack_top[1] == 0x0000 && stack_top[2] == 0x1006, @"Return address should point to instruction after DIVU.");
}
@ -177,28 +179,28 @@ class CPU::MC68000::ProcessorStorageTests {
// Perform MOVE #fb2e, D0
_machine->run_for_instructions(1);
auto state = _machine->get_processor_state();
XCTAssert(state.data[0] == 0xfb2e);
XCTAssert(state.registers.data[0] == 0xfb2e);
// Perform MOVE D0, D1
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.data[1] == 0xfb2e);
XCTAssert(state.registers.data[1] == 0xfb2e);
// Perform MOVEA D0, A0
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.address[0] == 0xfffffb2e, "A0 was %08x instead of 0xfffffb2e", state.address[0]);
XCTAssert(state.registers.address[0] == 0xfffffb2e, "A0 was %08x instead of 0xfffffb2e", state.registers.address[0]);
// Perform MOVEA.w (0x1000), A1
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssert(state.address[1] == 0x0000303c, "A1 was %08x instead of 0x0000303c", state.address[1]);
XCTAssert(state.registers.address[1] == 0x0000303c, "A1 was %08x instead of 0x0000303c", state.registers.address[1]);
// Perform MOVE #$400, A4; MOVE.l (A4), D2
_machine->run_for_instructions(2);
state = _machine->get_processor_state();
XCTAssert(state.address[4] == 0x1000, "A4 was %08x instead of 0x00001000", state.address[4]);
XCTAssert(state.data[2] == 0x303cfb2e, "D2 was %08x instead of 0x303cfb2e", state.data[2]);
XCTAssert(state.registers.address[4] == 0x1000, "A4 was %08x instead of 0x00001000", state.registers.address[4]);
XCTAssert(state.registers.data[2] == 0x303cfb2e, "D2 was %08x instead of 0x303cfb2e", state.registers.data[2]);
}
- (void)testVectoredInterrupt {
@ -223,7 +225,7 @@ class CPU::MC68000::ProcessorStorageTests {
_machine->run_for_instructions(1);
const auto state = _machine->processor().get_state();
XCTAssertEqual(state.program_counter, 0x1008); // i.e. the interrupt happened, the instruction performed was the one at 1004, and therefore
XCTAssertEqual(state.registers.program_counter, 0x1008); // i.e. the interrupt happened, the instruction performed was the one at 1004, and therefore
// by the wonders of prefetch the program counter is now at 1008.
}
@ -287,7 +289,7 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssertEqual(_machine->get_cycle_count(), 6 + 2);
}
- (void)testOpcodeCoverage {
/*- (void)testOpcodeCoverage {
// Perform an audit of implemented instructions.
CPU::MC68000::ProcessorStorageTests storage_tests(
_machine->processor(),
@ -479,6 +481,6 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssert(!trimmedInvalids.count, "%@ opcodes should be valid but aren't: %@", @(trimmedInvalids.count), trimmedInvalids.hexDump);
// XCTAssert(!falseInvalids.count, "%@ opcodes should be valid but aren't: %@", @(falseInvalids.count), falseInvalids.hexDump);
}
}*/
@end

View File

@ -10,17 +10,18 @@
#define TestRunner68000_h
#include <array>
#include <vector>
#include "../../../Processors/68000/68000.hpp"
#include "../../../Processors/68000Mk2/68000Mk2.hpp"
using Flag = CPU::MC68000::Flag;
using namespace InstructionSet::M68k;
/*!
Provides a 68000 with 64kb of RAM in its low address space;
/RESET will put the supervisor stack pointer at 0xFFFF and
begin execution at 0x0400.
*/
class RAM68000: public CPU::MC68000::BusHandler {
class RAM68000: public CPU::MC68000Mk2::BusHandler {
public:
RAM68000() : m68000_(*this) {
// Setup the /RESET vector.
@ -31,7 +32,7 @@ class RAM68000: public CPU::MC68000::BusHandler {
// Ensure the condition codes start unset.
auto state = get_processor_state();
state.status &= ~Flag::ConditionCodes;
state.registers.status &= ~ConditionCode::AllConditions;
set_processor_state(state);
}
@ -84,30 +85,30 @@ class RAM68000: public CPU::MC68000::BusHandler {
return &ram_[(address >> 1) % ram_.size()];
}
HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int) {
HalfCycles perform_bus_operation(const CPU::MC68000Mk2::Microcycle &cycle, int) {
const uint32_t word_address = cycle.word_address();
if(instructions_remaining_) duration_ += cycle.length;
using Microcycle = CPU::MC68000::Microcycle;
using Microcycle = CPU::MC68000Mk2::Microcycle;
if(cycle.data_select_active()) {
if(cycle.operation & Microcycle::InterruptAcknowledge) {
cycle.value->halves.low = 10;
cycle.value->b = 10;
} else {
switch(cycle.operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) {
default: break;
case Microcycle::SelectWord | Microcycle::Read:
cycle.value->full = ram_[word_address % ram_.size()];
cycle.value->w = ram_[word_address % ram_.size()];
break;
case Microcycle::SelectByte | Microcycle::Read:
cycle.value->halves.low = ram_[word_address % ram_.size()] >> cycle.byte_shift();
cycle.value->b = ram_[word_address % ram_.size()] >> cycle.byte_shift();
break;
case Microcycle::SelectWord:
ram_[word_address % ram_.size()] = cycle.value->full;
ram_[word_address % ram_.size()] = cycle.value->w;
break;
case Microcycle::SelectByte:
ram_[word_address % ram_.size()] = uint16_t(
(cycle.value->halves.low << cycle.byte_shift()) |
(cycle.value->b << cycle.byte_shift()) |
(ram_[word_address % ram_.size()] & cycle.untouched_byte_mask())
);
break;
@ -118,15 +119,15 @@ class RAM68000: public CPU::MC68000::BusHandler {
return HalfCycles(0);
}
CPU::MC68000::Processor<RAM68000, true>::State get_processor_state() {
CPU::MC68000Mk2::State get_processor_state() {
return m68000_.get_state();
}
void set_processor_state(const CPU::MC68000::Processor<RAM68000, true>::State &state) {
void set_processor_state(const CPU::MC68000Mk2::State &state) {
m68000_.set_state(state);
}
CPU::MC68000::Processor<RAM68000, true, true> &processor() {
auto &processor() {
return m68000_;
}
@ -139,7 +140,7 @@ class RAM68000: public CPU::MC68000::BusHandler {
}
private:
CPU::MC68000::Processor<RAM68000, true, true> m68000_;
CPU::MC68000Mk2::Processor<RAM68000, true, false, true> m68000_;
std::array<uint16_t, 256*1024> ram_{};
int instructions_remaining_;
HalfCycles duration_;