1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 15:29:36 +00:00

Imports DIVS, MULS and MOVE from SR tests.

Not all passing.
This commit is contained in:
Thomas Harte 2019-06-21 16:03:11 -04:00
parent 0c1c10bc66
commit ccfe1b13cb
3 changed files with 216 additions and 12 deletions

View File

@ -1066,7 +1066,7 @@ class CPU::MC68000::ProcessorStorageTests {
const auto state = _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, _machine->get_cycle_count());
}
- (void)testDIVSOverflow {
@ -1081,14 +1081,141 @@ class CPU::MC68000::ProcessorStorageTests {
[self performDIVSOverflowTestDivisor:0xeeff];
}
- (void)testDIVS {
- (void)testDIVS_2 {
[self performDivide:0xeef0 a1:0x0768f231];
const auto state = _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, _machine->get_cycle_count());
}
- (void)testDIVS_3 {
[self performDivide:0xffff a1:0xffffffff];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 1);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(158, _machine->get_cycle_count());
}
- (void)testDIVS_4 {
[self performDivide:0x3333 a1:0xffff0000];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0xfffffffb);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative);
// XCTAssertEqual(158, _machine->get_cycle_count());
}
- (void)testDIVS_5 {
[self performDivide:0x23 a1:0x8765];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0xb03de);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(138, _machine->get_cycle_count());
}
- (void)testDIVS_6 {
[self performDivide:0x8765 a1:0x65];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x650000);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Zero);
// XCTAssertEqual(156, _machine->get_cycle_count());
}
- (void)testDIVSExpensiveOverflow {
// DIVS.W #$ffff, D1 alt
[self performDivide:0xffff a1:0x80000000];
const auto state = _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());
}
- (void)testDIVS_8 {
// DIVS.W #$fffd, D1
[self performDivide:0xfffd a1:0xfffffffd];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x1);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(158, _machine->get_cycle_count());
}
- (void)testDIVS_9 {
// DIVS.W #$7aee, D1
[self performDivide:0x7aee a1:0xdaaa00fe];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0xc97eb240);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative);
// XCTAssertEqual(148, _machine->get_cycle_count());
}
- (void)testDIVS_10 {
// DIVS.W #$7fff, D1
[self performDivide:0x7fff a1:0x82f9fff];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x305e105f);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(142, _machine->get_cycle_count());
}
- (void)testDIVS_11 {
// DIVS.W #$f32, D1
[self performDivide:0xf32 a1:0x00e1d44];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x0bfa00ed);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(144, _machine->get_cycle_count());
}
- (void)testDIVS_12 {
// DIVS.W #$af32, D1
[self performDivide:0xaf32 a1:0xe1d44];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x39dcffd4);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative);
// XCTAssertEqual(150, _machine->get_cycle_count());
}
- (void)testDIVSException {
// DIVS.W #0, D1
auto state = _machine->get_processor_state();
state.supervisor_stack_pointer = 0;
_machine->set_processor_state(state);
[self performDivide:0x0 a1:0x1fffffff];
state = _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());
}
// MARK: MOVE from SR
- (void)testMoveFromSR {
_machine->set_program({
0x40c1 // MOVE SR, D1
});
auto state = _machine->get_processor_state();
state.status = 0x271f;
_machine->set_processor_state(state);
_machine->run_for_instructions(2);
state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x271f);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes);
// XCTAssertEqual(6, _machine->get_cycle_count());
}
// MARK: MOVE USP
@ -1107,6 +1234,81 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssertEqual(state.address[1], 0);
}
// MARK: MULS
- (void)performMULd1:(uint32_t)d1 d2:(uint32_t)d2 ccr:(uint8_t)ccr {
_machine->set_program({
0xc5c1 // MULS D1, D2
});
auto state = _machine->get_processor_state();
state.data[1] = d1;
state.data[2] = d2;
state.status = ccr;
_machine->set_processor_state(state);
_machine->run_for_instructions(2);
}
- (void)performMULConstant:(uint16_t)constant d2:(uint32_t)d2 {
_machine->set_program({
0xc5fc, constant // MULS #constant, D2
});
auto state = _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(2);
}
- (void)testMULS {
[self performMULd1:0x12345678 d2:0x12345678 ccr:0];
const auto state = _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());
}
- (void)testMULS_2 {
[self performMULd1:0x82348678 d2:0x823486ff ccr:0];
const auto state = _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());
}
- (void)testMULSZero {
[self performMULd1:1 d2:0 ccr:Flag::Carry | Flag::Overflow | Flag::Extend];
const auto state = _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());
}
- (void)testMULSFFFF {
[self performMULConstant:0xffff d2:0xffff];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[2], 1);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend);
// XCTAssertEqual(44, _machine->get_cycle_count());
}
- (void)testMULSNegative {
[self performMULConstant:0x1fff d2:0x8fff];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[2], 0xf2005001);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative);
// XCTAssertEqual(46, _machine->get_cycle_count());
}
// MARK: Scc
- (void)testSFDn {

View File

@ -1015,7 +1015,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
int32_t dividend = int32_t(active_program_->destination->full);
int32_t divisor = s_extend16(active_program_->source->halves.low.full);
const auto quotient = dividend / divisor;
const int64_t quotient = int64_t(dividend) / int64_t(divisor);
int cycles_expended = 12; // Covers the nn nnn n to get beyond the sign test.
if(dividend < 0) {
@ -1024,18 +1024,20 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
carry_flag_ = 0;
// These are officially undefined for results that overflow, so the below is a guess.
zero_result_ = decltype(zero_result_)(quotient & 0xffff);
negative_flag_ = zero_result_ & 0x8000;
// Check for overflow. If it exists, work here is already done.
if(quotient > 32767 || quotient < -32768) {
overflow_flag_ = 1;
active_step_->microcycle.length = HalfCycles(3*2*2);
// These are officially undefined for results that overflow, so the below is a guess.
zero_result_ = decltype(zero_result_)(divisor & 0xffff);
negative_flag_ = zero_result_ & 0x8000;
break;
}
zero_result_ = decltype(zero_result_)(quotient);
negative_flag_ = zero_result_ & 0x8000;
overflow_flag_ = 0;
// TODO: check sign rules here; am I necessarily giving the remainder the correct sign?
@ -1048,7 +1050,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// in the unsigned quotient; there is an additional microcycle for
// every bit that is set. Also, since the possibility of overflow
// was already dealt with, it's now a smaller number.
int positive_quotient = abs(quotient);
int positive_quotient = int(abs(quotient));
for(int c = 0; c < 15; ++c) {
if(positive_quotient & 0x8000) cycles_expended += 2;
positive_quotient <<= 1;

View File

@ -807,9 +807,9 @@ struct ProcessorStorageConstructor {
// Temporary storage for the Program fields.
ProcessorBase::Program program;
// if(instruction == 0x4e41) {
// printf("");
// }
if(instruction == 0x40c1) {
printf("");
}
#define dec(n) decrement_action(is_long_word_access, is_byte_access, n)
#define inc(n) increment_action(is_long_word_access, is_byte_access, n)