1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 03:32:01 +00:00

Corrects DIVU timing and flags, improves DIVS.

This commit is contained in:
Thomas Harte 2019-07-01 14:24:32 -04:00
parent d8fb6fb951
commit 514e57b3e9
2 changed files with 11 additions and 6 deletions

View File

@ -681,7 +681,7 @@
}); });
auto state = _machine->get_processor_state(); auto state = _machine->get_processor_state();
state.data[1] = d1; state.data[1] = d1;
state.status = Flag::ConditionCodes; state.status |= Flag::ConditionCodes;
_machine->set_processor_state(state); _machine->set_processor_state(state);
_machine->run_for_instructions(1); _machine->run_for_instructions(1);

View File

@ -965,6 +965,8 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
*/ */
#define announce_divide_by_zero() \ #define announce_divide_by_zero() \
negative_flag_ = overflow_flag_ = 0; \
zero_result_ = 1; \
active_program_ = nullptr; \ active_program_ = nullptr; \
active_micro_op_ = short_exception_micro_ops_; \ active_micro_op_ = short_exception_micro_ops_; \
bus_program = active_micro_op_->bus_program; \ bus_program = active_micro_op_->bus_program; \
@ -990,8 +992,11 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// If overflow would occur, appropriate flags are set and the result is not written back. // If overflow would occur, appropriate flags are set and the result is not written back.
if(quotient >= 65536) { if(quotient >= 65536) {
overflow_flag_ = 1; overflow_flag_ =
// TODO: is what should happen to the other flags known? 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)); set_next_microcycle_length(HalfCycles(3*2*2));
break; break;
} }
@ -1008,7 +1013,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// I could actually calculate the division result here, since this is // I could actually calculate the division result here, since this is
// a classic divide algorithm, but would rather that errors produce // a classic divide algorithm, but would rather that errors produce
// incorrect timing only, not incorrect timing plus incorrect results. // 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; divisor <<= 16;
for(int c = 0; c < 15; ++c) { for(int c = 0; c < 15; ++c) {
@ -1034,6 +1039,8 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
} break; } break;
case Operation::DIVS: { case Operation::DIVS: {
carry_flag_ = 0;
// An attempt to divide by zero schedules an exception. // An attempt to divide by zero schedules an exception.
if(!active_program_->source->halves.low.full) { if(!active_program_->source->halves.low.full) {
// Schedule a divide-by-zero exception. // Schedule a divide-by-zero exception.
@ -1050,8 +1057,6 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
cycles_expended += 2; // An additional microycle applies if the dividend is negative. 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. // Check for overflow. If it exists, work here is already done.
if(quotient > 32767 || quotient < -32768) { if(quotient > 32767 || quotient < -32768) {
overflow_flag_ = 1; overflow_flag_ = 1;