1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 16:31:31 +00:00

Incorporates ADDX tests and fixes ADDX PreDec.

This commit is contained in:
Thomas Harte 2019-06-25 19:18:07 -04:00
parent e12e8fc616
commit ecb5a0b8cc
2 changed files with 96 additions and 16 deletions

View File

@ -889,6 +889,89 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes);
}
// MARL: ADDX
- (void)testADDXl_Dn {
_machine->set_program({
0xd581 // ADDX.l D1, D2
});
auto state = _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);
state = _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());
}
- (void)testADDXb {
_machine->set_program({
0xd501 // ADDX.b D1, D2
});
auto state = _machine->get_processor_state();
state.data[1] = 0x80;
state.data[2] = 0x8080;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _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());
}
- (void)testADDXw {
_machine->set_program({
0xd541 // ADDX.w D1, D2
});
auto state = _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);
state = _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());
}
- (void)testADDXl_PreDec {
_machine->set_program({
0xd389 // ADDX.l -(A1), -(A1)
});
auto state = _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;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _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());
}
// MARK: ASL
- (void)testASLb_Dn_2 {

View File

@ -1705,24 +1705,21 @@ struct ProcessorStorageConstructor {
if(is_long_word_access) {
// Access order is very atypical here: it's lower parts each for both words,
// and then also a lower-part-first write.
op(int(Action::Decrement2) | MicroOp::SourceMask | MicroOp::DestinationMask);
op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask | MicroOp::DestinationMask,
seq("n nr- nR nrd- nRd+", { ea(0), ea(0), ea(1), ea(1) }));
op(int(Action::Decrement2) | MicroOp::SourceMask | MicroOp::DestinationMask);
op(int(Action::Decrement2) | MicroOp::SourceMask);
op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask,
seq("n nr- nR", { ea(0), ea(0) }));
op(int(Action::Decrement2) | MicroOp::DestinationMask | MicroOp::SourceMask);
op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask,
seq("nrd- nRd+", { ea(1), ea(1) }));
op(Action::PerformOperation, seq("nw- np nW", { ea(1), ea(1) }));
op(int(Action::Decrement2) | MicroOp::DestinationMask);
} else {
const int source_dec = dec(ea_register);
const int destination_dec = dec(data_register);
int first_action;
if(source_dec == destination_dec) {
first_action = int(Action::Decrement4) | MicroOp::SourceMask | MicroOp::DestinationMask;
} else {
op(source_dec | MicroOp::SourceMask);
first_action = destination_dec | MicroOp::DestinationMask;
}
op(first_action, seq("n nr nrd np", { ea(0), ea(1) }, !is_byte_access));
op(dec(ea_register) | MicroOp::SourceMask);
op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask,
seq("n nr", { ea(0) }, !is_byte_access));
op(dec(data_register) | MicroOp::DestinationMask);
op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask,
seq("nrd np", { ea(1) }, !is_byte_access));
op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access));
}
} else {