mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 01:30:56 +00:00
Takes a run at divide-by-zero exceptions and starts looking towards ways to improve startup time.
This commit is contained in:
parent
16fb3b49a5
commit
977f9ee831
@ -779,8 +779,10 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
case Operation::DIVU: {
|
case Operation::DIVU: {
|
||||||
// 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) {
|
||||||
// TODO: schedule an exception.
|
// Schedule a divide-by-zero exception.
|
||||||
assert(false);
|
active_program_ = nullptr;
|
||||||
|
active_micro_op_ = exception_micro_ops_;
|
||||||
|
populate_trap_steps(5, get_status());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -838,8 +840,10 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
case Operation::DIVS: {
|
case Operation::DIVS: {
|
||||||
// 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) {
|
||||||
// TODO: schedule an exception.
|
// Schedule a divide-by-zero exception.
|
||||||
assert(false);
|
active_program_ = nullptr;
|
||||||
|
active_micro_op_ = exception_micro_ops_;
|
||||||
|
populate_trap_steps(5, get_status());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,8 +1077,8 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
case Operation::TRAP: {
|
case Operation::TRAP: {
|
||||||
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
|
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
|
||||||
bus_program = trap_steps_;
|
bus_program = trap_steps_;
|
||||||
bus_program->microcycle.length = HalfCycles(8);
|
|
||||||
populate_trap_steps((decoded_instruction_ & 15) + 32, get_status());
|
populate_trap_steps((decoded_instruction_ & 15) + 32, get_status());
|
||||||
|
bus_program->microcycle.length = HalfCycles(8);
|
||||||
|
|
||||||
// The program counter to push is actually one slot ago.
|
// The program counter to push is actually one slot ago.
|
||||||
program_counter_.full -= 2;
|
program_counter_.full -= 2;
|
||||||
@ -1084,8 +1088,8 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
if(overflow_flag_) {
|
if(overflow_flag_) {
|
||||||
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
|
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
|
||||||
bus_program = trap_steps_;
|
bus_program = trap_steps_;
|
||||||
bus_program->microcycle.length = HalfCycles(0);
|
|
||||||
populate_trap_steps(7, get_status());
|
populate_trap_steps(7, get_status());
|
||||||
|
bus_program->microcycle.length = HalfCycles(0);
|
||||||
program_counter_.full -= 4;
|
program_counter_.full -= 4;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1100,12 +1104,12 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
negative_flag_ = is_under ? 1 : 0;
|
negative_flag_ = is_under ? 1 : 0;
|
||||||
|
|
||||||
bus_program = trap_steps_;
|
bus_program = trap_steps_;
|
||||||
|
populate_trap_steps(6, get_status());
|
||||||
if(is_under) {
|
if(is_under) {
|
||||||
bus_program->microcycle.length = HalfCycles(16);
|
bus_program->microcycle.length = HalfCycles(16);
|
||||||
} else {
|
} else {
|
||||||
bus_program->microcycle.length = HalfCycles(8);
|
bus_program->microcycle.length = HalfCycles(8);
|
||||||
}
|
}
|
||||||
populate_trap_steps(6, get_status());
|
|
||||||
|
|
||||||
// The program counter to push is two slots ago as whatever was the correct prefetch
|
// The program counter to push is two slots ago as whatever was the correct prefetch
|
||||||
// to continue without an exception has already happened, just in case.
|
// to continue without an exception has already happened, just in case.
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace CPU {
|
namespace CPU {
|
||||||
namespace MC68000 {
|
namespace MC68000 {
|
||||||
@ -364,9 +365,33 @@ struct ProcessorStorageConstructor {
|
|||||||
return size_t(position - storage_.all_bus_steps_.begin());
|
return size_t(position - storage_.all_bus_steps_.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// If the new steps already exist, just return the existing index to them;
|
||||||
|
// otherwise insert them. A lookup table of steps to start positions within
|
||||||
|
// all_bus_steps_ is maintained to shorten setup time here
|
||||||
|
auto potential_locations = locations_by_bus_step_[steps.front()];
|
||||||
|
for(auto index: potential_locations) {
|
||||||
|
if(index + steps.size() >= storage_.all_bus_steps_.size()) continue;
|
||||||
|
|
||||||
|
if(std::equal(
|
||||||
|
storage_.all_bus_steps_.begin() + ssize_t(index),
|
||||||
|
storage_.all_bus_steps_.begin() + ssize_t(index + steps.size()),
|
||||||
|
steps.begin())) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy to the end, and update potential_locations.
|
||||||
const auto start = storage_.all_bus_steps_.size();
|
const auto start = storage_.all_bus_steps_.size();
|
||||||
std::copy(steps.begin(), steps.end(), std::back_inserter(storage_.all_bus_steps_));
|
std::copy(steps.begin(), steps.end(), std::back_inserter(storage_.all_bus_steps_));
|
||||||
|
auto index = start;
|
||||||
|
for(const auto &step: steps) {
|
||||||
|
locations_by_bus_step_[step].push_back(index);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
return start;
|
return start;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3466,10 +3491,29 @@ struct ProcessorStorageConstructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("%lu total steps\n", storage_.all_bus_steps_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProcessorStorage &storage_;
|
ProcessorStorage &storage_;
|
||||||
|
|
||||||
|
/* struct BusStepOrderer {
|
||||||
|
bool operator()( BusStep const& lhs, BusStep const& rhs ) const {
|
||||||
|
int action_diff = int(lhs.action) - int(rhs.action);
|
||||||
|
if(action_diff < 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(action_diff > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
std::make_tuple(lhs.microcycle.value, lhs.microcycle.address, lhs.microcycle.length, lhs.microcycle.operation) <
|
||||||
|
std::make_tuple(rhs.microcycle.value, rhs.microcycle.address, rhs.microcycle.length, rhs.microcycle.operation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::map<BusStep, std::vector<size_t>, BusStepOrderer> locations_by_bus_step_;*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3514,7 +3558,9 @@ CPU::MC68000::ProcessorStorage::ProcessorStorage() {
|
|||||||
all_micro_ops_.emplace_back();
|
all_micro_ops_.emplace_back();
|
||||||
|
|
||||||
// Install operations.
|
// Install operations.
|
||||||
|
const std::clock_t start = std::clock();
|
||||||
constructor.install_instructions();
|
constructor.install_instructions();
|
||||||
|
std::cout << "Construction took " << double(std::clock() - start) / double(CLOCKS_PER_SEC / 1000) << "ms" << std::endl;
|
||||||
|
|
||||||
// Realise the special programs as direct pointers.
|
// Realise the special programs as direct pointers.
|
||||||
reset_bus_steps_ = &all_bus_steps_[reset_offset];
|
reset_bus_steps_ = &all_bus_steps_[reset_offset];
|
||||||
|
@ -421,6 +421,9 @@ class ProcessorStorage {
|
|||||||
precomputed_addresses_[1] = address_[7].full - 6;
|
precomputed_addresses_[1] = address_[7].full - 6;
|
||||||
precomputed_addresses_[2] = address_[7].full - 4;
|
precomputed_addresses_[2] = address_[7].full - 4;
|
||||||
address_[7].full -= 6;
|
address_[7].full -= 6;
|
||||||
|
|
||||||
|
// Set the default timing.
|
||||||
|
trap_steps_->microcycle.length = HalfCycles(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user