From 514e57b3e964bac8e433f985163593785882da7b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 1 Jul 2019 14:24:32 -0400 Subject: [PATCH] Corrects DIVU timing and flags, improves DIVS. --- .../Mac/Clock SignalTests/68000ArithmeticTests.mm | 2 +- .../68000/Implementation/68000Implementation.hpp | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm index cde5f63ed..00277c5f7 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm @@ -681,7 +681,7 @@ }); auto state = _machine->get_processor_state(); state.data[1] = d1; - state.status = Flag::ConditionCodes; + state.status |= Flag::ConditionCodes; _machine->set_processor_state(state); _machine->run_for_instructions(1); diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 358a6a6b4..0044a2330 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -965,6 +965,8 @@ template void Proces */ #define announce_divide_by_zero() \ + negative_flag_ = overflow_flag_ = 0; \ + zero_result_ = 1; \ active_program_ = nullptr; \ active_micro_op_ = short_exception_micro_ops_; \ bus_program = active_micro_op_->bus_program; \ @@ -990,8 +992,11 @@ template void Proces // If overflow would occur, appropriate flags are set and the result is not written back. if(quotient >= 65536) { - overflow_flag_ = 1; - // TODO: is what should happen to the other flags known? + overflow_flag_ = + zero_result_ = + negative_flag_ = 1; + // TODO: Zero and Negative flags as above are merely sufficient + // to satisfy the tests I currentl have. What should they really be? set_next_microcycle_length(HalfCycles(3*2*2)); break; } @@ -1008,7 +1013,7 @@ template void Proces // I could actually calculate the division result here, since this is // a classic divide algorithm, but would rather that errors produce // incorrect timing only, not incorrect timing plus incorrect results. - int cycles_expended = 6; // Covers the nn n to get into the loop. + int cycles_expended = 12; // Covers the nn n to get into the loop. divisor <<= 16; for(int c = 0; c < 15; ++c) { @@ -1034,6 +1039,8 @@ template void Proces } break; case Operation::DIVS: { + carry_flag_ = 0; + // An attempt to divide by zero schedules an exception. if(!active_program_->source->halves.low.full) { // Schedule a divide-by-zero exception. @@ -1050,8 +1057,6 @@ template void Proces cycles_expended += 2; // An additional microycle applies if the dividend is negative. } - carry_flag_ = 0; - // Check for overflow. If it exists, work here is already done. if(quotient > 32767 || quotient < -32768) { overflow_flag_ = 1;