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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user