diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme
index 610481df8..01069c685 100644
--- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme
+++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme
@@ -48,11 +48,6 @@
BlueprintName = "Clock SignalTests"
ReferencedContainer = "container:Clock Signal.xcodeproj">
-
-
-
-
diff --git a/Processors/65816/Implementation/65816Implementation.hpp b/Processors/65816/Implementation/65816Implementation.hpp
index 157563a20..5e888c359 100644
--- a/Processors/65816/Implementation/65816Implementation.hpp
+++ b/Processors/65816/Implementation/65816Implementation.hpp
@@ -50,8 +50,10 @@ template void Processorprogram_offsets[0]];
instruction_buffer_.clear();
data_buffer_.clear();
last_operation_pc_ = registers_.pc;
@@ -954,6 +956,7 @@ void ProcessorBase::set_power_on(bool active) {
pending_exceptions_ |= PowerOn;
} else {
pending_exceptions_ &= ~PowerOn;
+ selected_exceptions_ &= ~PowerOn;
}
}
diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp
index 4aa494b50..f254806f9 100644
--- a/Processors/65816/Implementation/65816Storage.cpp
+++ b/Processors/65816/Implementation/65816Storage.cpp
@@ -43,7 +43,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
typedef void (* Generator)(AccessType, bool, const std::function&);
using GeneratorKey = std::tuple;
- std::map> installed_patterns;
+ using PatternTable = std::map>;
+ PatternTable installed_patterns;
int opcode = 0;
enum class AccessMode {
@@ -51,55 +52,15 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
Always8Bit,
Always16Bit
};
+
void install(Generator generator, Operation operation, AccessMode access_mode = AccessMode::Mixed) {
// Determine the access type implied by this operation.
const AccessType access_type = access_type_for_operation(operation);
- // Check whether this access type + addressing mode generator has already been generated.
- const auto key = std::make_pair(access_type, generator);
- const auto map_entry = installed_patterns.find(key);
- size_t micro_op_location_8, micro_op_location_16;
-
- // If it wasn't found, generate it now in both 8- and 16-bit variants.
- // Otherwise, get the location of the existing entries.
- if(map_entry == installed_patterns.end()) {
- // Generate 8-bit steps.
- micro_op_location_8 = storage_.micro_ops_.size();
- (*generator)(access_type, true, [this] (MicroOp op) {
- this->storage_.micro_ops_.push_back(op);
- });
- storage_.micro_ops_.push_back(OperationMoveToNextProgram);
-
- // Generate 16-bit steps.
- micro_op_location_16 = storage_.micro_ops_.size();
- (*generator)(access_type, false, [this] (MicroOp op) {
- this->storage_.micro_ops_.push_back(op);
- });
- storage_.micro_ops_.push_back(OperationMoveToNextProgram);
-
- // Minor optimisation: elide the steps if 8- and 16-bit steps are equal.
- bool are_equal = true;
- size_t c = 0;
- while(true) {
- if(storage_.micro_ops_[micro_op_location_8 + c] != storage_.micro_ops_[micro_op_location_16 + c]) {
- are_equal = false;
- break;
- }
- if(storage_.micro_ops_[micro_op_location_8 + c] == OperationMoveToNextProgram) break;
- ++c;
- }
-
- if(are_equal) {
- storage_.micro_ops_.resize(micro_op_location_16);
- micro_op_location_16 = micro_op_location_8;
- }
-
- // Insert into the map.
- installed_patterns[key] = std::make_pair(micro_op_location_8, micro_op_location_16);
- } else {
- micro_op_location_8 = map_entry->second.first;
- micro_op_location_16 = map_entry->second.second;
- }
+ // Install the bus pattern.
+ const auto map_entry = install(generator, access_type);
+ const size_t micro_op_location_8 = map_entry->second.first;
+ const size_t micro_op_location_16 = map_entry->second.second;
// Fill in the proper table entries and increment the opcode pointer.
storage_.instructions[opcode].program_offsets[0] = (access_mode == AccessMode::Always8Bit) ? uint16_t(micro_op_location_8) : uint16_t(micro_op_location_16);
@@ -110,8 +71,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
}
void set_exception_generator(Generator generator) {
- const auto key = std::make_pair(AccessType::Read, generator);
- const auto map_entry = installed_patterns.find(key);
+ const auto map_entry = install(generator);
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[0] =
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[1] = uint16_t(map_entry->second.first);
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].operation = JMPind;
@@ -124,6 +84,57 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
storage_.micro_ops_.push_back(OperationDecode);
}
+ private:
+
+ PatternTable::iterator install(Generator generator, AccessType access_type = AccessType::Read) {
+ // Check whether this access type + addressing mode generator has already been generated.
+ const auto key = std::make_pair(access_type, generator);
+ const auto map_entry = installed_patterns.find(key);
+
+ // If it wasn't found, generate it now in both 8- and 16-bit variants.
+ // Otherwise, get the location of the existing entries.
+ if(map_entry != installed_patterns.end()) {
+ return map_entry;
+ }
+
+ // Generate 8-bit steps.
+ const size_t micro_op_location_8 = storage_.micro_ops_.size();
+ (*generator)(access_type, true, [this] (MicroOp op) {
+ this->storage_.micro_ops_.push_back(op);
+ });
+ storage_.micro_ops_.push_back(OperationMoveToNextProgram);
+
+ // Generate 16-bit steps.
+ size_t micro_op_location_16 = storage_.micro_ops_.size();
+ (*generator)(access_type, false, [this] (MicroOp op) {
+ this->storage_.micro_ops_.push_back(op);
+ });
+ storage_.micro_ops_.push_back(OperationMoveToNextProgram);
+
+ // Minor optimisation: elide the steps if 8- and 16-bit steps are equal.
+ bool are_equal = true;
+ size_t c = 0;
+ while(true) {
+ if(storage_.micro_ops_[micro_op_location_8 + c] != storage_.micro_ops_[micro_op_location_16 + c]) {
+ are_equal = false;
+ break;
+ }
+ if(storage_.micro_ops_[micro_op_location_8 + c] == OperationMoveToNextProgram) break;
+ ++c;
+ }
+
+ if(are_equal) {
+ storage_.micro_ops_.resize(micro_op_location_16);
+ micro_op_location_16 = micro_op_location_8;
+ }
+
+ // Insert into the map.
+ auto [iterator, _] = installed_patterns.insert(std::make_pair(key, std::make_pair(micro_op_location_8, micro_op_location_16)));
+ return iterator;
+ }
+
+ public:
+
/*
Code below is structured to ease translation from Table 5-7 of the 2018
edition of the WDC 65816 datasheet.
diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp
index 4edf9cf76..3dc0c55a4 100644
--- a/Processors/65816/Implementation/65816Storage.hpp
+++ b/Processors/65816/Implementation/65816Storage.hpp
@@ -292,8 +292,10 @@ struct ProcessorStorage {
static constexpr int IRQ = Flag::Interrupt; // This makes masking a lot easier later on; this is 1 << 2.
static constexpr int NMI = 1 << 3;
static constexpr int Abort = 1 << 4;
- int pending_exceptions_ = PowerOn; // By default.
- int selected_exceptions_ = 0;
+
+ static constexpr int default_exceptions = PowerOn;
+ int pending_exceptions_ = default_exceptions;
+ int selected_exceptions_ = default_exceptions;
bool ready_line_ = false;
bool memory_lock_ = false;