1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-11-27 03:18:00 +00:00

Attempts to introduce more rigour to variable-length instruction handling.

This commit is contained in:
Thomas Harte
2019-06-24 10:43:28 -04:00
parent db4ca746e3
commit d27ba90c07
5 changed files with 75 additions and 16 deletions

View File

@@ -49,6 +49,12 @@
#define s_extend16(x) int32_t(int16_t(x))
#define s_extend8(x) int32_t(int8_t(x))
// Sets the length of the next microcycle; if this is a debug build, also confirms
// that the microcycle being adjusted is the one that it's permissible to adjust.
#define set_next_microcycle_length(x) \
assert(resizeable_microcycle_ == &bus_program->microcycle); \
bus_program->microcycle.length = x
template <class T, bool dtack_is_implicit, bool signal_will_perform> void Processor<T, dtack_is_implicit, signal_will_perform>::run_for(HalfCycles duration) {
const HalfCycles remaining_duration = duration + half_cycles_left_to_run_;
@@ -623,13 +629,13 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
active_program_->destination->full &= ~(1 << (active_program_->source->full & 31));
// Clearing in the top word requires an extra four cycles.
active_step_->microcycle.length = HalfCycles(8 + ((active_program_->source->full & 31) / 16) * 4);
set_next_microcycle_length(HalfCycles(8 + ((active_program_->source->full & 31) / 16) * 4));
break;
case Operation::BCHGl:
zero_result_ = active_program_->destination->full & (1 << (active_program_->source->full & 31));
active_program_->destination->full ^= 1 << (active_program_->source->full & 31);
active_step_->microcycle.length = HalfCycles(4 + (((active_program_->source->full & 31) / 16) * 4));
set_next_microcycle_length(HalfCycles(4 + (((active_program_->source->full & 31) / 16) * 4)));
break;
case Operation::BCHGb:
@@ -640,7 +646,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
case Operation::BSETl:
zero_result_ = active_program_->destination->full & (1 << (active_program_->source->full & 31));
active_program_->destination->full |= 1 << (active_program_->source->full & 31);
bus_program->microcycle.length = HalfCycles(4 + (((active_program_->source->full & 31) / 16) * 4));
set_next_microcycle_length(HalfCycles(4 + (((active_program_->source->full & 31) / 16) * 4)));
break;
case Operation::BSETb:
@@ -908,7 +914,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
}
// Time taken = 38 cycles + 2 cycles per 1 in the source.
active_step_->microcycle.length = HalfCycles(4 * number_of_ones + 38*2);
set_next_microcycle_length(HalfCycles(4 * number_of_ones + 38*2));
} break;
case Operation::MULS: {
@@ -929,7 +935,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
}
// Time taken = 38 cycles + 2 cycles per 1 in the source.
active_step_->microcycle.length = HalfCycles(4 * number_of_pairs + 38*2);
set_next_microcycle_length(HalfCycles(4 * number_of_pairs + 38*2));
} break;
/*
@@ -942,7 +948,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
bus_program = active_micro_op_->bus_program; \
\
populate_trap_steps(5, get_status()); \
bus_program->microcycle.length = HalfCycles(8); \
set_next_microcycle_length(HalfCycles(8)); \
\
program_counter_.full -= 2;
@@ -964,7 +970,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
if(quotient >= 65536) {
overflow_flag_ = 1;
// TODO: is what should happen to the other flags known?
active_step_->microcycle.length = HalfCycles(3*2*2);
set_next_microcycle_length(HalfCycles(3*2*2));
break;
}
@@ -1002,7 +1008,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
}
}
}
active_step_->microcycle.length = HalfCycles(cycles_expended * 2);
set_next_microcycle_length(HalfCycles(cycles_expended * 2));
} break;
case Operation::DIVS: {
@@ -1027,7 +1033,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// 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);
set_next_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);
@@ -1064,7 +1070,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
} else if(dividend < 0) {
cycles_expended += 4;
}
active_step_->microcycle.length = HalfCycles(cycles_expended * 2);
set_next_microcycle_length(HalfCycles(cycles_expended * 2));
} break;
#undef announce_divide_by_zero
@@ -1254,7 +1260,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
bus_program = trap_steps_;
populate_trap_steps((decoded_instruction_.full & 15) + 32, get_status());
bus_program->microcycle.length = HalfCycles(8);
set_next_microcycle_length(HalfCycles(8));
// The program counter to push is actually one slot ago.
program_counter_.full -= 2;
@@ -1265,7 +1271,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
bus_program = trap_steps_;
populate_trap_steps(7, get_status());
bus_program->microcycle.length = HalfCycles(0);
set_next_microcycle_length(HalfCycles(0));
program_counter_.full -= 4;
}
} break;
@@ -1282,9 +1288,9 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
bus_program = trap_steps_;
populate_trap_steps(6, get_status());
if(is_under) {
bus_program->microcycle.length = HalfCycles(16);
set_next_microcycle_length(HalfCycles(16));
} else {
bus_program->microcycle.length = HalfCycles(8);
set_next_microcycle_length(HalfCycles(8));
}
// The program counter to push is two slots ago as whatever was the correct prefetch
@@ -1538,7 +1544,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
#define decode_shift_count() \
int shift_count = (decoded_instruction_.full & 32) ? data_[(decoded_instruction_.full >> 9) & 7].full&63 : ( ((decoded_instruction_.full >> 9)&7) ? ((decoded_instruction_.full >> 9)&7) : 8) ; \
bus_program->microcycle.length = HalfCycles(4 * shift_count);
set_next_microcycle_length(HalfCycles(4 * shift_count));
#define set_flags_b(t) set_flags(active_program_->destination->halves.low.halves.low, 0x80, t)
#define set_flags_w(t) set_flags(active_program_->destination->halves.low.full, 0x8000, t)
@@ -2139,3 +2145,4 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
#undef u_extend8
#undef s_extend16
#undef s_extend8
#undef set_next_microcycle_length