mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Alters the order of interrupt bus activity, to bring it into line with a real 68000.
This commit is contained in:
parent
93616a4903
commit
1d9608efc7
@ -399,6 +399,27 @@ struct ProcessorStorageConstructor {
|
||||
return start;*/
|
||||
}
|
||||
|
||||
/*!
|
||||
Walks through the sequence of bus steps beginning at @c start, replacing the value supplied for each write
|
||||
encountered with the respective value from @c values.
|
||||
*/
|
||||
void replace_write_values(BusStep *start, const std::vector<RegisterPair16 *> &values) {
|
||||
assert(replace_write_values(start, values.begin()) == values.end());
|
||||
}
|
||||
|
||||
/*!
|
||||
Walks through the sequence of micro-ops beginning at @c start, replacing the value supplied for each write
|
||||
encountered in each micro-op's bus steps with the respective value from @c values.
|
||||
*/
|
||||
void replace_write_values(ProcessorBase::MicroOp *start, const std::vector<RegisterPair16 *> &values) {
|
||||
auto value = values.begin();
|
||||
while(!start->is_terminal()) {
|
||||
value = replace_write_values(start->bus_program, value);
|
||||
++start;
|
||||
}
|
||||
assert(value == values.end());
|
||||
}
|
||||
|
||||
/*!
|
||||
Disassembles the instruction @c instruction and inserts it into the
|
||||
appropriate lookup tables.
|
||||
@ -3314,9 +3335,17 @@ struct ProcessorStorageConstructor {
|
||||
|
||||
// Throw in the interrupt program.
|
||||
const auto interrupt_pointer = storage_.all_micro_ops_.size();
|
||||
op(Action::None, seq("")); // WORKAROUND FOR THE BE68000 MAIN LOOP. Hopefully temporary.
|
||||
op(Action::PrepareINT, seq("int")); // Perform a cycle that will obtain an interrupt vector, or else dictate an autovector or a spurious interrupt.
|
||||
op(Action::PrepareINTVector); // The standard trap steps will be appended here, and PrepareINT will set them up according to the vector received.
|
||||
|
||||
// WORKAROUND FOR THE BE68000 MAIN LOOP. Hopefully temporary.
|
||||
op(Action::None, seq(""));
|
||||
|
||||
// Perform a single write and then a cycle that will obtain an interrupt vector, or else dictate an autovector or a spurious interrupt.
|
||||
op(Action::PrepareINT, seq("nw int", { &storage_.precomputed_addresses_[0] }));
|
||||
|
||||
// The reset of the standard trap steps occur here; PrepareINT will set them up according to the vector received.
|
||||
op(Action::PrepareINTVector, seq("nw nW nV nv np np", { &storage_.precomputed_addresses_[1], &storage_.precomputed_addresses_[2] }));
|
||||
|
||||
// Terminate the sequence.
|
||||
op();
|
||||
|
||||
#undef Dn
|
||||
@ -3373,6 +3402,20 @@ struct ProcessorStorageConstructor {
|
||||
private:
|
||||
ProcessorStorage &storage_;
|
||||
|
||||
std::vector<RegisterPair16 *>::const_iterator replace_write_values(BusStep *start, std::vector<RegisterPair16 *>::const_iterator value) {
|
||||
while(!start->is_terminal()) {
|
||||
// Look for any bus step that writes. Then replace its value, and that of the cycle before it.
|
||||
if(start->microcycle.data_select_active() && !(start->microcycle.operation & Microcycle::Read) && !(start->microcycle.operation & Microcycle::InterruptAcknowledge)) {
|
||||
start[0].microcycle.value = start[-1].microcycle.value = *value;
|
||||
++value;
|
||||
}
|
||||
|
||||
++start;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* struct BusStepOrderer {
|
||||
bool operator()( BusStep const& lhs, BusStep const& rhs ) const {
|
||||
int action_diff = int(lhs.action) - int(rhs.action);
|
||||
@ -3476,19 +3519,22 @@ CPU::MC68000::ProcessorStorage::ProcessorStorage() {
|
||||
//
|
||||
// Order of output is: PC.l, SR, PC.h.
|
||||
trap_steps_ = &all_bus_steps_[trap_offset];
|
||||
trap_steps_[1].microcycle.value = trap_steps_[2].microcycle.value = &program_counter_.halves.low;
|
||||
trap_steps_[3].microcycle.value = trap_steps_[4].microcycle.value = &destination_bus_data_[0].halves.low;
|
||||
trap_steps_[5].microcycle.value = trap_steps_[6].microcycle.value = &program_counter_.halves.high;
|
||||
constructor.replace_write_values(trap_steps_, { &program_counter_.halves.low, &destination_bus_data_[0].halves.low, &program_counter_.halves.high });
|
||||
|
||||
// Fill in the same order of writes for the interrupt micro-ops, though it divides the work differently.
|
||||
constructor.replace_write_values(interrupt_micro_ops_, { &program_counter_.halves.low, &destination_bus_data_[0].halves.low, &program_counter_.halves.high });
|
||||
|
||||
// Link the bus error exception steps and fill in the proper sources.
|
||||
bus_error_steps_ = &all_bus_steps_[bus_error_offset];
|
||||
bus_error_steps_[1].microcycle.value = bus_error_steps_[2].microcycle.value = &program_counter_.halves.low;
|
||||
bus_error_steps_[3].microcycle.value = bus_error_steps_[4].microcycle.value = &destination_bus_data_[0].halves.low;
|
||||
bus_error_steps_[5].microcycle.value = bus_error_steps_[6].microcycle.value = &program_counter_.halves.high;
|
||||
bus_error_steps_[7].microcycle.value = bus_error_steps_[8].microcycle.value = &decoded_instruction_;
|
||||
bus_error_steps_[9].microcycle.value = bus_error_steps_[10].microcycle.value = &effective_address_[0].halves.low;
|
||||
bus_error_steps_[11].microcycle.value = bus_error_steps_[12].microcycle.value = &destination_bus_data_[0].halves.high;
|
||||
bus_error_steps_[13].microcycle.value = bus_error_steps_[14].microcycle.value = &effective_address_[0].halves.high;
|
||||
constructor.replace_write_values(bus_error_steps_, {
|
||||
&program_counter_.halves.low,
|
||||
&destination_bus_data_[0].halves.low,
|
||||
&program_counter_.halves.high,
|
||||
&decoded_instruction_,
|
||||
&effective_address_[0].halves.low,
|
||||
&destination_bus_data_[0].halves.high,
|
||||
&effective_address_[0].halves.high
|
||||
});
|
||||
|
||||
// Also relink the RTE and RTR bus steps to collect the program counter.
|
||||
//
|
||||
@ -3509,9 +3555,6 @@ CPU::MC68000::ProcessorStorage::ProcessorStorage() {
|
||||
long_exception_micro_ops_ = &all_micro_ops_[long_exception_offset];
|
||||
long_exception_micro_ops_->bus_program = bus_error_steps_;
|
||||
|
||||
// Apply the TRAP steps to the interrupt routine.
|
||||
interrupt_micro_ops_[2].bus_program = trap_steps_;
|
||||
|
||||
// Set initial state.
|
||||
active_step_ = reset_bus_steps_;
|
||||
effective_address_[0] = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user