From 98aa597510bb3e90d538dd20fca2be32207cf23b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Mar 2019 17:42:13 -0400 Subject: [PATCH] A theoretical 68000 could now perform its /RESET. That's all though. --- Processors/68000/68000.hpp | 29 ++++---------- .../Implementation/68000Implementation.hpp | 40 ++++++++++++++++++- .../68000/Implementation/68000Storage.cpp | 7 ++-- .../68000/Implementation/68000Storage.hpp | 13 ++---- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/Processors/68000/68000.hpp b/Processors/68000/68000.hpp index 26087b9c8..8442f7f96 100644 --- a/Processors/68000/68000.hpp +++ b/Processors/68000/68000.hpp @@ -52,6 +52,9 @@ struct Microcycle { static const int LowerData = 1 << 2; static const int ReadWrite = 1 << 3; // Set = read; unset = write. + static const int IsData = 1 << 4; // i.e. this is FC0. + static const int IsProgram = 1 << 5; // i.e. this is FC1. + int operation = 0; HalfCycles length = HalfCycles(2); @@ -72,29 +75,13 @@ struct Microcycle { */ class BusHandler { public: - static const int Data = 1 << 0; - static const int Program = 1 << 1; - static const int Supervisor = 1 << 2; - static const int Interrupt = Data | Program | Supervisor; - /*! - Provides the bus handler with a single Microcycle to 'perform', along with the - contents of the FC0, FC1 and FC2 lines by way of processor_status. The symbols - above, Data, Program, Supervisor and Interrupt can be used to help to decode the - processor status if desired; in summary: + Provides the bus handler with a single Microcycle to 'perform'. - If all three bits are set, this is an interrupt acknowledgement. - - If the data bit is set, the 68000 is fetching data. - - If the program bit is set, the 68000 is fetching instructions. - - It the supervisor bit is set, the 68000 is currently in supervisor mode. - - Neither program nor data being set has an undefined meaning. As does both program - and data being set, but this not being an interrupt. + FC0 and FC1 are provided inside the microcycle as the IsData and IsProgram + flags; FC2 is provided here as is_supervisor — it'll be either 0 or 1. */ - HalfCycles perform_bus_operation(const Microcycle &cycle, int processor_status) { + HalfCycles perform_bus_operation(const Microcycle &cycle, int is_supervisor) { return HalfCycles(0); } @@ -106,7 +93,7 @@ class BusHandler { class ProcessorBase: public ProcessorStorage { }; -template class Processor: public ProcessorBase { +template class Processor: public ProcessorBase { public: void run_for(const Cycles cycles); diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 59ff4bbd8..8c570d128 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -6,5 +6,43 @@ // Copyright © 2019 Thomas Harte. All rights reserved. // -template void Processor::run_for(Cycles cycles) { +template void Processor::run_for(Cycles cycles) { + // TODO: obey the 'cycles' count. + while(true) { + // Check whether the program is exhausted. + if(active_program_->action == Step::Action::ScheduleNextProgram) { + std::cerr << "68000 Abilities exhausted" << std::endl; + return; + } + + // The program is not exhausted, so perform the microcycle. + + // Check for DTack if this isn't being treated implicitly. + if(!dtack_is_implicit) { + if(active_program_->microcycle.operation & (Microcycle::UpperData | Microcycle::LowerData) && !dtack_) { + // TODO: perform wait state. + continue; + } + } + + // Perform the microcycle. + bus_handler_.perform_bus_operation(active_program_->microcycle, is_supervisor_); + + // Perform the post-hoc action. + switch(active_program_->action) { + default: + std::cerr << "Unimplemented 68000 action: " << int(active_program_->action) << std::endl; + return; + break; + + case Step::Action::None: break; + + case Step::Action::IncrementEffectiveAddress: effective_address_ += 2; break; + case Step::Action::IncrementProgramCounter: program_counter_.full += 2; break; + + case Step::Action::AdvancePrefetch: + prefetch_queue_[0] = prefetch_queue_[1]; + break; + } + } } diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 3db0e75da..356ec4a0a 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -16,6 +16,7 @@ ProcessorStorage::ProcessorStorage() { // Set initial state. Largely TODO. active_program_ = reset_program_.data(); effective_address_ = 0; + is_supervisor_ = 1; } // TODO: allow actions to be specified, of course. @@ -49,7 +50,7 @@ std::vector ProcessorStorage::assemble_program(const cha case 'F': // Fetch SSP MSW. case 'f': // Fetch SSP LSW. step.microcycle.length = HalfCycles(5); - step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite; + step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite | Microcycle::IsProgram; // IsProgram is a guess. step.microcycle.address = &effective_address_; step.microcycle.value = isupper(access_pattern[1]) ? &stack_pointers_[1].halves.high : &stack_pointers_[1].halves.low; steps.push_back(step); @@ -65,7 +66,7 @@ std::vector ProcessorStorage::assemble_program(const cha case 'V': // Fetch exception vector low. case 'v': // Fetch exception vector high. step.microcycle.length = HalfCycles(5); - step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite; + step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite | Microcycle::IsProgram; // IsProgram is a guess. step.microcycle.address = &effective_address_; step.microcycle.value = isupper(access_pattern[1]) ? &program_counter_.halves.high : &program_counter_.halves.low; steps.push_back(step); @@ -80,7 +81,7 @@ std::vector ProcessorStorage::assemble_program(const cha case 'p': // Fetch from the program counter into the prefetch queue. step.microcycle.length = HalfCycles(5); - step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite; + step.microcycle.operation = Microcycle::Address | Microcycle::ReadWrite | Microcycle::IsProgram; step.microcycle.address = &program_counter_.full; step.microcycle.value = &prefetch_queue_[1]; step.action = Step::Action::AdvancePrefetch; diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index 78279d075..ac90504cb 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -20,11 +20,10 @@ class ProcessorStorage { RegisterPair32 program_counter_; RegisterPair16 prefetch_queue_[2]; + bool dtack_ = true; - enum class State { - Reset, - Normal - }; + // Various status bits. + int is_supervisor_; // Generic sources and targets for memory operations. uint32_t effective_address_; @@ -64,12 +63,6 @@ class ProcessorStorage { Step *active_program_ = nullptr; private: - enum class DataSize { - Byte, Word, LongWord - }; - enum class AddressingMode { - }; - /*! Produces a vector of Steps that implement the described program.