From 674941abdf3df7bb98c08eb9575c3d44af5d26f8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 4 Oct 2021 16:45:05 -0700 Subject: [PATCH] Starts to add a disk controller. --- Machines/Amiga/Chipset.cpp | 66 +++++++++++++++++++++++++--------- Machines/Amiga/Chipset.hpp | 73 ++++++++++++++++++++++++-------------- 2 files changed, 96 insertions(+), 43 deletions(-) diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 15fc7f004..703f67ddd 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -33,20 +33,16 @@ template struct DMAMask: Mask {}; } Chipset::Chipset(MemoryMap &map, int input_clock_rate) : - cia_a_handler_(map), - cia_a(cia_a_handler_), - cia_b(cia_b_handler_), blitter_(*this, reinterpret_cast(map.chip_ram.data()), map.chip_ram.size() >> 1), bitplanes_(*this, reinterpret_cast(map.chip_ram.data()), map.chip_ram.size() >> 1), copper_(*this, reinterpret_cast(map.chip_ram.data()), map.chip_ram.size() >> 1), - drives_{ - {input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY}, - {input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY}, - {input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY}, - {input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY} - }, + disk_controller_(Cycles(input_clock_rate)), disk_(*this, reinterpret_cast(map.chip_ram.data()), map.chip_ram.size() >> 1), - crt_(908, 4, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4) { + crt_(908, 4, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4), + cia_a_handler_(map, disk_controller_), + cia_b_handler_(disk_controller_), + cia_a(cia_a_handler_), + cia_b(cia_b_handler_) { } Chipset::Changes Chipset::run_for(HalfCycles length) { @@ -920,14 +916,14 @@ Outputs::Display::DisplayType Chipset::get_display_type() const { return crt_.get_display_type(); } -// MARK: - CIA Handlers. +// MARK: - CIA A. -Chipset::CIAAHandler::CIAAHandler(MemoryMap &map) : map_(map) {} +Chipset::CIAAHandler::CIAAHandler(MemoryMap &map, DiskController &controller) : map_(map), controller_(controller) {} void Chipset::CIAAHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) { if(port) { // Parallel port output. - LOG("TODO: parallel output " << PADHEX(2) << +value); + LOG("TODO: parallel output " << PADHEX(2) << +value); } else { // b7: /FIR1 // b6: /FIR0 @@ -965,6 +961,10 @@ void Chipset::CIAAHandler::set_activity_observer(Activity::Observer *observer) { } } +// MARK: - CIA B. + +Chipset::CIABHandler::CIABHandler(DiskController &controller) : controller_(controller) {} + void Chipset::CIABHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) { if(port) { // Serial port control. @@ -990,11 +990,43 @@ void Chipset::CIABHandler::set_port_output(MOS::MOS6526::Port port, uint8_t valu // b2: /SIDE // b1: DIR // b0: /STEP - LOG("TODO: Stepping, etc; " << PADHEX(2) << +value); + LOG("TODO: Stepping, etc; " << PADHEX(2) << +value); + + controller_.set_drive((value >> 3) & 0xf); + + // "[The MTR] signal is nonstandard on the Amiga system. + // Each drive will latch the motor signal at the time its + // select signal turns on." — The Hardware Reference Manual. + + previous_select_ = value; } } -uint8_t Chipset::CIABHandler::get_port_input(MOS::MOS6526::Port) { - LOG("Unexpected input for CIA B "); - return 0xff; +uint8_t Chipset::CIABHandler::get_port_input(MOS::MOS6526::Port port) { + LOG("Unexpected input for CIA B "); + if(port) { + return 0xff; + } else { + return previous_select_; + } +} + +// MARK: - Disk Controller. + +Chipset::DiskController::DiskController(Cycles clock_rate) : + Storage::Disk::Controller(clock_rate) { + + // Add four drives. + for(int c = 0; c < 4; c++) { + emplace_drive(clock_rate.as(), 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY); + } +} + +void Chipset::DiskController::process_input_bit(int value) { + // TODO: + (void)value; +} + +void Chipset::DiskController::process_index_hole() { + // TODO: does the Amiga care? } diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 4168f6e2e..792486068 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -16,6 +16,7 @@ #include "../../Components/6526/6526.hpp" #include "../../Outputs/CRT/CRT.hpp" #include "../../Processors/68000/68000.hpp" +#include "../../Storage/Disk/Controller/DiskController.hpp" #include "../../Storage/Disk/Drive.hpp" #include "Blitter.hpp" @@ -100,31 +101,6 @@ class Chipset { cia_a_handler_.set_activity_observer(observer); } - private: - class CIAAHandler: public MOS::MOS6526::PortHandler { - public: - CIAAHandler(MemoryMap &map); - void set_port_output(MOS::MOS6526::Port port, uint8_t value); - uint8_t get_port_input(MOS::MOS6526::Port port); - void set_activity_observer(Activity::Observer *observer); - - private: - MemoryMap &map_; - Activity::Observer *observer_ = nullptr; - inline static const std::string led_name = "Power"; - } cia_a_handler_; - - struct CIABHandler: public MOS::MOS6526::PortHandler { - void set_port_output(MOS::MOS6526::Port port, uint8_t value); - uint8_t get_port_input(MOS::MOS6526::Port); - } cia_b_handler_; - - public: - // CIAs are provided for direct access; it's up to the caller properly - // to distinguish relevant accesses. - MOS::MOS6526::MOS6526 cia_a; - MOS::MOS6526::MOS6526 cia_b; - private: friend class DMADeviceBase; @@ -242,7 +218,19 @@ class Chipset { // MARK: - Disk drives. - Storage::Disk::Drive drives_[4]; + class DiskController: private Storage::Disk::Controller { + public: + DiskController(Cycles clock_rate); + + void set_drive(int index_mask) { + Storage::Disk::Controller::set_drive(index_mask); + } + + private: + void process_input_bit(int value) final; + void process_index_hole() final; + + } disk_controller_; class DiskDMA: public DMADevice<1> { public: @@ -271,6 +259,39 @@ class Chipset { Outputs::CRT::CRT crt_; uint16_t palette_[32]{}; uint16_t swizzled_palette_[32]{}; + + // MARK: - CIAs + private: + class CIAAHandler: public MOS::MOS6526::PortHandler { + public: + CIAAHandler(MemoryMap &map, DiskController &controller); + void set_port_output(MOS::MOS6526::Port port, uint8_t value); + uint8_t get_port_input(MOS::MOS6526::Port port); + void set_activity_observer(Activity::Observer *observer); + + private: + MemoryMap &map_; + DiskController &controller_; + Activity::Observer *observer_ = nullptr; + inline static const std::string led_name = "Power"; + } cia_a_handler_; + + class CIABHandler: public MOS::MOS6526::PortHandler { + public: + CIABHandler(DiskController &controller); + void set_port_output(MOS::MOS6526::Port port, uint8_t value); + uint8_t get_port_input(MOS::MOS6526::Port); + + private: + DiskController &controller_; + uint8_t previous_select_ = 0; + } cia_b_handler_; + + public: + // CIAs are provided for direct access; it's up to the caller properly + // to distinguish relevant accesses. + MOS::MOS6526::MOS6526 cia_a; + MOS::MOS6526::MOS6526 cia_b; }; }